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

Commit 6a2d17f7 authored by Chet Haase's avatar Chet Haase
Browse files

Fix texture corruption

When memory gets low on a device, activities flush everything they can.
Hardware-accelerated activites, such as Launcher, flush GL resources and destroy
the GL context. However, some resources were still hanging around, due to deferred
destruction policies (we don't delete layers until the DisplayLists they are in
are finalized, to ensure we don't deref deleted objects). This meant that we were
referring to obsolete GL data in these objects. in particular, it meant that we might
come around later, after a new GL context was created, and delete a texture object
that was incorrect. We use the layer's "texture id" to refer to the texture underlying the
layer. But if there's a new GL context, then this texture ID is no longer valid, and
we may be deleting the texture that a different object (layer, icon, whatever) is referring
to, because the driver may return that same ID under the new GL context.

The fix is to more aggressively delete things that we know will not be used again
when the GL context is destroyed. In particular, we delete all resources being used
by all DisplayLists at GL context destruction time.

Issue #7195815 Textures corruption on all devices, in many apps

Change-Id: I52d2d208173690dbb794a83402d38f14ea4c6c22
parent 933a7546
Loading
Loading
Loading
Loading
+7 −0
Original line number Original line Diff line number Diff line
@@ -332,4 +332,11 @@ public abstract class DisplayList {
     * @see View#offsetTopAndBottom(int)
     * @see View#offsetTopAndBottom(int)
     */
     */
    public abstract void offsetTopBottom(int offset);
    public abstract void offsetTopBottom(int offset);

    /**
     * Reset native resources. This is called when cleaning up the state of DisplayLists
     * during destruction of hardware resources, to ensure that we do not hold onto
     * obsolete resources after related resources are gone.
     */
    public abstract void reset();
}
}
+8 −0
Original line number Original line Diff line number Diff line
@@ -86,6 +86,13 @@ class GLES20DisplayList extends DisplayList {
        }
        }
    }
    }


    @Override
    public void reset() {
        if (hasNativeDisplayList()) {
            nReset(mFinalizer.mNativeDisplayList);
        }
    }

    @Override
    @Override
    public boolean isValid() {
    public boolean isValid() {
        return mValid;
        return mValid;
@@ -294,6 +301,7 @@ class GLES20DisplayList extends DisplayList {
        }
        }
    }
    }


    private static native void nReset(int displayList);
    private static native void nOffsetTopBottom(int displayList, int offset);
    private static native void nOffsetTopBottom(int displayList, int offset);
    private static native void nOffsetLeftRight(int displayList, int offset);
    private static native void nOffsetLeftRight(int displayList, int offset);
    private static native void nSetLeftTopRightBottom(int displayList, int left, int top,
    private static native void nSetLeftTopRightBottom(int displayList, int left, int top,
+6 −0
Original line number Original line Diff line number Diff line
@@ -1508,6 +1508,9 @@ public abstract class HardwareRenderer {
        @Override
        @Override
        void destroyLayers(View view) {
        void destroyLayers(View view) {
            if (view != null && isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) {
            if (view != null && isEnabled() && checkCurrent() != SURFACE_STATE_ERROR) {
                if (mCanvas != null) {
                    mCanvas.clearLayerUpdates();
                }
                destroyHardwareLayer(view);
                destroyHardwareLayer(view);
                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
                GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
            }
            }
@@ -1556,6 +1559,9 @@ public abstract class HardwareRenderer {
                safelyRun(new Runnable() {
                safelyRun(new Runnable() {
                    @Override
                    @Override
                    public void run() {
                    public void run() {
                        if (mCanvas != null) {
                            mCanvas.clearLayerUpdates();
                        }
                        destroyResources(view);
                        destroyResources(view);
                        GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
                        GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
                    }
                    }
+3 −0
Original line number Original line Diff line number Diff line
@@ -12394,6 +12394,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
                mHardwareLayer.destroy();
                mHardwareLayer.destroy();
                mHardwareLayer = null;
                mHardwareLayer = null;
                if (mDisplayList != null) {
                    mDisplayList.reset();
                }
                invalidate(true);
                invalidate(true);
                invalidateParentCaches();
                invalidateParentCaches();
            }
            }
+3 −0
Original line number Original line Diff line number Diff line
@@ -931,6 +931,9 @@ static void doDrawTextDecorations(SkCanvas* canvas, jfloat x, jfloat y, jfloat l
        SkIRect ir;
        SkIRect ir;
        bool     result = canvas->getClipBounds(&r, SkCanvas::kBW_EdgeType);
        bool     result = canvas->getClipBounds(&r, SkCanvas::kBW_EdgeType);


        if (!result) {
            r.setEmpty();
        }
        r.round(&ir);
        r.round(&ir);
        (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
        (void)GraphicsJNI::irect_to_jrect(ir, env, bounds);
        return result;
        return result;
Loading