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/hwui/OpenGLRenderer.cpp | |
| 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/hwui/OpenGLRenderer.cpp')
| -rw-r--r-- | libs/hwui/OpenGLRenderer.cpp | 87 |
1 files changed, 55 insertions, 32 deletions
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); |
