sf: Use Dirty Rect optimization in "Show Surface Updates" setting
When "Show Surface Updates" setting is ON in developer options, flash the
updating part (union dirty rect) instead of full layers when
GPU Tiled DR optimization is ON.
CRs-Fixed: 679386
Change-Id: Id280cc2a22d46cc6539316d6dd0856e328c14c9e
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4b39f70..09e0849 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -152,11 +152,11 @@
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
+ mGpuTileRenderEnable(false),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mDaltonize(false),
- mHasColorMatrix(false),
- mGpuTileRenderEnable(false)
+ mHasColorMatrix(false)
{
ALOGI("SurfaceFlinger is starting");
@@ -178,10 +178,12 @@
}
}
#ifdef QCOM_BSP
- property_get("debug.sf.gpu_comp_tiling", value, "1");
+ mCanUseGpuTileRender = false;
+ property_get("debug.sf.gpu_comp_tiling", value, "0");
mGpuTileRenderEnable = atoi(value) ? true : false;
if(mGpuTileRenderEnable)
ALOGV("DirtyRect optimization enabled for FULL GPU Composition");
+ mUnionDirtyRect.clear();
#endif
ALOGI_IF(mDebugRegion, "showupdates enabled");
@@ -868,11 +870,24 @@
handlePageFlip();
}
+#ifdef QCOM_BSP
+/* Compute DirtyRegion, if DR optimization for GPU comp optimization
+ * is ON & and no external device is connected.*/
+void SurfaceFlinger::setUpTiledDr() {
+ if(mGpuTileRenderEnable && (mDisplays.size()==1)) {
+ const sp<DisplayDevice>& hw(mDisplays[HWC_DISPLAY_PRIMARY]);
+ mCanUseGpuTileRender = computeTiledDr(hw);
+ }
+}
+#endif
void SurfaceFlinger::handleMessageRefresh() {
ATRACE_CALL();
preComposition();
rebuildLayerStacks();
setUpHWComposer();
+#ifdef QCOM_BSP
+ setUpTiledDr();
+#endif
doDebugFlashRegions();
doComposition();
postComposition();
@@ -887,20 +902,45 @@
const bool repaintEverything = mRepaintEverything;
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp<DisplayDevice>& hw(mDisplays[dpy]);
+
if (hw->isDisplayOn()) {
- // transform the dirty region into this screen's coordinate space
- const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
- if (!dirtyRegion.isEmpty()) {
+ const int32_t height = hw->getHeight();
+ RenderEngine& engine(getRenderEngine());
+#ifdef QCOM_BSP
+ // Use Union DR, if it is valid & GPU Tiled DR optimization is ON
+ if(mCanUseGpuTileRender && !mUnionDirtyRect.isEmpty()) {
// redraw the whole screen
doComposeSurfaces(hw, Region(hw->bounds()));
-
+ Region dirtyRegion(mUnionDirtyRect);
+ Rect dr = mUnionDirtyRect;
+ hw->eglSwapPreserved(true);
+ engine.startTileComposition(dr.left, (height-dr.bottom),
+ (dr.right-dr.left),
+ (dr.bottom-dr.top), 1);
// and draw the dirty region
- const int32_t height = hw->getHeight();
- RenderEngine& engine(getRenderEngine());
engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
-
+ engine.endTileComposition(GL_PRESERVE);
hw->compositionComplete();
hw->swapBuffers(getHwComposer());
+ } else
+#endif
+ {
+ // transform the dirty region into this screen's coordinate
+ // space
+ const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
+ if (!dirtyRegion.isEmpty()) {
+ // redraw the whole screen
+ doComposeSurfaces(hw, Region(hw->bounds()));
+ // and draw the dirty region
+#ifdef QCOM_BSP
+ if(mGpuTileRenderEnable)
+ hw->eglSwapPreserved(false);
+#endif
+
+ engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
+ hw->compositionComplete();
+ hw->swapBuffers(getHwComposer());
+ }
}
}
}
@@ -1950,20 +1990,19 @@
}
#ifdef QCOM_BSP
-bool SurfaceFlinger::computeTiledDr(const sp<const DisplayDevice>& hw,
- Rect& unionDirtyRect) {
+bool SurfaceFlinger::computeTiledDr(const sp<const DisplayDevice>& hw) {
int fbWidth= hw->getWidth();
int fbHeight= hw->getHeight();
Rect fullScreenRect = Rect(0,0,fbWidth, fbHeight);
const int32_t id = hw->getHwcDisplayId();
- unionDirtyRect.clear();
+ mUnionDirtyRect.clear();
HWComposer& hwc(getHwComposer());
/* Compute and return the Union of Dirty Rects.
* Return false if the unionDR is fullscreen, as there is no benefit from
* preserving full screen.*/
- return (hwc.canUseTiledDR(id, unionDirtyRect) &&
- (unionDirtyRect != fullScreenRect));
+ return (hwc.canUseTiledDR(id, mUnionDirtyRect) &&
+ (mUnionDirtyRect != fullScreenRect));
}
#endif
@@ -1976,10 +2015,8 @@
HWComposer::LayerListIterator cur = hwc.begin(id);
const HWComposer::LayerListIterator end = hwc.end(id);
- Rect unionDirtyRect;
Region clearRegion;
bool hasGlesComposition = hwc.hasGlesComposition(id);
- bool canUseGpuTileRender = false;
if (hasGlesComposition) {
if (!hw->makeCurrent(mEGLDisplay, mEGLContext)) {
ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
@@ -1990,12 +2027,6 @@
}
return false;
}
-#ifdef QCOM_BSP
- /* Compute DirtyRegion , if DR optimization for GPU comp optimization
- * is ON & device is primary.*/
- if(mGpuTileRenderEnable && (mDisplays.size()==1))
- canUseGpuTileRender = computeTiledDr(hw, unionDirtyRect);
-#endif
// Never touch the framebuffer if we don't have any framebuffer layers
const bool hasHwcComposition = hwc.hasHwcComposition(id);
@@ -2029,11 +2060,11 @@
clearRegion = region;
if (cur == end) {
drawWormhole(hw, region);
- } else if(canUseGpuTileRender) {
+ } else if(mCanUseGpuTileRender) {
/* If GPUTileRect DR optimization on clear only the UnionDR
* (computed by computeTiledDr) which is the actual region
* that will be drawn on FB in this cycle.. */
- clearRegion = clearRegion.andSelf(Region(unionDirtyRect));
+ clearRegion = clearRegion.andSelf(Region(mUnionDirtyRect));
}
} else
#endif
@@ -2085,9 +2116,9 @@
* ii) do startTile with union DirtyRect
* else , Disable EGL_SWAP_PRESERVED */
if(mGpuTileRenderEnable && (mDisplays.size()==1)) {
- if(canUseGpuTileRender) {
+ if(mCanUseGpuTileRender && !mUnionDirtyRect.isEmpty()) {
hw->eglSwapPreserved(true);
- Rect dr = unionDirtyRect;
+ Rect dr = mUnionDirtyRect;
engine.startTileComposition(dr.left, (fbHeight-dr.bottom),
(dr.right-dr.left),
(dr.bottom-dr.top), 0);
@@ -2142,7 +2173,7 @@
#ifdef QCOM_BSP
// call EndTile, if starTile has been called in this cycle.
if(mGpuTileRenderEnable && (mDisplays.size()==1)) {
- if(canUseGpuTileRender) {
+ if(mCanUseGpuTileRender && !mUnionDirtyRect.isEmpty()) {
engine.endTileComposition(GL_PRESERVE);
}
}