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

Commit 7b5b6abf authored by Romain Guy's avatar Romain Guy
Browse files

Fix rendering artifact in edge fades.

Bug #4092053

The problem always existed but was made visible by partial invalidation.
When saving a layer, the renderer would try to postpone glClear()
operations until the next drawing command. This however does not work
since the clip might have changed. The fix is rather simple and
simply gets rid of this "optimization" (that turned out to be
usless anyway given how View issues saveLayer() calls.)

This change also fixes an issue with gradients (color stops where
not properly computed when using a null stops array) and optimizes
display lists rendering (quickly rejects larger portions of the
tree to avoid executing unnecessary code.)

Change-Id: I0f5b5f6e1220d41a09cc2fa84c212b0b4afd9c46
parent c7fcc507
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -245,12 +245,13 @@ class GLES20Canvas extends HardwareCanvas {
    private static native void nDestroyDisplayList(int displayList);

    @Override
    public boolean drawDisplayList(DisplayList displayList, Rect dirty) {
    public boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty) {
        return nDrawDisplayList(mRenderer,
                ((GLES20DisplayList) displayList).mNativeDisplayList, dirty);
                ((GLES20DisplayList) displayList).mNativeDisplayList, width, height, dirty);
    }

    private static native boolean nDrawDisplayList(int renderer, int displayList, Rect dirty);
    private static native boolean nDrawDisplayList(int renderer, int displayList,
            int width, int height, Rect dirty);

    ///////////////////////////////////////////////////////////////////////////
    // Hardware layer
+3 −1
Original line number Diff line number Diff line
@@ -53,13 +53,15 @@ public abstract class HardwareCanvas extends Canvas {
     * Draws the specified display list onto this canvas.
     * 
     * @param displayList The display list to replay.
     * @param width The width of the display list.
     * @param height The height of the display list.
     * @param dirty The dirty region to redraw in the next pass, matters only
     *        if this method returns true, can be null.
     * 
     * @return True if the content of the display list requires another
     *         drawing pass (invalidate()), false otherwise
     */
    abstract boolean drawDisplayList(DisplayList displayList, Rect dirty);
    abstract boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty);

    /**
     * Draws the specified layer onto this canvas.
+2 −1
Original line number Diff line number Diff line
@@ -608,7 +608,8 @@ public abstract class HardwareRenderer {

                        DisplayList displayList = view.getDisplayList();
                        if (displayList != null) {
                            if (canvas.drawDisplayList(displayList, mRedrawClip)) {
                            if (canvas.drawDisplayList(displayList, view.getWidth(),
                                    view.getHeight(), mRedrawClip)) {
                                if (mRedrawClip.isEmpty() || view.getParent() == null) {
                                    view.invalidate();
                                } else {
+9 −7
Original line number Diff line number Diff line
@@ -59,7 +59,6 @@ import android.util.Pools;
import android.util.SparseArray;
import android.util.TypedValue;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEventSource;
import android.view.accessibility.AccessibilityManager;
@@ -4651,6 +4650,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     * @return True if the event was handled by the view, false otherwise.
     */
    public boolean dispatchGenericMotionEvent(MotionEvent event) {
        //noinspection SimplifiableIfStatement
        if (mOnGenericMotionListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
                && mOnGenericMotionListener.onGenericMotion(this, event)) {
            return true;
@@ -9326,7 +9326,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        }

        final ScrollabilityCache scrollabilityCache = mScrollCache;
        int length = scrollabilityCache.fadingEdgeLength;
        final float fadeHeight = scrollabilityCache.fadingEdgeLength;        
        int length = (int) fadeHeight;

        // clip the fade length if top and bottom fades overlap
        // overlapping fades produce odd-looking artifacts
@@ -9341,16 +9342,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility

        if (verticalEdges) {
            topFadeStrength = Math.max(0.0f, Math.min(1.0f, getTopFadingEdgeStrength()));
            drawTop = topFadeStrength > 0.0f;
            drawTop = topFadeStrength * fadeHeight > 1.0f;
            bottomFadeStrength = Math.max(0.0f, Math.min(1.0f, getBottomFadingEdgeStrength()));
            drawBottom = bottomFadeStrength > 0.0f;
            drawBottom = bottomFadeStrength * fadeHeight > 1.0f;
        }

        if (horizontalEdges) {
            leftFadeStrength = Math.max(0.0f, Math.min(1.0f, getLeftFadingEdgeStrength()));
            drawLeft = leftFadeStrength > 0.0f;
            drawLeft = leftFadeStrength * fadeHeight > 1.0f;
            rightFadeStrength = Math.max(0.0f, Math.min(1.0f, getRightFadingEdgeStrength()));
            drawRight = rightFadeStrength > 0.0f;
            drawRight = rightFadeStrength * fadeHeight > 1.0f;
        }

        saveCount = canvas.getSaveCount();
@@ -9388,7 +9389,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        final Paint p = scrollabilityCache.paint;
        final Matrix matrix = scrollabilityCache.matrix;
        final Shader fade = scrollabilityCache.shader;
        final float fadeHeight = scrollabilityCache.fadingEdgeLength;

        if (drawTop) {
            matrix.setScale(1, fadeHeight * topFadeStrength);
@@ -9438,6 +9438,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     *
     * @return The known solid color background for this view, or 0 if the color may vary
     */
    @ViewDebug.ExportedProperty(category = "drawing")
    public int getSolidColor() {
        return 0;
    }
@@ -11644,6 +11645,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     * @return true if scrolling was clamped to an over-scroll boundary along either
     *          axis, false otherwise.
     */
    @SuppressWarnings({"UnusedParameters"})
    protected boolean overScrollBy(int deltaX, int deltaY,
            int scrollX, int scrollY,
            int scrollRangeX, int scrollRangeY,
+1 −1
Original line number Diff line number Diff line
@@ -2585,7 +2585,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
                    }
                } else {
                    child.mPrivateFlags &= ~DIRTY_MASK;
                    ((HardwareCanvas) canvas).drawDisplayList(displayList, null);
                    ((HardwareCanvas) canvas).drawDisplayList(displayList, cr - cl, cb - ct, null);
                }
            }
        } else if (cache != null) {
Loading