diff options
author | Jesse Hall <jessehall@google.com> | 2014-08-20 19:52:40 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-08-20 19:52:40 +0000 |
commit | 514e30a96cefad109509ce01622fa7f82f3f318c (patch) | |
tree | 256a554d3b92a7c09a723a8532df6d09e6a0a753 /services | |
parent | 2eaec5a833f69b3c460386e38aa6affe5e4b1772 (diff) | |
parent | c3d1889e508038efe240ed1974ed377a2e12835c (diff) | |
download | frameworks_native-514e30a96cefad109509ce01622fa7f82f3f318c.zip frameworks_native-514e30a96cefad109509ce01622fa7f82f3f318c.tar.gz frameworks_native-514e30a96cefad109509ce01622fa7f82f3f318c.tar.bz2 |
am c3d1889e: Merge "surfaceflinger: skip composition for empty frames" into klp-modular-dev
* commit 'c3d1889e508038efe240ed1974ed377a2e12835c':
surfaceflinger: skip composition for empty frames
Diffstat (limited to 'services')
-rw-r--r-- | services/surfaceflinger/DisplayDevice.cpp | 3 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayDevice.h | 1 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 27 |
3 files changed, 28 insertions, 3 deletions
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index f9034a6..3d46d14 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 f750c6c..620e598 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 3c447db..6bfebb8 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -882,9 +882,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()); |