Coord transforms are always computed and interpolated at high precision.
Bug: skia:
Change-Id: I5f7eadc2080df8ad5cbb080835c0dba09c59e63e
Reviewed-on: https://skia-review.googlesource.com/11180
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
#ifndef GrCoordTransform_DEFINED
#define GrCoordTransform_DEFINED
-#include "GrProcessor.h"
#include "SkMatrix.h"
#include "GrTexture.h"
-#include "GrTypes.h"
-#include "GrShaderVar.h"
+class GrResourceProvider;
class GrTextureProxy;
/**
GrCoordTransform()
: fTexture(nullptr)
, fNormalize(false)
- , fReverseY(false)
- , fPrecision(kDefault_GrSLPrecision) {
+ , fReverseY(false) {
SkDEBUGCODE(fInProcessor = false);
}
/**
- * Create a transformation that maps [0, 1] to a proxy's boundaries. The precision is inferred
- * from the proxy size and filter. The proxy origin also implies whether a y-reversal should
- * be performed.
+ * Create a transformation that maps [0, 1] to a proxy's boundaries. The proxy origin also
+ * implies whether a y-reversal should be performed.
*/
- GrCoordTransform(GrResourceProvider* resourceProvider, GrTextureProxy* proxy,
- GrSamplerParams::FilterMode filter) {
+ GrCoordTransform(GrResourceProvider* resourceProvider, GrTextureProxy* proxy) {
SkASSERT(proxy);
SkDEBUGCODE(fInProcessor = false);
- this->reset(resourceProvider, SkMatrix::I(), proxy, filter);
+ this->reset(resourceProvider, SkMatrix::I(), proxy);
}
/**
- * Create a transformation from a matrix. The precision is inferred from the proxy size and
- * filter. The proxy origin also implies whether a y-reversal should be performed.
+ * Create a transformation from a matrix. The proxy origin also implies whether a y-reversal
+ * should be performed.
*/
GrCoordTransform(GrResourceProvider* resourceProvider, const SkMatrix& m,
- GrTextureProxy* proxy, GrSamplerParams::FilterMode filter) {
+ GrTextureProxy* proxy) {
SkASSERT(proxy);
SkDEBUGCODE(fInProcessor = false);
- this->reset(resourceProvider, m, proxy, filter);
+ this->reset(resourceProvider, m, proxy);
}
/**
* Create a transformation that applies the matrix to a coord set.
*/
- GrCoordTransform(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) {
+ GrCoordTransform(const SkMatrix& m) {
SkDEBUGCODE(fInProcessor = false);
- this->reset(m, precision);
+ this->reset(m);
}
- void reset(GrResourceProvider*, const SkMatrix&, GrTextureProxy*,
- GrSamplerParams::FilterMode filter, bool normalize = true);
+ void reset(GrResourceProvider*, const SkMatrix&, GrTextureProxy*, bool normalize = true);
- void reset(const SkMatrix& m, GrSLPrecision precision = kDefault_GrSLPrecision) {
+ void reset(const SkMatrix& m) {
SkASSERT(!fInProcessor);
fMatrix = m;
fTexture = nullptr;
fNormalize = false;
fReverseY = false;
- fPrecision = precision;
}
GrCoordTransform& operator= (const GrCoordTransform& that) {
fTexture = that.fTexture;
fNormalize = that.fNormalize;
fReverseY = that.fReverseY;
- fPrecision = that.fPrecision;
return *this;
}
const GrTexture* texture() const { return fTexture; }
bool normalize() const { return fNormalize; }
bool reverseY() const { return fReverseY; }
- GrSLPrecision precision() const { return kHigh_GrSLPrecision; }
private:
// The textures' effect is to optionally normalize the final matrix, so a blind
const GrTexture* fTexture;
bool fNormalize;
bool fReverseY;
- GrSLPrecision fPrecision;
typedef SkNoncopyable INHERITED;
#ifdef SK_DEBUG
: INHERITED(OptFlags(outerThreshold))
, fInnerThreshold(innerThreshold)
, fOuterThreshold(outerThreshold)
- , fImageCoordTransform(resourceProvider, SkMatrix::I(), proxy.get(),
- GrSamplerParams::kNone_FilterMode)
+ , fImageCoordTransform(resourceProvider, SkMatrix::I(), proxy.get())
, fImageTextureSampler(resourceProvider, std::move(proxy))
, fColorSpaceXform(std::move(colorSpaceXform))
, fMaskCoordTransform(
resourceProvider,
SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
- maskProxy.get(),
- GrSamplerParams::kNone_FilterMode)
+ maskProxy.get())
, fMaskTextureSampler(resourceProvider, maskProxy) {
this->initClassID<GrAlphaThresholdFragmentProcessor>();
this->addCoordTransform(&fImageCoordTransform);
const SkISize& colorDimensions)
: INHERITED(GrPixelConfigIsOpaque(color->config()) ? kPreservesOpaqueInput_OptimizationFlag
: kNone_OptimizationFlags)
- , fDisplacementTransform(resourceProvider, offsetMatrix, displacement.get(),
- GrSamplerParams::kNone_FilterMode)
+ , fDisplacementTransform(resourceProvider, offsetMatrix, displacement.get())
, fDisplacementSampler(resourceProvider, displacement)
- , fColorTransform(resourceProvider, color.get(), GrSamplerParams::kNone_FilterMode)
+ , fColorTransform(resourceProvider, color.get())
, fDomain(color.get(), GrTextureDomain::MakeTexelDomain(SkIRect::MakeSize(colorDimensions)),
GrTextureDomain::kDecal_Mode)
, fColorSampler(resourceProvider, color)
fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNormalizedTexelHeight();
// This is 1/2 places where auto-normalization is disabled
fCoordTransform.reset(args.fContext->resourceProvider(), *args.fMatrix,
- fAtlas->asTextureProxyRef().get(),
- params.filterMode(), false);
+ fAtlas->asTextureProxyRef().get(), false);
fTextureSampler.reset(args.fContext->resourceProvider(),
fAtlas->asTextureProxyRef(), params);
} else {
}
// This is 2/2 places where auto-normalization is disabled
fCoordTransform.reset(args.fContext->resourceProvider(), *args.fMatrix,
- proxy.get(), params.filterMode(), false);
+ proxy.get(), false);
fTextureSampler.reset(args.fContext->resourceProvider(),
std::move(proxy), params);
fYCoord = SK_ScalarHalf;
*/
#include "GrCoordTransform.h"
-#include "GrCaps.h"
-#include "GrContext.h"
-#include "GrGpu.h"
#include "GrResourceProvider.h"
#include "GrTextureProxy.h"
-static GrSLPrecision compute_precision(const GrShaderCaps* caps,
- int width, int height,
- GrSamplerParams::FilterMode filter) {
- // 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 when bi- or tri-lerping and 1 value when nearest filtering. Note that
- // this still might not be enough when drawing with repeat or mirror-repeat modes but that case
- // can be arbitrarily bad.
- int subPixelThresh = filter > GrSamplerParams::kNone_FilterMode ? 4 : 1;
- GrSLPrecision precision = kDefault_GrSLPrecision;
- if (caps) {
- if (caps->floatPrecisionVaries()) {
- int maxD = SkTMax(width, height);
- const GrShaderCaps::PrecisionInfo* info;
- info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, precision);
- 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 > subPixelThresh) {
- break;
- }
- if (kHigh_GrSLPrecision == precision) {
- break;
- }
- GrSLPrecision nextP = static_cast<GrSLPrecision>(precision + 1);
- info = &caps->getFloatShaderPrecisionInfo(kFragment_GrShaderType, nextP);
- if (!info->supported()) {
- break;
- }
- precision = nextP;
- } while (true);
- }
- }
-
- return precision;
-}
-
void GrCoordTransform::reset(GrResourceProvider* resourceProvider, const SkMatrix& m,
- GrTextureProxy* proxy,
- GrSamplerParams::FilterMode filter, bool normalize) {
+ GrTextureProxy* proxy, bool normalize) {
SkASSERT(proxy);
SkASSERT(!fInProcessor);
fTexture = proxy->instantiate(resourceProvider);
fNormalize = normalize;
fReverseY = kBottomLeft_GrSurfaceOrigin == proxy->origin();
-
- const GrCaps* caps = resourceProvider->caps();
- fPrecision = compute_precision(caps->shaderCaps(),
- proxy->worstCaseWidth(*caps),
- proxy->worstCaseHeight(*caps), filter);
}
-
#include "GrCoordTransform.h"
/**
- * The key for an individual coord transform is made up of a matrix type, a precision, and a bit
- * that indicates the source of the input coords.
+ * The key for an individual coord transform is made up of a matrix type, and a bit that indicates
+ * the source of the input coords.
*/
enum {
kMatrixTypeKeyBits = 1,
- kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1,
-
- kPrecisionBits = 2,
- kPrecisionShift = kMatrixTypeKeyBits,
-
- kPositionCoords_Flag = (1 << (kPrecisionShift + kPrecisionBits)),
-
- kTransformKeyBits = kMatrixTypeKeyBits + kPrecisionBits + 2,
+ kPositionCoords_Flag = 1 << kMatrixTypeKeyBits,
+ kTransformKeyBits = kMatrixTypeKeyBits + 1,
};
-GR_STATIC_ASSERT(kHigh_GrSLPrecision < (1 << kPrecisionBits));
-
/**
* We specialize the vertex code for each of these matrix types.
*/
key |= kPositionCoords_Flag;
}
- GR_STATIC_ASSERT(kGrSLPrecisionCount <= (1 << kPrecisionBits));
- key |= (coordTransform->precision() << kPrecisionShift);
-
key <<= kTransformKeyBits * t;
SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to overlap
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& m)
: INHERITED(optFlags)
- , fCoordTransform(resourceProvider, m, proxy.get(), GrSamplerParams::kNone_FilterMode)
+ , fCoordTransform(resourceProvider, m, proxy.get())
, fTextureSampler(resourceProvider, std::move(proxy))
, fColorSpaceXform(std::move(colorSpaceXform)) {
this->addCoordTransform(&fCoordTransform);
const SkMatrix& m,
GrSamplerParams::FilterMode filterMode)
: INHERITED(optFlags)
- , fCoordTransform(resourceProvider, m, proxy.get(), filterMode)
+ , fCoordTransform(resourceProvider, m, proxy.get())
, fTextureSampler(resourceProvider, std::move(proxy), filterMode)
, fColorSpaceXform(std::move(colorSpaceXform)) {
this->addCoordTransform(&fCoordTransform);
sk_sp<GrColorSpaceXform> colorSpaceXform,
const SkMatrix& m, const GrSamplerParams& params)
: INHERITED(optFlags)
- , fCoordTransform(resourceProvider, m, proxy.get(), params.filterMode())
+ , fCoordTransform(resourceProvider, m, proxy.get())
, fTextureSampler(resourceProvider, std::move(proxy), params)
, fColorSpaceXform(std::move(colorSpaceXform)) {
this->addCoordTransform(&fCoordTransform);
sk_sp<GrTextureProxy> vProxy, const SkMatrix yuvMatrix[3],
GrSamplerParams::FilterMode uvFilterMode, SkYUVColorSpace colorSpace, bool nv12)
: INHERITED(kPreservesOpaqueInput_OptimizationFlag)
- , fYTransform(resourceProvider, yuvMatrix[0], yProxy.get(),
- GrSamplerParams::kNone_FilterMode)
+ , fYTransform(resourceProvider, yuvMatrix[0], yProxy.get())
, fYSampler(resourceProvider, std::move(yProxy))
- , fUTransform(resourceProvider, yuvMatrix[1], uProxy.get(), uvFilterMode)
+ , fUTransform(resourceProvider, yuvMatrix[1], uProxy.get())
, fUSampler(resourceProvider, std::move(uProxy), uvFilterMode)
, fVSampler(resourceProvider, vProxy, uvFilterMode)
, fColorSpace(colorSpace)
this->addCoordTransform(&fUTransform);
this->addTextureSampler(&fUSampler);
if (!fNV12) {
- fVTransform = GrCoordTransform(resourceProvider, yuvMatrix[2], vProxy.get(),
- uvFilterMode);
+ fVTransform = GrCoordTransform(resourceProvider, yuvMatrix[2], vProxy.get());
this->addCoordTransform(&fVTransform);
this->addTextureSampler(&fVSampler);
}
varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_GrSLType :
kVec2f_GrSLType;
- GrSLPrecision precision = coordTransform->precision();
+ // Coord transforms are always handled at high precision
+ const GrSLPrecision precision = kHigh_GrSLPrecision;
const char* uniName;