summaryrefslogtreecommitdiff
path: root/libs/hwui/renderstate/RenderState.cpp
diff options
context:
space:
mode:
authorArun <arun.demeure@imgtec.com>2017-01-23 11:59:21 +0000
committerChris Craik <ccraik@google.com>2017-06-01 13:42:12 -0700
commit06e9f324ef5b723622647a6f111c38cb2d479869 (patch)
tree1d4e45635bf9eb8c9c18e494f5be25711678ed84 /libs/hwui/renderstate/RenderState.cpp
parent142a392b75e7bf8e4e880b5cc49d111fd8d82533 (diff)
Optimised hwui rounded corners shader
This is a ~2x performance increase for the rounded corners shader which was previously shader limited even on many high-end GPUs. It simplifies the calculations by pre-dividing by the radius, which also allows to maintain mediump/FP16 precision (this improves performance and might improve image quality on GPUs that don't support highp e.g. Mali-400). It also uses a conditional in the shader to save much of the work on the vast majority of pixels which are not close to the corners. Test: manual - visual inspection on fugu (nexus player) Change-Id: I38f491cfb006e2991ef0b9d6b3d67d2c4d328d44
Diffstat (limited to 'libs/hwui/renderstate/RenderState.cpp')
-rw-r--r--libs/hwui/renderstate/RenderState.cpp16
1 files changed, 11 insertions, 5 deletions
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index c4e8e4f2df6e..2a3a9f3635ca 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -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);
}