Loading libs/hwui/ProgramCache.cpp +18 −13 Original line number Diff line number Diff line Loading @@ -58,7 +58,9 @@ const char* gVS_Header_Uniforms_HasBitmap = "uniform mat4 textureTransform;\n" "uniform mediump vec2 textureDimension;\n"; const char* gVS_Header_Uniforms_HasRoundRectClip = "uniform mat4 roundRectInvTransform;\n"; "uniform mat4 roundRectInvTransform;\n" "uniform mediump vec4 roundRectInnerRectLTWH;\n" "uniform mediump float roundRectRadius;\n"; const char* gVS_Header_Varyings_HasTexture = "varying vec2 outTexCoords;\n"; const char* gVS_Header_Varyings_HasColors = Loading Loading @@ -87,7 +89,7 @@ const char* gVS_Header_Varyings_HasGradient[6] = { "varying vec2 ditherTexCoords;\n", }; const char* gVS_Header_Varyings_HasRoundRectClip = "varying highp vec2 roundRectPos;\n"; "varying mediump vec2 roundRectPos;\n"; const char* gVS_Main = "\nvoid main(void) {\n"; const char* gVS_Main_OutTexCoords = Loading Loading @@ -125,7 +127,7 @@ const char* gVS_Main_VertexAlpha = " alpha = vtxAlpha;\n"; const char* gVS_Main_HasRoundRectClip = " roundRectPos = (roundRectInvTransform * transformedPosition).xy;\n"; " roundRectPos = ((roundRectInvTransform * transformedPosition).xy / roundRectRadius) - roundRectInnerRectLTWH.xy;\n"; const char* gVS_Footer = "}\n\n"; Loading Loading @@ -169,8 +171,8 @@ const char* gFS_Uniforms_ColorOp[3] = { }; const char* gFS_Uniforms_HasRoundRectClip = "uniform vec4 roundRectInnerRectLTRB;\n" "uniform float roundRectRadius;\n"; "uniform mediump vec4 roundRectInnerRectLTWH;\n" "uniform mediump float roundRectRadius;\n"; const char* gFS_Main = "\nvoid main(void) {\n" Loading Loading @@ -315,15 +317,18 @@ const char* gFS_Main_ApplyColorOp[3] = { " fragColor = blendColors(colorBlend, fragColor);\n" }; // Note: LTRB -> xyzw // Note: LTWH (left top width height) -> xyzw // roundRectPos is now divided by roundRectRadius in vertex shader // after we also subtract roundRectInnerRectLTWH.xy from roundRectPos const char* gFS_Main_FragColor_HasRoundRectClip = " mediump vec2 fragToLT = roundRectInnerRectLTRB.xy - roundRectPos;\n" " mediump vec2 fragFromRB = roundRectPos - roundRectInnerRectLTRB.zw;\n" // divide + multiply by 128 to avoid falling out of range in length() function " mediump vec2 dist = max(max(fragToLT, fragFromRB), vec2(0.0, 0.0)) / 128.0;\n" " mediump float linearDist = roundRectRadius - (length(dist) * 128.0);\n" " gl_FragColor *= clamp(linearDist, 0.0, 1.0);\n"; " mediump vec2 fragToLT = -roundRectPos;\n" " mediump vec2 fragFromRB = roundRectPos - roundRectInnerRectLTWH.zw;\n" // since distance is divided by radius, it's in [0;1] so precision is not an issue // this also lets us clamp(0.0, 1.0) instead of max() which is cheaper on GPUs " mediump vec2 dist = clamp(max(fragToLT, fragFromRB), 0.0, 1.0);\n" " mediump float linearDist = clamp(roundRectRadius - (length(dist) * roundRectRadius), 0.0, 1.0);\n" " gl_FragColor *= linearDist;\n"; const char* gFS_Main_DebugHighlight = " gl_FragColor.rgb = vec3(0.0, gl_FragColor.a, 0.0);\n"; Loading libs/hwui/renderstate/RenderState.cpp +11 −5 Original line number Diff line number Diff line Loading @@ -274,14 +274,20 @@ void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) { // TODO: avoid query, and cache values (or RRCS ptr) in program const RoundRectClipState* state = glop.roundRectClipState; const Rect& innerRect = state->innerRect; glUniform4f(fill.program->getUniform("roundRectInnerRectLTRB"), innerRect.left, innerRect.top, innerRect.right, innerRect.bottom); glUniformMatrix4fv(fill.program->getUniform("roundRectInvTransform"), 1, GL_FALSE, &state->matrix.data[0]); // add half pixel to round out integer rect space to cover pixel centers float roundedOutRadius = state->radius + 0.5f; // Divide by the radius to simplify the calculations in the fragment shader // roundRectPos is also passed from vertex shader relative to top/left & radius glUniform4f(fill.program->getUniform("roundRectInnerRectLTWH"), innerRect.left / roundedOutRadius, innerRect.top / roundedOutRadius, (innerRect.right - innerRect.left) / roundedOutRadius, (innerRect.bottom - innerRect.top) / roundedOutRadius); glUniformMatrix4fv(fill.program->getUniform("roundRectInvTransform"), 1, GL_FALSE, &state->matrix.data[0]); glUniform1f(fill.program->getUniform("roundRectRadius"), roundedOutRadius); } Loading Loading
libs/hwui/ProgramCache.cpp +18 −13 Original line number Diff line number Diff line Loading @@ -58,7 +58,9 @@ const char* gVS_Header_Uniforms_HasBitmap = "uniform mat4 textureTransform;\n" "uniform mediump vec2 textureDimension;\n"; const char* gVS_Header_Uniforms_HasRoundRectClip = "uniform mat4 roundRectInvTransform;\n"; "uniform mat4 roundRectInvTransform;\n" "uniform mediump vec4 roundRectInnerRectLTWH;\n" "uniform mediump float roundRectRadius;\n"; const char* gVS_Header_Varyings_HasTexture = "varying vec2 outTexCoords;\n"; const char* gVS_Header_Varyings_HasColors = Loading Loading @@ -87,7 +89,7 @@ const char* gVS_Header_Varyings_HasGradient[6] = { "varying vec2 ditherTexCoords;\n", }; const char* gVS_Header_Varyings_HasRoundRectClip = "varying highp vec2 roundRectPos;\n"; "varying mediump vec2 roundRectPos;\n"; const char* gVS_Main = "\nvoid main(void) {\n"; const char* gVS_Main_OutTexCoords = Loading Loading @@ -125,7 +127,7 @@ const char* gVS_Main_VertexAlpha = " alpha = vtxAlpha;\n"; const char* gVS_Main_HasRoundRectClip = " roundRectPos = (roundRectInvTransform * transformedPosition).xy;\n"; " roundRectPos = ((roundRectInvTransform * transformedPosition).xy / roundRectRadius) - roundRectInnerRectLTWH.xy;\n"; const char* gVS_Footer = "}\n\n"; Loading Loading @@ -169,8 +171,8 @@ const char* gFS_Uniforms_ColorOp[3] = { }; const char* gFS_Uniforms_HasRoundRectClip = "uniform vec4 roundRectInnerRectLTRB;\n" "uniform float roundRectRadius;\n"; "uniform mediump vec4 roundRectInnerRectLTWH;\n" "uniform mediump float roundRectRadius;\n"; const char* gFS_Main = "\nvoid main(void) {\n" Loading Loading @@ -315,15 +317,18 @@ const char* gFS_Main_ApplyColorOp[3] = { " fragColor = blendColors(colorBlend, fragColor);\n" }; // Note: LTRB -> xyzw // Note: LTWH (left top width height) -> xyzw // roundRectPos is now divided by roundRectRadius in vertex shader // after we also subtract roundRectInnerRectLTWH.xy from roundRectPos const char* gFS_Main_FragColor_HasRoundRectClip = " mediump vec2 fragToLT = roundRectInnerRectLTRB.xy - roundRectPos;\n" " mediump vec2 fragFromRB = roundRectPos - roundRectInnerRectLTRB.zw;\n" // divide + multiply by 128 to avoid falling out of range in length() function " mediump vec2 dist = max(max(fragToLT, fragFromRB), vec2(0.0, 0.0)) / 128.0;\n" " mediump float linearDist = roundRectRadius - (length(dist) * 128.0);\n" " gl_FragColor *= clamp(linearDist, 0.0, 1.0);\n"; " mediump vec2 fragToLT = -roundRectPos;\n" " mediump vec2 fragFromRB = roundRectPos - roundRectInnerRectLTWH.zw;\n" // since distance is divided by radius, it's in [0;1] so precision is not an issue // this also lets us clamp(0.0, 1.0) instead of max() which is cheaper on GPUs " mediump vec2 dist = clamp(max(fragToLT, fragFromRB), 0.0, 1.0);\n" " mediump float linearDist = clamp(roundRectRadius - (length(dist) * roundRectRadius), 0.0, 1.0);\n" " gl_FragColor *= linearDist;\n"; const char* gFS_Main_DebugHighlight = " gl_FragColor.rgb = vec3(0.0, gl_FragColor.a, 0.0);\n"; Loading
libs/hwui/renderstate/RenderState.cpp +11 −5 Original line number Diff line number Diff line Loading @@ -274,14 +274,20 @@ void RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) { // TODO: avoid query, and cache values (or RRCS ptr) in program const RoundRectClipState* state = glop.roundRectClipState; const Rect& innerRect = state->innerRect; glUniform4f(fill.program->getUniform("roundRectInnerRectLTRB"), innerRect.left, innerRect.top, innerRect.right, innerRect.bottom); glUniformMatrix4fv(fill.program->getUniform("roundRectInvTransform"), 1, GL_FALSE, &state->matrix.data[0]); // add half pixel to round out integer rect space to cover pixel centers float roundedOutRadius = state->radius + 0.5f; // Divide by the radius to simplify the calculations in the fragment shader // roundRectPos is also passed from vertex shader relative to top/left & radius glUniform4f(fill.program->getUniform("roundRectInnerRectLTWH"), innerRect.left / roundedOutRadius, innerRect.top / roundedOutRadius, (innerRect.right - innerRect.left) / roundedOutRadius, (innerRect.bottom - innerRect.top) / roundedOutRadius); glUniformMatrix4fv(fill.program->getUniform("roundRectInvTransform"), 1, GL_FALSE, &state->matrix.data[0]); glUniform1f(fill.program->getUniform("roundRectRadius"), roundedOutRadius); } Loading