SurfaceFlinger: Dont show Animation on External Display
- With this change the animation effect will not be shown on
external display.
- It will change from portrait to landscape in one shot.
- Primary would still continue the animation effect
- set property sys.disable_ext_animation to disable animation
CRs-fixed: 453747
Conflicts:
services/surfaceflinger/DisplayHardware/HWComposer.cpp
services/surfaceflinger/DisplayHardware/HWComposer.h
Conflicts:
services/surfaceflinger/DisplayHardware/HWComposer.cpp
Change-Id: Ibd94bf166f08eeab1d504afe69230f7c6a617eb6
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 273d190..9d6199f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -521,42 +521,50 @@
event, disp, enabled);
return;
}
- if (event != EVENT_VSYNC) {
- ALOGW("eventControl got unexpected event %d (disp=%d en=%d)",
- event, disp, enabled);
- return;
- }
status_t err = NO_ERROR;
- if (mHwc && !mDebugForceFakeVSync) {
- // NOTE: we use our own internal lock here because we have to call
- // into the HWC with the lock held, and we want to make sure
- // that even if HWC blocks (which it shouldn't), it won't
- // affect other threads.
- Mutex::Autolock _l(mEventControlLock);
- const int32_t eventBit = 1UL << event;
- const int32_t newValue = enabled ? eventBit : 0;
- const int32_t oldValue = mDisplayData[disp].events & eventBit;
- if (newValue != oldValue) {
- ATRACE_CALL();
- err = mHwc->eventControl(mHwc, disp, event, enabled);
- if (!err) {
- int32_t& events(mDisplayData[disp].events);
- events = (events & ~eventBit) | newValue;
+ switch(event) {
+ case EVENT_VSYNC:
+ if (mHwc && !mDebugForceFakeVSync) {
+ // NOTE: we use our own internal lock here because we have to
+ // call into the HWC with the lock held, and we want to make
+ // sure that even if HWC blocks (which it shouldn't), it won't
+ // affect other threads.
+ Mutex::Autolock _l(mEventControlLock);
+ const int32_t eventBit = 1UL << event;
+ const int32_t newValue = enabled ? eventBit : 0;
+ const int32_t oldValue = mDisplayData[disp].events & eventBit;
+ if (newValue != oldValue) {
+ ATRACE_CALL();
+ err = mHwc->eventControl(mHwc, disp, event, enabled);
+ if (!err) {
+ int32_t& events(mDisplayData[disp].events);
+ events = (events & ~eventBit) | newValue;
- char tag[16];
- snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", disp);
- ATRACE_INT(tag, enabled);
+ char tag[16];
+ snprintf(tag, sizeof(tag), "HW_VSYNC_ON_%1u", disp);
+ ATRACE_INT(tag, enabled);
+ }
+ }
+ // error here should not happen -- not sure what we should
+ // do if it does.
+ ALOGE_IF(err, "eventControl(%d, %d) failed %s",
+ event, enabled, strerror(-err));
}
- }
- // error here should not happen -- not sure what we should
- // do if it does.
- ALOGE_IF(err, "eventControl(%d, %d) failed %s",
- event, enabled, strerror(-err));
- }
- if (err == NO_ERROR && mVSyncThread != NULL) {
- mVSyncThread->setEnabled(enabled);
+ if (err == NO_ERROR && mVSyncThread != NULL) {
+ mVSyncThread->setEnabled(enabled);
+ }
+ break;
+ case EVENT_ORIENTATION:
+ // Orientation event
+ err = mHwc->eventControl(mHwc, disp, event, enabled);
+ break;
+ default:
+ ALOGW("eventControl got unexpected event %d (disp=%d en=%d)",
+ event, disp, enabled);
+ break;
}
+ return;
}
status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
@@ -689,13 +697,14 @@
disp.hasFbComp = false;
disp.hasOvComp = false;
if (disp.list) {
- for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {
- hwc_layer_1_t& l = disp.list->hwLayers[i];
+ for (size_t j=0 ; j<disp.list->numHwLayers ; j++) {
+ hwc_layer_1_t& l = disp.list->hwLayers[j];
//ALOGD("prepare: %d, type=%d, handle=%p",
- // i, l.compositionType, l.handle);
+ // j, l.compositionType, l.handle);
- if (l.flags & HWC_SKIP_LAYER) {
+ if ((i == DisplayDevice::DISPLAY_PRIMARY) &&
+ l.flags & HWC_SKIP_LAYER) {
l.compositionType = HWC_FRAMEBUFFER;
}
if (l.compositionType == HWC_FRAMEBUFFER) {
@@ -1001,6 +1010,13 @@
}
}
}
+ virtual void setAnimating(bool animating) {
+ if (animating) {
+ getLayer()->flags |= HWC_SCREENSHOT_ANIMATOR_LAYER;
+ } else {
+ getLayer()->flags &= ~HWC_SCREENSHOT_ANIMATOR_LAYER;
+ }
+ }
virtual void setBlending(uint32_t blending) {
getLayer()->blending = blending;
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 79674d5..16c0f04 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -166,6 +166,7 @@
virtual void setDefaultState() = 0;
virtual void setSkip(bool skip) = 0;
virtual void setIsCursorLayerHint(bool isCursor = true) = 0;
+ virtual void setAnimating(bool animating) = 0;
virtual void setBlending(uint32_t blending) = 0;
virtual void setTransform(uint32_t transform) = 0;
virtual void setFrame(const Rect& frame) = 0;
@@ -249,7 +250,8 @@
// Events handling ---------------------------------------------------------
enum {
- EVENT_VSYNC = HWC_EVENT_VSYNC
+ EVENT_VSYNC = HWC_EVENT_VSYNC,
+ EVENT_ORIENTATION = HWC_EVENT_ORIENTATION
};
void eventControl(int disp, int event, int enabled);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f8bf368..cf9845f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1066,6 +1066,26 @@
sp<const DisplayDevice> hw(mDisplays[dpy]);
const int32_t id = hw->getHwcDisplayId();
if (id >= 0) {
+ // Get the layers in the current drawying state
+ const LayerVector& layers(mDrawingState.layersSortedByZ);
+ bool freezeSurfacePresent = false;
+ const size_t layerCount = layers.size();
+ char value[PROPERTY_VALUE_MAX];
+ property_get("sys.disable_ext_animation", value, "0");
+ if(atoi(value)) {
+ for (size_t i = 0 ; i < layerCount ; ++i) {
+ static int screenShotLen = strlen("ScreenshotSurface");
+ const sp<Layer>& layer(layers[i]);
+ if(!strncmp(layer->getName(), "ScreenshotSurface",
+ screenShotLen)) {
+ // Screenshot layer is present, and animation in
+ // progress
+ freezeSurfacePresent = true;
+ break;
+ }
+ }
+ }
+
const Vector< sp<Layer> >& currentLayers(
hw->getVisibleLayersSortedByZ());
const size_t count = currentLayers.size();
@@ -1078,6 +1098,26 @@
*/
const sp<Layer>& layer(currentLayers[i]);
layer->setPerFrameData(hw, *cur);
+ if(freezeSurfacePresent) {
+ // if freezeSurfacePresent, set ANIMATING flag
+ cur->setAnimating(true);
+ } else {
+ const KeyedVector<wp<IBinder>, DisplayDeviceState>&
+ draw(mDrawingState.displays);
+ size_t dc = draw.size();
+ for (size_t i=0 ; i<dc ; i++) {
+ if (draw[i].isMainDisplay()) {
+ HWComposer& hwc(getHwComposer());
+ if (hwc.initCheck() == NO_ERROR)
+ // Pass the current orientation to HWC
+ // which will be used to block animation
+ // on external
+ hwc.eventControl(HWC_DISPLAY_PRIMARY,
+ SurfaceFlinger::EVENT_ORIENTATION,
+ uint32_t(draw[i].orientation));
+ }
+ }
+ }
}
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 2790ac1..53b616c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -98,7 +98,8 @@
void run() ANDROID_API;
enum {
- EVENT_VSYNC = HWC_EVENT_VSYNC
+ EVENT_VSYNC = HWC_EVENT_VSYNC,
+ EVENT_ORIENTATION = HWC_EVENT_ORIENTATION
};
// post an asynchronous message to the main thread