summaryrefslogtreecommitdiffstats
path: root/libs/hwui
diff options
context:
space:
mode:
authorChris Craik <ccraik@google.com>2013-09-17 16:20:29 -0700
committerChris Craik <ccraik@google.com>2013-09-17 17:48:14 -0700
commit32f05e343c5ffb17f3235942bcda651bd3b9f1d6 (patch)
treef3c0ed7a1a252728c21bd5b178ff69d625bf74d5 /libs/hwui
parent0f3e1487b26a822697f70747290809081c2072cc (diff)
downloadframeworks_base-32f05e343c5ffb17f3235942bcda651bd3b9f1d6.zip
frameworks_base-32f05e343c5ffb17f3235942bcda651bd3b9f1d6.tar.gz
frameworks_base-32f05e343c5ffb17f3235942bcda651bd3b9f1d6.tar.bz2
Conservatively estimate geometry bounds
bug:10761696 Avoids a case where a rect with top coordinate of (e.g.) 0.51f is assumed to not draw in the first row of pixels, which leads to it not being clipped. Since rounding can cause it to render in this first pixel anyway, we very slightly expand geometry bounds. Now, in ambiguous cases, the geometry bounds are expanded so clipping is more likely to happen. Change-Id: I119b7c7720de07bac1634549724ffb63935567fc
Diffstat (limited to 'libs/hwui')
-rw-r--r--libs/hwui/OpenGLRenderer.cpp9
-rw-r--r--libs/hwui/Program.cpp3
-rw-r--r--libs/hwui/Rect.h40
-rw-r--r--libs/hwui/Vertex.h9
4 files changed, 43 insertions, 18 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2066f69..89a82fd 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1628,14 +1628,7 @@ bool OpenGLRenderer::quickRejectNoScissor(float left, float top, float right, fl
Rect r(left, top, right, bottom);
currentTransform().mapRect(r);
-
- if (snapOut) {
- // snapOut is generally used to account for 1 pixel ramp (in window coordinates)
- // outside of the provided rect boundaries in tessellated AA geometry
- r.snapOutToPixelBoundaries();
- } else {
- r.snapToPixelBoundaries();
- }
+ r.snapGeometryToPixelBoundaries(snapOut);
Rect clipRect(*mSnapshot->clipRect);
clipRect.snapToPixelBoundaries();
diff --git a/libs/hwui/Program.cpp b/libs/hwui/Program.cpp
index 9e4670e..7814a01 100644
--- a/libs/hwui/Program.cpp
+++ b/libs/hwui/Program.cpp
@@ -20,6 +20,7 @@
#include <utils/Trace.h>
#include "Program.h"
+#include "Vertex.h"
namespace android {
namespace uirenderer {
@@ -172,7 +173,7 @@ void Program::set(const mat4& projectionMatrix, const mat4& modelViewMatrix,
// up and to the left.
// This offset value is based on an assumption that some hardware may use as
// little as 12.4 precision, so we offset by slightly more than 1/16.
- p.translate(.065, .065);
+ p.translate(Vertex::gGeometryFudgeFactor, Vertex::gGeometryFudgeFactor);
glUniformMatrix4fv(projection, 1, GL_FALSE, &p.data[0]);
}
mProjection = projectionMatrix;
diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h
index 7605307..dabd8d4 100644
--- a/libs/hwui/Rect.h
+++ b/libs/hwui/Rect.h
@@ -21,6 +21,8 @@
#include <utils/Log.h>
+#include "Vertex.h"
+
namespace android {
namespace uirenderer {
@@ -171,17 +173,37 @@ public:
}
/**
- * Similar to snapToPixelBoundaries, but used for AA geometry with a ramp perimeter.
+ * Similar to snapToPixelBoundaries, but estimates bounds conservatively to handle GL rounding
+ * errors.
*
- * We inset the data by a fudge factor of slightly over 1/16 (similar to when drawing non-AA
- * lines) before rounding out so that insignificant amounts of ramp geometry (esp. from rounding
- * errors) are ignored.
+ * This function should be used whenever estimating the damage rect of geometry already mapped
+ * into layer space.
*/
- void snapOutToPixelBoundaries() {
- left = floorf(left + 0.065f);
- top = floorf(top + 0.065f);
- right = ceilf(right - 0.065f);
- bottom = ceilf(bottom - 0.065f);
+ void snapGeometryToPixelBoundaries(bool snapOut) {
+ if (snapOut) {
+ /* For AA geometry with a ramp perimeter, don't snap by rounding - AA geometry will have
+ * a 0.5 pixel perimeter not accounted for in its bounds. Instead, snap by
+ * conservatively rounding out the bounds with floor/ceil.
+ *
+ * In order to avoid changing integer bounds with floor/ceil due to rounding errors
+ * inset the bounds first by the fudge factor. Very small fraction-of-a-pixel errors
+ * from this inset will only incur similarly small errors in output, due to transparency
+ * in extreme outside of the geometry.
+ */
+ left = floorf(left + Vertex::gGeometryFudgeFactor);
+ top = floorf(top + Vertex::gGeometryFudgeFactor);
+ right = ceilf(right - Vertex::gGeometryFudgeFactor);
+ bottom = ceilf(bottom - Vertex::gGeometryFudgeFactor);
+ } else {
+ /* For other geometry, we do the regular rounding in order to snap, but also outset the
+ * bounds by a fudge factor. This ensures that ambiguous geometry (e.g. a non-AA Rect
+ * with top left at (0.5, 0.5)) will err on the side of a larger damage rect.
+ */
+ left = floorf(left + 0.5f - Vertex::gGeometryFudgeFactor);
+ top = floorf(top + 0.5f - Vertex::gGeometryFudgeFactor);
+ right = floorf(right + 0.5f + Vertex::gGeometryFudgeFactor);
+ bottom = floorf(bottom + 0.5f + Vertex::gGeometryFudgeFactor);
+ }
}
void snapToPixelBoundaries() {
diff --git a/libs/hwui/Vertex.h b/libs/hwui/Vertex.h
index c06762f..790d4fc 100644
--- a/libs/hwui/Vertex.h
+++ b/libs/hwui/Vertex.h
@@ -26,6 +26,15 @@ namespace uirenderer {
* Simple structure to describe a vertex with a position and a texture.
*/
struct Vertex {
+ /**
+ * Fudge-factor used to disambiguate geometry pixel positioning.
+ *
+ * Used to offset lines and points to avoid ambiguous intersection with pixel centers (see
+ * Program::set()), and used to make geometry damage rect calculation conservative (see
+ * Rect::snapGeometryToPixelBoundaries())
+ */
+ static const float gGeometryFudgeFactor = 0.0656f;
+
float position[2];
static inline void set(Vertex* vertex, float x, float y) {