diff options
author | 2018-04-23 08:15:03 -0700 | |
---|---|---|
committer | 2018-04-26 13:46:12 -0700 | |
commit | 1e51071240e0333b1a6cf3dd77d22e45c8677669 (patch) | |
tree | 600cecbf07d5048878d9503a62a47670d0af180e | |
parent | 4afbedf988425e25b74e3d246cbefaff9e10c1bb (diff) |
Remove RenderThread from EglManager
Refactor to make EglManager re-usable.
Test: hwuiunit passes, hwuimacro works
Change-Id: Ie8e9398c703fada1dc5d8baca5f42485eadea202
-rw-r--r-- | libs/hwui/EglReadback.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp | 5 | ||||
-rw-r--r-- | libs/hwui/renderthread/CanvasContext.cpp | 2 | ||||
-rw-r--r-- | libs/hwui/renderthread/EglManager.cpp | 63 | ||||
-rw-r--r-- | libs/hwui/renderthread/EglManager.h | 14 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.cpp | 42 | ||||
-rw-r--r-- | libs/hwui/renderthread/RenderThread.h | 3 | ||||
-rw-r--r-- | libs/hwui/tests/common/TestUtils.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp | 2 |
9 files changed, 79 insertions, 58 deletions
diff --git a/libs/hwui/EglReadback.cpp b/libs/hwui/EglReadback.cpp index a836afe97c79..2d5367b2508a 100644 --- a/libs/hwui/EglReadback.cpp +++ b/libs/hwui/EglReadback.cpp @@ -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. diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp index b7aa78b7afae..c3357a2cf4e4 100644 --- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp +++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp @@ -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(); diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 95ca8d9d2612..a36dae44ede9 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -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); diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 6e239e357cf6..cd21822df5b1 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -16,27 +16,19 @@ #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 diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h index ef9effbf9953..ca6d1b8b74c6 100644 --- a/libs/hwui/renderthread/EglManager.h +++ b/libs/hwui/renderthread/EglManager.h @@ -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; diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 5e067dafed03..711ece46cf31 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -30,6 +30,13 @@ #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); diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h index 689f518bad1b..4a1fd9ee3d47 100644 --- a/libs/hwui/renderthread/RenderThread.h +++ b/libs/hwui/renderthread/RenderThread.h @@ -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. diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp index 16c5afdc3dcf..b2fccd4cac53 100644 --- a/libs/hwui/tests/common/TestUtils.cpp +++ b/libs/hwui/tests/common/TestUtils.cpp @@ -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(); } } diff --git a/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp b/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp index 9bfb08292be2..08b967964c59 100644 --- a/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp +++ b/libs/hwui/tests/unit/GpuMemoryTrackerTests.cpp @@ -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(); }); } } |