diff options
author | Chris Craik <ccraik@google.com> | 2014-08-07 14:34:46 -0700 |
---|---|---|
committer | Chris Craik <ccraik@google.com> | 2014-08-07 22:26:55 +0000 |
commit | 74cf7e6a25c6d7b331c231b7bc2512044f9d2950 (patch) | |
tree | 18e658508fa40721ce7c9ceb4308d875c8d718f3 /libs | |
parent | d224a9dfd2d2f1977e7a40ba3bbfb42a4165aedc (diff) | |
download | frameworks_base-74cf7e6a25c6d7b331c231b7bc2512044f9d2950.zip frameworks_base-74cf7e6a25c6d7b331c231b7bc2512044f9d2950.tar.gz frameworks_base-74cf7e6a25c6d7b331c231b7bc2512044f9d2950.tar.bz2 |
Cap scales used for tessellation with minimum and maximum
bug:15615144
Change-Id: I3e833864af3a7b34e444bd13db34b6c90496a8b6
Diffstat (limited to 'libs')
-rwxr-xr-x | libs/hwui/OpenGLRenderer.cpp | 7 | ||||
-rw-r--r-- | libs/hwui/PathTessellator.cpp | 37 | ||||
-rw-r--r-- | libs/hwui/RenderProperties.h | 2 | ||||
-rw-r--r-- | libs/hwui/utils/MathUtils.h | 17 |
4 files changed, 32 insertions, 31 deletions
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index e00d2e3..396c7f3 100755 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -58,11 +58,6 @@ namespace uirenderer { // Defines /////////////////////////////////////////////////////////////////////////////// -#define RAD_TO_DEG (180.0f / 3.14159265f) -#define MIN_ANGLE 0.001f - -#define ALPHA_THRESHOLD 0 - static GLenum getFilter(const SkPaint* paint) { if (!paint || paint->getFilterLevel() != SkPaint::kNone_FilterLevel) { return GL_LINEAR; @@ -692,7 +687,7 @@ void OpenGLRenderer::updateSnapshotIgnoreForLayer(const Rect& bounds, const Rect (fboLayer && clip.isEmpty())) { mSnapshot->empty = fboLayer; } else { - mSnapshot->invisible = mSnapshot->invisible || (alpha <= ALPHA_THRESHOLD && fboLayer); + mSnapshot->invisible = mSnapshot->invisible || (alpha <= 0 && fboLayer); } } diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp index 209341c..e30ac19 100644 --- a/libs/hwui/PathTessellator.cpp +++ b/libs/hwui/PathTessellator.cpp @@ -49,6 +49,7 @@ #include "Matrix.h" #include "Vector.h" #include "Vertex.h" +#include "utils/MathUtils.h" namespace android { namespace uirenderer { @@ -56,12 +57,11 @@ namespace uirenderer { #define OUTLINE_REFINE_THRESHOLD_SQUARED (0.5f * 0.5f) #define ROUND_CAP_THRESH 0.25f #define PI 3.1415926535897932f +#define MAX_DEPTH 15 -// temporary error thresholds -#define ERROR_DEPTH 20 -#define ERROR_SCALE 1e10 -#define ERROR_SQR_INV_THRESH 1e-20 - +/** + * Extracts the x and y scale from the transform as positive values, and clamps them + */ void PathTessellator::extractTessellationScales(const Matrix4& transform, float* scaleX, float* scaleY) { if (CC_LIKELY(transform.isPureTranslate())) { @@ -72,11 +72,8 @@ void PathTessellator::extractTessellationScales(const Matrix4& transform, float m01 = transform.data[Matrix4::kSkewY]; float m10 = transform.data[Matrix4::kSkewX]; float m11 = transform.data[Matrix4::kScaleY]; - *scaleX = sqrt(m00 * m00 + m01 * m01); - *scaleY = sqrt(m10 * m10 + m11 * m11); - - LOG_ALWAYS_FATAL_IF(*scaleX > ERROR_SCALE || *scaleY > ERROR_SCALE, - "scales %e x %e too large for tessellation", *scaleX, *scaleY); + *scaleX = MathUtils::clampTessellationScale(sqrt(m00 * m00 + m01 * m01)); + *scaleY = MathUtils::clampTessellationScale(sqrt(m10 * m10 + m11 * m11)); } } @@ -109,8 +106,8 @@ public: } else { float scaleX, scaleY; PathTessellator::extractTessellationScales(transform, &scaleX, &scaleY); - inverseScaleX = (scaleX != 0) ? (1.0f / scaleX) : 1.0f; - inverseScaleY = (scaleY != 0) ? (1.0f / scaleY) : 1.0f; + inverseScaleX = 1.0f / scaleX; + inverseScaleY = 1.0f / scaleY; } if (isAA && halfStrokeWidth != 0 && inverseScaleX == inverseScaleY && @@ -914,9 +911,6 @@ bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, bool fo Vector<Vertex>& outputVertices) { ATRACE_CALL(); - LOG_ALWAYS_FATAL_IF(sqrInvScaleX < ERROR_SQR_INV_THRESH || sqrInvScaleY < ERROR_SQR_INV_THRESH, - "Invalid scale factors used for approx %e, %e", sqrInvScaleX, sqrInvScaleY); - // TODO: to support joins other than sharp miter, join vertices should be labelled in the // perimeter, or resolved into more vertices. Reconsider forceClose-ing in that case. SkPath::Iter iter(path, forceClose); @@ -975,9 +969,6 @@ void PathTessellator::recursiveCubicBezierVertices( float p2x, float p2y, float c2x, float c2y, float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared, Vector<Vertex>& outputVertices, int depth) { - LOG_ALWAYS_FATAL_IF(depth >= ERROR_DEPTH, "ERROR DEPTH exceeded: cubic approx, invscale %e x %e, vertcount %d", - sqrInvScaleX, sqrInvScaleY, outputVertices.size()); - float dx = p2x - p1x; float dy = p2y - p1y; float d1 = fabs((c1x - p2x) * dy - (c1y - p2y) * dx); @@ -985,7 +976,8 @@ void PathTessellator::recursiveCubicBezierVertices( float d = d1 + d2; // multiplying by sqrInvScaleY/X equivalent to multiplying in dimensional scale factors - if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) { + if (depth >= MAX_DEPTH + || d * d <= thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) { // below thresh, draw line by adding endpoint pushToVector(outputVertices, p2x, p2y); } else { @@ -1023,14 +1015,13 @@ void PathTessellator::recursiveQuadraticBezierVertices( float cx, float cy, float sqrInvScaleX, float sqrInvScaleY, float thresholdSquared, Vector<Vertex>& outputVertices, int depth) { - LOG_ALWAYS_FATAL_IF(depth >= ERROR_DEPTH, "ERROR_DEPTH exceeded: quadratic approx, invscale %e x %e, vertcount %d", - sqrInvScaleX, sqrInvScaleY, outputVertices.size()); - float dx = bx - ax; float dy = by - ay; float d = (cx - bx) * dy - (cy - by) * dx; - if (d * d < thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) { + // multiplying by sqrInvScaleY/X equivalent to multiplying in dimensional scale factors + if (depth >= MAX_DEPTH + || d * d <= thresholdSquared * (dx * dx * sqrInvScaleY + dy * dy * sqrInvScaleX)) { // below thresh, draw line by adding endpoint pushToVector(outputVertices, bx, by); } else { diff --git a/libs/hwui/RenderProperties.h b/libs/hwui/RenderProperties.h index 41f48cd..0c8d07f 100644 --- a/libs/hwui/RenderProperties.h +++ b/libs/hwui/RenderProperties.h @@ -313,7 +313,6 @@ public: } bool setScaleX(float scaleX) { - LOG_ALWAYS_FATAL_IF(scaleX > 1000000, "invalid scaleX %e", scaleX); return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleX, scaleX); } @@ -322,7 +321,6 @@ public: } bool setScaleY(float scaleY) { - LOG_ALWAYS_FATAL_IF(scaleY > 1000000, "invalid scaleY %e", scaleY); return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleY, scaleY); } diff --git a/libs/hwui/utils/MathUtils.h b/libs/hwui/utils/MathUtils.h index 66bc127..6fb0411 100644 --- a/libs/hwui/utils/MathUtils.h +++ b/libs/hwui/utils/MathUtils.h @@ -35,6 +35,9 @@ public: return value >= NON_ZERO_EPSILON; } + /** + * Clamps alpha value, and snaps when very near 0 or 1 + */ inline static float clampAlpha(float alpha) { if (alpha <= ALPHA_EPSILON) { return 0; @@ -45,6 +48,20 @@ public: } } + /* + * Clamps positive tessellation scale values + */ + inline static float clampTessellationScale(float scale) { + const float MIN_SCALE = 0.0001; + const float MAX_SCALE = 1e10; + if (scale < MIN_SCALE) { + return MIN_SCALE; + } else if (scale > MAX_SCALE) { + return MAX_SCALE; + } + return scale; + } + inline static bool areEqual(float valueA, float valueB) { return isZero(valueA - valueB); } |