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

Commit 3696779b authored by Romain Guy's avatar Romain Guy
Browse files

Reinitialize hardware renderer after eglTerminate()

Bug #8066455

ViewRootImpl was properly detecting that the renderer was not
ready to draw but would simply schedule another frame, thus sending
the systemui into an inifite redraw loop. This change reinitializes
the renderer if needed (if the renderer is requested but not enabled.)

This CL also fixes an issue caused by the default wallpaper. Since it
never calls eglTerminate(), managed contexts are never reclaimed.

Change-Id: Idb8caa672be8ee35f6e6a7e942d9abd8aa100967
parent 6d2def71
Loading
Loading
Loading
Loading
+47 −46
Original line number Original line Diff line number Diff line
@@ -1513,16 +1513,7 @@ public final class ViewRootImpl implements ViewParent,
                                hwInitialized = mAttachInfo.mHardwareRenderer.initialize(
                                hwInitialized = mAttachInfo.mHardwareRenderer.initialize(
                                        mHolder.getSurface());
                                        mHolder.getSurface());
                            } catch (Surface.OutOfResourcesException e) {
                            } catch (Surface.OutOfResourcesException e) {
                                Log.e(TAG, "OutOfResourcesException initializing HW surface", e);
                                handleOutOfResourcesException(e);
                                try {
                                    if (!mWindowSession.outOfMemory(mWindow) &&
                                            Process.myUid() != Process.SYSTEM_UID) {
                                        Slog.w(TAG, "No processes killed for memory; killing self");
                                        Process.killProcess(Process.myPid());
                                    }
                                } catch (RemoteException ex) {
                                }
                                mLayoutRequested = true;    // ask wm for a new surface next time.
                                return;
                                return;
                            }
                            }
                        }
                        }
@@ -1549,15 +1540,7 @@ public final class ViewRootImpl implements ViewParent,
                    try {
                    try {
                        mAttachInfo.mHardwareRenderer.updateSurface(mHolder.getSurface());
                        mAttachInfo.mHardwareRenderer.updateSurface(mHolder.getSurface());
                    } catch (Surface.OutOfResourcesException e) {
                    } catch (Surface.OutOfResourcesException e) {
                        Log.e(TAG, "OutOfResourcesException updating HW surface", e);
                        handleOutOfResourcesException(e);
                        try {
                            if (!mWindowSession.outOfMemory(mWindow)) {
                                Slog.w(TAG, "No processes killed for memory; killing self");
                                Process.killProcess(Process.myPid());
                            }
                        } catch (RemoteException ex) {
                        }
                        mLayoutRequested = true;    // ask wm for a new surface next time.
                        return;
                        return;
                    }
                    }
                }
                }
@@ -1879,6 +1862,19 @@ public final class ViewRootImpl implements ViewParent,
        mIsInTraversal = false;
        mIsInTraversal = false;
    }
    }


    private void handleOutOfResourcesException(Surface.OutOfResourcesException e) {
        Log.e(TAG, "OutOfResourcesException initializing HW surface", e);
        try {
            if (!mWindowSession.outOfMemory(mWindow) &&
                    Process.myUid() != Process.SYSTEM_UID) {
                Slog.w(TAG, "No processes killed for memory; killing self");
                Process.killProcess(Process.myPid());
            }
        } catch (RemoteException ex) {
        }
        mLayoutRequested = true;    // ask wm for a new surface next time.
    }

    private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
    private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "measure");
        try {
        try {
@@ -2296,10 +2292,37 @@ public final class ViewRootImpl implements ViewParent,
                        animating ? null : mCurrentDirty)) {
                        animating ? null : mCurrentDirty)) {
                    mPreviousDirty.set(0, 0, mWidth, mHeight);
                    mPreviousDirty.set(0, 0, mWidth, mHeight);
                }
                }
            } else if (!drawSoftware(surface, attachInfo, yoff, scalingRequired, dirty)) {
            } else {
                // If we get here with a disabled & requested hardware renderer, something went
                // wrong (an invalidate posted right before we destroyed the hardware surface
                // for instance) so we should just bail out. Locking the surface with software
                // rendering at this point would lock it forever and prevent hardware renderer
                // from doing its job when it comes back.
                // Before we request a new frame we must however attempt to reinitiliaze the
                // hardware renderer if it's in requested state. This would happen after an
                // eglTerminate() for instance.
                if (attachInfo.mHardwareRenderer != null &&
                        !attachInfo.mHardwareRenderer.isEnabled() &&
                        attachInfo.mHardwareRenderer.isRequested()) {

                    try {
                        attachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
                                mHolder.getSurface());
                    } catch (Surface.OutOfResourcesException e) {
                        handleOutOfResourcesException(e);
                        return;
                    }

                    mFullRedrawNeeded = true;
                    scheduleTraversals();
                    return;
                }

                if (!drawSoftware(surface, attachInfo, yoff, scalingRequired, dirty)) {
                    return;
                    return;
                }
                }
            }
            }
        }


        if (animating) {
        if (animating) {
            mFullRedrawNeeded = true;
            mFullRedrawNeeded = true;
@@ -2313,18 +2336,6 @@ public final class ViewRootImpl implements ViewParent,
    private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int yoff,
    private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int yoff,
            boolean scalingRequired, Rect dirty) {
            boolean scalingRequired, Rect dirty) {


        // If we get here with a disabled & requested hardware renderer, something went
        // wrong (an invalidate posted right before we destroyed the hardware surface
        // for instance) so we should just bail out. Locking the surface with software
        // rendering at this point would lock it forever and prevent hardware renderer
        // from doing its job when it comes back.
        if (attachInfo.mHardwareRenderer != null && !attachInfo.mHardwareRenderer.isEnabled() &&
                attachInfo.mHardwareRenderer.isRequested()) {
            mFullRedrawNeeded = true;
            scheduleTraversals();
            return false;
        }

        // Draw with software renderer.
        // Draw with software renderer.
        Canvas canvas;
        Canvas canvas;
        try {
        try {
@@ -2343,15 +2354,7 @@ public final class ViewRootImpl implements ViewParent,
            // TODO: Do this in native
            // TODO: Do this in native
            canvas.setDensity(mDensity);
            canvas.setDensity(mDensity);
        } catch (Surface.OutOfResourcesException e) {
        } catch (Surface.OutOfResourcesException e) {
            Log.e(TAG, "OutOfResourcesException locking surface", e);
            handleOutOfResourcesException(e);
            try {
                if (!mWindowSession.outOfMemory(mWindow)) {
                    Slog.w(TAG, "No processes killed for memory; killing self");
                    Process.killProcess(Process.myPid());
                }
            } catch (RemoteException ex) {
            }
            mLayoutRequested = true;    // ask wm for a new surface next time.
            return false;
            return false;
        } catch (IllegalArgumentException e) {
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "Could not lock surface", e);
            Log.e(TAG, "Could not lock surface", e);
@@ -2996,10 +2999,8 @@ public final class ViewRootImpl implements ViewParent,
                                mSurface != null && mSurface.isValid()) {
                                mSurface != null && mSurface.isValid()) {
                            mFullRedrawNeeded = true;
                            mFullRedrawNeeded = true;
                            try {
                            try {
                                if (mAttachInfo.mHardwareRenderer.initializeIfNeeded(
                                mAttachInfo.mHardwareRenderer.initializeIfNeeded(
                                        mWidth, mHeight, mHolder.getSurface())) {
                                        mWidth, mHeight, mHolder.getSurface());
                                    mFullRedrawNeeded = true;
                                }
                            } catch (Surface.OutOfResourcesException e) {
                            } catch (Surface.OutOfResourcesException e) {
                                Log.e(TAG, "OutOfResourcesException locking surface", e);
                                Log.e(TAG, "OutOfResourcesException locking surface", e);
                                try {
                                try {
+6 −5
Original line number Original line Diff line number Diff line
@@ -604,6 +604,7 @@ public class ImageWallpaper extends WallpaperService {
            mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
            mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
            mEgl.eglDestroyContext(mEglDisplay, mEglContext);
            mEgl.eglDestroyContext(mEglDisplay, mEglContext);
            mEgl.eglTerminate(mEglDisplay);
        }
        }


        private boolean initGL(SurfaceHolder surfaceHolder) {
        private boolean initGL(SurfaceHolder surfaceHolder) {