Pass display arg to blank/unblank

This allows us to blank and unblank displays other than the built-in
display (e.g. HDMI).

Bug: 7240511
Change-Id: I89ea13f9e497be74c3e1231d0c62fb558e93e0f8
This commit is contained in:
Andy McFadden 2012-09-27 16:02:06 -07:00
parent 4c2732779a
commit c01a79d77b
6 changed files with 92 additions and 51 deletions

View File

@ -99,10 +99,10 @@ public:
/* triggers screen off and waits for it to complete */ /* triggers screen off and waits for it to complete */
virtual void blank() = 0; virtual void blank(const sp<IBinder>& display) = 0;
/* triggers screen on and waits for it to complete */ /* triggers screen on and waits for it to complete */
virtual void unblank() = 0; virtual void unblank(const sp<IBinder>& display) = 0;
/* returns information about a display /* returns information about a display
* intended to be used to get information about built-in displays */ * intended to be used to get information about built-in displays */

View File

@ -197,17 +197,19 @@ public:
return reply.readStrongBinder(); return reply.readStrongBinder();
} }
virtual void blank() virtual void blank(const sp<IBinder>& display)
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeStrongBinder(display);
remote()->transact(BnSurfaceComposer::BLANK, data, &reply); remote()->transact(BnSurfaceComposer::BLANK, data, &reply);
} }
virtual void unblank() virtual void unblank(const sp<IBinder>& display)
{ {
Parcel data, reply; Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeStrongBinder(display);
remote()->transact(BnSurfaceComposer::UNBLANK, data, &reply); remote()->transact(BnSurfaceComposer::UNBLANK, data, &reply);
} }
@ -320,11 +322,13 @@ status_t BnSurfaceComposer::onTransact(
} break; } break;
case BLANK: { case BLANK: {
CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply);
blank(); sp<IBinder> display = data.readStrongBinder();
blank(display);
} break; } break;
case UNBLANK: { case UNBLANK: {
CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply);
unblank(); sp<IBinder> display = data.readStrongBinder();
unblank(display);
} break; } break;
case GET_DISPLAY_INFO: { case GET_DISPLAY_INFO: {
CHECK_INTERFACE(ISurfaceComposer, data, reply); CHECK_INTERFACE(ISurfaceComposer, data, reply);

View File

@ -646,17 +646,19 @@ status_t HWComposer::commit() {
return (status_t)err; return (status_t)err;
} }
status_t HWComposer::release() const { status_t HWComposer::release(int disp) const {
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
if (mHwc) { if (mHwc) {
mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0); mHwc->eventControl(mHwc, disp, HWC_EVENT_VSYNC, 0);
return (status_t)mHwc->blank(mHwc, 0, 1); return (status_t)mHwc->blank(mHwc, disp, 1);
} }
return NO_ERROR; return NO_ERROR;
} }
status_t HWComposer::acquire() const { status_t HWComposer::acquire(int disp) const {
LOG_FATAL_IF(disp >= HWC_NUM_DISPLAY_TYPES);
if (mHwc) { if (mHwc) {
return (status_t)mHwc->blank(mHwc, 0, 0); return (status_t)mHwc->blank(mHwc, disp, 0);
} }
return NO_ERROR; return NO_ERROR;
} }

View File

@ -92,10 +92,10 @@ public:
status_t commit(); status_t commit();
// release hardware resources and blank screen // release hardware resources and blank screen
status_t release() const; status_t release(int disp) const;
// acquire hardware resources and unblank screen // acquire hardware resources and unblank screen
status_t acquire() const; status_t acquire(int disp) const;
// create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED. // create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
status_t createWorkList(int32_t id, size_t numLayers); status_t createWorkList(int32_t id, size_t numLayers);

View File

@ -490,11 +490,11 @@ status_t SurfaceFlinger::readyToRun()
static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue())); static_cast< sp<ISurfaceTexture> >(fbs->getBufferQueue()));
sp<DisplayDevice> hw = new DisplayDevice(this, sp<DisplayDevice> hw = new DisplayDevice(this,
type, token, stc, fbs, mEGLConfig); type, token, stc, fbs, mEGLConfig);
if (i > DisplayDevice::DISPLAY_PRIMARY) { if (i > DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: currently we don't really handle blank/unblank // FIXME: currently we don't get blank/unblank requests
// for displays other than the main display, so we always // for displays other than the main display, so we always
// assume a connected display is unblanked. // assume a connected display is unblanked.
ALOGD("marking display %d as acquired/unblanked", i);
hw->acquireScreen(); hw->acquireScreen();
} }
mDisplays.add(token, hw); mDisplays.add(token, hw);
@ -1972,59 +1972,94 @@ void SurfaceFlinger::initializeDisplays() {
void SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) { void SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {
ALOGD("Screen about to return, flinger = %p", this); ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this);
getHwComposer().acquire(); if (hw->isScreenAcquired()) {
// this is expected, e.g. when power manager wakes up during boot
ALOGD(" screen was previously acquired");
return;
}
hw->acquireScreen(); hw->acquireScreen();
if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) { int32_t type = hw->getDisplayType();
// FIXME: eventthread only knows about the main display right now if (type < DisplayDevice::NUM_DISPLAY_TYPES) {
mEventThread->onScreenAcquired(); // built-in display, tell the HWC
getHwComposer().acquire(type);
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenAcquired();
}
} }
mVisibleRegionsDirty = true; mVisibleRegionsDirty = true;
repaintEverything(); repaintEverything();
} }
void SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) { void SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) {
ALOGD("About to give-up screen, flinger = %p", this); ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this);
if (hw->isScreenAcquired()) { if (!hw->isScreenAcquired()) {
if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) { ALOGD(" screen was previously released");
return;
}
hw->releaseScreen();
int32_t type = hw->getDisplayType();
if (type < DisplayDevice::NUM_DISPLAY_TYPES) {
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: eventthread only knows about the main display right now // FIXME: eventthread only knows about the main display right now
mEventThread->onScreenReleased(); mEventThread->onScreenReleased();
} }
hw->releaseScreen();
getHwComposer().release(); // built-in display, tell the HWC
mVisibleRegionsDirty = true; getHwComposer().release(type);
// from this point on, SF will stop drawing }
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
}
void SurfaceFlinger::unblank(const sp<IBinder>& display) {
class MessageScreenAcquired : public MessageBase {
SurfaceFlinger* mFlinger;
const sp<DisplayDevice>& mHw;
public:
MessageScreenAcquired(SurfaceFlinger* flinger,
const sp<DisplayDevice>& hw) : mFlinger(flinger), mHw(hw) { }
virtual bool handler() {
mFlinger->onScreenAcquired(mHw);
return true;
}
};
const sp<DisplayDevice>& hw = getDisplayDevice(display);
if (hw == NULL) {
ALOGE("Attempt to unblank null display %p", display.get());
} else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) {
ALOGW("Attempt to unblank virtual display");
} else {
sp<MessageBase> msg = new MessageScreenAcquired(this, hw);
postMessageSync(msg);
} }
} }
void SurfaceFlinger::unblank() { void SurfaceFlinger::blank(const sp<IBinder>& display) {
class MessageScreenAcquired : public MessageBase {
SurfaceFlinger* flinger;
public:
MessageScreenAcquired(SurfaceFlinger* flinger) : flinger(flinger) { }
virtual bool handler() {
// FIXME: should this be per-display?
flinger->onScreenAcquired(flinger->getDefaultDisplayDevice());
return true;
}
};
sp<MessageBase> msg = new MessageScreenAcquired(this);
postMessageSync(msg);
}
void SurfaceFlinger::blank() {
class MessageScreenReleased : public MessageBase { class MessageScreenReleased : public MessageBase {
SurfaceFlinger* flinger; SurfaceFlinger* mFlinger;
const sp<DisplayDevice>& mHw;
public: public:
MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { } MessageScreenReleased(SurfaceFlinger* flinger,
const sp<DisplayDevice>& hw) : mFlinger(flinger), mHw(hw) { }
virtual bool handler() { virtual bool handler() {
// FIXME: should this be per-display? mFlinger->onScreenReleased(mHw);
flinger->onScreenReleased(flinger->getDefaultDisplayDevice());
return true; return true;
} }
}; };
sp<MessageBase> msg = new MessageScreenReleased(this); const sp<DisplayDevice>& hw = getDisplayDevice(display);
postMessageSync(msg); if (hw == NULL) {
ALOGE("Attempt to blank null display %p", display.get());
} else if (hw->getDisplayType() >= DisplayDevice::NUM_DISPLAY_TYPES) {
ALOGW("Attempt to blank virtual display");
} else {
sp<MessageBase> msg = new MessageScreenReleased(this, hw);
postMessageSync(msg);
}
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -196,9 +196,9 @@ private:
uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ,
uint32_t maxLayerZ); uint32_t maxLayerZ);
// called when screen needs to turn off // called when screen needs to turn off
virtual void blank(); virtual void blank(const sp<IBinder>& display);
// called when screen is turning back on // called when screen is turning back on
virtual void unblank(); virtual void unblank(const sp<IBinder>& display);
virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info); virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info);
virtual void connectDisplay(const sp<ISurfaceTexture>& display); virtual void connectDisplay(const sp<ISurfaceTexture>& display);