diff options
Diffstat (limited to 'libs')
| -rw-r--r-- | libs/hwui/Caches.cpp | 2 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 39 | ||||
| -rw-r--r-- | libs/hwui/OpenGLRenderer.h | 15 | ||||
| -rw-r--r-- | libs/hwui/Program.h | 3 | ||||
| -rw-r--r-- | libs/hwui/ProgramCache.cpp | 15 | ||||
| -rw-r--r-- | libs/hwui/Properties.h | 4 | ||||
| -rw-r--r-- | libs/hwui/thread/TaskManager.h | 2 |
7 files changed, 73 insertions, 7 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index c60848c..f08b5ca 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -152,7 +152,7 @@ bool Caches::initProperties() { if (property_get(PROPERTY_DEBUG_OVERDRAW, property, NULL) > 0) { INIT_LOGD(" Overdraw debug enabled: %s", property); - debugOverdraw = !strcmp(property, "true"); + debugOverdraw = !strcmp(property, "show"); } else { debugOverdraw = false; } diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 025e9f8..1447eb7 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -21,7 +21,6 @@ #include <sys/types.h> #include <SkCanvas.h> -#include <SkPathMeasure.h> #include <SkTypeface.h> #include <utils/Log.h> @@ -120,6 +119,7 @@ OpenGLRenderer::OpenGLRenderer(): mFirstSnapshot = new Snapshot; mFrameStarted = false; + mCountOverdraw = false; mScissorOptimizationDisabled = false; } @@ -222,6 +222,7 @@ status_t OpenGLRenderer::prepare(bool opaque) { status_t OpenGLRenderer::prepareDirty(float left, float top, float right, float bottom, bool opaque) { + setupFrameState(left, top, right, bottom, opaque); // Layer renderers will start the frame immediately @@ -253,7 +254,7 @@ void OpenGLRenderer::discardFramebuffer(float left, float top, float right, floa } status_t OpenGLRenderer::clear(float left, float top, float right, float bottom, bool opaque) { - if (!opaque) { + if (!opaque || mCountOverdraw) { mCaches.enableScissor(); mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top); glClear(GL_COLOR_BUFFER_BIT); @@ -335,6 +336,10 @@ void OpenGLRenderer::finish() { #endif } + if (mCountOverdraw) { + countOverdraw(); + } + mFrameStarted = false; } @@ -524,6 +529,21 @@ void OpenGLRenderer::renderOverdraw() { } } +void OpenGLRenderer::countOverdraw() { + size_t count = mWidth * mHeight; + uint32_t* buffer = new uint32_t[count]; + glReadPixels(0, 0, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, &buffer[0]); + + size_t total = 0; + for (size_t i = 0; i < count; i++) { + total += buffer[i] & 0xff; + } + + mOverdraw = total / float(count); + + delete[] buffer; +} + /////////////////////////////////////////////////////////////////////////////// // Layers /////////////////////////////////////////////////////////////////////////////// @@ -1656,6 +1676,8 @@ void OpenGLRenderer::setupDraw(bool clear) { mDescription.hasDebugHighlight = !mCaches.debugOverdraw && mCaches.debugStencilClip == Caches::kStencilShowHighlight && mCaches.stencil.isTestEnabled(); + + mDescription.emulateStencil = mCountOverdraw; } void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) { @@ -3546,6 +3568,19 @@ void OpenGLRenderer::drawAlpha8TextureMesh(float left, float top, float right, f void OpenGLRenderer::chooseBlending(bool blend, SkXfermode::Mode mode, ProgramDescription& description, bool swapSrcDst) { + if (mCountOverdraw) { + if (!mCaches.blend) glEnable(GL_BLEND); + if (mCaches.lastSrcMode != GL_ONE || mCaches.lastDstMode != GL_ONE) { + glBlendFunc(GL_ONE, GL_ONE); + } + + mCaches.blend = true; + mCaches.lastSrcMode = GL_ONE; + mCaches.lastDstMode = GL_ONE; + + return; + } + blend = blend || mode != SkXfermode::kSrcOver_Mode; if (blend) { diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 640c7db..df275d7 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -192,6 +192,14 @@ public: */ virtual void resume(); + ANDROID_API void setCountOverdrawEnabled(bool enabled) { + mCountOverdraw = enabled; + } + + ANDROID_API float getOverdraw() { + return mCountOverdraw ? mOverdraw : 0.0f; + } + ANDROID_API status_t invokeFunctors(Rect& dirty); ANDROID_API void detachFunctor(Functor* functor); ANDROID_API void attachFunctor(Functor* functor); @@ -981,6 +989,7 @@ private: void debugOverdraw(bool enable, bool clear); void renderOverdraw(); + void countOverdraw(); /** * Should be invoked every time the glScissor is modified. @@ -1072,6 +1081,12 @@ private: // No-ops start/endTiling when set bool mSuppressTiling; + + // If true, this renderer will setup drawing to emulate + // an increment stencil buffer in the color buffer + bool mCountOverdraw; + float mOverdraw; + // Optional name of the renderer String8 mName; diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index a252209..dd1aaa2 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -85,6 +85,7 @@ namespace uirenderer { #define PROGRAM_HAS_COLORS 42 #define PROGRAM_HAS_DEBUG_HIGHLIGHT 43 +#define PROGRAM_EMULATE_STENCIL 44 /////////////////////////////////////////////////////////////////////////////// // Types @@ -163,6 +164,7 @@ struct ProgramDescription { float gamma; bool hasDebugHighlight; + bool emulateStencil; /** * Resets this description. All fields are reset back to the default @@ -275,6 +277,7 @@ struct ProgramDescription { if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT; if (hasColors) key |= programid(0x1) << PROGRAM_HAS_COLORS; if (hasDebugHighlight) key |= programid(0x1) << PROGRAM_HAS_DEBUG_HIGHLIGHT; + if (emulateStencil) key |= programid(0x1) << PROGRAM_EMULATE_STENCIL; return key; } diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 8eb85e5..367294c 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -342,6 +342,12 @@ const char* gFS_Main_ApplyColorOp[4] = { }; const char* gFS_Main_DebugHighlight = " gl_FragColor.rgb = vec3(0.0, gl_FragColor.a, 0.0);\n"; +const char* gFS_Main_EmulateStencil = + " gl_FragColor.rgba = vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 1.0);\n" + " return;\n" + " /*\n"; +const char* gFS_Footer_EmulateStencil = + " */\n"; const char* gFS_Footer = "}\n\n"; @@ -603,7 +609,8 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti // Optimization for common cases if (!description.isAA && !blendFramebuffer && !description.hasColors && description.colorOp == ProgramDescription::kColorNone && - !description.isPoint && !description.hasDebugHighlight) { + !description.isPoint && !description.hasDebugHighlight && + !description.emulateStencil) { bool fast = false; const bool noShader = !description.hasGradient && !description.hasBitmap; @@ -683,6 +690,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti // Begin the shader shader.append(gFS_Main); { + if (description.emulateStencil) { + shader.append(gFS_Main_EmulateStencil); + } // Stores the result in fragColor directly if (description.hasTexture || description.hasExternalTexture) { if (description.hasAlpha8Texture) { @@ -757,6 +767,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti shader.append(gFS_Main_DebugHighlight); } } + if (description.emulateStencil) { + shader.append(gFS_Footer_EmulateStencil); + } // End the shader shader.append(gFS_Footer); diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 87ac845..7c68b5b 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -71,9 +71,9 @@ enum DebugLevel { /** * Used to enable/disable overdraw debugging. The accepted values are - * "true" and "false". The default value is "false". + * "show", "count" and "false". The default value is "false". */ -#define PROPERTY_DEBUG_OVERDRAW "debug.hwui.show_overdraw" +#define PROPERTY_DEBUG_OVERDRAW "debug.hwui.overdraw" /** * Used to enable/disable non-rectangular clipping debugging. diff --git a/libs/hwui/thread/TaskManager.h b/libs/hwui/thread/TaskManager.h index 477314b..f2a216f 100644 --- a/libs/hwui/thread/TaskManager.h +++ b/libs/hwui/thread/TaskManager.h @@ -43,7 +43,7 @@ public: /** * Returns true if this task manager can run tasks, * false otherwise. This method will typically return - * true on a single CPU core device. + * false on a single CPU core device. */ bool canRunTasks() const; |
