diff options
author | Chris Craik <ccraik@google.com> | 2012-09-06 10:52:13 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-09-06 10:52:14 -0700 |
commit | 378d131e65348d199db36c21ba7156542bbf0045 (patch) | |
tree | b2e41ab4962973acea7fe8a3b9b3f97581ead2be /libs | |
parent | 369bb97d02209fa800081fc3b4e8675ea7e75d34 (diff) | |
parent | 6ebdc114e0d72137394f02bc8ffe9d7a782a65c4 (diff) | |
download | frameworks_base-378d131e65348d199db36c21ba7156542bbf0045.zip frameworks_base-378d131e65348d199db36c21ba7156542bbf0045.tar.gz frameworks_base-378d131e65348d199db36c21ba7156542bbf0045.tar.bz2 |
Merge "Varying-based AA rect drawing" into jb-mr1-dev
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/Caches.h | 1 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 87 | ||||
-rw-r--r-- | libs/hwui/OpenGLRenderer.h | 2 | ||||
-rw-r--r-- | libs/hwui/Program.h | 5 | ||||
-rw-r--r-- | libs/hwui/ProgramCache.cpp | 31 |
5 files changed, 87 insertions, 39 deletions
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index b9a6336..6d27d6e 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -68,6 +68,7 @@ static const GLsizei gVertexStride = sizeof(Vertex); static const GLsizei gAlphaVertexStride = sizeof(AlphaVertex); static const GLsizei gAAVertexStride = sizeof(AAVertex); static const GLsizei gMeshTextureOffset = 2 * sizeof(float); +static const GLsizei gVertexAlphaOffset = 2 * sizeof(float); static const GLsizei gVertexAAWidthOffset = 2 * sizeof(float); static const GLsizei gVertexAALengthOffset = 3 * sizeof(float); static const GLsizei gMeshCount = 4; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7abcc63..a1bb6a2 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -1141,6 +1141,10 @@ void OpenGLRenderer::setupDrawAALine() { mDescription.isAA = true; } +void OpenGLRenderer::setupDrawAARect() { + mDescription.isAARect = true; +} + void OpenGLRenderer::setupDrawPoint(float pointSize) { mDescription.isPoint = true; mDescription.pointSize = pointSize; @@ -1741,9 +1745,9 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const /** * This function uses a similar approach to that of AA lines in the drawLines() function. - * We expand the rectangle by a half pixel in screen space on all sides, and use a fragment - * shader to compute the translucency of the color, determined by whether a given pixel is - * within that boundary region and how far into the region it is. + * We expand the rectangle by a half pixel in screen space on all sides. However, instead of using + * a fragment shader to compute the translucency of the color from its position, we simply use a + * varying parameter to define how far a given pixel is into the region. */ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom, int color, SkXfermode::Mode mode) { @@ -1755,10 +1759,8 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom Matrix4 *mat = mSnapshot->transform; float m00 = mat->data[Matrix4::kScaleX]; float m01 = mat->data[Matrix4::kSkewY]; - float m02 = mat->data[2]; float m10 = mat->data[Matrix4::kSkewX]; float m11 = mat->data[Matrix4::kScaleX]; - float m12 = mat->data[6]; float scaleX = sqrt(m00 * m00 + m01 * m01); float scaleY = sqrt(m10 * m10 + m11 * m11); inverseScaleX = (scaleX != 0) ? (inverseScaleX / scaleX) : 0; @@ -1768,6 +1770,11 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom float boundarySizeX = .5 * inverseScaleX; float boundarySizeY = .5 * inverseScaleY; + float innerLeft = left + boundarySizeX; + float innerRight = right - boundarySizeX; + float innerTop = top + boundarySizeY; + float innerBottom = bottom - boundarySizeY; + // Adjust the rect by the AA boundary padding left -= boundarySizeX; right += boundarySizeX; @@ -1777,7 +1784,7 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom if (!quickReject(left, top, right, bottom)) { setupDraw(); setupDrawNoTexture(); - setupDrawAALine(); + setupDrawAARect(); setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha); setupDrawColorFilter(); setupDrawShader(); @@ -1788,34 +1795,52 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom setupDrawColorFilterUniforms(); setupDrawShaderIdentityUniforms(); - AAVertex rects[4]; - AAVertex* aaVertices = &rects[0]; - void* widthCoords = ((GLbyte*) aaVertices) + gVertexAAWidthOffset; - void* lengthCoords = ((GLbyte*) aaVertices) + gVertexAALengthOffset; - - int widthSlot; - int lengthSlot; + AlphaVertex rects[14]; + AlphaVertex* aVertices = &rects[0]; + void* alphaCoords = ((GLbyte*) aVertices) + gVertexAlphaOffset; + + bool force = mCaches.unbindMeshBuffer(); + mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position, + aVertices, gAlphaVertexStride); + mCaches.resetTexCoordsVertexPointer(); + mCaches.unbindIndicesBuffer(); + + int alphaSlot = mCaches.currentProgram->getAttrib("vtxAlpha"); + glEnableVertexAttribArray(alphaSlot); + glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords); + + // draw left + AlphaVertex::set(aVertices++, left, bottom, 0); + AlphaVertex::set(aVertices++, innerLeft, innerBottom, 1); + AlphaVertex::set(aVertices++, left, top, 0); + AlphaVertex::set(aVertices++, innerLeft, innerTop, 1); + + // draw top + AlphaVertex::set(aVertices++, right, top, 0); + AlphaVertex::set(aVertices++, innerRight, innerTop, 1); + + // draw right + AlphaVertex::set(aVertices++, right, bottom, 0); + AlphaVertex::set(aVertices++, innerRight, innerBottom, 1); + + // draw bottom + AlphaVertex::set(aVertices++, left, bottom, 0); + AlphaVertex::set(aVertices++, innerLeft, innerBottom, 1); + + // draw inner rect (repeating last vertex to create degenerate bridge triangles) + // TODO: also consider drawing the inner rect without the blending-forced shader, if + // blending is expensive. Note: can't use drawColorRect() since it doesn't use vertex + // buffers like below, resulting in slightly different transformed coordinates. + AlphaVertex::set(aVertices++, innerLeft, innerBottom, 1); + AlphaVertex::set(aVertices++, innerLeft, innerTop, 1); + AlphaVertex::set(aVertices++, innerRight, innerBottom, 1); + AlphaVertex::set(aVertices++, innerRight, innerTop, 1); - float width = right - left; - float height = bottom - top; - - float boundaryWidthProportion = .5 - ((width != 0) ? (2 * boundarySizeX) / width : 0); - float boundaryHeightProportion = .5 - ((height != 0) ? (2 * boundarySizeY) / height : 0); - setupDrawAALine((void*) aaVertices, widthCoords, lengthCoords, - boundaryWidthProportion, widthSlot, lengthSlot); - - int boundaryLengthSlot = mCaches.currentProgram->getUniform("boundaryLength"); - glUniform1f(boundaryLengthSlot, boundaryHeightProportion); - - AAVertex::set(aaVertices++, left, bottom, 1, 1); - AAVertex::set(aaVertices++, left, top, 1, 0); - AAVertex::set(aaVertices++, right, bottom, 0, 1); - AAVertex::set(aaVertices++, right, top, 0, 0); dirtyLayer(left, top, right, bottom, *mSnapshot->transform); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 14); - finishDrawAALine(widthSlot, lengthSlot); + glDisableVertexAttribArray(alphaSlot); } } @@ -1870,10 +1895,8 @@ status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) { Matrix4 *mat = mSnapshot->transform; float m00 = mat->data[Matrix4::kScaleX]; float m01 = mat->data[Matrix4::kSkewY]; - float m02 = mat->data[2]; float m10 = mat->data[Matrix4::kSkewX]; float m11 = mat->data[Matrix4::kScaleX]; - float m12 = mat->data[6]; float scaleX = sqrtf(m00 * m00 + m01 * m01); float scaleY = sqrtf(m10 * m10 + m11 * m11); diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index 4c7cf0a..f2b5f0a 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -434,7 +434,6 @@ private: * @param color The rectangle's ARGB color, defined as a packed 32 bits word * @param mode The Skia xfermode to use * @param ignoreTransform True if the current transform should be ignored - * @param ignoreBlending True if the blending is set by the caller */ void drawColorRect(float left, float top, float right, float bottom, int color, SkXfermode::Mode mode, bool ignoreTransform = false); @@ -649,6 +648,7 @@ private: void setupDrawWithExternalTexture(); void setupDrawNoTexture(); void setupDrawAALine(); + void setupDrawAARect(); void setupDrawPoint(float pointSize); void setupDrawColor(int color); void setupDrawColor(int color, int alpha); diff --git a/libs/hwui/Program.h b/libs/hwui/Program.h index 1818f82..a3bfaa4 100644 --- a/libs/hwui/Program.h +++ b/libs/hwui/Program.h @@ -81,6 +81,8 @@ namespace uirenderer { #define PROGRAM_IS_SIMPLE_GRADIENT 41 +#define PROGRAM_IS_AA_RECT_SHIFT 42 + /////////////////////////////////////////////////////////////////////////////// // Types /////////////////////////////////////////////////////////////////////////////// @@ -128,6 +130,7 @@ struct ProgramDescription { bool isBitmapNpot; bool isAA; + bool isAARect; bool hasGradient; Gradient gradientType; @@ -165,6 +168,7 @@ struct ProgramDescription { hasTextureTransform = false; isAA = false; + isAARect = false; modulate = false; @@ -260,6 +264,7 @@ struct ProgramDescription { if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT; if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION; if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT; + if (isAARect) key |= programid(0x1) << PROGRAM_IS_AA_RECT_SHIFT; return key; } diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp index 8a9a2ac..0ed8008 100644 --- a/libs/hwui/ProgramCache.cpp +++ b/libs/hwui/ProgramCache.cpp @@ -43,6 +43,8 @@ const char* gVS_Header_Attributes_TexCoords = const char* gVS_Header_Attributes_AAParameters = "attribute float vtxWidth;\n" "attribute float vtxLength;\n"; +const char* gVS_Header_Attributes_AARectParameters = + "attribute float vtxAlpha;\n"; const char* gVS_Header_Uniforms_TextureTransform = "uniform mat4 mainTextureTransform;\n"; const char* gVS_Header_Uniforms = @@ -65,6 +67,8 @@ const char* gVS_Header_Varyings_HasTexture = const char* gVS_Header_Varyings_IsAA = "varying float widthProportion;\n" "varying float lengthProportion;\n"; +const char* gVS_Header_Varyings_IsAARect = + "varying float alpha;\n"; const char* gVS_Header_Varyings_HasBitmap = "varying highp vec2 outBitmapTexCoords;\n"; const char* gVS_Header_Varyings_PointHasBitmap = @@ -112,6 +116,8 @@ const char* gVS_Main_PointSize = const char* gVS_Main_AA = " widthProportion = vtxWidth;\n" " lengthProportion = vtxLength;\n"; +const char* gVS_Main_AARect = + " alpha = vtxAlpha;\n"; const char* gVS_Footer = "}\n\n"; @@ -242,6 +248,8 @@ const char* gFS_Main_ModulateColor_ApplyGamma = const char* gFS_Main_AccountForAA = " fragColor *= (1.0 - smoothstep(boundaryWidth, 0.5, abs(0.5 - widthProportion)))\n" " * (1.0 - smoothstep(boundaryLength, 0.5, abs(0.5 - lengthProportion)));\n"; +const char* gFS_Main_AccountForAARect = + " fragColor *= alpha;\n"; const char* gFS_Main_FetchTexture[2] = { // Don't modulate @@ -439,7 +447,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description if (description.hasTexture || description.hasExternalTexture) { shader.append(gVS_Header_Attributes_TexCoords); } - if (description.isAA) { + if (description.isAARect) { + shader.append(gVS_Header_Attributes_AARectParameters); + } else if (description.isAA) { shader.append(gVS_Header_Attributes_AAParameters); } // Uniforms @@ -460,7 +470,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description if (description.hasTexture || description.hasExternalTexture) { shader.append(gVS_Header_Varyings_HasTexture); } - if (description.isAA) { + if (description.isAARect) { + shader.append(gVS_Header_Varyings_IsAARect); + } else if (description.isAA) { shader.append(gVS_Header_Varyings_IsAA); } if (description.hasGradient) { @@ -479,7 +491,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description } else if (description.hasTexture || description.hasExternalTexture) { shader.append(gVS_Main_OutTexCoords); } - if (description.isAA) { + if (description.isAARect) { + shader.append(gVS_Main_AARect); + } else if (description.isAA) { shader.append(gVS_Main_AA); } if (description.hasGradient) { @@ -521,7 +535,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti if (description.hasTexture || description.hasExternalTexture) { shader.append(gVS_Header_Varyings_HasTexture); } - if (description.isAA) { + if (description.isAARect) { + shader.append(gVS_Header_Varyings_IsAARect); + } else if (description.isAA) { shader.append(gVS_Header_Varyings_IsAA); } if (description.hasGradient) { @@ -562,7 +578,8 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti // Optimization for common cases if (!description.isAA && !blendFramebuffer && - description.colorOp == ProgramDescription::kColorNone && !description.isPoint) { + description.colorOp == ProgramDescription::kColorNone && + !description.isPoint && !description.isAARect) { bool fast = false; const bool noShader = !description.hasGradient && !description.hasBitmap; @@ -654,7 +671,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti shader.append(gFS_Main_FetchColor); } } - if (description.isAA) { + if (description.isAARect) { + shader.append(gFS_Main_AccountForAARect); + } else if (description.isAA) { shader.append(gFS_Main_AccountForAA); } if (description.hasGradient) { |