Reland "Improve precision and speed of oval rendering."
This reverts commitcd2253d07f
. Reason for revert: Tweaks for Adreno. Original change's description: > Revert "Improve precision and speed of oval rendering." > > This reverts commit551dc3e911
. > > Reason for revert: Centers of ovals are dropping out on Adreno330 > > Original change's description: > > Improve precision and speed of oval rendering. > > > > Reduces computations, and fixes some issues with large ovals. > > > > Change-Id: I2a961f2115e4e5fcb756714dd7e45c7528ed679a > > Reviewed-on: https://skia-review.googlesource.com/136229 > > Reviewed-by: Brian Osman <brianosman@google.com> > > Commit-Queue: Jim Van Verth <jvanverth@google.com> > > TBR=jvanverth@google.com,brianosman@google.com > > Change-Id: I704dcd591217f04cedb5b6c5c5ade3df928f8249 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Reviewed-on: https://skia-review.googlesource.com/138040 > Reviewed-by: Jim Van Verth <jvanverth@google.com> > Commit-Queue: Jim Van Verth <jvanverth@google.com> TBR=jvanverth@google.com,brianosman@google.com Change-Id: I710b79376dfd75b718fd867b149b28faebd1946a No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/138180 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
b06be0e8b9
commit
b1b87d9df8
@ -578,25 +578,37 @@ private:
|
||||
egp.kInPosition.asShaderVar(),
|
||||
egp.fLocalMatrix,
|
||||
args.fFPCoordTransformHandler);
|
||||
// For stroked ellipses, we use the full ellipse equation (x^2/a^2 + y^2/b^2 = 1)
|
||||
// to compute both the edges because we need two separate test equations for
|
||||
// the single offset.
|
||||
// For filled ellipses we can use a unit circle equation (x^2 + y^2 = 1), and warp
|
||||
// the distance by the gradient, non-uniformly scaled by the inverse of the
|
||||
// ellipse size.
|
||||
|
||||
// for outer curve
|
||||
fragBuilder->codeAppendf("half2 scaledOffset = %s*%s.xy;", ellipseOffsets.fsIn(),
|
||||
ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppend("half test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fragBuilder->codeAppendf("half2 grad = 2.0*scaledOffset*%s.xy;", ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppendf("half2 offset = %s;", ellipseOffsets.fsIn());
|
||||
if (egp.fStroke) {
|
||||
fragBuilder->codeAppendf("offset *= %s.xy;", ellipseRadii.fsIn());
|
||||
}
|
||||
fragBuilder->codeAppend("half test = dot(offset, offset) - 1.0;");
|
||||
fragBuilder->codeAppendf("half2 grad = 2.0*offset*%s.xy;", ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppend("half grad_dot = dot(grad, grad);");
|
||||
|
||||
// avoid calling inversesqrt on zero.
|
||||
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
|
||||
if (args.fShaderCaps->halfIs32Bits()) {
|
||||
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-6);");
|
||||
} else {
|
||||
fragBuilder->codeAppend("grad_dot = max(grad_dot, 3.1e-5);");
|
||||
}
|
||||
fragBuilder->codeAppend("half invlen = inversesqrt(grad_dot);");
|
||||
fragBuilder->codeAppend("half edgeAlpha = clamp(0.5-test*invlen, 0.0, 1.0);");
|
||||
|
||||
// for inner curve
|
||||
if (egp.fStroke) {
|
||||
fragBuilder->codeAppendf("scaledOffset = %s*%s.zw;", ellipseOffsets.fsIn(),
|
||||
fragBuilder->codeAppendf("offset = %s*%s.zw;", ellipseOffsets.fsIn(),
|
||||
ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppend("test = dot(scaledOffset, scaledOffset) - 1.0;");
|
||||
fragBuilder->codeAppendf("grad = 2.0*scaledOffset*%s.zw;", ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppend("test = dot(offset, offset) - 1.0;");
|
||||
fragBuilder->codeAppendf("grad = 2.0*offset*%s.zw;", ellipseRadii.fsIn());
|
||||
fragBuilder->codeAppend("invlen = inversesqrt(dot(grad, grad));");
|
||||
fragBuilder->codeAppend("edgeAlpha *= clamp(0.5+test*invlen, 0.0, 1.0);");
|
||||
}
|
||||
@ -739,7 +751,11 @@ private:
|
||||
|
||||
fragBuilder->codeAppend("half grad_dot = dot(grad, grad);");
|
||||
// avoid calling inversesqrt on zero.
|
||||
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
|
||||
if (args.fShaderCaps->halfIs32Bits()) {
|
||||
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-6);");
|
||||
} else {
|
||||
fragBuilder->codeAppend("grad_dot = max(grad_dot, 3.1e-5);");
|
||||
}
|
||||
fragBuilder->codeAppend("half invlen = inversesqrt(grad_dot);");
|
||||
if (DIEllipseStyle::kHairline == diegp.fStyle) {
|
||||
// can probably do this with one step
|
||||
@ -1975,11 +1991,16 @@ private:
|
||||
SkScalar yRadRecip = SkScalarInvert(yRadius);
|
||||
SkScalar xInnerRadRecip = SkScalarInvert(ellipse.fInnerXRadius);
|
||||
SkScalar yInnerRadRecip = SkScalarInvert(ellipse.fInnerYRadius);
|
||||
|
||||
// fOffsets are expanded from xyRadii to include the half-pixel antialiasing width.
|
||||
SkScalar xMaxOffset = xRadius + SK_ScalarHalf;
|
||||
SkScalar yMaxOffset = yRadius + SK_ScalarHalf;
|
||||
|
||||
if (!fStroked) {
|
||||
// For filled ellipses we map a unit circle in the vertex attributes rather than
|
||||
// computing an ellipse and modifying that distance, so we normalize to 1
|
||||
xMaxOffset /= xRadius;
|
||||
yMaxOffset /= yRadius;
|
||||
}
|
||||
|
||||
// The inner radius in the vertex data must be specified in normalized space.
|
||||
verts[0].fPos = SkPoint::Make(ellipse.fDevBounds.fLeft, ellipse.fDevBounds.fTop);
|
||||
verts[0].fColor = color;
|
||||
@ -2919,19 +2940,28 @@ private:
|
||||
SkScalar xOuterRadius = rrect.fXRadius + SK_ScalarHalf;
|
||||
SkScalar yOuterRadius = rrect.fYRadius + SK_ScalarHalf;
|
||||
|
||||
SkScalar xMaxOffset = xOuterRadius;
|
||||
SkScalar yMaxOffset = yOuterRadius;
|
||||
if (!fStroked) {
|
||||
// For filled rrects we map a unit circle in the vertex attributes rather than
|
||||
// computing an ellipse and modifying that distance, so we normalize to 1.
|
||||
xMaxOffset /= rrect.fXRadius;
|
||||
yMaxOffset /= rrect.fYRadius;
|
||||
}
|
||||
|
||||
const SkRect& bounds = rrect.fDevBounds;
|
||||
|
||||
SkScalar yCoords[4] = {bounds.fTop, bounds.fTop + yOuterRadius,
|
||||
bounds.fBottom - yOuterRadius, bounds.fBottom};
|
||||
SkScalar yOuterOffsets[4] = {yOuterRadius,
|
||||
SkScalar yOuterOffsets[4] = {yMaxOffset,
|
||||
SK_ScalarNearlyZero, // we're using inversesqrt() in
|
||||
// shader, so can't be exactly 0
|
||||
SK_ScalarNearlyZero, yOuterRadius};
|
||||
SK_ScalarNearlyZero, yMaxOffset};
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
verts->fPos = SkPoint::Make(bounds.fLeft, yCoords[i]);
|
||||
verts->fColor = color;
|
||||
verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]);
|
||||
verts->fOffset = SkPoint::Make(xMaxOffset, yOuterOffsets[i]);
|
||||
verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
|
||||
verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
|
||||
verts++;
|
||||
@ -2952,7 +2982,7 @@ private:
|
||||
|
||||
verts->fPos = SkPoint::Make(bounds.fRight, yCoords[i]);
|
||||
verts->fColor = color;
|
||||
verts->fOffset = SkPoint::Make(xOuterRadius, yOuterOffsets[i]);
|
||||
verts->fOffset = SkPoint::Make(xMaxOffset, yOuterOffsets[i]);
|
||||
verts->fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
|
||||
verts->fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
|
||||
verts++;
|
||||
|
Loading…
Reference in New Issue
Block a user