diff options
author | Arun <arun.demeure@imgtec.com> | 2017-01-23 11:59:21 +0000 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2017-06-01 13:42:12 -0700 |
commit | 06e9f324ef5b723622647a6f111c38cb2d479869 (patch) | |
tree | 1d4e45635bf9eb8c9c18e494f5be25711678ed84 /libs/hwui/renderstate/RenderState.cpp | |
parent | 142a392b75e7bf8e4e880b5cc49d111fd8d82533 (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.cpp | 16 |
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); } |