Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3d922ad authored by Sravan Kumar D.V.N's avatar Sravan Kumar D.V.N Committed by Linux Build Service Account
Browse files

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
parent 260f6015
Loading
Loading
Loading
Loading
+59 −28
Original line number Diff line number Diff line
@@ -152,11 +152,11 @@ SurfaceFlinger::SurfaceFlinger()
        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 @@ SurfaceFlinger::SurfaceFlinger()
        }
    }
#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 @@ 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();
@@ -887,23 +902,48 @@ void SurfaceFlinger::doDebugFlashRegions()
    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 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
                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
                const int32_t height = hw->getHeight();
                RenderEngine& engine(getRenderEngine());
                engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
#ifdef QCOM_BSP
                   if(mGpuTileRenderEnable)
                       hw->eglSwapPreserved(false);
#endif

                   engine.fillRegionWithColor(dirtyRegion, height, 1, 0, 1, 1);
                   hw->compositionComplete();
                   hw->swapBuffers(getHwComposer());
               }
            }
        }
    }

    postFramebuffer();

@@ -1950,20 +1990,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
@@ -1976,10 +2015,8 @@ bool 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",
@@ -1990,12 +2027,6 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
            }
            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 @@ bool 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
@@ -2085,9 +2116,9 @@ bool 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);
@@ -2142,7 +2173,7 @@ bool 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);
            }
        }
+7 −3
Original line number Diff line number Diff line
@@ -482,11 +482,15 @@ private:

    // 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