From 65fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6 Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Mon, 26 Jan 2015 18:06:29 -0800 Subject: Move scissor state to RenderState Change-Id: I1227a3886fb24e4d9fad79fca469794f06cfb15e --- libs/hwui/Android.common.mk | 26 ++--- libs/hwui/Caches.cpp | 80 +------------- libs/hwui/Caches.h | 20 ---- libs/hwui/DisplayListOp.h | 16 +-- libs/hwui/Layer.cpp | 7 +- libs/hwui/LayerRenderer.cpp | 19 ++-- libs/hwui/OpenGLRenderer.cpp | 90 +++++++-------- libs/hwui/OpenGLRenderer.h | 14 +-- libs/hwui/RenderState.cpp | 183 ------------------------------ libs/hwui/RenderState.h | 111 ------------------- libs/hwui/renderstate/RenderState.cpp | 184 +++++++++++++++++++++++++++++++ libs/hwui/renderstate/RenderState.h | 115 +++++++++++++++++++ libs/hwui/renderstate/Scissor.cpp | 84 ++++++++++++++ libs/hwui/renderstate/Scissor.h | 45 ++++++++ libs/hwui/renderthread/CanvasContext.cpp | 10 +- libs/hwui/renderthread/EglManager.cpp | 8 +- libs/hwui/renderthread/RenderThread.cpp | 10 +- libs/hwui/utils/Macros.h | 4 +- 18 files changed, 538 insertions(+), 488 deletions(-) delete mode 100644 libs/hwui/RenderState.cpp delete mode 100644 libs/hwui/RenderState.h create mode 100644 libs/hwui/renderstate/RenderState.cpp create mode 100644 libs/hwui/renderstate/RenderState.h create mode 100644 libs/hwui/renderstate/Scissor.cpp create mode 100644 libs/hwui/renderstate/Scissor.h diff --git a/libs/hwui/Android.common.mk b/libs/hwui/Android.common.mk index b1673fe..5079852 100644 --- a/libs/hwui/Android.common.mk +++ b/libs/hwui/Android.common.mk @@ -5,12 +5,21 @@ LOCAL_CLANG_CFLAGS += \ -Wno-gnu-static-float-init LOCAL_SRC_FILES := \ + font/CacheTexture.cpp \ + font/Font.cpp \ + renderstate/RenderState.cpp \ + renderstate/Scissor.cpp \ + renderthread/CanvasContext.cpp \ + renderthread/DrawFrameTask.cpp \ + renderthread/EglManager.cpp \ + renderthread/RenderProxy.cpp \ + renderthread/RenderTask.cpp \ + renderthread/RenderThread.cpp \ + renderthread/TimeLord.cpp \ + thread/TaskManager.cpp \ utils/Blur.cpp \ utils/GLUtils.cpp \ utils/SortedListImpl.cpp \ - thread/TaskManager.cpp \ - font/CacheTexture.cpp \ - font/Font.cpp \ AmbientShadow.cpp \ AnimationContext.cpp \ Animator.cpp \ @@ -48,7 +57,6 @@ LOCAL_SRC_FILES := \ RenderBufferCache.cpp \ RenderNode.cpp \ RenderProperties.cpp \ - RenderState.cpp \ ResourceCache.cpp \ ShadowTessellator.cpp \ SkiaCanvas.cpp \ @@ -61,16 +69,6 @@ LOCAL_SRC_FILES := \ TextureCache.cpp \ TextDropShadowCache.cpp -# RenderThread stuff -LOCAL_SRC_FILES += \ - renderthread/CanvasContext.cpp \ - renderthread/DrawFrameTask.cpp \ - renderthread/EglManager.cpp \ - renderthread/RenderProxy.cpp \ - renderthread/RenderTask.cpp \ - renderthread/RenderThread.cpp \ - renderthread/TimeLord.cpp - intermediates := $(call intermediates-dir-for,STATIC_LIBRARIES,libRS,TARGET,) LOCAL_C_INCLUDES += \ diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 107eb08..20dd21c 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -16,16 +16,17 @@ #define LOG_TAG "OpenGLRenderer" -#include -#include - #include "Caches.h" + #include "DisplayListRenderer.h" #include "GammaFontRenderer.h" -#include "Properties.h" #include "LayerRenderer.h" +#include "Properties.h" +#include "renderstate/RenderState.h" #include "ShadowTessellator.h" -#include "RenderState.h" + +#include +#include namespace android { @@ -80,10 +81,6 @@ bool Caches::init() { mTexCoordsArrayEnabled = false; - glDisable(GL_SCISSOR_TEST); - scissorEnabled = false; - mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0; - glActiveTexture(gTextureUnits[0]); mTextureUnit = 0; @@ -579,71 +576,6 @@ void Caches::unbindTexture(GLuint texture) { } /////////////////////////////////////////////////////////////////////////////// -// Scissor -/////////////////////////////////////////////////////////////////////////////// - -bool Caches::setScissor(GLint x, GLint y, GLint width, GLint height) { - if (scissorEnabled && (x != mScissorX || y != mScissorY || - width != mScissorWidth || height != mScissorHeight)) { - - if (x < 0) { - width += x; - x = 0; - } - if (y < 0) { - height += y; - y = 0; - } - if (width < 0) { - width = 0; - } - if (height < 0) { - height = 0; - } - glScissor(x, y, width, height); - - mScissorX = x; - mScissorY = y; - mScissorWidth = width; - mScissorHeight = height; - - return true; - } - return false; -} - -bool Caches::enableScissor() { - if (!scissorEnabled) { - glEnable(GL_SCISSOR_TEST); - scissorEnabled = true; - resetScissor(); - return true; - } - return false; -} - -bool Caches::disableScissor() { - if (scissorEnabled) { - glDisable(GL_SCISSOR_TEST); - scissorEnabled = false; - return true; - } - return false; -} - -void Caches::setScissorEnabled(bool enabled) { - if (scissorEnabled != enabled) { - if (enabled) glEnable(GL_SCISSOR_TEST); - else glDisable(GL_SCISSOR_TEST); - scissorEnabled = enabled; - } -} - -void Caches::resetScissor() { - mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0; -} - -/////////////////////////////////////////////////////////////////////////////// // Tiling /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index b0eebd7..fb75dd3 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -272,20 +272,6 @@ public: */ void unbindTexture(GLuint texture); - /** - * Sets the scissor for the current surface. - */ - bool setScissor(GLint x, GLint y, GLint width, GLint height); - - /** - * Resets the scissor state. - */ - void resetScissor(); - - bool enableScissor(); - bool disableScissor(); - void setScissorEnabled(bool enabled); - void startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool discard); void endTiling(); @@ -310,7 +296,6 @@ public: GLenum lastSrcMode; GLenum lastDstMode; Program* currentProgram; - bool scissorEnabled; bool drawDeferDisabled; bool drawReorderDisabled; @@ -408,11 +393,6 @@ private: GLuint mTextureUnit; - GLint mScissorX; - GLint mScissorY; - GLint mScissorWidth; - GLint mScissorHeight; - Extensions& mExtensions; // Used to render layers diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 36c14c4..d128ffe 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -17,13 +17,6 @@ #ifndef ANDROID_HWUI_DISPLAY_OPERATION_H #define ANDROID_HWUI_DISPLAY_OPERATION_H -#include -#include -#include -#include - -#include - #include "OpenGLRenderer.h" #include "AssetAtlas.h" #include "DeferredDisplayList.h" @@ -31,11 +24,18 @@ #include "GammaFontRenderer.h" #include "Patch.h" #include "RenderNode.h" -#include "RenderState.h" +#include "renderstate/RenderState.h" #include "UvMapper.h" #include "utils/LinearAllocator.h" #include "utils/PaintUtils.h" +#include +#include +#include +#include + +#include + // Use OP_LOG for logging with arglist, OP_LOGS if just printing char* #define OP_LOGS(s) OP_LOG("%s", (s)) #define OP_LOG(s, ...) ALOGD( "%*s" s, level * 2, "", __VA_ARGS__ ) diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 7388e3c..ee6154f 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -16,17 +16,18 @@ #define LOG_TAG "OpenGLRenderer" -#include +#include "Layer.h" #include "Caches.h" #include "DeferredDisplayList.h" -#include "Layer.h" #include "LayerRenderer.h" #include "OpenGLRenderer.h" #include "RenderNode.h" -#include "RenderState.h" +#include "renderstate/RenderState.h" #include "utils/TraceUtils.h" +#include + #define ATRACE_LAYER_WORK(label) \ ATRACE_FORMAT("%s HW Layer DisplayList %s %ux%u", \ label, \ diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp index 6ad1b19..076251f 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -17,18 +17,19 @@ #define LOG_TAG "OpenGLRenderer" #define ATRACE_TAG ATRACE_TAG_VIEW -#include - -#include - -#include "RenderState.h" #include "LayerCache.h" #include "LayerRenderer.h" #include "Matrix.h" #include "Properties.h" #include "Rect.h" +#include "renderstate/RenderState.h" #include "utils/TraceUtils.h" +#include + +#include + + namespace android { namespace uirenderer { @@ -48,7 +49,7 @@ void LayerRenderer::prepareDirty(float left, float top, float right, float botto bool opaque) { LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->getFbo()); - renderState().bindFramebuffer(mLayer->getFbo()); + mRenderState.bindFramebuffer(mLayer->getFbo()); const float width = mLayer->layer.getWidth(); const float height = mLayer->layer.getHeight(); @@ -70,10 +71,10 @@ void LayerRenderer::prepareDirty(float left, float top, float right, float botto void LayerRenderer::clear(float left, float top, float right, float bottom, bool opaque) { if (mLayer->isDirty()) { - getCaches().disableScissor(); + mRenderState.scissor().setEnabled(false); glClear(GL_COLOR_BUFFER_BIT); - getCaches().resetScissor(); + mRenderState.scissor().reset(); mLayer->setDirty(false); } else { OpenGLRenderer::clear(left, top, right, bottom, opaque); @@ -436,7 +437,7 @@ bool LayerRenderer::copyLayer(RenderState& renderState, Layer* layer, SkBitmap* renderer.OpenGLRenderer::prepareDirty(0.0f, 0.0f, bitmap->width(), bitmap->height(), !layer->isBlend()); - caches.disableScissor(); + renderState.scissor().setEnabled(false); renderer.translate(0.0f, bitmap->height()); renderer.scale(1.0f, -1.0f); diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 82f6ddd..0844cb6 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -16,23 +16,8 @@ #define LOG_TAG "OpenGLRenderer" -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - -#include - #include "OpenGLRenderer.h" + #include "DeferredDisplayList.h" #include "DisplayListRenderer.h" #include "Fence.h" @@ -41,7 +26,7 @@ #include "PathTessellator.h" #include "Properties.h" #include "RenderNode.h" -#include "RenderState.h" +#include "renderstate/RenderState.h" #include "ShadowTessellator.h" #include "SkiaShader.h" #include "Vector.h" @@ -50,6 +35,22 @@ #include "utils/PaintUtils.h" #include "utils/TraceUtils.h" +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include + #if DEBUG_DETAILED_EVENTS #define EVENT_LOGD(...) eventMarkDEBUG(__VA_ARGS__) #else @@ -135,10 +136,10 @@ static inline T min(T a, T b) { OpenGLRenderer::OpenGLRenderer(RenderState& renderState) : mState(*this) - , mFrameStarted(false) , mCaches(Caches::getInstance()) , mExtensions(Extensions::getInstance()) , mRenderState(renderState) + , mFrameStarted(false) , mScissorOptimizationDisabled(false) , mSuppressTiling(false) , mFirstFrameAfterResize(true) @@ -256,14 +257,14 @@ void OpenGLRenderer::discardFramebuffer(float left, float top, float right, floa void OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) { if (!opaque) { - mCaches.enableScissor(); - mCaches.setScissor(left, getViewportHeight() - bottom, right - left, bottom - top); + mRenderState.scissor().setEnabled(true); + mRenderState.scissor().set(left, getViewportHeight() - bottom, right - left, bottom - top); glClear(GL_COLOR_BUFFER_BIT); mDirty = true; return; } - mCaches.resetScissor(); + mRenderState.scissor().reset(); } void OpenGLRenderer::syncState() { @@ -347,7 +348,7 @@ void OpenGLRenderer::resumeAfterLayer() { mRenderState.bindFramebuffer(currentSnapshot()->fbo); debugOverdraw(true, false); - mCaches.resetScissor(); + mRenderState.scissor().reset(); dirtyClip(); } @@ -378,7 +379,7 @@ void OpenGLRenderer::callDrawGLFunction(Functor* functor, Rect& dirty) { if (mState.getDirtyClip()) { setStencilFromClip(); // can issue draws, so must precede enableScissor()/interrupt() } - if (mCaches.enableScissor() || prevDirtyClip) { + if (mRenderState.scissor().setEnabled(true) || prevDirtyClip) { setScissorFromClip(); } @@ -428,9 +429,11 @@ void OpenGLRenderer::renderOverdraw() { if (mCaches.debugOverdraw && onGetTargetFbo() == 0) { const Rect* clip = &mTilingClip; - mCaches.enableScissor(); - mCaches.setScissor(clip->left, mState.firstSnapshot()->getViewportHeight() - clip->bottom, - clip->right - clip->left, clip->bottom - clip->top); + mRenderState.scissor().setEnabled(true); + mRenderState.scissor().set(clip->left, + mState.firstSnapshot()->getViewportHeight() - clip->bottom, + clip->right - clip->left, + clip->bottom - clip->top); // 1x overdraw mCaches.stencil.enableDebugTest(2); @@ -835,8 +838,8 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip) { startTilingCurrentClip(true, true); // Clear the FBO, expand the clear region by 1 to get nice bilinear filtering - mCaches.enableScissor(); - mCaches.setScissor(clip.left - 1.0f, bounds.getHeight() - clip.bottom - 1.0f, + mRenderState.scissor().setEnabled(true); + mRenderState.scissor().set(clip.left - 1.0f, bounds.getHeight() - clip.bottom - 1.0f, clip.getWidth() + 2.0f, clip.getHeight() + 2.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -863,7 +866,7 @@ void OpenGLRenderer::composeLayer(const Snapshot& removed, const Snapshot& resto bool clipRequired = false; mState.calculateQuickRejectForScissor(rect.left, rect.top, rect.right, rect.bottom, &clipRequired, nullptr, false); // safely ignore return, should never be rejected - mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); + mRenderState.scissor().setEnabled(mScissorOptimizationDisabled || clipRequired); if (fboLayer) { endTiling(); @@ -1286,7 +1289,7 @@ void OpenGLRenderer::clearLayerRegions() { // The list contains bounds that have already been clipped // against their initial clip rect, and the current clip // is likely different so we need to disable clipping here - bool scissorChanged = mCaches.disableScissor(); + bool scissorChanged = mRenderState.scissor().setEnabled(false); Vertex mesh[count * 4]; Vertex* vertex = mesh; @@ -1317,7 +1320,7 @@ void OpenGLRenderer::clearLayerRegions() { issueIndexedQuadDraw(&mesh[0], count); - if (scissorChanged) mCaches.enableScissor(); + if (scissorChanged) mRenderState.scissor().setEnabled(true); } else { mLayers.clear(); } @@ -1406,7 +1409,8 @@ void OpenGLRenderer::setupMergedMultiDraw(const Rect* clipRect) { writableSnapshot()->setClip(0, 0, mState.getWidth(), mState.getHeight()); } dirtyClip(); - mCaches.setScissorEnabled(clipRect != nullptr || mScissorOptimizationDisabled); + bool enableScissor = (clipRect != nullptr) || mScissorOptimizationDisabled; + mRenderState.scissor().setEnabled(enableScissor); } /////////////////////////////////////////////////////////////////////////////// @@ -1417,7 +1421,7 @@ void OpenGLRenderer::setScissorFromClip() { Rect clip(mState.currentClipRect()); clip.snapToPixelBoundaries(); - if (mCaches.setScissor(clip.left, getViewportHeight() - clip.bottom, + if (mRenderState.scissor().set(clip.left, getViewportHeight() - clip.bottom, clip.getWidth(), clip.getHeight())) { mState.setDirtyClip(false); } @@ -1491,7 +1495,7 @@ void OpenGLRenderer::drawRectangleList(const RectangleList& rectangleList) { } } - mCaches.setScissor(scissorBox.left, getViewportHeight() - scissorBox.bottom, + mRenderState.scissor().set(scissorBox.left, getViewportHeight() - scissorBox.bottom, scissorBox.getWidth(), scissorBox.getHeight()); const SkPaint* paint = nullptr; @@ -1537,7 +1541,7 @@ void OpenGLRenderer::setStencilFromClip() { // Clean and update the stencil, but first make sure we restrict drawing // to the region's bounds - bool resetScissor = mCaches.enableScissor(); + bool resetScissor = mRenderState.scissor().setEnabled(true); if (resetScissor) { // The scissor was not set so we now need to update it setScissorFromClip(); @@ -1564,7 +1568,7 @@ void OpenGLRenderer::setStencilFromClip() { // so we don't want to dirty the current layer, if any drawRegionRects(clipArea.getClipRegion(), paint, false); } - if (resetScissor) mCaches.disableScissor(); + if (resetScissor) mRenderState.scissor().setEnabled(false); mSkipOutlineClip = storedSkipOutlineClip; mCaches.stencil.enableTest(incrementThreshold); @@ -1611,7 +1615,7 @@ bool OpenGLRenderer::quickRejectSetupScissor(float left, float top, float right, } // not quick rejected, so enable the scissor if clipRequired - mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); + mRenderState.scissor().setEnabled(mScissorOptimizationDisabled || clipRequired); mSkipOutlineClip = !roundRectClipRequired; return false; } @@ -1638,7 +1642,7 @@ void OpenGLRenderer::setupDraw(bool clearLayer) { // Make sure setScissor & setStencil happen at the beginning of // this method if (mState.getDirtyClip()) { - if (mCaches.scissorEnabled) { + if (mRenderState.scissor().isEnabled()) { setScissorFromClip(); } @@ -2094,7 +2098,7 @@ void OpenGLRenderer::drawBitmapMesh(const SkBitmap* bitmap, int meshWidth, int m } // TODO: use quickReject on bounds from vertices - mCaches.enableScissor(); + mRenderState.scissor().setEnabled(true); float left = FLT_MAX; float top = FLT_MAX; @@ -2738,7 +2742,7 @@ void OpenGLRenderer::drawPosText(const char* text, int bytesCount, int count, return; } - mCaches.enableScissor(); + mRenderState.scissor().setEnabled(true); float x = 0.0f; float y = 0.0f; @@ -2964,7 +2968,7 @@ void OpenGLRenderer::drawTextOnPath(const char* text, int bytesCount, int count, } // TODO: avoid scissor by calculating maximum bounds using path bounds + font metrics - mCaches.enableScissor(); + mRenderState.scissor().setEnabled(true); FontRenderer& fontRenderer = mCaches.fontRenderer->getFontRenderer(paint); fontRenderer.setFont(paint, SkMatrix::I()); @@ -3038,7 +3042,7 @@ void OpenGLRenderer::drawLayer(Layer* layer, float x, float y) { updateLayer(layer, true); - mCaches.setScissorEnabled(mScissorOptimizationDisabled || clipRequired); + mRenderState.scissor().setEnabled(mScissorOptimizationDisabled || clipRequired); mCaches.activeTexture(0); if (CC_LIKELY(!layer->region.isEmpty())) { @@ -3220,7 +3224,7 @@ void OpenGLRenderer::drawShadow(float casterAlpha, if (mState.currentlyIgnored()) return; // TODO: use quickRejectWithScissor. For now, always force enable scissor. - mCaches.enableScissor(); + mRenderState.scissor().setEnabled(true); SkPaint paint; paint.setAntiAlias(true); // want to use AlphaVertex diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 76ad6ce..94054ff 100755 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -222,6 +222,10 @@ public: return mCaches; } + RenderState& renderState() { + return mRenderState; + } + int getViewportWidth() { return mState.getViewportWidth(); } int getViewportHeight() { return mState.getViewportHeight(); } @@ -523,9 +527,10 @@ protected: return false; } - inline RenderState& renderState() { return mRenderState; } - CanvasState mState; + Caches& mCaches; + Extensions& mExtensions; // TODO: move to RenderState + RenderState& mRenderState; private: /** @@ -1027,11 +1032,6 @@ private: DrawModifiers mDrawModifiers; SkPaint mFilteredPaint; - // Various caches - Caches& mCaches; - Extensions& mExtensions; - RenderState& mRenderState; - // List of rectangles to clear after saveLayer() is invoked std::vector mLayers; // List of layers to update at the beginning of a frame diff --git a/libs/hwui/RenderState.cpp b/libs/hwui/RenderState.cpp deleted file mode 100644 index 45a97fb..0000000 --- a/libs/hwui/RenderState.cpp +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "RenderState.h" - -#include "renderthread/CanvasContext.h" -#include "renderthread/EglManager.h" - -namespace android { -namespace uirenderer { - -RenderState::RenderState(renderthread::RenderThread& thread) - : mRenderThread(thread) - , mCaches(nullptr) - , mViewportWidth(0) - , mViewportHeight(0) - , mFramebuffer(0) { - mThreadId = pthread_self(); -} - -RenderState::~RenderState() { -} - -void RenderState::onGLContextCreated() { - // This is delayed because the first access of Caches makes GL calls - mCaches = &Caches::getInstance(); - mCaches->init(); - mCaches->setRenderState(this); - mCaches->textureCache.setAssetAtlas(&mAssetAtlas); -} - -void RenderState::onGLContextDestroyed() { -/* - size_t size = mActiveLayers.size(); - if (CC_UNLIKELY(size != 0)) { - ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d", - mRegisteredContexts.size(), size, mActiveLayers.empty()); - mCaches->dumpMemoryUsage(); - for (std::set::iterator cit = mRegisteredContexts.begin(); - cit != mRegisteredContexts.end(); cit++) { - renderthread::CanvasContext* context = *cit; - ALOGE("Context: %p (root = %p)", context, context->mRootRenderNode.get()); - ALOGE(" Prefeteched layers: %zu", context->mPrefetechedLayers.size()); - for (std::set::iterator pit = context->mPrefetechedLayers.begin(); - pit != context->mPrefetechedLayers.end(); pit++) { - (*pit)->debugDumpLayers(" "); - } - context->mRootRenderNode->debugDumpLayers(" "); - } - - - if (mActiveLayers.begin() == mActiveLayers.end()) { - ALOGE("set has become empty. wat."); - } - for (std::set::iterator lit = mActiveLayers.begin(); - lit != mActiveLayers.end(); lit++) { - const Layer* layer = *(lit); - ALOGE("Layer %p, state %d, texlayer %d, fbo %d, buildlayered %d", - layer, layer->state, layer->isTextureLayer(), layer->getFbo(), layer->wasBuildLayered); - } - LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size); - } -*/ - mAssetAtlas.terminate(); -} - -void RenderState::setViewport(GLsizei width, GLsizei height) { - mViewportWidth = width; - mViewportHeight = height; - glViewport(0, 0, mViewportWidth, mViewportHeight); -} - - -void RenderState::getViewport(GLsizei* outWidth, GLsizei* outHeight) { - *outWidth = mViewportWidth; - *outHeight = mViewportHeight; -} - -void RenderState::bindFramebuffer(GLuint fbo) { - if (mFramebuffer != fbo) { - mFramebuffer = fbo; - glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); - } -} - -void RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) { - interruptForFunctorInvoke(); - (*functor)(mode, info); - resumeFromFunctorInvoke(); -} - -void RenderState::interruptForFunctorInvoke() { - if (mCaches->currentProgram) { - if (mCaches->currentProgram->isInUse()) { - mCaches->currentProgram->remove(); - mCaches->currentProgram = nullptr; - } - } - mCaches->resetActiveTexture(); - mCaches->unbindMeshBuffer(); - mCaches->unbindIndicesBuffer(); - mCaches->resetVertexPointers(); - mCaches->disableTexCoordsVertexArray(); - debugOverdraw(false, false); -} - -void RenderState::resumeFromFunctorInvoke() { - glViewport(0, 0, mViewportWidth, mViewportHeight); - glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); - debugOverdraw(false, false); - - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - - mCaches->scissorEnabled = glIsEnabled(GL_SCISSOR_TEST); - mCaches->enableScissor(); - mCaches->resetScissor(); - - mCaches->activeTexture(0); - mCaches->resetBoundTextures(); - - mCaches->blend = true; - glEnable(GL_BLEND); - glBlendFunc(mCaches->lastSrcMode, mCaches->lastDstMode); - glBlendEquation(GL_FUNC_ADD); -} - -void RenderState::debugOverdraw(bool enable, bool clear) { - if (mCaches->debugOverdraw && mFramebuffer == 0) { - if (clear) { - mCaches->disableScissor(); - mCaches->stencil.clear(); - } - if (enable) { - mCaches->stencil.enableDebugWrite(); - } else { - mCaches->stencil.disable(); - } - } -} - -void RenderState::requireGLContext() { - assertOnGLThread(); - mRenderThread.eglManager().requireGlContext(); -} - -void RenderState::assertOnGLThread() { - pthread_t curr = pthread_self(); - LOG_ALWAYS_FATAL_IF(!pthread_equal(mThreadId, curr), "Wrong thread!"); -} - - -class DecStrongTask : public renderthread::RenderTask { -public: - DecStrongTask(VirtualLightRefBase* object) : mObject(object) {} - - virtual void run() override { - mObject->decStrong(nullptr); - mObject = nullptr; - delete this; - } - -private: - VirtualLightRefBase* mObject; -}; - -void RenderState::postDecStrong(VirtualLightRefBase* object) { - mRenderThread.queue(new DecStrongTask(object)); -} - -} /* namespace uirenderer */ -} /* namespace android */ diff --git a/libs/hwui/RenderState.h b/libs/hwui/RenderState.h deleted file mode 100644 index 629fe0d..0000000 --- a/libs/hwui/RenderState.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef RENDERSTATE_H -#define RENDERSTATE_H - -#include -#include -#include -#include -#include -#include - -#include - -#include "AssetAtlas.h" -#include "Caches.h" -#include "utils/Macros.h" - -namespace android { -namespace uirenderer { - -class Caches; -class Layer; - -namespace renderthread { -class CanvasContext; -class RenderThread; -} - -// TODO: Replace Cache's GL state tracking with this. For now it's more a thin -// wrapper of Caches for users to migrate to. -class RenderState { - PREVENT_COPY_AND_ASSIGN(RenderState); -public: - void onGLContextCreated(); - void onGLContextDestroyed(); - - void setViewport(GLsizei width, GLsizei height); - void getViewport(GLsizei* outWidth, GLsizei* outHeight); - - void bindFramebuffer(GLuint fbo); - GLint getFramebuffer() { return mFramebuffer; } - - void invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info); - - void debugOverdraw(bool enable, bool clear); - - void registerLayer(const Layer* layer) { - mActiveLayers.insert(layer); - } - void unregisterLayer(const Layer* layer) { - mActiveLayers.erase(layer); - } - - void registerCanvasContext(renderthread::CanvasContext* context) { - mRegisteredContexts.insert(context); - } - - void unregisterCanvasContext(renderthread::CanvasContext* context) { - mRegisteredContexts.erase(context); - } - - void requireGLContext(); - - // TODO: This system is a little clunky feeling, this could use some - // more thinking... - void postDecStrong(VirtualLightRefBase* object); - - AssetAtlas& assetAtlas() { return mAssetAtlas; } - -private: - friend class renderthread::RenderThread; - friend class Caches; - - void interruptForFunctorInvoke(); - void resumeFromFunctorInvoke(); - void assertOnGLThread(); - - RenderState(renderthread::RenderThread& thread); - ~RenderState(); - - renderthread::RenderThread& mRenderThread; - Caches* mCaches; - AssetAtlas mAssetAtlas; - std::set mActiveLayers; - std::set mRegisteredContexts; - - GLsizei mViewportWidth; - GLsizei mViewportHeight; - GLuint mFramebuffer; - - pthread_t mThreadId; -}; - -} /* namespace uirenderer */ -} /* namespace android */ - -#endif /* RENDERSTATE_H */ diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp new file mode 100644 index 0000000..3a9a92e --- /dev/null +++ b/libs/hwui/renderstate/RenderState.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "RenderState.h" + +#include "renderthread/CanvasContext.h" +#include "renderthread/EglManager.h" + +namespace android { +namespace uirenderer { + +RenderState::RenderState(renderthread::RenderThread& thread) + : mRenderThread(thread) + , mCaches(nullptr) + , mViewportWidth(0) + , mViewportHeight(0) + , mFramebuffer(0) { + mThreadId = pthread_self(); +} + +RenderState::~RenderState() { +} + +void RenderState::onGLContextCreated() { + // This is delayed because the first access of Caches makes GL calls + mCaches = &Caches::getInstance(); + mCaches->init(); + mCaches->setRenderState(this); + mCaches->textureCache.setAssetAtlas(&mAssetAtlas); + + LOG_ALWAYS_FATAL_IF(scissor().isEnabled(), "scissor used before GL context created"); + glDisable(GL_SCISSOR_TEST); +} + +void RenderState::onGLContextDestroyed() { +/* + size_t size = mActiveLayers.size(); + if (CC_UNLIKELY(size != 0)) { + ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d", + mRegisteredContexts.size(), size, mActiveLayers.empty()); + mCaches->dumpMemoryUsage(); + for (std::set::iterator cit = mRegisteredContexts.begin(); + cit != mRegisteredContexts.end(); cit++) { + renderthread::CanvasContext* context = *cit; + ALOGE("Context: %p (root = %p)", context, context->mRootRenderNode.get()); + ALOGE(" Prefeteched layers: %zu", context->mPrefetechedLayers.size()); + for (std::set::iterator pit = context->mPrefetechedLayers.begin(); + pit != context->mPrefetechedLayers.end(); pit++) { + (*pit)->debugDumpLayers(" "); + } + context->mRootRenderNode->debugDumpLayers(" "); + } + + + if (mActiveLayers.begin() == mActiveLayers.end()) { + ALOGE("set has become empty. wat."); + } + for (std::set::iterator lit = mActiveLayers.begin(); + lit != mActiveLayers.end(); lit++) { + const Layer* layer = *(lit); + ALOGE("Layer %p, state %d, texlayer %d, fbo %d, buildlayered %d", + layer, layer->state, layer->isTextureLayer(), layer->getFbo(), layer->wasBuildLayered); + } + LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size); + } +*/ + mAssetAtlas.terminate(); +} + +void RenderState::setViewport(GLsizei width, GLsizei height) { + mViewportWidth = width; + mViewportHeight = height; + glViewport(0, 0, mViewportWidth, mViewportHeight); +} + + +void RenderState::getViewport(GLsizei* outWidth, GLsizei* outHeight) { + *outWidth = mViewportWidth; + *outHeight = mViewportHeight; +} + +void RenderState::bindFramebuffer(GLuint fbo) { + if (mFramebuffer != fbo) { + mFramebuffer = fbo; + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + } +} + +void RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) { + interruptForFunctorInvoke(); + (*functor)(mode, info); + resumeFromFunctorInvoke(); +} + +void RenderState::interruptForFunctorInvoke() { + if (mCaches->currentProgram) { + if (mCaches->currentProgram->isInUse()) { + mCaches->currentProgram->remove(); + mCaches->currentProgram = nullptr; + } + } + mCaches->resetActiveTexture(); + mCaches->unbindMeshBuffer(); + mCaches->unbindIndicesBuffer(); + mCaches->resetVertexPointers(); + mCaches->disableTexCoordsVertexArray(); + debugOverdraw(false, false); +} + +void RenderState::resumeFromFunctorInvoke() { + glViewport(0, 0, mViewportWidth, mViewportHeight); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + debugOverdraw(false, false); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + + scissor().invalidate(); + + mCaches->activeTexture(0); + mCaches->resetBoundTextures(); + + mCaches->blend = true; + glEnable(GL_BLEND); + glBlendFunc(mCaches->lastSrcMode, mCaches->lastDstMode); + glBlendEquation(GL_FUNC_ADD); +} + +void RenderState::debugOverdraw(bool enable, bool clear) { + if (mCaches->debugOverdraw && mFramebuffer == 0) { + if (clear) { + scissor().setEnabled(false); + mCaches->stencil.clear(); + } + if (enable) { + mCaches->stencil.enableDebugWrite(); + } else { + mCaches->stencil.disable(); + } + } +} + +void RenderState::requireGLContext() { + assertOnGLThread(); + mRenderThread.eglManager().requireGlContext(); +} + +void RenderState::assertOnGLThread() { + pthread_t curr = pthread_self(); + LOG_ALWAYS_FATAL_IF(!pthread_equal(mThreadId, curr), "Wrong thread!"); +} + + +class DecStrongTask : public renderthread::RenderTask { +public: + DecStrongTask(VirtualLightRefBase* object) : mObject(object) {} + + virtual void run() override { + mObject->decStrong(nullptr); + mObject = nullptr; + delete this; + } + +private: + VirtualLightRefBase* mObject; +}; + +void RenderState::postDecStrong(VirtualLightRefBase* object) { + mRenderThread.queue(new DecStrongTask(object)); +} + +} /* namespace uirenderer */ +} /* namespace android */ diff --git a/libs/hwui/renderstate/RenderState.h b/libs/hwui/renderstate/RenderState.h new file mode 100644 index 0000000..b2d5cc5 --- /dev/null +++ b/libs/hwui/renderstate/RenderState.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef RENDERSTATE_H +#define RENDERSTATE_H + +#include +#include +#include +#include +#include +#include + +#include + +#include "AssetAtlas.h" +#include "Caches.h" +#include "Scissor.h" +#include "utils/Macros.h" + +namespace android { +namespace uirenderer { + +class Caches; +class Layer; + +namespace renderthread { +class CanvasContext; +class RenderThread; +} + +// TODO: Replace Cache's GL state tracking with this. For now it's more a thin +// wrapper of Caches for users to migrate to. +class RenderState { + PREVENT_COPY_AND_ASSIGN(RenderState); +public: + void onGLContextCreated(); + void onGLContextDestroyed(); + + void setViewport(GLsizei width, GLsizei height); + void getViewport(GLsizei* outWidth, GLsizei* outHeight); + + void bindFramebuffer(GLuint fbo); + GLint getFramebuffer() { return mFramebuffer; } + + void invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info); + + void debugOverdraw(bool enable, bool clear); + + void registerLayer(const Layer* layer) { + mActiveLayers.insert(layer); + } + void unregisterLayer(const Layer* layer) { + mActiveLayers.erase(layer); + } + + void registerCanvasContext(renderthread::CanvasContext* context) { + mRegisteredContexts.insert(context); + } + + void unregisterCanvasContext(renderthread::CanvasContext* context) { + mRegisteredContexts.erase(context); + } + + void requireGLContext(); + + // TODO: This system is a little clunky feeling, this could use some + // more thinking... + void postDecStrong(VirtualLightRefBase* object); + + AssetAtlas& assetAtlas() { return mAssetAtlas; } + + Scissor& scissor() { return mScissor; } +private: + friend class renderthread::RenderThread; + friend class Caches; + + void interruptForFunctorInvoke(); + void resumeFromFunctorInvoke(); + void assertOnGLThread(); + + RenderState(renderthread::RenderThread& thread); + ~RenderState(); + + Scissor mScissor; + + renderthread::RenderThread& mRenderThread; + Caches* mCaches; + AssetAtlas mAssetAtlas; + std::set mActiveLayers; + std::set mRegisteredContexts; + + GLsizei mViewportWidth; + GLsizei mViewportHeight; + GLuint mFramebuffer; + + pthread_t mThreadId; +}; + +} /* namespace uirenderer */ +} /* namespace android */ + +#endif /* RENDERSTATE_H */ diff --git a/libs/hwui/renderstate/Scissor.cpp b/libs/hwui/renderstate/Scissor.cpp new file mode 100644 index 0000000..ede57be --- /dev/null +++ b/libs/hwui/renderstate/Scissor.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "Scissor.h" + +namespace android { +namespace uirenderer { + +Scissor::Scissor() + : mEnabled(false) + , mScissorX(0) + , mScissorY(0) + , mScissorWidth(0) + , mScissorHeight(0) { +} + +bool Scissor::setEnabled(bool enabled) { + if (mEnabled != enabled) { + if (enabled) { + glEnable(GL_SCISSOR_TEST); + } else { + glDisable(GL_SCISSOR_TEST); + } + mEnabled = enabled; + return true; + } + return false; +} + +bool Scissor::set(GLint x, GLint y, GLint width, GLint height) { + if (mEnabled && (x != mScissorX || y != mScissorY + || width != mScissorWidth || height != mScissorHeight)) { + + if (x < 0) { + width += x; + x = 0; + } + if (y < 0) { + height += y; + y = 0; + } + if (width < 0) { + width = 0; + } + if (height < 0) { + height = 0; + } + glScissor(x, y, width, height); + + mScissorX = x; + mScissorY = y; + mScissorWidth = width; + mScissorHeight = height; + + return true; + } + return false; +} + +void Scissor::reset() { + mScissorX = mScissorY = mScissorWidth = mScissorHeight = 0; +} + +void Scissor::invalidate() { + mEnabled = glIsEnabled(GL_SCISSOR_TEST); + setEnabled(true); + reset(); +} + +} /* namespace uirenderer */ +} /* namespace android */ + diff --git a/libs/hwui/renderstate/Scissor.h b/libs/hwui/renderstate/Scissor.h new file mode 100644 index 0000000..eabf3a7 --- /dev/null +++ b/libs/hwui/renderstate/Scissor.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef RENDERSTATE_SCISSOR_H +#define RENDERSTATE_SCISSOR_H + +#include +#include + +namespace android { +namespace uirenderer { + +class Scissor { + friend class RenderState; +public: + Scissor(); + bool setEnabled(bool enabled); + bool set(GLint x, GLint y, GLint width, GLint height); + void reset(); + bool isEnabled() { return mEnabled; } +private: + void invalidate(); + bool mEnabled; + GLint mScissorX; + GLint mScissorY; + GLint mScissorWidth; + GLint mScissorHeight; +}; + +} /* namespace uirenderer */ +} /* namespace android */ + +#endif // RENDERSTATE_SCISSOR_H diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 71ecba5..4d5d8c8 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -16,20 +16,20 @@ #include "CanvasContext.h" -#include -#include -#include - #include "EglManager.h" #include "RenderThread.h" #include "../AnimationContext.h" #include "../Caches.h" #include "../DeferredLayerUpdater.h" -#include "../RenderState.h" +#include "../renderstate/RenderState.h" #include "../LayerRenderer.h" #include "../OpenGLRenderer.h" #include "../Stencil.h" +#include +#include +#include + #define TRIM_MEMORY_COMPLETE 80 #define TRIM_MEMORY_UI_HIDDEN 20 diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index 0aa0439..c4feb41 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -16,13 +16,13 @@ #include "EglManager.h" -#include -#include - #include "../Caches.h" -#include "../RenderState.h" +#include "../renderstate/RenderState.h" #include "RenderThread.h" +#include +#include + #define PROPERTY_RENDER_DIRTY_REGIONS "debug.hwui.render_dirty_regions" #define GLES_VERSION 2 diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 22b5a97..9a0fbad 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -16,15 +16,15 @@ #include "RenderThread.h" -#include -#include -#include - -#include "../RenderState.h" +#include "../renderstate/RenderState.h" #include "CanvasContext.h" #include "EglManager.h" #include "RenderProxy.h" +#include +#include +#include + namespace android { using namespace uirenderer::renderthread; ANDROID_SINGLETON_STATIC_INSTANCE(RenderThread); diff --git a/libs/hwui/utils/Macros.h b/libs/hwui/utils/Macros.h index 5b7c87c..fe43fdb 100644 --- a/libs/hwui/utils/Macros.h +++ b/libs/hwui/utils/Macros.h @@ -18,8 +18,8 @@ #define PREVENT_COPY_AND_ASSIGN(Type) \ private: \ - Type(const Type&); \ - void operator=(const Type&) + Type(const Type&) = delete; \ + void operator=(const Type&) = delete #define DESCRIPTION_TYPE(Type) \ int compare(const Type& rhs) const { return memcmp(this, &rhs, sizeof(Type));} \ -- cgit v1.1