Index: src/gpu/GrCoordTransform.cpp |
diff --git a/src/gpu/GrCoordTransform.cpp b/src/gpu/GrCoordTransform.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..53285a27eb40d8cb234b9dc002566190606fc4d5 |
--- /dev/null |
+++ b/src/gpu/GrCoordTransform.cpp |
@@ -0,0 +1,61 @@ |
+/* |
+ * Copyright 2014 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "GrCoordTransform.h" |
+#include "GrContext.h" |
+#include "GrDrawTargetCaps.h" |
+#include "GrGpu.h" |
+ |
+void GrCoordTransform::reset(GrCoordSet sourceCoords, const SkMatrix& m, const GrTexture* texture) { |
+ SkASSERT(texture); |
+ SkASSERT(!fInProcessor); |
+ |
+ fSourceCoords = sourceCoords; |
+ fMatrix = m; |
+ fReverseY = kBottomLeft_GrSurfaceOrigin == texture->origin(); |
+ |
+ // Always start at kDefault. Then if precisions differ we see if the precision needs to be |
+ // increased. Our rule is that we want at least 4 subpixel values in the representation for |
+ // coords between 0 to 1. Note that this still might not be enough when drawing with repeat |
+ // or mirror-repeat modes but that case can be arbitrarily bad. |
+ fPrecision = GrShaderVar::kDefault_Precision; |
+ if (texture->getContext()) { |
+ const GrDrawTargetCaps* caps = texture->getContext()->getGpu()->caps(); |
+ if (caps->floatPrecisionVaries()) { |
+ int maxD = SkTMax(texture->width(), texture->height()); |
+ const GrDrawTargetCaps::PrecisionInfo* info; |
+ info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, fPrecision); |
+ do { |
+ SkASSERT(info->supported()); |
+ // Make sure there is at least 2 bits of subpixel precision in the range of |
+ // texture coords from 0.5 to 1.0. |
+ if ((2 << info->fBits) / maxD > 4) { |
+ break; |
+ } |
+ if (GrShaderVar::kHigh_Precision == fPrecision) { |
+ break; |
+ } |
+ GrShaderVar::Precision nextP = static_cast<GrShaderVar::Precision>(fPrecision + 1); |
+ info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, nextP); |
+ if (!info->supported()) { |
+ break; |
+ } |
+ fPrecision = nextP; |
+ } while (true); |
+ } |
+ } |
+} |
+ |
+void GrCoordTransform::reset(GrCoordSet sourceCoords, |
+ const SkMatrix& m, |
+ GrShaderVar::Precision precision) { |
+ SkASSERT(!fInProcessor); |
+ fSourceCoords = sourceCoords; |
+ fMatrix = m; |
+ fReverseY = false; |
+ fPrecision = precision; |
+} |