surfaceflinger: Replace blank/unblank with setPowerMode
We replace the blank/unblank calls in surfaceFlinger with a more generic setPowerMode() routine. Some displays support different power modes (for example, with reduced color palettes). Depending on the use case we should be able to toggle these modes, so as to achieve incremental power savings. Initially, three power modes will be supported: - HWC_POWER_MODE_OFF - HWC_POWER_MODE_DOZE - HWC_POWER_MODE_NORMAL HWC_POWER_MODE_OFF will correspond to blanking the display, while HWC_POWER_MODE_NORMAL will correspond to unblanking. HWC_POWER_MODE_DOZE will put the display into a low power setting, if it is supported in hardware. If such a low power mode is not supported, it should be treated as a call to set the mode to HWC_POWER_MODE_NORMAL. As a consequence of adding the mPowerMode field, the mScreenAcquired is no longer required, and thus references to it are removed and replaced equivalent references to mPowerMode. We also add the glue code to connect the services invocation of setting a power mode and the HAL implementation in HWComposer. Bug: 13472578 Change-Id: I431595ecf16d2f2c94259272db3dd42f29636204 Signed-off-by: Prashant Malani <pmalani@google.com>
This commit is contained in:
parent
edcf7f4d3a
commit
2c9b11f029
|
@ -104,15 +104,11 @@ public:
|
||||||
virtual bool authenticateSurfaceTexture(
|
virtual bool authenticateSurfaceTexture(
|
||||||
const sp<IGraphicBufferProducer>& surface) const = 0;
|
const sp<IGraphicBufferProducer>& surface) const = 0;
|
||||||
|
|
||||||
/* triggers screen off and waits for it to complete
|
/* set display power mode. depending on the mode, it can either trigger
|
||||||
|
* screen on, off or low power mode and wait for it to complete.
|
||||||
* requires ACCESS_SURFACE_FLINGER permission.
|
* requires ACCESS_SURFACE_FLINGER permission.
|
||||||
*/
|
*/
|
||||||
virtual void blank(const sp<IBinder>& display) = 0;
|
virtual void setPowerMode(const sp<IBinder>& display, int mode) = 0;
|
||||||
|
|
||||||
/* triggers screen on and waits for it to complete
|
|
||||||
* requires ACCESS_SURFACE_FLINGER permission.
|
|
||||||
*/
|
|
||||||
virtual void unblank(const sp<IBinder>& display) = 0;
|
|
||||||
|
|
||||||
/* returns information for each configuration of the given display
|
/* returns information for each configuration of the given display
|
||||||
* intended to be used to get information about built-in displays */
|
* intended to be used to get information about built-in displays */
|
||||||
|
@ -165,15 +161,14 @@ public:
|
||||||
GET_BUILT_IN_DISPLAY,
|
GET_BUILT_IN_DISPLAY,
|
||||||
SET_TRANSACTION_STATE,
|
SET_TRANSACTION_STATE,
|
||||||
AUTHENTICATE_SURFACE,
|
AUTHENTICATE_SURFACE,
|
||||||
BLANK,
|
|
||||||
UNBLANK,
|
|
||||||
GET_DISPLAY_CONFIGS,
|
GET_DISPLAY_CONFIGS,
|
||||||
GET_ACTIVE_CONFIG,
|
GET_ACTIVE_CONFIG,
|
||||||
SET_ACTIVE_CONFIG,
|
SET_ACTIVE_CONFIG,
|
||||||
CONNECT_DISPLAY,
|
CONNECT_DISPLAY,
|
||||||
CAPTURE_SCREEN,
|
CAPTURE_SCREEN,
|
||||||
CLEAR_ANIMATION_FRAME_STATS,
|
CLEAR_ANIMATION_FRAME_STATS,
|
||||||
GET_ANIMATION_FRAME_STATS
|
GET_ANIMATION_FRAME_STATS,
|
||||||
|
SET_POWER_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual status_t onTransact(uint32_t code, const Parcel& data,
|
virtual status_t onTransact(uint32_t code, const Parcel& data,
|
||||||
|
|
|
@ -82,11 +82,8 @@ public:
|
||||||
// returned by getDisplayInfo
|
// returned by getDisplayInfo
|
||||||
static status_t setActiveConfig(const sp<IBinder>& display, int id);
|
static status_t setActiveConfig(const sp<IBinder>& display, int id);
|
||||||
|
|
||||||
/* triggers screen off and waits for it to complete */
|
/* Triggers screen on/off or low power mode and waits for it to complete */
|
||||||
static void blankDisplay(const sp<IBinder>& display);
|
static void setDisplayPowerMode(const sp<IBinder>& display, int mode);
|
||||||
|
|
||||||
/* triggers screen on and waits for it to complete */
|
|
||||||
static void unblankDisplay(const sp<IBinder>& display);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// surface creation / destruction
|
// surface creation / destruction
|
||||||
|
|
|
@ -205,20 +205,13 @@ public:
|
||||||
return reply.readStrongBinder();
|
return reply.readStrongBinder();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void blank(const sp<IBinder>& display)
|
virtual void setPowerMode(const sp<IBinder>& display, int mode)
|
||||||
{
|
{
|
||||||
Parcel data, reply;
|
Parcel data, reply;
|
||||||
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
|
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
|
||||||
data.writeStrongBinder(display);
|
data.writeStrongBinder(display);
|
||||||
remote()->transact(BnSurfaceComposer::BLANK, data, &reply);
|
data.writeInt32(mode);
|
||||||
}
|
remote()->transact(BnSurfaceComposer::SET_POWER_MODE, data, &reply);
|
||||||
|
|
||||||
virtual void unblank(const sp<IBinder>& display)
|
|
||||||
{
|
|
||||||
Parcel data, reply;
|
|
||||||
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
|
|
||||||
data.writeStrongBinder(display);
|
|
||||||
remote()->transact(BnSurfaceComposer::UNBLANK, data, &reply);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
|
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
|
||||||
|
@ -378,18 +371,6 @@ status_t BnSurfaceComposer::onTransact(
|
||||||
reply->writeStrongBinder(display);
|
reply->writeStrongBinder(display);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
case BLANK: {
|
|
||||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
|
||||||
sp<IBinder> display = data.readStrongBinder();
|
|
||||||
blank(display);
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
case UNBLANK: {
|
|
||||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
|
||||||
sp<IBinder> display = data.readStrongBinder();
|
|
||||||
unblank(display);
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
case GET_DISPLAY_CONFIGS: {
|
case GET_DISPLAY_CONFIGS: {
|
||||||
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
Vector<DisplayInfo> configs;
|
Vector<DisplayInfo> configs;
|
||||||
|
@ -434,6 +415,13 @@ status_t BnSurfaceComposer::onTransact(
|
||||||
reply->writeInt32(result);
|
reply->writeInt32(result);
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
case SET_POWER_MODE: {
|
||||||
|
CHECK_INTERFACE(ISurfaceComposer, data, reply);
|
||||||
|
sp<IBinder> display = data.readStrongBinder();
|
||||||
|
int32_t mode = data.readInt32();
|
||||||
|
setPowerMode(display, mode);
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
return BBinder::onTransact(code, data, reply, flags);
|
return BBinder::onTransact(code, data, reply, flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -655,12 +655,9 @@ status_t SurfaceComposerClient::setActiveConfig(const sp<IBinder>& display, int
|
||||||
return ComposerService::getComposerService()->setActiveConfig(display, id);
|
return ComposerService::getComposerService()->setActiveConfig(display, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceComposerClient::blankDisplay(const sp<IBinder>& token) {
|
void SurfaceComposerClient::setDisplayPowerMode(const sp<IBinder>& token,
|
||||||
ComposerService::getComposerService()->blank(token);
|
int mode) {
|
||||||
}
|
ComposerService::getComposerService()->setPowerMode(token, mode);
|
||||||
|
|
||||||
void SurfaceComposerClient::unblankDisplay(const sp<IBinder>& token) {
|
|
||||||
ComposerService::getComposerService()->unblank(token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t SurfaceComposerClient::clearAnimationFrameStats() {
|
status_t SurfaceComposerClient::clearAnimationFrameStats() {
|
||||||
|
|
|
@ -70,9 +70,9 @@ DisplayDevice::DisplayDevice(
|
||||||
mPageFlipCount(),
|
mPageFlipCount(),
|
||||||
mIsSecure(isSecure),
|
mIsSecure(isSecure),
|
||||||
mSecureLayerVisible(false),
|
mSecureLayerVisible(false),
|
||||||
mScreenAcquired(false),
|
|
||||||
mLayerStack(NO_LAYER_STACK),
|
mLayerStack(NO_LAYER_STACK),
|
||||||
mOrientation()
|
mOrientation(),
|
||||||
|
mPowerMode(HWC_POWER_MODE_OFF)
|
||||||
{
|
{
|
||||||
mNativeWindow = new Surface(producer, false);
|
mNativeWindow = new Surface(producer, false);
|
||||||
ANativeWindow* const window = mNativeWindow.get();
|
ANativeWindow* const window = mNativeWindow.get();
|
||||||
|
@ -109,7 +109,8 @@ DisplayDevice::DisplayDevice(
|
||||||
mFrame.makeInvalid();
|
mFrame.makeInvalid();
|
||||||
|
|
||||||
// virtual displays are always considered enabled
|
// virtual displays are always considered enabled
|
||||||
mScreenAcquired = (mType >= DisplayDevice::DISPLAY_VIRTUAL);
|
mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
|
||||||
|
HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
|
||||||
|
|
||||||
// Name the display. The name will be replaced shortly if the display
|
// Name the display. The name will be replaced shortly if the display
|
||||||
// was created with createDisplay().
|
// was created with createDisplay().
|
||||||
|
@ -322,21 +323,16 @@ Region DisplayDevice::getDirtyRegion(bool repaintEverything) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
void DisplayDevice::setPowerMode(int mode) {
|
||||||
bool DisplayDevice::canDraw() const {
|
mPowerMode = mode;
|
||||||
return mScreenAcquired;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayDevice::releaseScreen() const {
|
int DisplayDevice::getPowerMode() const {
|
||||||
mScreenAcquired = false;
|
return mPowerMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayDevice::acquireScreen() const {
|
bool DisplayDevice::isDisplayOn() const {
|
||||||
mScreenAcquired = true;
|
return (mPowerMode != HWC_POWER_MODE_OFF);
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayDevice::isScreenAcquired() const {
|
|
||||||
return mScreenAcquired;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -465,13 +461,13 @@ void DisplayDevice::dump(String8& result) const {
|
||||||
result.appendFormat(
|
result.appendFormat(
|
||||||
"+ DisplayDevice: %s\n"
|
"+ DisplayDevice: %s\n"
|
||||||
" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
|
" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
|
||||||
"flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%zu\n"
|
"flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, numLayers=%zu\n"
|
||||||
" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
|
" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
|
||||||
"transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
|
"transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
|
||||||
mDisplayName.string(), mType, mHwcDisplayId,
|
mDisplayName.string(), mType, mHwcDisplayId,
|
||||||
mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
|
mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
|
||||||
mOrientation, tr.getType(), getPageFlipCount(),
|
mOrientation, tr.getType(), getPageFlipCount(),
|
||||||
mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
|
mIsSecure, mSecureLayerVisible, mPowerMode, mVisibleLayersSortedByZ.size(),
|
||||||
mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
|
mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
|
||||||
mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
|
mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
|
||||||
mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
|
mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
|
||||||
|
|
|
@ -147,12 +147,11 @@ public:
|
||||||
void setViewportAndProjection() const;
|
void setViewportAndProjection() const;
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
/* ------------------------------------------------------------------------
|
||||||
* blank / unblank management
|
* Display power mode management.
|
||||||
*/
|
*/
|
||||||
void releaseScreen() const;
|
int getPowerMode() const;
|
||||||
void acquireScreen() const;
|
void setPowerMode(int mode);
|
||||||
bool isScreenAcquired() const;
|
bool isDisplayOn() const;
|
||||||
bool canDraw() const;
|
|
||||||
|
|
||||||
// release HWC resources (if any) for removable displays
|
// release HWC resources (if any) for removable displays
|
||||||
void disconnect(HWComposer& hwc);
|
void disconnect(HWComposer& hwc);
|
||||||
|
@ -197,9 +196,6 @@ private:
|
||||||
// Whether we have a visible secure layer on this display
|
// Whether we have a visible secure layer on this display
|
||||||
bool mSecureLayerVisible;
|
bool mSecureLayerVisible;
|
||||||
|
|
||||||
// Whether the screen is blanked;
|
|
||||||
mutable int mScreenAcquired;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transaction state
|
* Transaction state
|
||||||
|
@ -217,6 +213,8 @@ private:
|
||||||
Rect mScissor;
|
Rect mScissor;
|
||||||
Transform mGlobalTransform;
|
Transform mGlobalTransform;
|
||||||
bool mNeedsFiltering;
|
bool mNeedsFiltering;
|
||||||
|
// Current power mode
|
||||||
|
int mPowerMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // namespace android
|
}; // namespace android
|
||||||
|
|
|
@ -759,19 +759,18 @@ status_t HWComposer::commit() {
|
||||||
return (status_t)err;
|
return (status_t)err;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t HWComposer::release(int disp) {
|
status_t HWComposer::setPowerMode(int disp, int mode) {
|
||||||
LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
|
LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
|
||||||
if (mHwc) {
|
if (mHwc) {
|
||||||
eventControl(disp, HWC_EVENT_VSYNC, 0);
|
if (mode == HWC_POWER_MODE_OFF) {
|
||||||
return (status_t)mHwc->blank(mHwc, disp, 1);
|
eventControl(disp, HWC_EVENT_VSYNC, 0);
|
||||||
}
|
}
|
||||||
return NO_ERROR;
|
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
|
||||||
}
|
return (status_t)mHwc->setPowerMode(mHwc, disp, mode);
|
||||||
|
} else {
|
||||||
status_t HWComposer::acquire(int disp) {
|
return (status_t)mHwc->blank(mHwc, disp,
|
||||||
LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
|
mode == HWC_POWER_MODE_OFF ? 1 : 0);
|
||||||
if (mHwc) {
|
}
|
||||||
return (status_t)mHwc->blank(mHwc, disp, 0);
|
|
||||||
}
|
}
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,11 +97,8 @@ public:
|
||||||
// commits the list
|
// commits the list
|
||||||
status_t commit();
|
status_t commit();
|
||||||
|
|
||||||
// release hardware resources and blank screen
|
// set power mode
|
||||||
status_t release(int disp);
|
status_t setPowerMode(int disp, int mode);
|
||||||
|
|
||||||
// acquire hardware resources and unblank screen
|
|
||||||
status_t acquire(int disp);
|
|
||||||
|
|
||||||
// reset state when an external, non-virtual display is disconnected
|
// reset state when an external, non-virtual display is disconnected
|
||||||
void disconnectDisplay(int disp);
|
void disconnectDisplay(int disp);
|
||||||
|
|
|
@ -437,7 +437,7 @@ void SurfaceFlinger::init() {
|
||||||
// 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 %zu as acquired/unblanked", i);
|
ALOGD("marking display %zu as acquired/unblanked", i);
|
||||||
hw->acquireScreen();
|
hw->setPowerMode(HWC_POWER_MODE_NORMAL);
|
||||||
}
|
}
|
||||||
mDisplays.add(token, hw);
|
mDisplays.add(token, hw);
|
||||||
}
|
}
|
||||||
|
@ -793,7 +793,7 @@ void SurfaceFlinger::doDebugFlashRegions()
|
||||||
const bool repaintEverything = mRepaintEverything;
|
const bool repaintEverything = mRepaintEverything;
|
||||||
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
||||||
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
||||||
if (hw->canDraw()) {
|
if (hw->isDisplayOn()) {
|
||||||
// transform the dirty region into this screen's coordinate space
|
// transform the dirty region into this screen's coordinate space
|
||||||
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
|
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
|
||||||
if (!dirtyRegion.isEmpty()) {
|
if (!dirtyRegion.isEmpty()) {
|
||||||
|
@ -860,7 +860,7 @@ void SurfaceFlinger::postComposition()
|
||||||
|
|
||||||
if (runningWithoutSyncFramework) {
|
if (runningWithoutSyncFramework) {
|
||||||
const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
|
const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
|
||||||
if (hw->isScreenAcquired()) {
|
if (hw->isDisplayOn()) {
|
||||||
enableHardwareVsync();
|
enableHardwareVsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -895,7 +895,7 @@ void SurfaceFlinger::rebuildLayerStacks() {
|
||||||
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
||||||
const Transform& tr(hw->getTransform());
|
const Transform& tr(hw->getTransform());
|
||||||
const Rect bounds(hw->getBounds());
|
const Rect bounds(hw->getBounds());
|
||||||
if (hw->canDraw()) {
|
if (hw->isDisplayOn()) {
|
||||||
SurfaceFlinger::computeVisibleRegions(layers,
|
SurfaceFlinger::computeVisibleRegions(layers,
|
||||||
hw->getLayerStack(), dirtyRegion, opaqueRegion);
|
hw->getLayerStack(), dirtyRegion, opaqueRegion);
|
||||||
|
|
||||||
|
@ -991,7 +991,7 @@ void SurfaceFlinger::doComposition() {
|
||||||
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
|
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
|
||||||
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
|
||||||
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
const sp<DisplayDevice>& hw(mDisplays[dpy]);
|
||||||
if (hw->canDraw()) {
|
if (hw->isDisplayOn()) {
|
||||||
// transform the dirty region into this screen's coordinate space
|
// transform the dirty region into this screen's coordinate space
|
||||||
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
|
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
|
||||||
|
|
||||||
|
@ -2082,7 +2082,7 @@ void SurfaceFlinger::onInitializeDisplays() {
|
||||||
d.viewport.makeInvalid();
|
d.viewport.makeInvalid();
|
||||||
displays.add(d);
|
displays.add(d);
|
||||||
setTransactionState(state, displays, 0);
|
setTransactionState(state, displays, 0);
|
||||||
onScreenAcquired(getDefaultDisplayDevice());
|
setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
|
||||||
|
|
||||||
const nsecs_t period =
|
const nsecs_t period =
|
||||||
getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
|
getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
|
||||||
|
@ -2103,42 +2103,35 @@ void SurfaceFlinger::initializeDisplays() {
|
||||||
postMessageAsync(msg); // we may be called from main thread, use async message
|
postMessageAsync(msg); // we may be called from main thread, use async message
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
|
||||||
|
int mode) {
|
||||||
|
ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
|
||||||
|
this);
|
||||||
|
int32_t type = hw->getDisplayType();
|
||||||
|
int currentMode = hw->getPowerMode();
|
||||||
|
|
||||||
void SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {
|
if (mode == currentMode) {
|
||||||
ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this);
|
ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
|
||||||
if (hw->isScreenAcquired()) {
|
|
||||||
// this is expected, e.g. when power manager wakes up during boot
|
|
||||||
ALOGD(" screen was previously acquired");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
hw->acquireScreen();
|
hw->setPowerMode(mode);
|
||||||
int32_t type = hw->getDisplayType();
|
if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
|
||||||
if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
|
ALOGW("Trying to set power mode for virtual display");
|
||||||
// built-in display, tell the HWC
|
return;
|
||||||
getHwComposer().acquire(type);
|
}
|
||||||
|
|
||||||
|
if (currentMode == HWC_POWER_MODE_OFF) {
|
||||||
|
getHwComposer().setPowerMode(type, mode);
|
||||||
if (type == DisplayDevice::DISPLAY_PRIMARY) {
|
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->onScreenAcquired();
|
mEventThread->onScreenAcquired();
|
||||||
|
|
||||||
resyncToHardwareVsync(true);
|
resyncToHardwareVsync(true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
mVisibleRegionsDirty = true;
|
|
||||||
repaintEverything();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) {
|
mVisibleRegionsDirty = true;
|
||||||
ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this);
|
repaintEverything();
|
||||||
if (!hw->isScreenAcquired()) {
|
} else if (mode == HWC_POWER_MODE_OFF) {
|
||||||
ALOGD(" screen was previously released");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hw->releaseScreen();
|
|
||||||
int32_t type = hw->getDisplayType();
|
|
||||||
if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
|
|
||||||
if (type == DisplayDevice::DISPLAY_PRIMARY) {
|
if (type == DisplayDevice::DISPLAY_PRIMARY) {
|
||||||
disableHardwareVsync(true); // also cancels any in-progress resync
|
disableHardwareVsync(true); // also cancels any in-progress resync
|
||||||
|
|
||||||
|
@ -2146,56 +2139,38 @@ void SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) {
|
||||||
mEventThread->onScreenReleased();
|
mEventThread->onScreenReleased();
|
||||||
}
|
}
|
||||||
|
|
||||||
// built-in display, tell the HWC
|
getHwComposer().setPowerMode(type, mode);
|
||||||
getHwComposer().release(type);
|
mVisibleRegionsDirty = true;
|
||||||
|
// from this point on, SF will stop drawing on this display
|
||||||
|
} else {
|
||||||
|
getHwComposer().setPowerMode(type, mode);
|
||||||
}
|
}
|
||||||
mVisibleRegionsDirty = true;
|
|
||||||
// from this point on, SF will stop drawing on this display
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::unblank(const sp<IBinder>& display) {
|
void SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
|
||||||
class MessageScreenAcquired : public MessageBase {
|
class MessageSetPowerMode: public MessageBase {
|
||||||
SurfaceFlinger& mFlinger;
|
SurfaceFlinger& mFlinger;
|
||||||
sp<IBinder> mDisplay;
|
sp<IBinder> mDisplay;
|
||||||
|
int mMode;
|
||||||
public:
|
public:
|
||||||
MessageScreenAcquired(SurfaceFlinger& flinger,
|
MessageSetPowerMode(SurfaceFlinger& flinger,
|
||||||
const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
|
const sp<IBinder>& disp, int mode) : mFlinger(flinger),
|
||||||
|
mDisplay(disp) { mMode = mode; }
|
||||||
virtual bool handler() {
|
virtual bool handler() {
|
||||||
const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
|
sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
|
||||||
if (hw == NULL) {
|
if (hw == NULL) {
|
||||||
ALOGE("Attempt to unblank null display %p", mDisplay.get());
|
ALOGE("Attempt to set power mode = %d for null display %p",
|
||||||
|
mDisplay.get(), mMode);
|
||||||
} else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
|
} else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
|
||||||
ALOGW("Attempt to unblank virtual display");
|
ALOGW("Attempt to set power mode = %d for virtual display",
|
||||||
|
mMode);
|
||||||
} else {
|
} else {
|
||||||
mFlinger.onScreenAcquired(hw);
|
mFlinger.setPowerModeInternal(hw, mMode);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
sp<MessageBase> msg = new MessageScreenAcquired(*this, display);
|
sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
|
||||||
postMessageSync(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SurfaceFlinger::blank(const sp<IBinder>& display) {
|
|
||||||
class MessageScreenReleased : public MessageBase {
|
|
||||||
SurfaceFlinger& mFlinger;
|
|
||||||
sp<IBinder> mDisplay;
|
|
||||||
public:
|
|
||||||
MessageScreenReleased(SurfaceFlinger& flinger,
|
|
||||||
const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
|
|
||||||
virtual bool handler() {
|
|
||||||
const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
|
|
||||||
if (hw == NULL) {
|
|
||||||
ALOGE("Attempt to blank null display %p", mDisplay.get());
|
|
||||||
} else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
|
|
||||||
ALOGW("Attempt to blank virtual display");
|
|
||||||
} else {
|
|
||||||
mFlinger.onScreenReleased(hw);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
sp<MessageBase> msg = new MessageScreenReleased(*this, display);
|
|
||||||
postMessageSync(msg);
|
postMessageSync(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2456,8 +2431,8 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
|
||||||
mRenderEngine->dump(result);
|
mRenderEngine->dump(result);
|
||||||
|
|
||||||
hw->undefinedRegion.dump(result, "undefinedRegion");
|
hw->undefinedRegion.dump(result, "undefinedRegion");
|
||||||
result.appendFormat(" orientation=%d, canDraw=%d\n",
|
result.appendFormat(" orientation=%d, isDisplayOn=%d\n",
|
||||||
hw->getOrientation(), hw->canDraw());
|
hw->getOrientation(), hw->isDisplayOn());
|
||||||
result.appendFormat(
|
result.appendFormat(
|
||||||
" last eglSwapBuffers() time: %f us\n"
|
" last eglSwapBuffers() time: %f us\n"
|
||||||
" last transaction time : %f us\n"
|
" last transaction time : %f us\n"
|
||||||
|
@ -2549,10 +2524,9 @@ status_t SurfaceFlinger::onTransact(
|
||||||
case CREATE_DISPLAY:
|
case CREATE_DISPLAY:
|
||||||
case SET_TRANSACTION_STATE:
|
case SET_TRANSACTION_STATE:
|
||||||
case BOOT_FINISHED:
|
case BOOT_FINISHED:
|
||||||
case BLANK:
|
|
||||||
case UNBLANK:
|
|
||||||
case CLEAR_ANIMATION_FRAME_STATS:
|
case CLEAR_ANIMATION_FRAME_STATS:
|
||||||
case GET_ANIMATION_FRAME_STATS:
|
case GET_ANIMATION_FRAME_STATS:
|
||||||
|
case SET_POWER_MODE:
|
||||||
{
|
{
|
||||||
// codes that require permission check
|
// codes that require permission check
|
||||||
IPCThreadState* ipc = IPCThreadState::self();
|
IPCThreadState* ipc = IPCThreadState::self();
|
||||||
|
|
|
@ -205,13 +205,10 @@ private:
|
||||||
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
|
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
|
||||||
uint32_t minLayerZ, uint32_t maxLayerZ,
|
uint32_t minLayerZ, uint32_t maxLayerZ,
|
||||||
bool useIdentityTransform);
|
bool useIdentityTransform);
|
||||||
// called when screen needs to turn off
|
|
||||||
virtual void blank(const sp<IBinder>& display);
|
|
||||||
// called when screen is turning back on
|
|
||||||
virtual void unblank(const sp<IBinder>& display);
|
|
||||||
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
|
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
|
||||||
Vector<DisplayInfo>* configs);
|
Vector<DisplayInfo>* configs);
|
||||||
virtual int getActiveConfig(const sp<IBinder>& display);
|
virtual int getActiveConfig(const sp<IBinder>& display);
|
||||||
|
virtual void setPowerMode(const sp<IBinder>& display, int mode);
|
||||||
virtual status_t setActiveConfig(const sp<IBinder>& display, int id);
|
virtual status_t setActiveConfig(const sp<IBinder>& display, int id);
|
||||||
virtual status_t clearAnimationFrameStats();
|
virtual status_t clearAnimationFrameStats();
|
||||||
virtual status_t getAnimationFrameStats(FrameStats* outStats) const;
|
virtual status_t getAnimationFrameStats(FrameStats* outStats) const;
|
||||||
|
@ -242,10 +239,8 @@ private:
|
||||||
|
|
||||||
// called on the main thread in response to initializeDisplays()
|
// called on the main thread in response to initializeDisplays()
|
||||||
void onInitializeDisplays();
|
void onInitializeDisplays();
|
||||||
// called on the main thread in response to blank()
|
// called on the main thread in response to setPowerMode()
|
||||||
void onScreenReleased(const sp<const DisplayDevice>& hw);
|
void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode);
|
||||||
// called on the main thread in response to unblank()
|
|
||||||
void onScreenAcquired(const sp<const DisplayDevice>& hw);
|
|
||||||
|
|
||||||
void handleMessageTransaction();
|
void handleMessageTransaction();
|
||||||
void handleMessageInvalidate();
|
void handleMessageInvalidate();
|
||||||
|
|
Loading…
Reference in New Issue