OSDN Git Service

Remove RenderThread from EglManager
authorJohn Reck <jreck@google.com>
Mon, 23 Apr 2018 15:15:03 +0000 (08:15 -0700)
committerJohn Reck <jreck@google.com>
Thu, 26 Apr 2018 20:46:12 +0000 (13:46 -0700)
Refactor to make EglManager re-usable.

Test: hwuiunit passes, hwuimacro works

Change-Id: Ie8e9398c703fada1dc5d8baca5f42485eadea202

libs/hwui/EglReadback.cpp
libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
libs/hwui/renderthread/CanvasContext.cpp
libs/hwui/renderthread/EglManager.cpp
libs/hwui/renderthread/EglManager.h
libs/hwui/renderthread/RenderThread.cpp
libs/hwui/renderthread/RenderThread.h
libs/hwui/tests/common/TestUtils.cpp
libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp

index a836afe..2d5367b 100644 (file)
@@ -58,7 +58,7 @@ CopyResult EglReadback::copySurfaceInto(Surface& surface, const Rect& srcRect,
 CopyResult EglReadback::copyGraphicBufferInto(GraphicBuffer* graphicBuffer,
                                                  Matrix4& texTransform, const Rect& srcRect,
                                                  SkBitmap* bitmap) {
-    mRenderThread.eglManager().initialize();
+    mRenderThread.requireGlContext();
     // TODO: Can't use Image helper since it forces GL_TEXTURE_2D usage via
     // GL_OES_EGL_image, which doesn't work since we need samplerExternalOES
     // to be able to properly sample from the buffer.
index b7aa78b..c3357a2 100644 (file)
@@ -166,7 +166,7 @@ static Layer* createLayer(RenderState& renderState, uint32_t layerWidth, uint32_
 }
 
 DeferredLayerUpdater* SkiaOpenGLPipeline::createTextureLayer() {
-    mEglManager.initialize();
+    mRenderThread.requireGlContext();
     return new DeferredLayerUpdater(mRenderThread.renderState(), createLayer, Layer::Api::OpenGL);
 }
 
@@ -184,6 +184,7 @@ bool SkiaOpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior,
     }
 
     if (surface) {
+        mRenderThread.requireGlContext();
         const bool wideColorGamut = colorMode == ColorMode::WideColorGamut;
         mEglSurface = mEglManager.createSurface(surface, wideColorGamut);
     }
@@ -274,7 +275,7 @@ private:
 
 sk_sp<Bitmap> SkiaOpenGLPipeline::allocateHardwareBitmap(renderthread::RenderThread& renderThread,
                                                          SkBitmap& skBitmap) {
-    renderThread.eglManager().initialize();
+    renderThread.requireGlContext();
 
     sk_sp<GrContext> grContext = sk_ref_sp(renderThread.getGrContext());
     const SkImageInfo& info = skBitmap.info();
index 95ca8d9..a36dae4 100644 (file)
@@ -552,7 +552,7 @@ void CanvasContext::trimMemory(RenderThread& thread, int level) {
     ATRACE_CALL();
     if (level >= TRIM_MEMORY_COMPLETE) {
         thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::Complete);
-        thread.eglManager().destroy();
+        thread.destroyGlContext();
         thread.vulkanManager().destroy();
     } else if (level >= TRIM_MEMORY_UI_HIDDEN) {
         thread.cacheManager().trimMemory(CacheManager::TrimMemoryMode::UiHidden);
index 6e239e3..cd21822 100644 (file)
 
 #include "EglManager.h"
 
-#include <string>
-
 #include <cutils/properties.h>
 #include <log/log.h>
+#include <utils/Trace.h>
 #include "utils/StringUtils.h"
 
-#include "Caches.h"
 #include "DeviceInfo.h"
 #include "Frame.h"
 #include "Properties.h"
-#include "RenderThread.h"
-#include "Texture.h"
-#include "renderstate/RenderState.h"
 
 #include <EGL/eglext.h>
-#include <GrContextOptions.h>
-#include <gl/GrGLInterface.h>
 
-#ifdef HWUI_GLES_WRAP_ENABLED
-#include "debug/GlesDriver.h"
-#endif
+#include <string>
+#include <vector>
 
 #define GLES_VERSION 2
 
@@ -83,17 +75,21 @@ static struct {
     bool glColorSpace = false;
     bool scRGB = false;
     bool contextPriority = false;
+    bool surfacelessContext = false;
 } EglExtensions;
 
-EglManager::EglManager(RenderThread& thread)
-        : mRenderThread(thread)
-        , mEglDisplay(EGL_NO_DISPLAY)
+EglManager::EglManager()
+        : mEglDisplay(EGL_NO_DISPLAY)
         , mEglConfig(nullptr)
         , mEglConfigWideGamut(nullptr)
         , mEglContext(EGL_NO_CONTEXT)
         , mPBufferSurface(EGL_NO_SURFACE)
         , mCurrentSurface(EGL_NO_SURFACE) {}
 
+EglManager::~EglManager() {
+    destroy();
+}
+
 void EglManager::initialize() {
     if (hasEglContext()) return;
 
@@ -126,26 +122,8 @@ void EglManager::initialize() {
     loadConfigs();
     createContext();
     createPBufferSurface();
-    makeCurrent(mPBufferSurface);
+    makeCurrent(mPBufferSurface, nullptr, /* force */ true);
     DeviceInfo::initialize();
-    mRenderThread.renderState().onGLContextCreated();
-
-    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
-#ifdef HWUI_GLES_WRAP_ENABLED
-        debug::GlesDriver* driver = debug::GlesDriver::get();
-        sk_sp<const GrGLInterface> glInterface(driver->getSkiaInterface());
-#else
-        sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
-#endif
-        LOG_ALWAYS_FATAL_IF(!glInterface.get());
-
-        GrContextOptions options;
-        options.fDisableDistanceFieldPaths = true;
-        mRenderThread.cacheManager().configureContext(&options);
-        sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
-        LOG_ALWAYS_FATAL_IF(!grContext.get());
-        mRenderThread.setGrContext(grContext);
-    }
 }
 
 void EglManager::initExtensions() {
@@ -170,6 +148,7 @@ void EglManager::initExtensions() {
     EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb");
 #endif
     EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority");
+    EglExtensions.surfacelessContext = extensions.has("EGL_KHR_surfaceless_context");
 }
 
 bool EglManager::hasEglContext() {
@@ -195,7 +174,7 @@ void EglManager::loadConfigs() {
                         EGL_CONFIG_CAVEAT,
                         EGL_NONE,
                         EGL_STENCIL_SIZE,
-                        Stencil::getStencilSize(),
+                        STENCIL_BUFFER_SIZE,
                         EGL_SURFACE_TYPE,
                         EGL_WINDOW_BIT | swapBehavior,
                         EGL_NONE};
@@ -232,7 +211,7 @@ void EglManager::loadConfigs() {
                                EGL_DEPTH_SIZE,
                                0,
                                EGL_STENCIL_SIZE,
-                               Stencil::getStencilSize(),
+                               STENCIL_BUFFER_SIZE,
                                EGL_SURFACE_TYPE,
                                EGL_WINDOW_BIT | swapBehavior,
                                EGL_NONE};
@@ -269,14 +248,14 @@ void EglManager::createPBufferSurface() {
     LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
                         "usePBufferSurface() called on uninitialized GlobalContext!");
 
-    if (mPBufferSurface == EGL_NO_SURFACE) {
+    if (mPBufferSurface == EGL_NO_SURFACE && !EglExtensions.surfacelessContext) {
         EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
         mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs);
     }
 }
 
 EGLSurface EglManager::createSurface(EGLNativeWindowType window, bool wideColorGamut) {
-    initialize();
+    LOG_ALWAYS_FATAL_IF(!hasEglContext(), "Not initialized");
 
     wideColorGamut = wideColorGamut && EglExtensions.glColorSpace && EglExtensions.scRGB &&
                      EglExtensions.pixelFormatFloat && EglExtensions.noConfigContext;
@@ -350,10 +329,10 @@ void EglManager::destroySurface(EGLSurface surface) {
 void EglManager::destroy() {
     if (mEglDisplay == EGL_NO_DISPLAY) return;
 
-    mRenderThread.setGrContext(nullptr);
-    mRenderThread.renderState().onGLContextDestroyed();
     eglDestroyContext(mEglDisplay, mEglContext);
-    eglDestroySurface(mEglDisplay, mPBufferSurface);
+    if (mPBufferSurface != EGL_NO_SURFACE) {
+        eglDestroySurface(mEglDisplay, mPBufferSurface);
+    }
     eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
     eglTerminate(mEglDisplay);
     eglReleaseThread();
@@ -364,8 +343,8 @@ void EglManager::destroy() {
     mCurrentSurface = EGL_NO_SURFACE;
 }
 
-bool EglManager::makeCurrent(EGLSurface surface, EGLint* errOut) {
-    if (isCurrent(surface)) return false;
+bool EglManager::makeCurrent(EGLSurface surface, EGLint* errOut, bool force) {
+    if (!force && isCurrent(surface)) return false;
 
     if (surface == EGL_NO_SURFACE) {
         // Ensure we always have a valid surface & context
index ef9effb..ca6d1b8 100644 (file)
@@ -33,8 +33,12 @@ class RenderThread;
 // and EGLConfig, which are re-used by CanvasContext
 class EglManager {
 public:
+    explicit EglManager();
+
+    ~EglManager();
+
     static const char* eglErrorString();
-    // Returns true on success, false on failure
+
     void initialize();
 
     bool hasEglContext();
@@ -46,7 +50,7 @@ public:
 
     bool isCurrent(EGLSurface surface) { return mCurrentSurface == surface; }
     // Returns true if the current surface changed, false if it was already current
-    bool makeCurrent(EGLSurface surface, EGLint* errOut = nullptr);
+    bool makeCurrent(EGLSurface surface, EGLint* errOut = nullptr, bool force = false);
     Frame beginFrame(EGLSurface surface);
     void damageFrame(const Frame& frame, const SkRect& dirty);
     // If this returns true it is mandatory that swapBuffers is called
@@ -61,10 +65,6 @@ public:
     void fence();
 
 private:
-    friend class RenderThread;
-    explicit EglManager(RenderThread& thread);
-    // EglContext is never destroyed, method is purposely not implemented
-    ~EglManager();
 
     void initExtensions();
     void createPBufferSurface();
@@ -72,8 +72,6 @@ private:
     void createContext();
     EGLint queryBufferAge(EGLSurface surface);
 
-    RenderThread& mRenderThread;
-
     EGLDisplay mEglDisplay;
     EGLConfig mEglConfig;
     EGLConfig mEglConfigWideGamut;
index 5e067da..711ece4 100644 (file)
 #include "utils/FatVector.h"
 #include "utils/TimeUtils.h"
 
+#ifdef HWUI_GLES_WRAP_ENABLED
+#include "debug/GlesDriver.h"
+#endif
+
+#include <GrContextOptions.h>
+#include <gl/GrGLInterface.h>
+
 #include <gui/DisplayEventReceiver.h>
 #include <sys/resource.h>
 #include <utils/Condition.h>
@@ -163,12 +170,45 @@ void RenderThread::initThreadLocals() {
     nsecs_t frameIntervalNanos = static_cast<nsecs_t>(1000000000 / mDisplayInfo.fps);
     mTimeLord.setFrameInterval(frameIntervalNanos);
     initializeDisplayEventReceiver();
-    mEglManager = new EglManager(*this);
+    mEglManager = new EglManager();
     mRenderState = new RenderState(*this);
     mVkManager = new VulkanManager(*this);
     mCacheManager = new CacheManager(mDisplayInfo);
 }
 
+void RenderThread::requireGlContext() {
+    if (mEglManager->hasEglContext()) {
+        return;
+    }
+    mEglManager->initialize();
+    renderState().onGLContextCreated();
+
+    if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaGL) {
+#ifdef HWUI_GLES_WRAP_ENABLED
+        debug::GlesDriver* driver = debug::GlesDriver::get();
+        sk_sp<const GrGLInterface> glInterface(driver->getSkiaInterface());
+#else
+        sk_sp<const GrGLInterface> glInterface(GrGLCreateNativeInterface());
+#endif
+        LOG_ALWAYS_FATAL_IF(!glInterface.get());
+
+        GrContextOptions options;
+        options.fDisableDistanceFieldPaths = true;
+        cacheManager().configureContext(&options);
+        sk_sp<GrContext> grContext(GrContext::MakeGL(std::move(glInterface), options));
+        LOG_ALWAYS_FATAL_IF(!grContext.get());
+        setGrContext(grContext);
+    }
+}
+
+void RenderThread::destroyGlContext() {
+    if (mEglManager->hasEglContext()) {
+        setGrContext(nullptr);
+        renderState().onGLContextDestroyed();
+        mEglManager->destroy();
+    }
+}
+
 void RenderThread::dumpGraphicsMemory(int fd) {
     globalProfileData()->dump(fd);
 
index 689f518..4a1fd9e 100644 (file)
@@ -103,6 +103,9 @@ public:
     sk_sp<Bitmap> allocateHardwareBitmap(SkBitmap& skBitmap);
     void dumpGraphicsMemory(int fd);
 
+    void requireGlContext();
+    void destroyGlContext();
+
     /**
      * isCurrent provides a way to query, if the caller is running on
      * the render thread.
index 16c5afd..b2fccd4 100644 (file)
@@ -140,7 +140,7 @@ void TestUtils::TestTask::run() {
     if (Properties::getRenderPipelineType() == RenderPipelineType::SkiaVulkan) {
         renderThread.vulkanManager().initialize();
     } else {
-        renderThread.eglManager().initialize();
+        renderThread.requireGlContext();
     }
 
     rtCallback(renderThread);
@@ -149,7 +149,7 @@ void TestUtils::TestTask::run() {
         renderThread.vulkanManager().destroy();
     } else {
         renderThread.renderState().flush(Caches::FlushMode::Full);
-        renderThread.eglManager().destroy();
+        renderThread.destroyGlContext();
     }
 }
 
index 9bfb082..08b9679 100644 (file)
@@ -39,7 +39,7 @@ public:
 // current thread can spoof being a GPU thread
 static void destroyEglContext() {
     if (TestUtils::isRenderThreadRunning()) {
-        TestUtils::runOnRenderThread([](RenderThread& thread) { thread.eglManager().destroy(); });
+        TestUtils::runOnRenderThread([](RenderThread& thread) { thread.destroyGlContext(); });
     }
 }