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

Commit 2725c097 authored by Alec Mouri's avatar Alec Mouri
Browse files

Tidy up GL resources

Currently it's not safe to destroy and recreate RenderEngine because
certain GL resources are persisted in GLESRenderEngine, which is
imposing limitations on testing. This patch adds some cleanup steps,
including:
* Supporting destruction of glPrograms once they're unused.
* Purging the ProgramCache of shaders when RenderEngine is destroyed
* Tidy up Framebuffer destruction when backed by an EGLImage
* Make sure shadow resources are destroyed prior to display termination
* Disable vertex attribute used for positioning layers.
* Check that EGL objects are valid before display termination.

Bug: 173416417
Test: librenderengine_test, and observe logcat
Change-Id: Id5d858d21a400ef170788d917f0bc0ac5e318bdc
parent 82ba2ecd
Loading
Loading
Loading
Loading
+19 −3
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

//#define LOG_NDEBUG 0
#include "EGL/egl.h"
#undef LOG_TAG
#define LOG_TAG "RenderEngine"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
@@ -446,19 +447,34 @@ GLESRenderEngine::GLESRenderEngine(const RenderEngineCreationArgs& args, EGLDisp
                                          mPlaceholderBuffer, attributes);
    ALOGE_IF(mPlaceholderImage == EGL_NO_IMAGE_KHR, "Failed to create placeholder image: %#x",
             eglGetError());

    mShadowTexture = std::make_unique<GLShadowTexture>();
}

GLESRenderEngine::~GLESRenderEngine() {
    // Destroy the image manager first.
    mImageManager = nullptr;
    mShadowTexture = nullptr;
    cleanFramebufferCache();
    ProgramCache::getInstance().purgeCaches();
    std::lock_guard<std::mutex> lock(mRenderingMutex);
    glDisableVertexAttribArray(Program::position);
    unbindFrameBuffer(mDrawingBuffer.get());
    mDrawingBuffer = nullptr;
    eglDestroyImageKHR(mEGLDisplay, mPlaceholderImage);
    mImageCache.clear();
    if (mStubSurface != EGL_NO_SURFACE) {
        eglDestroySurface(mEGLDisplay, mStubSurface);
    }
    if (mProtectedStubSurface != EGL_NO_SURFACE) {
        eglDestroySurface(mEGLDisplay, mProtectedStubSurface);
    }
    if (mEGLContext != EGL_NO_CONTEXT) {
        eglDestroyContext(mEGLDisplay, mEGLContext);
    }
    if (mProtectedEGLContext != EGL_NO_CONTEXT) {
        eglDestroyContext(mEGLDisplay, mProtectedEGLContext);
    }
    eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglTerminate(mEGLDisplay);
    eglReleaseThread();
@@ -1803,7 +1819,7 @@ void GLESRenderEngine::handleShadow(const FloatRect& casterRect, float casterCor

    mState.cornerRadius = 0.0f;
    mState.drawShadows = true;
    setupLayerTexturing(mShadowTexture.getTexture());
    setupLayerTexturing(mShadowTexture->getTexture());
    drawMesh(mesh);
    mState.drawShadows = false;
}
+2 −2
Original line number Diff line number Diff line
@@ -193,7 +193,7 @@ private:
    GLuint mVpWidth;
    GLuint mVpHeight;
    Description mState;
    GLShadowTexture mShadowTexture;
    std::unique_ptr<GLShadowTexture> mShadowTexture = nullptr;

    mat4 mSrgbToXyz;
    mat4 mDisplayP3ToXyz;
@@ -294,7 +294,7 @@ private:
    friend class BlurFilter;
    friend class GenericProgram;
    std::unique_ptr<FlushTracer> mFlushTracer;
    std::unique_ptr<ImageManager> mImageManager = std::make_unique<ImageManager>(this);
    std::unique_ptr<ImageManager> mImageManager;
};

} // namespace gl
+1 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ GLFramebuffer::GLFramebuffer(GLESRenderEngine& engine)
}

GLFramebuffer::~GLFramebuffer() {
    setNativeWindowBuffer(nullptr, false, false);
    glDeleteFramebuffers(1, &mFramebufferName);
    glDeleteTextures(1, &mTextureName);
}
+8 −0
Original line number Diff line number Diff line
@@ -82,6 +82,14 @@ Program::Program(const ProgramCache::Key& /*needs*/, const char* vertex, const c
    }
}

Program::~Program() {
    glDetachShader(mProgram, mVertexShader);
    glDetachShader(mProgram, mFragmentShader);
    glDeleteShader(mVertexShader);
    glDeleteShader(mFragmentShader);
    glDeleteProgram(mProgram);
}

bool Program::isValid() const {
    return mInitialized;
}
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ public:
    };

    Program(const ProgramCache::Key& needs, const char* vertex, const char* fragment);
    ~Program() = default;
    ~Program();

    /* whether this object is usable */
    bool isValid() const;
Loading