Skip to content

Commit

Permalink
sf: Use Dirty Rect optimization in "Show Surface Updates" setting
Browse files Browse the repository at this point in the history
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.

Change-Id: Id280cc2a22d46cc6539316d6dd0856e328c14c9e
CRs-Fixed: 679386
  • Loading branch information
Sravan Kumar D.V.N authored and hyperb1iss committed Jul 14, 2014
1 parent 87ab443 commit 24165a2
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 30 deletions.
84 changes: 57 additions & 27 deletions services/surfaceflinger/SurfaceFlinger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ SurfaceFlinger::SurfaceFlinger()
mLastTransactionTime(0),
mBootFinished(false),
mUseDithering(false),
mGpuTileRenderEnable(false),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
mDaltonize(false),
mGpuTileRenderEnable(false)
mDaltonize(false)
{
ALOGI("SurfaceFlinger is starting");

Expand All @@ -183,10 +183,12 @@ SurfaceFlinger::SurfaceFlinger()
}
}
#ifdef QCOM_BSP
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");
Expand Down Expand Up @@ -933,11 +935,24 @@ void SurfaceFlinger::handleMessageInvalidate() {
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();
Expand All @@ -953,19 +968,43 @@ void SurfaceFlinger::doDebugFlashRegions()
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp<DisplayDevice>& hw(mDisplays[dpy]);
if (hw->canDraw()) {
// 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());
}
}
}
}
Expand Down Expand Up @@ -1902,20 +1941,19 @@ void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
}

#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
Expand All @@ -1928,22 +1966,14 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
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",
hw->getDisplayName().string());
return;
}
#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);
Expand Down Expand Up @@ -1977,11 +2007,11 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
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
Expand Down Expand Up @@ -2033,9 +2063,9 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
* 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);
Expand Down Expand Up @@ -2089,7 +2119,7 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
#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);
}
}
Expand Down
10 changes: 7 additions & 3 deletions services/surfaceflinger/SurfaceFlinger.h
Original file line number Diff line number Diff line change
Expand Up @@ -497,11 +497,15 @@ class SurfaceFlinger : public BnSurfaceComposer,

// Set if the Gpu Tile render DR optimization enabled
bool mGpuTileRenderEnable;
bool mCanUseGpuTileRender;
Rect mUnionDirtyRect;

#ifdef QCOM_BSP
// Set up the DirtyRect/flags for GPU Comp optimization if required.
void setUpTiledDr();
// Find out if GPU composition can use Dirtyregion optimization
// Get the mode individual layer Dirty rect / union dirty rect to operate &
// the dirty region
bool computeTiledDr(const sp<const DisplayDevice>& hw,Rect& dirtyRect);
// Get the union dirty rect to operate
bool computeTiledDr(const sp<const DisplayDevice>& hw);
enum {
GL_PRESERVE_NONE = 0,
GL_PRESERVE = 1
Expand Down

0 comments on commit 24165a2

Please sign in to comment.