GrMatrixEffect applies coord normalization/flip for GrTextureEffect.
It checks if its child is a GrTextureEffect and if so the child supplies a matrix to concat. Additionally, GrTextureEffect shader modes that operate on unnormalized texture coords no longer receive prenormalized coords that must be unnormalized. Hoping this addresses (maybe partially) this regression: https://perf.skia.org/e/?begin=1618332600&end=1618386249&keys=Xdf47e259cd874b84b2e0c31c9465abe8&num_commits=50&request_type=1&xbaroffset=54589 Bug: skia:11844 Change-Id: I97eeb88440d5d81acb3edd8c406b17680da67438 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/397218 Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
59f1a9cb7a
commit
816db16d19
@ -29,7 +29,13 @@ private:
|
|||||||
void onSetData(const GrGLSLProgramDataManager& pdman,
|
void onSetData(const GrGLSLProgramDataManager& pdman,
|
||||||
const GrFragmentProcessor& proc) override {
|
const GrFragmentProcessor& proc) override {
|
||||||
const GrMatrixEffect& mtx = proc.cast<GrMatrixEffect>();
|
const GrMatrixEffect& mtx = proc.cast<GrMatrixEffect>();
|
||||||
pdman.setSkMatrix(fMatrixVar, mtx.matrix());
|
if (auto te = mtx.childProcessor(0)->asTextureEffect()) {
|
||||||
|
SkMatrix m = te->coordAdjustmentMatrix();
|
||||||
|
m.preConcat(mtx.matrix());
|
||||||
|
pdman.setSkMatrix(fMatrixVar, m);
|
||||||
|
} else {
|
||||||
|
pdman.setSkMatrix(fMatrixVar, mtx.matrix());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UniformHandle fMatrixVar;
|
UniformHandle fMatrixVar;
|
||||||
|
@ -150,61 +150,16 @@ bool GrTextureEffect::Sampling::hasBorderAlpha() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_matrix(const SkMatrix& preMatrix, const GrSurfaceProxyView& view,
|
|
||||||
SkMatrix* outMatrix, bool* outLazyProxyNormalization) {
|
|
||||||
SkMatrix combined = preMatrix;
|
|
||||||
bool canNormalize = view.proxy()->backendFormat().textureType() != GrTextureType::kRectangle;
|
|
||||||
if (canNormalize) {
|
|
||||||
if (view.proxy()->isFullyLazy()) {
|
|
||||||
*outLazyProxyNormalization = true;
|
|
||||||
} else {
|
|
||||||
SkMatrixPriv::PostIDiv(&combined, view.proxy()->backingStoreDimensions().fWidth,
|
|
||||||
view.proxy()->backingStoreDimensions().fHeight);
|
|
||||||
*outLazyProxyNormalization = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*outLazyProxyNormalization = false;
|
|
||||||
}
|
|
||||||
if (view.origin() == kBottomLeft_GrSurfaceOrigin) {
|
|
||||||
if (canNormalize) {
|
|
||||||
if (!view.proxy()->isFullyLazy()) {
|
|
||||||
// combined.postScale(1,-1);
|
|
||||||
// combined.postTranslate(0,1);
|
|
||||||
combined.set(SkMatrix::kMSkewY,
|
|
||||||
combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
|
|
||||||
combined.set(SkMatrix::kMScaleY,
|
|
||||||
combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
|
|
||||||
combined.set(SkMatrix::kMTransY,
|
|
||||||
combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// combined.postScale(1, -1);
|
|
||||||
// combined.postTranslate(0,1);
|
|
||||||
SkScalar h = view.proxy()->backingStoreDimensions().fHeight;
|
|
||||||
combined.set(SkMatrix::kMSkewY,
|
|
||||||
h * combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]);
|
|
||||||
combined.set(SkMatrix::kMScaleY,
|
|
||||||
h * combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]);
|
|
||||||
combined.set(SkMatrix::kMTransY,
|
|
||||||
h * combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*outMatrix = combined;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView view,
|
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView view,
|
||||||
SkAlphaType alphaType,
|
SkAlphaType alphaType,
|
||||||
const SkMatrix& matrix,
|
const SkMatrix& matrix,
|
||||||
Filter filter,
|
Filter filter,
|
||||||
MipmapMode mm) {
|
MipmapMode mm) {
|
||||||
SkMatrix final;
|
Sampling sampling = Sampling(filter, mm);
|
||||||
bool lazyProxyNormalization;
|
std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
|
||||||
get_matrix(matrix, view, &final, &lazyProxyNormalization);
|
alphaType,
|
||||||
return GrMatrixEffect::Make(final, std::unique_ptr<GrFragmentProcessor>(
|
sampling));
|
||||||
new GrTextureEffect(std::move(view),
|
return GrMatrixEffect::Make(matrix, std::move(te));
|
||||||
alphaType,
|
|
||||||
Sampling(filter, mm),
|
|
||||||
lazyProxyNormalization)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView view,
|
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView view,
|
||||||
@ -213,16 +168,16 @@ std::unique_ptr<GrFragmentProcessor> GrTextureEffect::Make(GrSurfaceProxyView vi
|
|||||||
GrSamplerState sampler,
|
GrSamplerState sampler,
|
||||||
const GrCaps& caps,
|
const GrCaps& caps,
|
||||||
const float border[4]) {
|
const float border[4]) {
|
||||||
Sampling sampling(*view.proxy(), sampler, SkRect::Make(view.proxy()->dimensions()), nullptr,
|
Sampling sampling(*view.proxy(),
|
||||||
border, caps);
|
sampler,
|
||||||
SkMatrix final;
|
SkRect::Make(view.proxy()->dimensions()),
|
||||||
bool lazyProxyNormalization;
|
nullptr,
|
||||||
get_matrix(matrix, view, &final, &lazyProxyNormalization);
|
border,
|
||||||
return GrMatrixEffect::Make(final, std::unique_ptr<GrFragmentProcessor>(
|
caps);
|
||||||
new GrTextureEffect(std::move(view),
|
std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
|
||||||
alphaType,
|
alphaType,
|
||||||
sampling,
|
sampling));
|
||||||
lazyProxyNormalization)));
|
return GrMatrixEffect::Make(matrix, std::move(te));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyView view,
|
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyView view,
|
||||||
@ -233,14 +188,10 @@ std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyV
|
|||||||
const GrCaps& caps,
|
const GrCaps& caps,
|
||||||
const float border[4]) {
|
const float border[4]) {
|
||||||
Sampling sampling(*view.proxy(), sampler, subset, nullptr, border, caps);
|
Sampling sampling(*view.proxy(), sampler, subset, nullptr, border, caps);
|
||||||
SkMatrix final;
|
std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
|
||||||
bool lazyProxyNormalization;
|
alphaType,
|
||||||
get_matrix(matrix, view, &final, &lazyProxyNormalization);
|
sampling));
|
||||||
return GrMatrixEffect::Make(final, std::unique_ptr<GrFragmentProcessor>(
|
return GrMatrixEffect::Make(matrix, std::move(te));
|
||||||
new GrTextureEffect(std::move(view),
|
|
||||||
alphaType,
|
|
||||||
sampling,
|
|
||||||
lazyProxyNormalization)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyView view,
|
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyView view,
|
||||||
@ -252,14 +203,10 @@ std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeSubset(GrSurfaceProxyV
|
|||||||
const GrCaps& caps,
|
const GrCaps& caps,
|
||||||
const float border[4]) {
|
const float border[4]) {
|
||||||
Sampling sampling(*view.proxy(), sampler, subset, &domain, border, caps);
|
Sampling sampling(*view.proxy(), sampler, subset, &domain, border, caps);
|
||||||
SkMatrix final;
|
std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
|
||||||
bool lazyProxyNormalization;
|
alphaType,
|
||||||
get_matrix(matrix, view, &final, &lazyProxyNormalization);
|
sampling));
|
||||||
return GrMatrixEffect::Make(final, std::unique_ptr<GrFragmentProcessor>(
|
return GrMatrixEffect::Make(matrix, std::move(te));
|
||||||
new GrTextureEffect(std::move(view),
|
|
||||||
alphaType,
|
|
||||||
sampling,
|
|
||||||
lazyProxyNormalization)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeCustomLinearFilterInset(
|
std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeCustomLinearFilterInset(
|
||||||
@ -275,12 +222,28 @@ std::unique_ptr<GrFragmentProcessor> GrTextureEffect::MakeCustomLinearFilterInse
|
|||||||
const float border[4]) {
|
const float border[4]) {
|
||||||
GrSamplerState sampler(wx, wy, Filter::kLinear);
|
GrSamplerState sampler(wx, wy, Filter::kLinear);
|
||||||
Sampling sampling(*view.proxy(), sampler, subset, domain, border, caps, inset);
|
Sampling sampling(*view.proxy(), sampler, subset, domain, border, caps, inset);
|
||||||
SkMatrix final;
|
std::unique_ptr<GrFragmentProcessor> te(new GrTextureEffect(std::move(view),
|
||||||
bool lazyProxyNormalization;
|
alphaType,
|
||||||
get_matrix(matrix, view, &final, &lazyProxyNormalization);
|
sampling));
|
||||||
return GrMatrixEffect::Make(
|
return GrMatrixEffect::Make(matrix, std::move(te));
|
||||||
final, std::unique_ptr<GrFragmentProcessor>(new GrTextureEffect(
|
}
|
||||||
std::move(view), alphaType, sampling, lazyProxyNormalization)));
|
|
||||||
|
SkMatrix GrTextureEffect::coordAdjustmentMatrix() const {
|
||||||
|
SkMatrix m;
|
||||||
|
GrTexture* texture = this->texture();
|
||||||
|
SkISize d = texture->dimensions();
|
||||||
|
if (this->matrixEffectShouldNormalize()) {
|
||||||
|
if (fView.origin() == kBottomLeft_GrSurfaceOrigin) {
|
||||||
|
m.setScaleTranslate(1.f / d.width(), -1.f / d.height(), 0, 1);
|
||||||
|
} else {
|
||||||
|
m.setScale(1.f / d.width(), 1.f / d.height());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (fView.origin() == kBottomLeft_GrSurfaceOrigin) {
|
||||||
|
m.setScaleTranslate(1.f, -1.f, 0, d.height());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrTextureEffect::ShaderMode GrTextureEffect::GetShaderMode(Wrap wrap,
|
GrTextureEffect::ShaderMode GrTextureEffect::GetShaderMode(Wrap wrap,
|
||||||
@ -319,6 +282,21 @@ inline bool GrTextureEffect::ShaderModeIsClampToBorder(ShaderMode m) {
|
|||||||
return m == ShaderMode::kClampToBorder_Nearest || m == ShaderMode::kClampToBorder_Filter;
|
return m == ShaderMode::kClampToBorder_Nearest || m == ShaderMode::kClampToBorder_Filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GrTextureEffect::ShaderModeRequiresUnormCoord(ShaderMode m) {
|
||||||
|
switch (m) {
|
||||||
|
case ShaderMode::kNone: return false;
|
||||||
|
case ShaderMode::kClamp: return false;
|
||||||
|
case ShaderMode::kRepeat_Nearest_None: return false;
|
||||||
|
case ShaderMode::kRepeat_Linear_None: return true;
|
||||||
|
case ShaderMode::kRepeat_Nearest_Mipmap: return true;
|
||||||
|
case ShaderMode::kRepeat_Linear_Mipmap: return true;
|
||||||
|
case ShaderMode::kMirrorRepeat: return false;
|
||||||
|
case ShaderMode::kClampToBorder_Nearest: return true;
|
||||||
|
case ShaderMode::kClampToBorder_Filter: return true;
|
||||||
|
}
|
||||||
|
SkUNREACHABLE;
|
||||||
|
};
|
||||||
|
|
||||||
void GrTextureEffect::Impl::emitCode(EmitArgs& args) {
|
void GrTextureEffect::Impl::emitCode(EmitArgs& args) {
|
||||||
using ShaderMode = GrTextureEffect::ShaderMode;
|
using ShaderMode = GrTextureEffect::ShaderMode;
|
||||||
|
|
||||||
@ -328,15 +306,7 @@ void GrTextureEffect::Impl::emitCode(EmitArgs& args) {
|
|||||||
if (te.fShaderModes[0] == ShaderMode::kNone &&
|
if (te.fShaderModes[0] == ShaderMode::kNone &&
|
||||||
te.fShaderModes[1] == ShaderMode::kNone) {
|
te.fShaderModes[1] == ShaderMode::kNone) {
|
||||||
fb->codeAppendf("return ");
|
fb->codeAppendf("return ");
|
||||||
if (te.fLazyProxyNormalization) {
|
fb->appendTextureLookup(fSamplerHandle, args.fSampleCoord);
|
||||||
const char* norm = nullptr;
|
|
||||||
fNormUni = args.fUniformHandler->addUniform(&te, kFragment_GrShaderFlag,
|
|
||||||
kFloat4_GrSLType, "norm", &norm);
|
|
||||||
SkString coordString = SkStringPrintf("%s * %s.zw", args.fSampleCoord, norm);
|
|
||||||
fb->appendTextureLookup(fSamplerHandle, coordString.c_str());
|
|
||||||
} else {
|
|
||||||
fb->appendTextureLookup(fSamplerHandle, args.fSampleCoord);
|
|
||||||
}
|
|
||||||
fb->codeAppendf(";");
|
fb->codeAppendf(";");
|
||||||
} else {
|
} else {
|
||||||
// Here is the basic flow of the various ShaderModes are implemented in a series of
|
// Here is the basic flow of the various ShaderModes are implemented in a series of
|
||||||
@ -361,8 +331,6 @@ void GrTextureEffect::Impl::emitCode(EmitArgs& args) {
|
|||||||
fb->codeAppendf("float2 inCoord = %s;", args.fSampleCoord);
|
fb->codeAppendf("float2 inCoord = %s;", args.fSampleCoord);
|
||||||
|
|
||||||
const auto& m = te.fShaderModes;
|
const auto& m = te.fShaderModes;
|
||||||
GrTextureType textureType = te.view().proxy()->backendFormat().textureType();
|
|
||||||
bool canNormalize = textureType != GrTextureType::kRectangle;
|
|
||||||
|
|
||||||
const char* borderName = nullptr;
|
const char* borderName = nullptr;
|
||||||
if (te.hasClampToBorderShaderMode()) {
|
if (te.hasClampToBorderShaderMode()) {
|
||||||
@ -399,24 +367,6 @@ void GrTextureEffect::Impl::emitCode(EmitArgs& args) {
|
|||||||
SkUNREACHABLE;
|
SkUNREACHABLE;
|
||||||
};
|
};
|
||||||
|
|
||||||
// To keep things a little simpler, when we have filtering logic in the shader we
|
|
||||||
// operate on unnormalized texture coordinates. We will add a uniform that stores
|
|
||||||
// {w, h, 1/w, 1/h} in a float4 below.
|
|
||||||
auto modeRequiresUnormCoords = [](ShaderMode m) {
|
|
||||||
switch (m) {
|
|
||||||
case ShaderMode::kNone: return false;
|
|
||||||
case ShaderMode::kClamp: return false;
|
|
||||||
case ShaderMode::kRepeat_Nearest_None: return false;
|
|
||||||
case ShaderMode::kRepeat_Linear_None: return true;
|
|
||||||
case ShaderMode::kRepeat_Nearest_Mipmap: return true;
|
|
||||||
case ShaderMode::kRepeat_Linear_Mipmap: return true;
|
|
||||||
case ShaderMode::kMirrorRepeat: return false;
|
|
||||||
case ShaderMode::kClampToBorder_Nearest: return true;
|
|
||||||
case ShaderMode::kClampToBorder_Filter: return true;
|
|
||||||
}
|
|
||||||
SkUNREACHABLE;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool useSubset[2] = {modeUsesSubset(m[0]), modeUsesSubset(m[1])};
|
bool useSubset[2] = {modeUsesSubset(m[0]), modeUsesSubset(m[1])};
|
||||||
bool useClamp [2] = {modeUsesClamp (m[0]), modeUsesClamp (m[1])};
|
bool useClamp [2] = {modeUsesClamp (m[0]), modeUsesClamp (m[1])};
|
||||||
|
|
||||||
@ -432,30 +382,28 @@ void GrTextureEffect::Impl::emitCode(EmitArgs& args) {
|
|||||||
&te, kFragment_GrShaderFlag, kFloat4_GrSLType, "clamp", &clampName);
|
&te, kFragment_GrShaderFlag, kFloat4_GrSLType, "clamp", &clampName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unormCoordsRequired = modeRequiresUnormCoords(m[0]) || modeRequiresUnormCoords(m[1]);
|
bool unormCoordsRequiredForShaderMode = ShaderModeRequiresUnormCoord(m[0]) ||
|
||||||
|
ShaderModeRequiresUnormCoord(m[1]);
|
||||||
|
// We should not pre-normalize the input coords with GrMatrixEffect if we're going to
|
||||||
|
// operate on unnormalized coords and then normalize after the shader mode.
|
||||||
|
SkASSERT(!(unormCoordsRequiredForShaderMode && te.matrixEffectShouldNormalize()));
|
||||||
|
bool sampleCoordsMustBeNormalized =
|
||||||
|
te.fView.asTextureProxy()->textureType() != GrTextureType::kRectangle;
|
||||||
|
|
||||||
const char* norm = nullptr;
|
const char* idims = nullptr;
|
||||||
if (canNormalize && (unormCoordsRequired || te.fLazyProxyNormalization)) {
|
if (unormCoordsRequiredForShaderMode && sampleCoordsMustBeNormalized) {
|
||||||
// TODO: Detect support for textureSize() or polyfill textureSize() in SkSL and
|
// TODO: Detect support for textureSize() or polyfill textureSize() in SkSL and
|
||||||
// always use?
|
// always use?
|
||||||
fNormUni = args.fUniformHandler->addUniform(&te, kFragment_GrShaderFlag,
|
fIDimsUni = args.fUniformHandler->addUniform(&te, kFragment_GrShaderFlag,
|
||||||
kFloat4_GrSLType, "norm", &norm);
|
kFloat2_GrSLType, "idims", &idims);
|
||||||
|
|
||||||
if (!te.fLazyProxyNormalization) {
|
|
||||||
// TODO: Remove the normalization from the CoordTransform to skip unnormalizing
|
|
||||||
// step here.
|
|
||||||
fb->codeAppendf("inCoord *= %s.xy;", norm);
|
|
||||||
} else if (te.view().origin() == kBottomLeft_GrSurfaceOrigin) {
|
|
||||||
fb->codeAppendf("inCoord.y = %s.y - inCoord.y;", norm);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates a string to read at a coordinate, normalizing coords if necessary.
|
// Generates a string to read at a coordinate, normalizing coords if necessary.
|
||||||
auto read = [&](const char* coord) {
|
auto read = [&](const char* coord) {
|
||||||
SkString result;
|
SkString result;
|
||||||
SkString normCoord;
|
SkString normCoord;
|
||||||
if (norm) {
|
if (idims) {
|
||||||
normCoord.printf("(%s) * %s.zw", coord, norm);
|
normCoord.printf("(%s) * %s", coord, idims);
|
||||||
} else {
|
} else {
|
||||||
normCoord = coord;
|
normCoord = coord;
|
||||||
}
|
}
|
||||||
@ -724,10 +672,10 @@ void GrTextureEffect::Impl::onSetData(const GrGLSLProgramDataManager& pdm,
|
|||||||
|
|
||||||
auto type = te.texture()->textureType();
|
auto type = te.texture()->textureType();
|
||||||
|
|
||||||
float norm[4] = {w, h, 1.f/w, 1.f/h};
|
float idims[2] = {1.f/w, 1.f/h};
|
||||||
|
|
||||||
if (fNormUni.isValid()) {
|
if (fIDimsUni.isValid()) {
|
||||||
pdm.set4fv(fNormUni, 1, norm);
|
pdm.set2fv(fIDimsUni, 1, idims);
|
||||||
SkASSERT(type != GrTextureType::kRectangle);
|
SkASSERT(type != GrTextureType::kRectangle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -737,11 +685,11 @@ void GrTextureEffect::Impl::onSetData(const GrGLSLProgramDataManager& pdm,
|
|||||||
rect[3] = h - rect[3];
|
rect[3] = h - rect[3];
|
||||||
std::swap(rect[1], rect[3]);
|
std::swap(rect[1], rect[3]);
|
||||||
}
|
}
|
||||||
if (!fNormUni.isValid() && type != GrTextureType::kRectangle) {
|
if (!fIDimsUni.isValid() && type != GrTextureType::kRectangle) {
|
||||||
rect[0] *= norm[2];
|
rect[0] *= idims[0];
|
||||||
rect[2] *= norm[2];
|
rect[2] *= idims[0];
|
||||||
rect[1] *= norm[3];
|
rect[1] *= idims[1];
|
||||||
rect[3] *= norm[3];
|
rect[3] *= idims[1];
|
||||||
}
|
}
|
||||||
pdm.set4fv(uni, 1, rect);
|
pdm.set4fv(uni, 1, rect);
|
||||||
};
|
};
|
||||||
@ -769,13 +717,6 @@ void GrTextureEffect::onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyB
|
|||||||
|
|
||||||
auto m1 = static_cast<uint32_t>(fShaderModes[1]);
|
auto m1 = static_cast<uint32_t>(fShaderModes[1]);
|
||||||
b->addBits(8, m1, "shaderMode1");
|
b->addBits(8, m1, "shaderMode1");
|
||||||
|
|
||||||
// The origin only affects the shader code when we're doing last minute normalization
|
|
||||||
// for lazy proxies.
|
|
||||||
b->addBool(fLazyProxyNormalization, "normalization");
|
|
||||||
if (fLazyProxyNormalization) {
|
|
||||||
b->addBits(1, this->view().origin(), "origin");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrTextureEffect::onIsEqual(const GrFragmentProcessor& other) const {
|
bool GrTextureEffect::onIsEqual(const GrFragmentProcessor& other) const {
|
||||||
@ -798,18 +739,22 @@ bool GrTextureEffect::onIsEqual(const GrFragmentProcessor& other) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GrTextureEffect::matrixEffectShouldNormalize() const {
|
||||||
|
return fView.asTextureProxy()->textureType() != GrTextureType::kRectangle &&
|
||||||
|
!ShaderModeRequiresUnormCoord(fShaderModes[0]) &&
|
||||||
|
!ShaderModeRequiresUnormCoord(fShaderModes[1]);
|
||||||
|
}
|
||||||
|
|
||||||
GrTextureEffect::GrTextureEffect(GrSurfaceProxyView view,
|
GrTextureEffect::GrTextureEffect(GrSurfaceProxyView view,
|
||||||
SkAlphaType alphaType,
|
SkAlphaType alphaType,
|
||||||
const Sampling& sampling,
|
const Sampling& sampling)
|
||||||
bool lazyProxyNormalization)
|
|
||||||
: GrFragmentProcessor(kGrTextureEffect_ClassID,
|
: GrFragmentProcessor(kGrTextureEffect_ClassID,
|
||||||
ModulateForSamplerOptFlags(alphaType, sampling.hasBorderAlpha()))
|
ModulateForSamplerOptFlags(alphaType, sampling.hasBorderAlpha()))
|
||||||
, fView(std::move(view))
|
, fView(std::move(view))
|
||||||
, fSamplerState(sampling.fHWSampler)
|
, fSamplerState(sampling.fHWSampler)
|
||||||
, fSubset(sampling.fShaderSubset)
|
, fSubset(sampling.fShaderSubset)
|
||||||
, fClamp(sampling.fShaderClamp)
|
, fClamp(sampling.fShaderClamp)
|
||||||
, fShaderModes{sampling.fShaderModes[0], sampling.fShaderModes[1]}
|
, fShaderModes{sampling.fShaderModes[0], sampling.fShaderModes[1]} {
|
||||||
, fLazyProxyNormalization(lazyProxyNormalization) {
|
|
||||||
// We always compare the range even when it isn't used so assert we have canonical don't care
|
// We always compare the range even when it isn't used so assert we have canonical don't care
|
||||||
// values.
|
// values.
|
||||||
SkASSERT(fShaderModes[0] != ShaderMode::kNone || (fSubset.fLeft == 0 && fSubset.fRight == 0));
|
SkASSERT(fShaderModes[0] != ShaderMode::kNone || (fSubset.fLeft == 0 && fSubset.fRight == 0));
|
||||||
@ -824,8 +769,7 @@ GrTextureEffect::GrTextureEffect(const GrTextureEffect& src)
|
|||||||
, fSamplerState(src.fSamplerState)
|
, fSamplerState(src.fSamplerState)
|
||||||
, fSubset(src.fSubset)
|
, fSubset(src.fSubset)
|
||||||
, fClamp(src.fClamp)
|
, fClamp(src.fClamp)
|
||||||
, fShaderModes{src.fShaderModes[0], src.fShaderModes[1]}
|
, fShaderModes{src.fShaderModes[0], src.fShaderModes[1]} {
|
||||||
, fLazyProxyNormalization(src.fLazyProxyNormalization) {
|
|
||||||
std::copy_n(src.fBorder, 4, fBorder);
|
std::copy_n(src.fBorder, 4, fBorder);
|
||||||
this->setUsesSampleCoordsDirectly();
|
this->setUsesSampleCoordsDirectly();
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,12 @@ public:
|
|||||||
|
|
||||||
const GrSurfaceProxyView& view() const { return fView; }
|
const GrSurfaceProxyView& view() const { return fView; }
|
||||||
|
|
||||||
|
// Gets a matrix that is concat'ed by wrapping GrMatrixEffect that handles y-flip and coord
|
||||||
|
// normalization if required. This matrix is not always known when we make the GrTextureEffect
|
||||||
|
// because of fully-lazy proxies. Hence, this method exists to allow this concat to happen
|
||||||
|
// after proxy instantiation with coordination from GrMatrixEffect.
|
||||||
|
SkMatrix coordAdjustmentMatrix() const;
|
||||||
|
|
||||||
class Impl : public GrGLSLFragmentProcessor {
|
class Impl : public GrGLSLFragmentProcessor {
|
||||||
public:
|
public:
|
||||||
void emitCode(EmitArgs&) override;
|
void emitCode(EmitArgs&) override;
|
||||||
@ -112,7 +118,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
UniformHandle fSubsetUni;
|
UniformHandle fSubsetUni;
|
||||||
UniformHandle fClampUni;
|
UniformHandle fClampUni;
|
||||||
UniformHandle fNormUni;
|
UniformHandle fIDimsUni;
|
||||||
UniformHandle fBorderUni;
|
UniformHandle fBorderUni;
|
||||||
GrGLSLShaderBuilder::SamplerHandle fSamplerHandle;
|
GrGLSLShaderBuilder::SamplerHandle fSamplerHandle;
|
||||||
};
|
};
|
||||||
@ -139,6 +145,11 @@ private:
|
|||||||
GrSamplerState::Filter,
|
GrSamplerState::Filter,
|
||||||
GrSamplerState::MipmapMode);
|
GrSamplerState::MipmapMode);
|
||||||
static bool ShaderModeIsClampToBorder(ShaderMode);
|
static bool ShaderModeIsClampToBorder(ShaderMode);
|
||||||
|
// To keep things a little simpler, when we have filtering logic in the shader we
|
||||||
|
// operate on unnormalized texture coordinates. We will add a uniform that stores
|
||||||
|
// {1/w, 1/h} in a float2 and normalizes after the mode is handled if the texture
|
||||||
|
// is not rectangle.
|
||||||
|
static bool ShaderModeRequiresUnormCoord(ShaderMode);
|
||||||
|
|
||||||
GrSurfaceProxyView fView;
|
GrSurfaceProxyView fView;
|
||||||
GrSamplerState fSamplerState;
|
GrSamplerState fSamplerState;
|
||||||
@ -146,10 +157,8 @@ private:
|
|||||||
SkRect fSubset;
|
SkRect fSubset;
|
||||||
SkRect fClamp;
|
SkRect fClamp;
|
||||||
ShaderMode fShaderModes[2];
|
ShaderMode fShaderModes[2];
|
||||||
// true if we are dealing with a fully lazy proxy which can't be normalized until runtime
|
|
||||||
bool fLazyProxyNormalization;
|
|
||||||
|
|
||||||
inline GrTextureEffect(GrSurfaceProxyView, SkAlphaType, const Sampling&, bool);
|
inline GrTextureEffect(GrSurfaceProxyView, SkAlphaType, const Sampling&);
|
||||||
|
|
||||||
explicit GrTextureEffect(const GrTextureEffect& src);
|
explicit GrTextureEffect(const GrTextureEffect& src);
|
||||||
|
|
||||||
@ -159,6 +168,8 @@ private:
|
|||||||
|
|
||||||
bool onIsEqual(const GrFragmentProcessor&) const override;
|
bool onIsEqual(const GrFragmentProcessor&) const override;
|
||||||
|
|
||||||
|
bool matrixEffectShouldNormalize() const;
|
||||||
|
|
||||||
bool hasClampToBorderShaderMode() const {
|
bool hasClampToBorderShaderMode() const {
|
||||||
return ShaderModeIsClampToBorder(fShaderModes[0]) ||
|
return ShaderModeIsClampToBorder(fShaderModes[0]) ||
|
||||||
ShaderModeIsClampToBorder(fShaderModes[1]);
|
ShaderModeIsClampToBorder(fShaderModes[1]);
|
||||||
|
Loading…
Reference in New Issue
Block a user