From 3ff0bfdd144bba3b023eda8c49b25fb0d0de8653 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Mon, 25 Feb 2013 14:15:37 -0800 Subject: [PATCH] Add new property to debug non-rectangular clip operations This change adds a new property called "debug.hwui.show_stencil_clip" that accepts the following values: - "highlight", colorizes in green any drawing command that's tested against a non-rectangular clip region - "region", shows the non-rectangular clip region in blue every time it is used - "hide", default value, nothing is shown Change-Id: I83c8602310edc4aaeb8b905371cdd185b17d32b5 --- libs/hwui/Caches.cpp | 19 ++++++++++++++++++- libs/hwui/Caches.h | 9 +++++++++ libs/hwui/Debug.h | 1 + libs/hwui/OpenGLRenderer.cpp | 14 ++++++++++++++ libs/hwui/Program.h | 7 +++++++ libs/hwui/ProgramCache.cpp | 8 +++++++- libs/hwui/Properties.h | 14 ++++++++++++++ libs/hwui/Stencil.h | 7 +++++++ 8 files changed, 77 insertions(+), 2 deletions(-) diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 88f1d83bf84de..5befb9518dd19 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -91,6 +91,7 @@ void Caches::init() { debugLayersUpdates = false; debugOverdraw = false; + debugStencilClip = kStencilHide; mInitialized = true; } @@ -132,6 +133,7 @@ void Caches::initConstraints() { bool Caches::initProperties() { bool prevDebugLayersUpdates = debugLayersUpdates; bool prevDebugOverdraw = debugOverdraw; + StencilClipDebug prevDebugStencilClip = debugStencilClip; char property[PROPERTY_VALUE_MAX]; if (property_get(PROPERTY_DEBUG_LAYERS_UPDATES, property, NULL) > 0) { @@ -148,8 +150,23 @@ bool Caches::initProperties() { debugOverdraw = false; } + // See Properties.h for valid values + if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, NULL) > 0) { + INIT_LOGD(" Stencil clip debug enabled: %s", property); + if (!strcmp(property, "hide")) { + debugStencilClip = kStencilHide; + } else if (!strcmp(property, "highlight")) { + debugStencilClip = kStencilShowHighlight; + } else if (!strcmp(property, "region")) { + debugStencilClip = kStencilShowRegion; + } + } else { + debugStencilClip = kStencilHide; + } + return (prevDebugLayersUpdates != debugLayersUpdates) || - (prevDebugOverdraw != debugOverdraw); + (prevDebugOverdraw != debugOverdraw) || + (prevDebugStencilClip != debugStencilClip); } void Caches::terminate() { diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 0ca2ffd40a802..c35ad8838f2b9 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -245,9 +245,18 @@ public: // Misc GLint maxTextureSize; + + // Debugging bool debugLayersUpdates; bool debugOverdraw; + enum StencilClipDebug { + kStencilHide, + kStencilShowHighlight, + kStencilShowRegion + }; + StencilClipDebug debugStencilClip; + TextureCache textureCache; LayerCache layerCache; RenderBufferCache renderBufferCache; diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h index 9a6494fac2fc1..773fe82f31a55 100644 --- a/libs/hwui/Debug.h +++ b/libs/hwui/Debug.h @@ -48,6 +48,7 @@ #define DEBUG_RENDER_BUFFERS 0 // Turn on to make stencil operations easier to debug +// (writes 255 instead of 1 in the buffer, forces 8 bit stencil) #define DEBUG_STENCIL 0 // Turn on to display debug info about 9patch objects diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 1afeaf0a04444..34d1c983f87d0 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1368,6 +1368,12 @@ void OpenGLRenderer::setStencilFromClip() { drawRegionRects(*mSnapshot->clipRegion, 0xff000000, SkXfermode::kSrc_Mode, false); mCaches.stencil.enableTest(); + + // Draw the region used to generate the stencil if the appropriate debug + // mode is enabled + if (mCaches.debugStencilClip == Caches::kStencilShowRegion) { + drawRegionRects(*mSnapshot->clipRegion, 0x7f0000ff, SkXfermode::kSrcOver_Mode); + } } else { mCaches.stencil.disable(); } @@ -1515,12 +1521,20 @@ void OpenGLRenderer::setupDraw(bool clear) { } setStencilFromClip(); } + mDescription.reset(); + mSetShaderColor = false; mColorSet = false; mColorA = mColorR = mColorG = mColorB = 0.0f; mTextureUnit = 0; mTrackDirtyRegions = true; + + // Enable debug highlight when what we're about to draw is tested against + // the stencil buffer and if stencil highlight debugging is on + mDescription.hasDebugHighlight = !mCaches.debugOverdraw && + mCaches.debugStencilClip == Caches::kStencilShowHighlight && + mCaches.stencil.isTestEnabled(); } void OpenGLRenderer::setupDrawWithTexture(bool isAlpha8) { diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index 7b67b3c3ffc3c..13ee336192d7f 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -83,6 +83,8 @@ namespace uirenderer { #define PROGRAM_HAS_COLORS 42 +#define PROGRAM_HAS_DEBUG_HIGHLIGHT 43 + /////////////////////////////////////////////////////////////////////////////// // Types /////////////////////////////////////////////////////////////////////////////// @@ -159,6 +161,8 @@ struct ProgramDescription { bool hasGammaCorrection; float gamma; + bool hasDebugHighlight; + /** * Resets this description. All fields are reset back to the default * values they hold after building a new instance. @@ -199,6 +203,8 @@ struct ProgramDescription { hasGammaCorrection = false; gamma = 2.2f; + + hasDebugHighlight = false; } /** @@ -267,6 +273,7 @@ struct ProgramDescription { if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION; 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; return key; } diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 74d598d5311e9..0f014cbfa96ac 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -351,6 +351,8 @@ const char* gFS_Main_ApplyColorOp[4] = { // PorterDuff " fragColor = blendColors(colorBlend, fragColor);\n" }; +const char* gFS_Main_DebugHighlight = + " gl_FragColor.rgb = vec3(0.0, gl_FragColor.a, 0.0);\n"; const char* gFS_Footer = "}\n\n"; @@ -604,7 +606,8 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti // Optimization for common cases if (!description.isAA && !blendFramebuffer && !description.hasColors && - description.colorOp == ProgramDescription::kColorNone && !description.isPoint) { + description.colorOp == ProgramDescription::kColorNone && + !description.isPoint && !description.hasDebugHighlight) { bool fast = false; const bool noShader = !description.hasGradient && !description.hasBitmap; @@ -752,6 +755,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti if (description.hasColors) { shader.append(gFS_Main_FragColor_HasColors); } + if (description.hasDebugHighlight) { + shader.append(gFS_Main_DebugHighlight); + } } // End the shader shader.append(gFS_Footer); diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index f3957cfc26079..4ee16edf36696 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -67,6 +67,20 @@ enum DebugLevel { */ #define PROPERTY_DEBUG_OVERDRAW "debug.hwui.show_overdraw" +/** + * Used to enable/disable non-rectangular clipping debugging. + * + * The accepted values are: + * "highlight", drawing commands clipped by the stencil will + * be colored differently + * "region", renders the clipping region on screen whenever + * the stencil is set + * "hide", don't show the clip + * + * The default value is "hide". + */ +#define PROPERTY_DEBUG_STENCIL_CLIP "debug.hwui.show_stencil_clip" + /** * Used to enable/disable scissor optimization. The accepted values are * "true" and "false". The default value is "false". diff --git a/libs/hwui/Stencil.h b/libs/hwui/Stencil.h index 047f7ee111a0d..83ad6681a7f84 100644 --- a/libs/hwui/Stencil.h +++ b/libs/hwui/Stencil.h @@ -87,6 +87,13 @@ public: return mState != kDisabled; } + /** + * Indicates whether testing only is enabled. + */ + bool isTestEnabled() { + return mState == kTest; + } + private: void enable();