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

Commit 03985752 authored by Romain Guy's avatar Romain Guy
Browse files

Always make GL calls with a valid EGL context.

Bug #5010760

Change-Id: If7500ef69683948e727df1406f458f18b11259d1
parent aa695940
Loading
Loading
Loading
Loading
+34 −9
Original line number Diff line number Diff line
@@ -128,10 +128,19 @@ public abstract class HardwareRenderer {
    abstract void updateSurface(SurfaceHolder holder) throws Surface.OutOfResourcesException;

    /**
     * Invoked whenever the size of the target surface changes. This will
     * not be invoked when the surface is first created.
     * This method should be invoked whenever the current hardware renderer
     * context should be reset. 
     */
    abstract void preapareSurfaceForResize();
    abstract void invalidate();

    /**
     * This method should be invoked to ensure the hardware renderer is in
     * valid state (for instance, to ensure the correct EGL context is bound
     * to the current thread.)
     * 
     * @return true if the renderer is now valid, false otherwise
     */
    abstract boolean validate();

    /**
     * Setup the hardware renderer for drawing. This is called whenever the
@@ -629,13 +638,18 @@ public abstract class HardwareRenderer {
        }

        @Override
        void preapareSurfaceForResize() {
        void invalidate() {
            // Cancels any existing buffer to ensure we'll get a buffer
            // of the right size before we call eglSwapBuffers
            sEgl.eglMakeCurrent(sEglDisplay, EGL10.EGL_NO_SURFACE,
                    EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
        }
        
        @Override
        boolean validate() {
            return checkCurrent() != SURFACE_STATE_ERROR;
        }

        @Override
        void setup(int width, int height) {
            mCanvas.setViewport(width, height);
@@ -724,9 +738,20 @@ public abstract class HardwareRenderer {
            }
        }

        /**
         * Ensures the currnet EGL context is the one we expect.
         * 
         * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current,
         *         {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or
         *         {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one
         */
        private int checkCurrent() {
            // TODO: Don't check the current context when we have one per UI thread
            // TODO: Use a threadlocal flag to know whether the surface has changed
            if (sEglThread != Thread.currentThread()) {
                throw new IllegalStateException("Hardware acceleration can only be used with a " +
                        "single UI thread.\nOriginal thread: " + sEglThread + "\n" +
                        "Current thread: " + Thread.currentThread());
            }

            if (!sEglContext.equals(sEgl.eglGetCurrentContext()) ||
                    !mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
                if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, sEglContext)) {
+3 −2
Original line number Diff line number Diff line
@@ -901,6 +901,7 @@ public final class ViewAncestor extends Handler implements ViewParent,
                            !mAttachInfo.mTurnOffWindowResizeAnim &&
                            mAttachInfo.mHardwareRenderer != null &&
                            mAttachInfo.mHardwareRenderer.isEnabled() &&
                            mAttachInfo.mHardwareRenderer.validate() &&
                            lp != null && !PixelFormat.formatHasAlpha(lp.format)) {

                        disposeResizeBuffer();
@@ -1314,10 +1315,10 @@ public final class ViewAncestor extends Handler implements ViewParent,
            if (hwInitialized || ((windowShouldResize || params != null) &&
                    mAttachInfo.mHardwareRenderer != null &&
                    mAttachInfo.mHardwareRenderer.isEnabled())) {
                mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
                if (!hwInitialized) {
                    mAttachInfo.mHardwareRenderer.preapareSurfaceForResize();
                    mAttachInfo.mHardwareRenderer.invalidate();
                }
                mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight);
            }

            if (!mStopped) {
+5 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <cutils/properties.h>
#include <cutils/memory.h>

#include <utils/CallStack.h>
#include <utils/String8.h>

#include "egldefs.h"
@@ -147,6 +148,10 @@ static int gl_no_context() {
    if (egl_tls_t::logNoContextCall()) {
        LOGE("call to OpenGL ES API with no current context "
             "(logged once per thread)");
        LOGE("call stack before error:");
        CallStack stack;
        stack.update();
        stack.dump();
    }
    return 0;
}