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 */
virtual void blank() = 0;
virtual void blank(const sp<IBinder>& display) = 0;
/* 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
* intended to be used to get information about built-in displays */

View File

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

View File

@ -646,17 +646,19 @@ status_t HWComposer::commit() {
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) {
mHwc->eventControl(mHwc, HWC_DISPLAY_PRIMARY, HWC_EVENT_VSYNC, 0);
return (status_t)mHwc->blank(mHwc, 0, 1);
mHwc->eventControl(mHwc, disp, HWC_EVENT_VSYNC, 0);
return (status_t)mHwc->blank(mHwc, disp, 1);
}
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) {
return (status_t)mHwc->blank(mHwc, 0, 0);
return (status_t)mHwc->blank(mHwc, disp, 0);
}
return NO_ERROR;
}

View File

@ -92,10 +92,10 @@ public:
status_t commit();
// release hardware resources and blank screen
status_t release() const;
status_t release(int disp) const;
// 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.
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()));
sp<DisplayDevice> hw = new DisplayDevice(this,
type, token, stc, fbs, mEGLConfig);
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
// assume a connected display is unblanked.
ALOGD("marking display %d as acquired/unblanked", i);
hw->acquireScreen();
}
mDisplays.add(token, hw);
@ -1972,59 +1972,94 @@ void SurfaceFlinger::initializeDisplays() {
void SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {
ALOGD("Screen about to return, flinger = %p", this);
getHwComposer().acquire();
ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this);
if (hw->isScreenAcquired()) {
// this is expected, e.g. when power manager wakes up during boot
ALOGD(" screen was previously acquired");
return;
}
hw->acquireScreen();
if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenAcquired();
int32_t type = hw->getDisplayType();
if (type < DisplayDevice::NUM_DISPLAY_TYPES) {
// 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;
repaintEverything();
}
void SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) {
ALOGD("About to give-up screen, flinger = %p", this);
if (hw->isScreenAcquired()) {
if (hw->getDisplayType() == DisplayDevice::DISPLAY_PRIMARY) {
ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this);
if (!hw->isScreenAcquired()) {
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
mEventThread->onScreenReleased();
}
hw->releaseScreen();
getHwComposer().release();
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing
// built-in display, tell the HWC
getHwComposer().release(type);
}
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() {
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() {
void SurfaceFlinger::blank(const sp<IBinder>& display) {
class MessageScreenReleased : public MessageBase {
SurfaceFlinger* flinger;
SurfaceFlinger* mFlinger;
const sp<DisplayDevice>& mHw;
public:
MessageScreenReleased(SurfaceFlinger* flinger) : flinger(flinger) { }
MessageScreenReleased(SurfaceFlinger* flinger,
const sp<DisplayDevice>& hw) : mFlinger(flinger), mHw(hw) { }
virtual bool handler() {
// FIXME: should this be per-display?
flinger->onScreenReleased(flinger->getDefaultDisplayDevice());
mFlinger->onScreenReleased(mHw);
return true;
}
};
sp<MessageBase> msg = new MessageScreenReleased(this);
postMessageSync(msg);
const sp<DisplayDevice>& hw = getDisplayDevice(display);
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 maxLayerZ);
// called when screen needs to turn off
virtual void blank();
virtual void blank(const sp<IBinder>& display);
// 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 void connectDisplay(const sp<ISurfaceTexture>& display);