summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2014-08-20 20:02:02 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-08-20 20:02:02 +0000
commitd4548dd0272f5a4edee1d7ff070458728848b35c (patch)
tree74519947a8abf33eae5f9ff76f2d6e8cb45bcb86 /services
parent4d7c41008d0945b58d802e04d0bea28e9b739a5f (diff)
parent514e30a96cefad109509ce01622fa7f82f3f318c (diff)
downloadframeworks_native-d4548dd0272f5a4edee1d7ff070458728848b35c.zip
frameworks_native-d4548dd0272f5a4edee1d7ff070458728848b35c.tar.gz
frameworks_native-d4548dd0272f5a4edee1d7ff070458728848b35c.tar.bz2
am 514e30a9: am c3d1889e: Merge "surfaceflinger: skip composition for empty frames" into klp-modular-dev
* commit '514e30a96cefad109509ce01622fa7f82f3f318c': surfaceflinger: skip composition for empty frames
Diffstat (limited to 'services')
-rw-r--r--services/surfaceflinger/DisplayDevice.cpp3
-rw-r--r--services/surfaceflinger/DisplayDevice.h1
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp27
3 files changed, 28 insertions, 3 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 05f500e..bf42b77 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -59,7 +59,8 @@ DisplayDevice::DisplayDevice(
const sp<DisplaySurface>& displaySurface,
const sp<IGraphicBufferProducer>& producer,
EGLConfig config)
- : mFlinger(flinger),
+ : lastCompositionHadVisibleLayers(false),
+ mFlinger(flinger),
mType(type), mHwcDisplayId(hwcId),
mDisplayToken(displayToken),
mDisplaySurface(displaySurface),
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 00e0918..d3f784a 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -53,6 +53,7 @@ public:
mutable Region swapRegion;
// region in screen space
Region undefinedRegion;
+ bool lastCompositionHadVisibleLayers;
enum DisplayType {
DISPLAY_ID_INVALID = -1,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b9c70e0..4070f03 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -987,9 +987,32 @@ void SurfaceFlinger::rebuildLayerStacks() {
void SurfaceFlinger::setUpHWComposer() {
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
- bool mustRecompose =
- !(mDisplays[dpy]->getDirtyRegion(false).isEmpty());
+ bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
+ bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
+ bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;
+
+ // If nothing has changed (!dirty), don't recompose.
+ // If something changed, but we don't currently have any visible layers,
+ // and didn't when we last did a composition, then skip it this time.
+ // The second rule does two things:
+ // - When all layers are removed from a display, we'll emit one black
+ // frame, then nothing more until we get new layers.
+ // - When a display is created with a private layer stack, we won't
+ // emit any black frames until a layer is added to the layer stack.
+ bool mustRecompose = dirty && !(empty && wasEmpty);
+
+ ALOGV_IF(mDisplays[dpy]->getDisplayType() == DisplayDevice::DISPLAY_VIRTUAL,
+ "dpy[%zu]: %s composition (%sdirty %sempty %swasEmpty)", dpy,
+ mustRecompose ? "doing" : "skipping",
+ dirty ? "+" : "-",
+ empty ? "+" : "-",
+ wasEmpty ? "+" : "-");
+
mDisplays[dpy]->beginFrame(mustRecompose);
+
+ if (mustRecompose) {
+ mDisplays[dpy]->lastCompositionHadVisibleLayers = !empty;
+ }
}
HWComposer& hwc(getHwComposer());