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

Commit 8add8021 authored by Romain Guy's avatar Romain Guy Committed by Android (Google) Code Review
Browse files

Merge "Add an on-screen overdraw counter"

parents 9473f0cd 78dd96d5
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -274,6 +274,18 @@ class GLES20Canvas extends HardwareCanvas {

    private static native int nGetStencilSize();

    void setCountOverdrawEnabled(boolean enabled) {
        nSetCountOverdrawEnabled(mRenderer, enabled);
    }

    static native void nSetCountOverdrawEnabled(int renderer, boolean enabled);

    float getOverdraw() {
        return nGetOverdraw(mRenderer);
    }

    static native float nGetOverdraw(int renderer);

    ///////////////////////////////////////////////////////////////////////////
    // Functor
    ///////////////////////////////////////////////////////////////////////////
+6 −1
Original line number Diff line number Diff line
@@ -100,12 +100,17 @@ class GLES20RenderLayer extends GLES20Layer {

    @Override
    HardwareCanvas start(Canvas currentCanvas) {
        return start(currentCanvas, null);
    }

    @Override
    HardwareCanvas start(Canvas currentCanvas, Rect dirty) {
        if (currentCanvas instanceof GLES20Canvas) {
            ((GLES20Canvas) currentCanvas).interrupt();
        }
        HardwareCanvas canvas = getCanvas();
        canvas.setViewport(mWidth, mHeight);
        canvas.onPreDraw(null);
        canvas.onPreDraw(dirty);
        return canvas;
    }

+5 −0
Original line number Diff line number Diff line
@@ -62,6 +62,11 @@ class GLES20TextureLayer extends GLES20Layer {
        return null;
    }

    @Override
    HardwareCanvas start(Canvas currentCanvas, Rect dirty) {
        return null;
    }

    @Override
    void end(Canvas currentCanvas) {
    }
+10 −2
Original line number Diff line number Diff line
@@ -158,14 +158,22 @@ abstract class HardwareLayer {
    /**
     * This must be invoked before drawing onto this layer.
     *
     * @param currentCanvas
     * @param currentCanvas The canvas whose rendering needs to be interrupted
     */
    abstract HardwareCanvas start(Canvas currentCanvas);

    /**
     * This must be invoked before drawing onto this layer.
     *
     * @param dirty The dirty area to repaint
     * @param currentCanvas The canvas whose rendering needs to be interrupted
     */
    abstract HardwareCanvas start(Canvas currentCanvas, Rect dirty);

    /**
     * This must be invoked after drawing onto this layer.
     *
     * @param currentCanvas
     * @param currentCanvas The canvas whose rendering needs to be resumed
     */
    abstract void end(Canvas currentCanvas);

+122 −15
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view;

import android.content.ComponentCallbacks2;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
@@ -45,7 +46,6 @@ import javax.microedition.khronos.opengles.GL;

import java.io.File;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.concurrent.locks.ReentrantLock;

import static javax.microedition.khronos.egl.EGL10.*;
@@ -165,15 +165,32 @@ public abstract class HardwareRenderer {
            "debug.hwui.show_layers_updates";

    /**
     * Turn on to show overdraw level.
     * Controls overdraw debugging.
     *
     * Possible values:
     * "true", to enable overdraw debugging
     * "false", to disable overdraw debugging
     * "show", to show overdraw areas on screen
     * "count", to display an overdraw counter
     *
     * @hide
     */
    public static final String DEBUG_SHOW_OVERDRAW_PROPERTY = "debug.hwui.show_overdraw";
    public static final String DEBUG_OVERDRAW_PROPERTY = "debug.hwui.overdraw";

    /**
     * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
     * value, overdraw will be shown on screen by coloring pixels.
     *
     * @hide
     */
    public static final String OVERDRAW_PROPERTY_SHOW = "show";

    /**
     * Value for {@link #DEBUG_OVERDRAW_PROPERTY}. When the property is set to this
     * value, an overdraw counter will be shown on screen.
     *
     * @hide
     */
    public static final String OVERDRAW_PROPERTY_COUNT = "count";

    /**
     * Turn on to debug non-rectangular clip operations.
@@ -765,6 +782,17 @@ public abstract class HardwareRenderer {
        private static final int PROFILE_DRAW_THRESHOLD_STROKE_WIDTH = 2;
        private static final int PROFILE_DRAW_DP_PER_MS = 7;

        private static final String[] VISUALIZERS = {
                PROFILE_PROPERTY_VISUALIZE_BARS,
                PROFILE_PROPERTY_VISUALIZE_LINES
        };

        private static final String[] OVERDRAW = {
                OVERDRAW_PROPERTY_SHOW,
                OVERDRAW_PROPERTY_COUNT
        };
        private static final int OVERDRAW_TYPE_COUNT = 1;

        static EGL10 sEgl;
        static EGLDisplay sEglDisplay;
        static EGLConfig sEglConfig;
@@ -810,7 +838,9 @@ public abstract class HardwareRenderer {
        Paint mProfilePaint;

        boolean mDebugDirtyRegions;
        boolean mShowOverdraw;
        int mDebugOverdraw = -1;
        HardwareLayer mDebugOverdrawLayer;
        Paint mDebugOverdrawPaint;

        final int mGlVersion;
        final boolean mTranslucent;
@@ -829,18 +859,13 @@ public abstract class HardwareRenderer {
            loadSystemProperties(null);
        }

        private static final String[] VISUALIZERS = {
                PROFILE_PROPERTY_VISUALIZE_BARS,
                PROFILE_PROPERTY_VISUALIZE_LINES
        };

        @Override
        boolean loadSystemProperties(Surface surface) {
            boolean value;
            boolean changed = false;

            String profiling = SystemProperties.get(PROFILE_PROPERTY);
            int graphType = Arrays.binarySearch(VISUALIZERS, profiling);
            int graphType = search(VISUALIZERS, profiling);
            value = graphType >= 0;

            if (graphType != mProfileVisualizerType) {
@@ -897,11 +922,19 @@ public abstract class HardwareRenderer {
                }
            }

            value = SystemProperties.getBoolean(
                    HardwareRenderer.DEBUG_SHOW_OVERDRAW_PROPERTY, false);
            if (value != mShowOverdraw) {
            String overdraw = SystemProperties.get(HardwareRenderer.DEBUG_OVERDRAW_PROPERTY);
            int debugOverdraw = search(OVERDRAW, overdraw);
            if (debugOverdraw != mDebugOverdraw) {
                changed = true;
                mShowOverdraw = value;
                mDebugOverdraw = debugOverdraw;

                if (mDebugOverdraw != OVERDRAW_TYPE_COUNT) {
                    if (mDebugOverdrawLayer != null) {
                        mDebugOverdrawLayer.destroy();
                        mDebugOverdrawLayer = null;
                        mDebugOverdrawPaint = null;
                    }
                }
            }

            if (nLoadProperties()) {
@@ -911,6 +944,13 @@ public abstract class HardwareRenderer {
            return changed;
        }

        private static int search(String[] values, String value) {
            for (int i = 0; i < values.length; i++) {
                if (values[i].equals(value)) return i;
            }
            return -1;
        }

        @Override
        void dumpGfxInfo(PrintWriter pw) {
            if (mProfileEnabled) {
@@ -1392,6 +1432,8 @@ public abstract class HardwareRenderer {
                        canvas.restoreToCount(saveCount);
                        view.mRecreateDisplayList = false;

                        debugOverdraw(attachInfo, dirty, canvas, displayList);

                        mFrameCount++;

                        debugDirtyRegions(dirty, canvas);
@@ -1411,6 +1453,61 @@ public abstract class HardwareRenderer {
            }
        }

        abstract void countOverdraw(HardwareCanvas canvas);
        abstract float getOverdraw(HardwareCanvas canvas);

        private void debugOverdraw(View.AttachInfo attachInfo, Rect dirty,
                HardwareCanvas canvas, DisplayList displayList) {

            if (mDebugOverdraw == OVERDRAW_TYPE_COUNT) {
                // TODO: Use an alpha layer allocated from a GraphicBuffer
                // The alpha format will help with rendering performance and
                // the GraphicBuffer will let us skip the read pixels step
                if (mDebugOverdrawLayer == null) {
                    mDebugOverdrawLayer = createHardwareLayer(mWidth, mHeight, true);
                } else if (mDebugOverdrawLayer.getWidth() != mWidth ||
                        mDebugOverdrawLayer.getHeight() != mHeight) {
                    mDebugOverdrawLayer.resize(mWidth, mHeight);
                }

                if (!mDebugOverdrawLayer.isValid()) {
                    mDebugOverdraw = -1;
                    return;
                }

                HardwareCanvas layerCanvas = mDebugOverdrawLayer.start(canvas, dirty);
                countOverdraw(layerCanvas);
                final int restoreCount = layerCanvas.save();
                layerCanvas.drawDisplayList(displayList, null, DisplayList.FLAG_CLIP_CHILDREN);
                layerCanvas.restoreToCount(restoreCount);
                mDebugOverdrawLayer.end(canvas);

                float overdraw = getOverdraw(layerCanvas);
                DisplayMetrics metrics = attachInfo.mRootView.getResources().getDisplayMetrics();

                drawOverdrawCounter(canvas, overdraw, metrics.density);
            }
        }

        private void drawOverdrawCounter(HardwareCanvas canvas, float overdraw, float density) {
            final String text = String.format("%.2fx", overdraw);
            final Paint paint = setupPaint(density);
            // HSBtoColor will clamp the values in the 0..1 range
            paint.setColor(Color.HSBtoColor(0.28f - 0.28f * overdraw / 3.5f, 0.8f, 1.0f));

            canvas.drawText(text, density * 4.0f, mHeight - paint.getFontMetrics().bottom, paint);
        }

        private Paint setupPaint(float density) {
            if (mDebugOverdrawPaint == null) {
                mDebugOverdrawPaint = new Paint();
                mDebugOverdrawPaint.setAntiAlias(true);
                mDebugOverdrawPaint.setShadowLayer(density * 3.0f, 0.0f, 0.0f, 0xff000000);
                mDebugOverdrawPaint.setTextSize(density * 20.0f);
            }
            return mDebugOverdrawPaint;
        }

        private DisplayList buildDisplayList(View view, HardwareCanvas canvas) {
            view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
                    == View.PFLAG_INVALIDATED;
@@ -2018,6 +2115,16 @@ public abstract class HardwareRenderer {
            return new GLES20RenderLayer(width, height, isOpaque);
        }

        @Override
        void countOverdraw(HardwareCanvas canvas) {
            ((GLES20Canvas) canvas).setCountOverdrawEnabled(true);
        }

        @Override
        float getOverdraw(HardwareCanvas canvas) {
            return ((GLES20Canvas) canvas).getOverdraw();
        }

        @Override
        public SurfaceTexture createSurfaceTexture(HardwareLayer layer) {
            return ((GLES20TextureLayer) layer).getSurfaceTexture();
Loading