summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/gui/DisplayEventReceiver.h9
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp2
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h1
-rw-r--r--services/surfaceflinger/EventThread.cpp51
-rw-r--r--services/surfaceflinger/EventThread.h4
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp17
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h1
7 files changed, 65 insertions, 20 deletions
diff --git a/include/gui/DisplayEventReceiver.h b/include/gui/DisplayEventReceiver.h
index e631cca..1117f95 100644
--- a/include/gui/DisplayEventReceiver.h
+++ b/include/gui/DisplayEventReceiver.h
@@ -40,7 +40,8 @@ class IDisplayEventConnection;
class DisplayEventReceiver {
public:
enum {
- DISPLAY_EVENT_VSYNC = 'vsyn'
+ DISPLAY_EVENT_VSYNC = 'vsyn',
+ DISPLAY_EVENT_HOTPLUG = 'plug'
};
struct Event {
@@ -54,9 +55,15 @@ public:
uint32_t count;
};
+ struct Hotplug {
+ int32_t id;
+ bool connected;
+ };
+
Header header;
union {
VSync vsync;
+ Hotplug hotplug;
};
};
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index caec250..09ac78d 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -305,7 +305,7 @@ void HWComposer::hotplug(int disp, int connected) {
if (connected)
queryDisplayProperties(disp);
- // TODO: tell someone else about this
+ mEventHandler.onHotplugReceived(disp, bool(connected));
}
static const uint32_t DISPLAY_ATTRIBUTES[] = {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 4156332..ff39bc1 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -56,6 +56,7 @@ public:
class EventHandler {
friend class HWComposer;
virtual void onVSyncReceived(int disp, nsecs_t timestamp) = 0;
+ virtual void onHotplugReceived(int disp, bool connected) = 0;
protected:
virtual ~EventHandler() {}
};
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index 19e711e..6e7424e 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -106,19 +106,30 @@ void EventThread::onScreenAcquired() {
}
-void EventThread::onVSyncReceived(const wp<IBinder>&, nsecs_t timestamp) {
+void EventThread::onVSyncReceived(int type, nsecs_t timestamp) {
Mutex::Autolock _l(mLock);
mVSyncTimestamp = timestamp;
mVSyncCount++;
mCondition.broadcast();
}
+void EventThread::onHotplugReceived(int type, bool connected) {
+ Mutex::Autolock _l(mLock);
+ DisplayEventReceiver::Event event;
+ event.header.type = DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG;
+ event.header.timestamp = systemTime();
+ event.hotplug.id = type;
+ event.hotplug.connected = connected;
+ mPendingEvents.add(event);
+ mCondition.broadcast();
+}
+
bool EventThread::threadLoop() {
DisplayEventReceiver::Event vsync;
Vector< sp<EventThread::Connection> > signalConnections;
signalConnections = waitForEvent(&vsync);
- // dispatch vsync events to listeners...
+ // dispatch events to listeners...
const size_t count = signalConnections.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Connection>& conn(signalConnections[i]);
@@ -146,18 +157,29 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
DisplayEventReceiver::Event* event)
{
Mutex::Autolock _l(mLock);
-
- size_t vsyncCount;
- nsecs_t timestamp;
Vector< sp<EventThread::Connection> > signalConnections;
do {
- // latch VSYNC event if any
+ bool eventPending = false;
bool waitForVSync = false;
- vsyncCount = mVSyncCount;
- timestamp = mVSyncTimestamp;
+ size_t vsyncCount = mVSyncCount;
+ nsecs_t timestamp = mVSyncTimestamp;
mVSyncTimestamp = 0;
+ if (timestamp) {
+ // we have a vsync event to dispatch
+ event->header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
+ event->header.timestamp = timestamp;
+ event->vsync.count = vsyncCount;
+ } else {
+ eventPending = !mPendingEvents.isEmpty();
+ if (eventPending) {
+ // we have some other event to dispatch
+ *event = mPendingEvents[0];
+ mPendingEvents.removeAt(0);
+ }
+ }
+
// find out connections waiting for events
size_t count = mDisplayEventConnections.size();
for (size_t i=0 ; i<count ; i++) {
@@ -179,6 +201,11 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
// continuous event, and time to report it
signalConnections.add(connection);
}
+ } else if (eventPending) {
+ // we don't have a vsync event to process
+ // (timestamp==0), but we have some pending
+ // messages.
+ signalConnections.add(connection);
}
}
} else {
@@ -206,7 +233,7 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
// note: !timestamp implies signalConnections.isEmpty(), because we
// don't populate signalConnections if there's no vsync pending
- if (!timestamp) {
+ if (!timestamp && !eventPending) {
// wait for something to happen
if (waitForVSync) {
// This is where we spend most of our time, waiting
@@ -241,12 +268,6 @@ Vector< sp<EventThread::Connection> > EventThread::waitForEvent(
// here we're guaranteed to have a timestamp and some connections to signal
// (The connections might have dropped out of mDisplayEventConnections
// while we were asleep, but we'll still have strong references to them.)
-
- // fill in vsync event info
- event->header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
- event->header.timestamp = timestamp;
- event->vsync.count = vsyncCount;
-
return signalConnections;
}
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index a92ba5c..1c6e637 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -76,7 +76,8 @@ public:
void onScreenAcquired();
// called when receiving a vsync event
- void onVSyncReceived(const wp<IBinder>& display, nsecs_t timestamp);
+ void onVSyncReceived(int type, nsecs_t timestamp);
+ void onHotplugReceived(int type, bool connected);
Vector< sp<EventThread::Connection> > waitForEvent(
DisplayEventReceiver::Event* event);
@@ -100,6 +101,7 @@ private:
// protected by mLock
SortedVector< wp<Connection> > mDisplayEventConnections;
+ Vector< DisplayEventReceiver::Event > mPendingEvents;
nsecs_t mVSyncTimestamp;
bool mUseSoftwareVSync;
size_t mVSyncCount;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index bd587f2..427e46f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -671,8 +671,21 @@ void SurfaceFlinger::onVSyncReceived(int type, nsecs_t timestamp) {
}
if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
// we should only receive DisplayDevice::DisplayType from the vsync callback
- const wp<IBinder>& token(mDefaultDisplays[type]);
- mEventThread->onVSyncReceived(token, timestamp);
+ mEventThread->onVSyncReceived(type, timestamp);
+ }
+}
+
+void SurfaceFlinger::onHotplugReceived(int type, bool connected) {
+ if (mEventThread == NULL) {
+ // This is a temporary workaround for b/7145521. A non-null pointer
+ // does not mean EventThread has finished initializing, so this
+ // is not a correct fix.
+ ALOGW("WARNING: EventThread not started, ignoring hotplug");
+ return;
+ }
+ if (uint32_t(type) < DisplayDevice::NUM_DISPLAY_TYPES) {
+ // we should only receive DisplayDevice::DisplayType from the vsync callback
+ mEventThread->onHotplugReceived(type, connected);
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 80f5d4b..c9877b2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -218,6 +218,7 @@ private:
* HWComposer::EventHandler interface
*/
virtual void onVSyncReceived(int type, nsecs_t timestamp);
+ virtual void onHotplugReceived(int disp, bool connected);
/* ------------------------------------------------------------------------
* Message handling