diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/Caches.cpp | 11 | ||||
-rw-r--r-- | libs/hwui/Caches.h | 1 | ||||
-rwxr-xr-x | libs/hwui/Dither.cpp | 4 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 47 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 3 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.cpp | 53 | ||||
-rw-r--r-- | libs/hwui/Properties.h | 10 | ||||
-rw-r--r-- | libs/hwui/Stencil.cpp | 23 | ||||
-rw-r--r-- | libs/hwui/Stencil.h | 10 |
9 files changed, 136 insertions, 26 deletions
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index 068eb9e..22f1dec 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -131,6 +131,13 @@ void Caches::initProperties() { } else { debugLayersUpdates = false; } + + if (property_get(PROPERTY_DEBUG_OVERDRAW, property, NULL) > 0) { + INIT_LOGD(" Overdraw debug enabled: %s", property); + debugOverdraw = !strcmp(property, "true"); + } else { + debugOverdraw = false; + } } void Caches::terminate() { @@ -429,7 +436,9 @@ void Caches::resetScissor() { void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool opaque) { if (extensions.hasTiledRendering()) { - glStartTilingQCOM(x, y, width, height, opaque ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM); + glStartTilingQCOM(x, y, width, height, + (opaque ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM) | + (debugOverdraw ? GL_STENCIL_BUFFER_BIT0_QCOM : 0)); } } diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 50e9e75..48efd10 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -242,6 +242,7 @@ public: // Misc GLint maxTextureSize; bool debugLayersUpdates; + bool debugOverdraw; TextureCache textureCache; LayerCache layerCache; diff --git a/libs/hwui/Dither.cpp b/libs/hwui/Dither.cpp index 5817977..e80b325 100755 --- a/libs/hwui/Dither.cpp +++ b/libs/hwui/Dither.cpp @@ -76,8 +76,10 @@ void Dither::setupProgram(Program* program, GLuint* textureUnit) { bindDitherTexture(); + float ditherSize = 1.0f / DITHER_KERNEL_SIZE; glUniform1i(program->getUniform("ditherSampler"), textureSlot); - glUniform1f(program->getUniform("ditherSize"), 1.0f / DITHER_KERNEL_SIZE); + glUniform1f(program->getUniform("ditherSize"), ditherSize); + glUniform1f(program->getUniform("ditherSizeSquared"), ditherSize * ditherSize); } }; // namespace uirenderer diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index bdf1229..a4403c8 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -194,6 +194,8 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto mTilingSnapshot = mSnapshot; startTiling(mTilingSnapshot, true); + debugOverdraw(true, true); + if (!opaque) { mCaches.enableScissor(); mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top); @@ -231,6 +233,7 @@ void OpenGLRenderer::endTiling() { } void OpenGLRenderer::finish() { + renderOverdraw(); endTiling(); if (!suppressErrorChecks()) { @@ -265,6 +268,40 @@ void OpenGLRenderer::finish() { } } +void OpenGLRenderer::debugOverdraw(bool enable, bool clear) { + if (mCaches.debugOverdraw && getTargetFbo() == 0) { + if (clear) { + mCaches.disableScissor(); + mCaches.stencil.clear(); + } + if (enable) { + mCaches.stencil.enableDebugWrite(); + } else { + mCaches.stencil.disable(); + } + } +} + +void OpenGLRenderer::renderOverdraw() { + if (mCaches.debugOverdraw && getTargetFbo() == 0) { + const Rect* clip = mTilingSnapshot->clipRect; + + mCaches.enableScissor(); + mCaches.setScissor(clip->left, mTilingSnapshot->height - clip->bottom, + clip->right - clip->left, clip->bottom - clip->top); + + mCaches.stencil.enableDebugTest(2); + drawColor(0x2f0000ff, SkXfermode::kSrcOver_Mode); + mCaches.stencil.enableDebugTest(3); + drawColor(0x2f00ff00, SkXfermode::kSrcOver_Mode); + mCaches.stencil.enableDebugTest(4); + drawColor(0x3fff0000, SkXfermode::kSrcOver_Mode); + mCaches.stencil.enableDebugTest(4, true); + drawColor(0x7fff0000, SkXfermode::kSrcOver_Mode); + mCaches.stencil.disable(); + } +} + void OpenGLRenderer::interrupt() { if (mCaches.currentProgram) { if (mCaches.currentProgram->isInUse()) { @@ -276,12 +313,14 @@ void OpenGLRenderer::interrupt() { mCaches.unbindIndicesBuffer(); mCaches.resetVertexPointers(); mCaches.disbaleTexCoordsVertexArray(); + debugOverdraw(false, false); } void OpenGLRenderer::resume() { sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot; glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight()); glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo); + debugOverdraw(true, false); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); @@ -302,6 +341,7 @@ void OpenGLRenderer::resumeAfterLayer() { sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot; glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight()); glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo); + debugOverdraw(true, false); mCaches.resetScissor(); dirtyClip(); @@ -407,7 +447,10 @@ bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) { OpenGLRenderer* renderer = layer->renderer; Rect& dirty = layer->dirtyRect; - if (inFrame) endTiling(); + if (inFrame) { + endTiling(); + debugOverdraw(false, false); + } renderer->setViewport(layer->layer.getWidth(), layer->layer.getHeight()); renderer->prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, !layer->isBlend()); @@ -724,6 +767,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui mSnapshot->orthoMatrix.load(mOrthoMatrix); endTiling(); + debugOverdraw(false, false); // Bind texture to FBO glBindFramebuffer(GL_FRAMEBUFFER, layer->getFbo()); layer->bindTexture(); @@ -772,6 +816,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); // Unbind current FBO and restore previous one glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo); + debugOverdraw(true, false); startTiling(previous); } diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 7d5da68..46e66cb 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -723,6 +723,9 @@ private: */ void drawRegionRects(const Region& region); + void debugOverdraw(bool enable, bool clear); + void renderOverdraw(); + /** * Should be invoked every time the glScissor is modified. */ diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index de7afed..c81319e 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -53,11 +53,14 @@ const char* gVS_Header_Uniforms_IsPoint = "uniform mediump float pointSize;\n"; const char* gVS_Header_Uniforms_HasGradient[3] = { // Linear - "uniform mat4 screenSpace;\n", + "uniform mat4 screenSpace;\n" + "uniform float ditherSize;\n", // Circular - "uniform mat4 screenSpace;\n", + "uniform mat4 screenSpace;\n" + "uniform float ditherSize;\n", // Sweep "uniform mat4 screenSpace;\n" + "uniform float ditherSize;\n" }; const char* gVS_Header_Uniforms_HasBitmap = "uniform mat4 textureTransform;\n" @@ -75,16 +78,22 @@ const char* gVS_Header_Varyings_PointHasBitmap = "varying highp vec2 outPointBitmapTexCoords;\n"; const char* gVS_Header_Varyings_HasGradient[6] = { // Linear - "varying highp vec2 linear;\n", - "varying float linear;\n", + "varying highp vec2 linear;\n" + "varying vec2 ditherTexCoords;\n", + "varying float linear;\n" + "varying vec2 ditherTexCoords;\n", // Circular - "varying highp vec2 circular;\n", - "varying highp vec2 circular;\n", + "varying highp vec2 circular;\n" + "varying vec2 ditherTexCoords;\n", + "varying highp vec2 circular;\n" + "varying vec2 ditherTexCoords;\n", // Sweep - "varying highp vec2 sweep;\n", - "varying highp vec2 sweep;\n", + "varying highp vec2 sweep;\n" + "varying vec2 ditherTexCoords;\n", + "varying highp vec2 sweep;\n" + "varying vec2 ditherTexCoords;\n", }; const char* gVS_Main = "\nvoid main(void) {\n"; @@ -94,16 +103,22 @@ const char* gVS_Main_OutTransformedTexCoords = " outTexCoords = (mainTextureTransform * vec4(texCoords, 0.0, 1.0)).xy;\n"; const char* gVS_Main_OutGradient[6] = { // Linear - " linear = vec2((screenSpace * position).x, 0.5);\n", - " linear = (screenSpace * position).x;\n", + " linear = vec2((screenSpace * position).x, 0.5);\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", + " linear = (screenSpace * position).x;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", // Circular - " circular = (screenSpace * position).xy;\n", - " circular = (screenSpace * position).xy;\n", + " circular = (screenSpace * position).xy;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", + " circular = (screenSpace * position).xy;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", // Sweep - " sweep = (screenSpace * position).xy;\n", - " sweep = (screenSpace * position).xy;\n", + " sweep = (screenSpace * position).xy;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", + " sweep = (screenSpace * position).xy;\n" + " ditherTexCoords = (gl_Position * ditherSize).xy;\n", }; const char* gVS_Main_OutBitmapTexCoords = " outBitmapTexCoords = (textureTransform * position).xy * textureDimension;\n"; @@ -144,7 +159,7 @@ const char* gFS_Uniforms_TextureSampler = const char* gFS_Uniforms_ExternalTextureSampler = "uniform samplerExternalOES baseSampler;\n"; #define FS_UNIFORMS_DITHER \ - "uniform float ditherSize;\n" \ + "uniform float ditherSizeSquared;\n" \ "uniform sampler2D ditherSampler;\n" #define FS_UNIFORMS_GRADIENT \ "uniform vec4 startColor;\n" \ @@ -188,7 +203,7 @@ const char* gFS_Main_PointBitmapTexCoords = "((gl_PointCoord - vec2(0.5, 0.5)) * textureDimension * vec2(pointSize, pointSize));\n"; #define FS_MAIN_DITHER \ - "texture2D(ditherSampler, gl_FragCoord.xy * ditherSize).a * ditherSize * ditherSize" + "texture2D(ditherSampler, ditherTexCoords).a * ditherSizeSquared" const char* gFS_Main_AddDitherToGradient = " gradientColor += " FS_MAIN_DITHER ";\n"; @@ -511,9 +526,6 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description shader.append(gVS_Main_AALine); } } - if (description.hasGradient) { - shader.append(gVS_Main_OutGradient[gradientIndex(description)]); - } if (description.hasBitmap) { shader.append(description.isPoint ? gVS_Main_OutPointBitmapTexCoords : @@ -524,6 +536,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description } // Output transformed position shader.append(gVS_Main_Position); + if (description.hasGradient) { + shader.append(gVS_Main_OutGradient[gradientIndex(description)]); + } } // End the shader shader.append(gVS_Footer); diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h index 0e3268e..31e60e4 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -37,7 +37,7 @@ // Defines the size in bits of the stencil buffer // Note: Only 1 bit is required for clipping but more bits are required // to properly implement the winding fill rule when rasterizing paths -#define STENCIL_BUFFER_SIZE 0 +#define STENCIL_BUFFER_SIZE 8 /** * Debug level for app developers. The value is a numeric value defined @@ -56,11 +56,17 @@ enum DebugLevel { }; /** - * Used to enable/disbale layers update debugging. The accepted values are + * Used to enable/disable layers update debugging. The accepted values are * "true" and "false". The default value is "false". */ #define PROPERTY_DEBUG_LAYERS_UPDATES "debug.hwui.show_layers_updates" +/** + * Used to enable/disable overdraw debugging. The accepted values are + * "true" and "false". The default value is "false". + */ +#define PROPERTY_DEBUG_OVERDRAW "debug.hwui.show_overdraw" + // These properties are defined in mega-bytes #define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size" #define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size" diff --git a/libs/hwui/Stencil.cpp b/libs/hwui/Stencil.cpp index 7dfdf0e..84df82b 100644 --- a/libs/hwui/Stencil.cpp +++ b/libs/hwui/Stencil.cpp @@ -37,7 +37,7 @@ void Stencil::clear() { void Stencil::enableTest() { if (mState != kTest) { enable(); - glStencilFunc(GL_EQUAL, 0x0, 0x1); + glStencilFunc(GL_EQUAL, 0x1, 0x1); // We only want to test, let's keep everything glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -56,8 +56,27 @@ void Stencil::enableWrite() { } } +void Stencil::enableDebugTest(GLint value, bool greater) { + enable(); + glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff); + // We only want to test, let's keep everything + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + mState = kTest; +} + +void Stencil::enableDebugWrite() { + if (mState != kWrite) { + enable(); + glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff); + // The test always passes so the first two values are meaningless + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + mState = kWrite; + } +} + void Stencil::enable() { - if (!mState == kDisabled) { + if (mState == kDisabled) { glEnable(GL_STENCIL_TEST); } } diff --git a/libs/hwui/Stencil.h b/libs/hwui/Stencil.h index 67ccc78..2f8a66a 100644 --- a/libs/hwui/Stencil.h +++ b/libs/hwui/Stencil.h @@ -59,6 +59,16 @@ public: void enableWrite(); /** + * The test passes only when equal to the specified value. + */ + void enableDebugTest(GLint value, bool greater = false); + + /** + * Used for debugging. The stencil test always passes and increments. + */ + void enableDebugWrite(); + + /** * Disables stencil test and write. */ void disable(); |