Skip to content

Commit 378d131

Browse files
ChrisCraikAndroid (Google) Code Review
authored andcommitted
Merge "Varying-based AA rect drawing" into jb-mr1-dev
2 parents 369bb97 + 6ebdc11 commit 378d131

File tree

6 files changed

+93
-39
lines changed

6 files changed

+93
-39
lines changed

libs/hwui/Caches.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ static const GLsizei gVertexStride = sizeof(Vertex);
6868
static const GLsizei gAlphaVertexStride = sizeof(AlphaVertex);
6969
static const GLsizei gAAVertexStride = sizeof(AAVertex);
7070
static const GLsizei gMeshTextureOffset = 2 * sizeof(float);
71+
static const GLsizei gVertexAlphaOffset = 2 * sizeof(float);
7172
static const GLsizei gVertexAAWidthOffset = 2 * sizeof(float);
7273
static const GLsizei gVertexAALengthOffset = 3 * sizeof(float);
7374
static const GLsizei gMeshCount = 4;

libs/hwui/OpenGLRenderer.cpp

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,6 +1141,10 @@ void OpenGLRenderer::setupDrawAALine() {
11411141
mDescription.isAA = true;
11421142
}
11431143

1144+
void OpenGLRenderer::setupDrawAARect() {
1145+
mDescription.isAARect = true;
1146+
}
1147+
11441148
void OpenGLRenderer::setupDrawPoint(float pointSize) {
11451149
mDescription.isPoint = true;
11461150
mDescription.pointSize = pointSize;
@@ -1741,9 +1745,9 @@ status_t OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const
17411745

17421746
/**
17431747
* This function uses a similar approach to that of AA lines in the drawLines() function.
1744-
* We expand the rectangle by a half pixel in screen space on all sides, and use a fragment
1745-
* shader to compute the translucency of the color, determined by whether a given pixel is
1746-
* within that boundary region and how far into the region it is.
1748+
* We expand the rectangle by a half pixel in screen space on all sides. However, instead of using
1749+
* a fragment shader to compute the translucency of the color from its position, we simply use a
1750+
* varying parameter to define how far a given pixel is into the region.
17471751
*/
17481752
void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom,
17491753
int color, SkXfermode::Mode mode) {
@@ -1755,10 +1759,8 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom
17551759
Matrix4 *mat = mSnapshot->transform;
17561760
float m00 = mat->data[Matrix4::kScaleX];
17571761
float m01 = mat->data[Matrix4::kSkewY];
1758-
float m02 = mat->data[2];
17591762
float m10 = mat->data[Matrix4::kSkewX];
17601763
float m11 = mat->data[Matrix4::kScaleX];
1761-
float m12 = mat->data[6];
17621764
float scaleX = sqrt(m00 * m00 + m01 * m01);
17631765
float scaleY = sqrt(m10 * m10 + m11 * m11);
17641766
inverseScaleX = (scaleX != 0) ? (inverseScaleX / scaleX) : 0;
@@ -1768,6 +1770,11 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom
17681770
float boundarySizeX = .5 * inverseScaleX;
17691771
float boundarySizeY = .5 * inverseScaleY;
17701772

1773+
float innerLeft = left + boundarySizeX;
1774+
float innerRight = right - boundarySizeX;
1775+
float innerTop = top + boundarySizeY;
1776+
float innerBottom = bottom - boundarySizeY;
1777+
17711778
// Adjust the rect by the AA boundary padding
17721779
left -= boundarySizeX;
17731780
right += boundarySizeX;
@@ -1777,7 +1784,7 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom
17771784
if (!quickReject(left, top, right, bottom)) {
17781785
setupDraw();
17791786
setupDrawNoTexture();
1780-
setupDrawAALine();
1787+
setupDrawAARect();
17811788
setupDrawColor(color, ((color >> 24) & 0xFF) * mSnapshot->alpha);
17821789
setupDrawColorFilter();
17831790
setupDrawShader();
@@ -1788,34 +1795,52 @@ void OpenGLRenderer::drawAARect(float left, float top, float right, float bottom
17881795
setupDrawColorFilterUniforms();
17891796
setupDrawShaderIdentityUniforms();
17901797

1791-
AAVertex rects[4];
1792-
AAVertex* aaVertices = &rects[0];
1793-
void* widthCoords = ((GLbyte*) aaVertices) + gVertexAAWidthOffset;
1794-
void* lengthCoords = ((GLbyte*) aaVertices) + gVertexAALengthOffset;
1795-
1796-
int widthSlot;
1797-
int lengthSlot;
1798+
AlphaVertex rects[14];
1799+
AlphaVertex* aVertices = &rects[0];
1800+
void* alphaCoords = ((GLbyte*) aVertices) + gVertexAlphaOffset;
1801+
1802+
bool force = mCaches.unbindMeshBuffer();
1803+
mCaches.bindPositionVertexPointer(force, mCaches.currentProgram->position,
1804+
aVertices, gAlphaVertexStride);
1805+
mCaches.resetTexCoordsVertexPointer();
1806+
mCaches.unbindIndicesBuffer();
1807+
1808+
int alphaSlot = mCaches.currentProgram->getAttrib("vtxAlpha");
1809+
glEnableVertexAttribArray(alphaSlot);
1810+
glVertexAttribPointer(alphaSlot, 1, GL_FLOAT, GL_FALSE, gAlphaVertexStride, alphaCoords);
1811+
1812+
// draw left
1813+
AlphaVertex::set(aVertices++, left, bottom, 0);
1814+
AlphaVertex::set(aVertices++, innerLeft, innerBottom, 1);
1815+
AlphaVertex::set(aVertices++, left, top, 0);
1816+
AlphaVertex::set(aVertices++, innerLeft, innerTop, 1);
1817+
1818+
// draw top
1819+
AlphaVertex::set(aVertices++, right, top, 0);
1820+
AlphaVertex::set(aVertices++, innerRight, innerTop, 1);
1821+
1822+
// draw right
1823+
AlphaVertex::set(aVertices++, right, bottom, 0);
1824+
AlphaVertex::set(aVertices++, innerRight, innerBottom, 1);
1825+
1826+
// draw bottom
1827+
AlphaVertex::set(aVertices++, left, bottom, 0);
1828+
AlphaVertex::set(aVertices++, innerLeft, innerBottom, 1);
1829+
1830+
// draw inner rect (repeating last vertex to create degenerate bridge triangles)
1831+
// TODO: also consider drawing the inner rect without the blending-forced shader, if
1832+
// blending is expensive. Note: can't use drawColorRect() since it doesn't use vertex
1833+
// buffers like below, resulting in slightly different transformed coordinates.
1834+
AlphaVertex::set(aVertices++, innerLeft, innerBottom, 1);
1835+
AlphaVertex::set(aVertices++, innerLeft, innerTop, 1);
1836+
AlphaVertex::set(aVertices++, innerRight, innerBottom, 1);
1837+
AlphaVertex::set(aVertices++, innerRight, innerTop, 1);
17981838

1799-
float width = right - left;
1800-
float height = bottom - top;
1801-
1802-
float boundaryWidthProportion = .5 - ((width != 0) ? (2 * boundarySizeX) / width : 0);
1803-
float boundaryHeightProportion = .5 - ((height != 0) ? (2 * boundarySizeY) / height : 0);
1804-
setupDrawAALine((void*) aaVertices, widthCoords, lengthCoords,
1805-
boundaryWidthProportion, widthSlot, lengthSlot);
1806-
1807-
int boundaryLengthSlot = mCaches.currentProgram->getUniform("boundaryLength");
1808-
glUniform1f(boundaryLengthSlot, boundaryHeightProportion);
1809-
1810-
AAVertex::set(aaVertices++, left, bottom, 1, 1);
1811-
AAVertex::set(aaVertices++, left, top, 1, 0);
1812-
AAVertex::set(aaVertices++, right, bottom, 0, 1);
1813-
AAVertex::set(aaVertices++, right, top, 0, 0);
18141839
dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
18151840

1816-
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1841+
glDrawArrays(GL_TRIANGLE_STRIP, 0, 14);
18171842

1818-
finishDrawAALine(widthSlot, lengthSlot);
1843+
glDisableVertexAttribArray(alphaSlot);
18191844
}
18201845
}
18211846

@@ -1870,10 +1895,8 @@ status_t OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
18701895
Matrix4 *mat = mSnapshot->transform;
18711896
float m00 = mat->data[Matrix4::kScaleX];
18721897
float m01 = mat->data[Matrix4::kSkewY];
1873-
float m02 = mat->data[2];
18741898
float m10 = mat->data[Matrix4::kSkewX];
18751899
float m11 = mat->data[Matrix4::kScaleX];
1876-
float m12 = mat->data[6];
18771900

18781901
float scaleX = sqrtf(m00 * m00 + m01 * m01);
18791902
float scaleY = sqrtf(m10 * m10 + m11 * m11);

libs/hwui/OpenGLRenderer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,6 @@ class OpenGLRenderer {
434434
* @param color The rectangle's ARGB color, defined as a packed 32 bits word
435435
* @param mode The Skia xfermode to use
436436
* @param ignoreTransform True if the current transform should be ignored
437-
* @param ignoreBlending True if the blending is set by the caller
438437
*/
439438
void drawColorRect(float left, float top, float right, float bottom,
440439
int color, SkXfermode::Mode mode, bool ignoreTransform = false);
@@ -649,6 +648,7 @@ class OpenGLRenderer {
649648
void setupDrawWithExternalTexture();
650649
void setupDrawNoTexture();
651650
void setupDrawAALine();
651+
void setupDrawAARect();
652652
void setupDrawPoint(float pointSize);
653653
void setupDrawColor(int color);
654654
void setupDrawColor(int color, int alpha);

libs/hwui/Program.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ namespace uirenderer {
8181

8282
#define PROGRAM_IS_SIMPLE_GRADIENT 41
8383

84+
#define PROGRAM_IS_AA_RECT_SHIFT 42
85+
8486
///////////////////////////////////////////////////////////////////////////////
8587
// Types
8688
///////////////////////////////////////////////////////////////////////////////
@@ -128,6 +130,7 @@ struct ProgramDescription {
128130
bool isBitmapNpot;
129131

130132
bool isAA;
133+
bool isAARect;
131134

132135
bool hasGradient;
133136
Gradient gradientType;
@@ -165,6 +168,7 @@ struct ProgramDescription {
165168
hasTextureTransform = false;
166169

167170
isAA = false;
171+
isAARect = false;
168172

169173
modulate = false;
170174

@@ -260,6 +264,7 @@ struct ProgramDescription {
260264
if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
261265
if (hasGammaCorrection) key |= programid(0x1) << PROGRAM_HAS_GAMMA_CORRECTION;
262266
if (isSimpleGradient) key |= programid(0x1) << PROGRAM_IS_SIMPLE_GRADIENT;
267+
if (isAARect) key |= programid(0x1) << PROGRAM_IS_AA_RECT_SHIFT;
263268
return key;
264269
}
265270

libs/hwui/ProgramCache.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const char* gVS_Header_Attributes_TexCoords =
4343
const char* gVS_Header_Attributes_AAParameters =
4444
"attribute float vtxWidth;\n"
4545
"attribute float vtxLength;\n";
46+
const char* gVS_Header_Attributes_AARectParameters =
47+
"attribute float vtxAlpha;\n";
4648
const char* gVS_Header_Uniforms_TextureTransform =
4749
"uniform mat4 mainTextureTransform;\n";
4850
const char* gVS_Header_Uniforms =
@@ -65,6 +67,8 @@ const char* gVS_Header_Varyings_HasTexture =
6567
const char* gVS_Header_Varyings_IsAA =
6668
"varying float widthProportion;\n"
6769
"varying float lengthProportion;\n";
70+
const char* gVS_Header_Varyings_IsAARect =
71+
"varying float alpha;\n";
6872
const char* gVS_Header_Varyings_HasBitmap =
6973
"varying highp vec2 outBitmapTexCoords;\n";
7074
const char* gVS_Header_Varyings_PointHasBitmap =
@@ -112,6 +116,8 @@ const char* gVS_Main_PointSize =
112116
const char* gVS_Main_AA =
113117
" widthProportion = vtxWidth;\n"
114118
" lengthProportion = vtxLength;\n";
119+
const char* gVS_Main_AARect =
120+
" alpha = vtxAlpha;\n";
115121
const char* gVS_Footer =
116122
"}\n\n";
117123

@@ -242,6 +248,8 @@ const char* gFS_Main_ModulateColor_ApplyGamma =
242248
const char* gFS_Main_AccountForAA =
243249
" fragColor *= (1.0 - smoothstep(boundaryWidth, 0.5, abs(0.5 - widthProportion)))\n"
244250
" * (1.0 - smoothstep(boundaryLength, 0.5, abs(0.5 - lengthProportion)));\n";
251+
const char* gFS_Main_AccountForAARect =
252+
" fragColor *= alpha;\n";
245253

246254
const char* gFS_Main_FetchTexture[2] = {
247255
// Don't modulate
@@ -439,7 +447,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
439447
if (description.hasTexture || description.hasExternalTexture) {
440448
shader.append(gVS_Header_Attributes_TexCoords);
441449
}
442-
if (description.isAA) {
450+
if (description.isAARect) {
451+
shader.append(gVS_Header_Attributes_AARectParameters);
452+
} else if (description.isAA) {
443453
shader.append(gVS_Header_Attributes_AAParameters);
444454
}
445455
// Uniforms
@@ -460,7 +470,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
460470
if (description.hasTexture || description.hasExternalTexture) {
461471
shader.append(gVS_Header_Varyings_HasTexture);
462472
}
463-
if (description.isAA) {
473+
if (description.isAARect) {
474+
shader.append(gVS_Header_Varyings_IsAARect);
475+
} else if (description.isAA) {
464476
shader.append(gVS_Header_Varyings_IsAA);
465477
}
466478
if (description.hasGradient) {
@@ -479,7 +491,9 @@ String8 ProgramCache::generateVertexShader(const ProgramDescription& description
479491
} else if (description.hasTexture || description.hasExternalTexture) {
480492
shader.append(gVS_Main_OutTexCoords);
481493
}
482-
if (description.isAA) {
494+
if (description.isAARect) {
495+
shader.append(gVS_Main_AARect);
496+
} else if (description.isAA) {
483497
shader.append(gVS_Main_AA);
484498
}
485499
if (description.hasGradient) {
@@ -521,7 +535,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
521535
if (description.hasTexture || description.hasExternalTexture) {
522536
shader.append(gVS_Header_Varyings_HasTexture);
523537
}
524-
if (description.isAA) {
538+
if (description.isAARect) {
539+
shader.append(gVS_Header_Varyings_IsAARect);
540+
} else if (description.isAA) {
525541
shader.append(gVS_Header_Varyings_IsAA);
526542
}
527543
if (description.hasGradient) {
@@ -562,7 +578,8 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
562578

563579
// Optimization for common cases
564580
if (!description.isAA && !blendFramebuffer &&
565-
description.colorOp == ProgramDescription::kColorNone && !description.isPoint) {
581+
description.colorOp == ProgramDescription::kColorNone &&
582+
!description.isPoint && !description.isAARect) {
566583
bool fast = false;
567584

568585
const bool noShader = !description.hasGradient && !description.hasBitmap;
@@ -654,7 +671,9 @@ String8 ProgramCache::generateFragmentShader(const ProgramDescription& descripti
654671
shader.append(gFS_Main_FetchColor);
655672
}
656673
}
657-
if (description.isAA) {
674+
if (description.isAARect) {
675+
shader.append(gFS_Main_AccountForAARect);
676+
} else if (description.isAA) {
658677
shader.append(gFS_Main_AccountForAA);
659678
}
660679
if (description.hasGradient) {

tests/HwAccelerationTest/src/com/android/test/hwui/ColoredRectsActivity.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,12 @@ protected void onDraw(Canvas canvas) {
113113
canvas.rotate(45);
114114
canvas.drawRect(0, 0, 20, 10, p);
115115
canvas.restore();
116+
canvas.save();
117+
canvas.translate(mOffset + 280, yOffset);
118+
canvas.scale(0.5f, 8);
119+
canvas.rotate(0.5f);
120+
canvas.drawRect(0, 0, 80, 5, p);
121+
canvas.restore();
116122
canvas.restore();
117123

118124
yOffset += 100;

0 commit comments

Comments
 (0)