Re-land of "converted GrSimpleTextureEffect to sksl"
This reverts commit baf981f716
.
Bug: skia:
Change-Id: I36f6bfb616f1ec2b89043e3a6f7cbdf473bc9588
Reviewed-on: https://skia-review.googlesource.com/22369
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
c20b5f8359
commit
68990be759
@ -27,4 +27,5 @@ skia_gpu_processor_sources = [
|
||||
"$_src/effects/GrAlphaThresholdFragmentProcessor.fp",
|
||||
"$_src/effects/GrCircleBlurFragmentProcessor.fp",
|
||||
"$_src/gpu/effects/GrDitherEffect.fp",
|
||||
"$_src/gpu/effects/GrSimpleTextureEffect.fp",
|
||||
]
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
fOuterThresholdVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "outerThreshold");
|
||||
SkSL::String sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
|
||||
SkSL::String sk_TransformedCoords2D_1 = fragBuilder->ensureCoords2D(args.fTransformedCoords[1]);
|
||||
fragBuilder->codeAppendf("vec4 _tmp0;\nvec4 color = (_tmp0 = texture(%s, %s).%s , %s != mat4(1.0) ? vec4(clamp((%s * vec4(_tmp0.xyz, 1.0)).xyz, 0.0, _tmp0.w), _tmp0.w) : _tmp0);\nvec4 mask_color = texture(%s, %s).%s;\nif (mask_color.w < 0.5) {\n if (color.w > %s) {\n float scale = %s / color.w;\n color.xyz *= scale;\n color.w = %s;\n }\n} else if (color.w < %s) {\n float scale = %s / max(0.001, color.w);\n color.xyz *= scale;\n color.w = %s;\n}\n%s = color;\n", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), sk_TransformedCoords2D_0.c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), fColorSpaceHelper.isValid() ? args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "mat4(1.0)", fColorSpaceHelper.isValid() ? args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform()) : "mat4(1.0)", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(), sk_TransformedCoords2D_1.c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fOutputColor);
|
||||
fragBuilder->codeAppendf("vec4 _tmpVar1;vec4 color = %stexture(%s, %s).%s%s;\nvec4 mask_color = texture(%s, %s).%s;\nif (mask_color.w < 0.5) {\n if (color.w > %s) {\n float scale = %s / color.w;\n color.xyz *= scale;\n color.w = %s;\n }\n} else if (color.w < %s) {\n float scale = %s / max(0.001, color.w);\n color.xyz *= scale;\n color.w = %s;\n}\n%s = color;\n", fColorSpaceHelper.isValid() ? "(_tmpVar1 = " : "", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), sk_TransformedCoords2D_0.c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), fColorSpaceHelper.isValid() ? SkStringPrintf(", vec4(clamp((%s * vec4(_tmpVar1.rgb, 1.0)).rgb, 0.0, _tmpVar1.a), _tmpVar1.a))", args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform())).c_str() : "", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[1]).c_str(), sk_TransformedCoords2D_1.c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[1]).c_str(), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fOuterThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fUniformHandler->getUniformCStr(fInnerThresholdVar), args.fOutputColor);
|
||||
}
|
||||
private:
|
||||
void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
|
||||
|
@ -28,20 +28,12 @@ in uniform float outerThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
@fields {
|
||||
GrCoordTransform fImageCoordTransform;
|
||||
GrCoordTransform fMaskCoordTransform;
|
||||
@coordTransform(image) {
|
||||
SkMatrix::I()
|
||||
}
|
||||
|
||||
@initializers {
|
||||
fImageCoordTransform(SkMatrix::I(), image.get()),
|
||||
fMaskCoordTransform(SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
|
||||
mask.get())
|
||||
}
|
||||
|
||||
@constructorCode {
|
||||
this->addCoordTransform(&fImageCoordTransform);
|
||||
this->addCoordTransform(&fMaskCoordTransform);
|
||||
@coordTransform(mask) {
|
||||
SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y()))
|
||||
}
|
||||
|
||||
@header {
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "GrColorSpaceXform.h"
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrCoordTransform.h"
|
||||
#include "GrColorSpaceXform.h"
|
||||
#include "effects/GrProxyMove.h"
|
||||
class GrAlphaThresholdFragmentProcessor : public GrFragmentProcessor {
|
||||
public:
|
||||
@ -44,35 +45,34 @@ private:
|
||||
const SkIRect& bounds
|
||||
)
|
||||
: INHERITED(kNone_OptimizationFlags)
|
||||
,
|
||||
fImageCoordTransform(SkMatrix::I(), image.get()),
|
||||
fMaskCoordTransform(SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y())),
|
||||
mask.get())
|
||||
|
||||
, fImage(std::move(image))
|
||||
, fColorXform(colorXform)
|
||||
, fMask(std::move(mask))
|
||||
, fInnerThreshold(innerThreshold)
|
||||
, fOuterThreshold(outerThreshold) {
|
||||
|
||||
this->addCoordTransform(&fImageCoordTransform);
|
||||
this->addCoordTransform(&fMaskCoordTransform);
|
||||
, fOuterThreshold(outerThreshold)
|
||||
, fImageCoordTransform(
|
||||
SkMatrix::I()
|
||||
, fImage.proxy())
|
||||
, fMaskCoordTransform(
|
||||
SkMatrix::MakeTrans(SkIntToScalar(-bounds.x()), SkIntToScalar(-bounds.y()))
|
||||
, fMask.proxy()) {
|
||||
this->addTextureSampler(&fImage);
|
||||
this->addTextureSampler(&fMask);
|
||||
this->addCoordTransform(&fImageCoordTransform);
|
||||
this->addCoordTransform(&fMaskCoordTransform);
|
||||
this->initClassID<GrAlphaThresholdFragmentProcessor>();
|
||||
}
|
||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
||||
void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) const override;
|
||||
bool onIsEqual(const GrFragmentProcessor&) const override;
|
||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
|
||||
|
||||
GrCoordTransform fImageCoordTransform;
|
||||
GrCoordTransform fMaskCoordTransform;
|
||||
TextureSampler fImage;
|
||||
sk_sp<GrColorSpaceXform> fColorXform;
|
||||
TextureSampler fMask;
|
||||
float fInnerThreshold;
|
||||
float fOuterThreshold;
|
||||
GrCoordTransform fImageCoordTransform;
|
||||
GrCoordTransform fMaskCoordTransform;
|
||||
typedef GrFragmentProcessor INHERITED;
|
||||
};
|
||||
#endif
|
||||
|
@ -14,6 +14,7 @@
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrCoordTransform.h"
|
||||
#include "GrColorSpaceXform.h"
|
||||
#include "effects/GrProxyMove.h"
|
||||
class GrCircleBlurFragmentProcessor : public GrFragmentProcessor {
|
||||
public:
|
||||
|
@ -14,6 +14,7 @@
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrCoordTransform.h"
|
||||
#include "GrColorSpaceXform.h"
|
||||
#include "effects/GrProxyMove.h"
|
||||
class GrDitherEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
|
@ -1,111 +1,81 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc.
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was autogenerated from GrSimpleTextureEffect.fp; do not modify.
|
||||
*/
|
||||
#include "GrSimpleTextureEffect.h"
|
||||
#include "GrProxyMove.h"
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "glsl/GrGLSLColorSpaceXformHelper.h"
|
||||
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||
|
||||
GrSimpleTextureEffect::GrSimpleTextureEffect(sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& matrix,
|
||||
GrSamplerParams::FilterMode filterMode)
|
||||
: INHERITED{ModulationFlags(proxy->config()),
|
||||
GR_PROXY_MOVE(proxy),
|
||||
std::move(colorSpaceXform),
|
||||
matrix,
|
||||
filterMode} {
|
||||
this->initClassID<GrSimpleTextureEffect>();
|
||||
}
|
||||
|
||||
GrSimpleTextureEffect::GrSimpleTextureEffect(sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& matrix,
|
||||
const GrSamplerParams& params)
|
||||
: INHERITED{ModulationFlags(proxy->config()),
|
||||
GR_PROXY_MOVE(proxy),
|
||||
std::move(colorSpaceXform),
|
||||
matrix,
|
||||
params} {
|
||||
this->initClassID<GrSimpleTextureEffect>();
|
||||
}
|
||||
|
||||
class GrGLSimpleTextureEffect : public GrGLSLFragmentProcessor {
|
||||
#include "glsl/GrGLSLProgramBuilder.h"
|
||||
#include "SkSLCPP.h"
|
||||
#include "SkSLUtil.h"
|
||||
class GrGLSLSimpleTextureEffect : public GrGLSLFragmentProcessor {
|
||||
public:
|
||||
GrGLSLSimpleTextureEffect() {}
|
||||
void emitCode(EmitArgs& args) override {
|
||||
const GrSimpleTextureEffect& textureEffect = args.fFp.cast<GrSimpleTextureEffect>();
|
||||
fColorSpaceHelper.emitCode(args.fUniformHandler, textureEffect.colorSpaceXform());
|
||||
|
||||
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
fragBuilder->codeAppendf("%s = ", args.fOutputColor);
|
||||
fragBuilder->appendTextureLookupAndModulate(args.fInputColor,
|
||||
args.fTexSamplers[0],
|
||||
args.fTransformedCoords[0].c_str(),
|
||||
args.fTransformedCoords[0].getType(),
|
||||
&fColorSpaceHelper);
|
||||
fragBuilder->codeAppend(";");
|
||||
const GrSimpleTextureEffect& _outer = args.fFp.cast<GrSimpleTextureEffect>();
|
||||
(void) _outer;
|
||||
fColorSpaceHelper.emitCode(args.fUniformHandler, _outer.colorXform().get());
|
||||
SkSL::String sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
|
||||
fragBuilder->codeAppendf("vec4 _tmpVar1;%s = %s * %stexture(%s, %s).%s%s;\n", args.fOutputColor, args.fInputColor ? args.fInputColor : "vec4(1)", fColorSpaceHelper.isValid() ? "(_tmpVar1 = " : "", fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), sk_TransformedCoords2D_0.c_str(), fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), fColorSpaceHelper.isValid() ? SkStringPrintf(", vec4(clamp((%s * vec4(_tmpVar1.rgb, 1.0)).rgb, 0.0, _tmpVar1.a), _tmpVar1.a))", args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform())).c_str() : "");
|
||||
}
|
||||
|
||||
static inline void GenKey(const GrProcessor& effect, const GrShaderCaps&,
|
||||
GrProcessorKeyBuilder* b) {
|
||||
const GrSimpleTextureEffect& textureEffect = effect.cast<GrSimpleTextureEffect>();
|
||||
b->add32(GrColorSpaceXform::XformKey(textureEffect.colorSpaceXform()));
|
||||
}
|
||||
|
||||
protected:
|
||||
void onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
const GrFragmentProcessor& processor) override {
|
||||
const GrSimpleTextureEffect& textureEffect = processor.cast<GrSimpleTextureEffect>();
|
||||
if (SkToBool(textureEffect.colorSpaceXform())) {
|
||||
fColorSpaceHelper.setData(pdman, textureEffect.colorSpaceXform());
|
||||
private:
|
||||
void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
|
||||
const GrSimpleTextureEffect& _outer = _proc.cast<GrSimpleTextureEffect>();
|
||||
{
|
||||
if (fColorSpaceHelper.isValid()) {
|
||||
fColorSpaceHelper.setData(pdman, _outer.colorXform().get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef GrGLSLFragmentProcessor INHERITED;
|
||||
|
||||
UniformHandle fImageVar;
|
||||
GrGLSLColorSpaceXformHelper fColorSpaceHelper;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void GrSimpleTextureEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
GrProcessorKeyBuilder* b) const {
|
||||
GrGLSimpleTextureEffect::GenKey(*this, caps, b);
|
||||
GrGLSLFragmentProcessor* GrSimpleTextureEffect::onCreateGLSLInstance() const {
|
||||
return new GrGLSLSimpleTextureEffect();
|
||||
}
|
||||
|
||||
GrGLSLFragmentProcessor* GrSimpleTextureEffect::onCreateGLSLInstance() const {
|
||||
return new GrGLSimpleTextureEffect;
|
||||
void GrSimpleTextureEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
|
||||
b->add32(GrColorSpaceXform::XformKey(fColorXform.get()));
|
||||
}
|
||||
bool GrSimpleTextureEffect::onIsEqual(const GrFragmentProcessor& other) const {
|
||||
const GrSimpleTextureEffect& that = other.cast<GrSimpleTextureEffect>();
|
||||
(void) that;
|
||||
if (fImage != that.fImage) return false;
|
||||
if (fColorXform != that.fColorXform) return false;
|
||||
if (fMatrix != that.fMatrix) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrSimpleTextureEffect);
|
||||
|
||||
#if GR_TEST_UTILS
|
||||
sk_sp<GrFragmentProcessor> GrSimpleTextureEffect::TestCreate(GrProcessorTestData* d) {
|
||||
int texIdx = d->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
|
||||
: GrProcessorUnitTest::kAlphaTextureIdx;
|
||||
sk_sp<GrFragmentProcessor> GrSimpleTextureEffect::TestCreate(GrProcessorTestData* testData) {
|
||||
|
||||
int texIdx = testData->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
|
||||
: GrProcessorUnitTest::kAlphaTextureIdx;
|
||||
static const SkShader::TileMode kTileModes[] = {
|
||||
SkShader::kClamp_TileMode,
|
||||
SkShader::kRepeat_TileMode,
|
||||
SkShader::kMirror_TileMode,
|
||||
};
|
||||
SkShader::TileMode tileModes[] = {
|
||||
kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
||||
kTileModes[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
||||
kTileModes[testData->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
||||
kTileModes[testData->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
||||
};
|
||||
GrSamplerParams params(tileModes, d->fRandom->nextBool() ? GrSamplerParams::kBilerp_FilterMode
|
||||
: GrSamplerParams::kNone_FilterMode);
|
||||
GrSamplerParams params(tileModes, testData->fRandom->nextBool()
|
||||
? GrSamplerParams::kBilerp_FilterMode
|
||||
: GrSamplerParams::kNone_FilterMode);
|
||||
|
||||
const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom);
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(d->fRandom);
|
||||
return GrSimpleTextureEffect::Make(d->textureProxy(texIdx),
|
||||
std::move(colorSpaceXform), matrix);
|
||||
const SkMatrix& matrix = GrTest::TestMatrix(testData->fRandom);
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(testData->fRandom);
|
||||
return GrSimpleTextureEffect::Make(testData->textureProxy(texIdx), std::move(colorSpaceXform),
|
||||
matrix);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
82
src/gpu/effects/GrSimpleTextureEffect.fp
Normal file
82
src/gpu/effects/GrSimpleTextureEffect.fp
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
in uniform sampler2D image;
|
||||
in uniform colorSpaceXform colorXform;
|
||||
in mat4 matrix;
|
||||
|
||||
@constructorParams {
|
||||
GrSamplerParams samplerParams
|
||||
}
|
||||
|
||||
@coordTransform(image) {
|
||||
matrix
|
||||
}
|
||||
|
||||
@samplerParams(image) {
|
||||
samplerParams
|
||||
}
|
||||
|
||||
@make {
|
||||
static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& matrix) {
|
||||
return sk_sp<GrFragmentProcessor>(
|
||||
new GrSimpleTextureEffect(std::move(proxy), std::move(colorSpaceXform), matrix,
|
||||
GrSamplerParams(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode)));
|
||||
}
|
||||
|
||||
/* clamp mode */
|
||||
static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& matrix,
|
||||
GrSamplerParams::FilterMode filterMode) {
|
||||
return sk_sp<GrFragmentProcessor>(
|
||||
new GrSimpleTextureEffect(std::move(proxy), std::move(colorSpaceXform), matrix,
|
||||
GrSamplerParams(SkShader::kClamp_TileMode, filterMode)));
|
||||
}
|
||||
|
||||
static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& matrix,
|
||||
const GrSamplerParams& p) {
|
||||
return sk_sp<GrFragmentProcessor>(
|
||||
new GrSimpleTextureEffect(std::move(proxy), std::move(colorSpaceXform), matrix, p));
|
||||
}
|
||||
}
|
||||
|
||||
@optimizationFlags {
|
||||
kCompatibleWithCoverageAsAlpha_OptimizationFlag |
|
||||
(GrPixelConfigIsOpaque(image->config()) ? kPreservesOpaqueInput_OptimizationFlag :
|
||||
kNone_OptimizationFlags)
|
||||
}
|
||||
|
||||
void main() {
|
||||
sk_OutColor = sk_InColor * texture(image, sk_TransformedCoords2D[0], colorXform);
|
||||
}
|
||||
|
||||
@test(testData) {
|
||||
int texIdx = testData->fRandom->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx
|
||||
: GrProcessorUnitTest::kAlphaTextureIdx;
|
||||
static const SkShader::TileMode kTileModes[] = {
|
||||
SkShader::kClamp_TileMode,
|
||||
SkShader::kRepeat_TileMode,
|
||||
SkShader::kMirror_TileMode,
|
||||
};
|
||||
SkShader::TileMode tileModes[] = {
|
||||
kTileModes[testData->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
||||
kTileModes[testData->fRandom->nextULessThan(SK_ARRAY_COUNT(kTileModes))],
|
||||
};
|
||||
GrSamplerParams params(tileModes, testData->fRandom->nextBool()
|
||||
? GrSamplerParams::kBilerp_FilterMode
|
||||
: GrSamplerParams::kNone_FilterMode);
|
||||
|
||||
const SkMatrix& matrix = GrTest::TestMatrix(testData->fRandom);
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(testData->fRandom);
|
||||
return GrSimpleTextureEffect::Make(testData->textureProxy(texIdx), std::move(colorSpaceXform),
|
||||
matrix);
|
||||
}
|
@ -1,77 +1,82 @@
|
||||
/*
|
||||
* Copyright 2013 Google Inc.
|
||||
* Copyright 2017 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was autogenerated from GrSimpleTextureEffect.fp; do not modify.
|
||||
*/
|
||||
#ifndef GrSimpleTextureEffect_DEFINED
|
||||
#define GrSimpleTextureEffect_DEFINED
|
||||
|
||||
#include "GrSingleTextureEffect.h"
|
||||
#include "GrTextureProxy.h"
|
||||
|
||||
class GrInvariantOutput;
|
||||
|
||||
/**
|
||||
* The output color of this effect is a modulation of the input color and a sample from a texture.
|
||||
* It allows explicit specification of the filtering and wrap modes (GrSamplerParams) and accepts
|
||||
* a matrix that is used to compute texture coordinates from local coordinates.
|
||||
*/
|
||||
class GrSimpleTextureEffect : public GrSingleTextureEffect {
|
||||
#include "SkTypes.h"
|
||||
#if SK_SUPPORT_GPU
|
||||
#include "GrFragmentProcessor.h"
|
||||
#include "GrCoordTransform.h"
|
||||
#include "GrColorSpaceXform.h"
|
||||
#include "effects/GrProxyMove.h"
|
||||
class GrSimpleTextureEffect : public GrFragmentProcessor {
|
||||
public:
|
||||
/* unfiltered, clamp mode */
|
||||
sk_sp<GrColorSpaceXform> colorXform() const { return fColorXform; }
|
||||
SkMatrix44 matrix() const { return fMatrix; }
|
||||
|
||||
static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& matrix) {
|
||||
return sk_sp<GrFragmentProcessor>(
|
||||
new GrSimpleTextureEffect(std::move(proxy),
|
||||
std::move(colorSpaceXform), matrix,
|
||||
GrSamplerParams::kNone_FilterMode));
|
||||
new GrSimpleTextureEffect(std::move(proxy), std::move(colorSpaceXform), matrix,
|
||||
GrSamplerParams(SkShader::kClamp_TileMode, GrSamplerParams::kNone_FilterMode)));
|
||||
}
|
||||
|
||||
/* clamp mode */
|
||||
|
||||
static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& matrix,
|
||||
GrSamplerParams::FilterMode filterMode) {
|
||||
return sk_sp<GrFragmentProcessor>(
|
||||
new GrSimpleTextureEffect(std::move(proxy),
|
||||
std::move(colorSpaceXform),
|
||||
matrix, filterMode));
|
||||
}
|
||||
new GrSimpleTextureEffect(std::move(proxy), std::move(colorSpaceXform), matrix,
|
||||
GrSamplerParams(SkShader::kClamp_TileMode, filterMode)));
|
||||
}
|
||||
|
||||
static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTextureProxy> proxy,
|
||||
sk_sp<GrColorSpaceXform> colorSpaceXform,
|
||||
const SkMatrix& matrix,
|
||||
const GrSamplerParams& p) {
|
||||
return sk_sp<GrFragmentProcessor>(new GrSimpleTextureEffect(std::move(proxy),
|
||||
std::move(colorSpaceXform),
|
||||
matrix, p));
|
||||
return sk_sp<GrFragmentProcessor>(
|
||||
new GrSimpleTextureEffect(std::move(proxy), std::move(colorSpaceXform), matrix, p));
|
||||
}
|
||||
|
||||
~GrSimpleTextureEffect() override {}
|
||||
|
||||
const char* name() const override { return "SimpleTexture"; }
|
||||
|
||||
const char* name() const override { return "SimpleTextureEffect"; }
|
||||
private:
|
||||
GrSimpleTextureEffect(sk_sp<GrTextureProxy>,
|
||||
sk_sp<GrColorSpaceXform>, const SkMatrix& matrix,
|
||||
GrSamplerParams::FilterMode);
|
||||
|
||||
GrSimpleTextureEffect(sk_sp<GrTextureProxy>,
|
||||
sk_sp<GrColorSpaceXform>, const SkMatrix& matrix,
|
||||
const GrSamplerParams&);
|
||||
|
||||
GrSimpleTextureEffect(sk_sp<GrTextureProxy> image, sk_sp<GrColorSpaceXform> colorXform, SkMatrix44 matrix,
|
||||
GrSamplerParams samplerParams
|
||||
)
|
||||
: INHERITED((OptimizationFlags)
|
||||
kCompatibleWithCoverageAsAlpha_OptimizationFlag |
|
||||
(GrPixelConfigIsOpaque(image->config()) ? kPreservesOpaqueInput_OptimizationFlag :
|
||||
kNone_OptimizationFlags)
|
||||
)
|
||||
, fImage(std::move(image),
|
||||
samplerParams
|
||||
)
|
||||
, fColorXform(colorXform)
|
||||
, fMatrix(matrix)
|
||||
, fImageCoordTransform(
|
||||
matrix
|
||||
, fImage.proxy()) {
|
||||
this->addTextureSampler(&fImage);
|
||||
this->addCoordTransform(&fImageCoordTransform);
|
||||
this->initClassID<GrSimpleTextureEffect>();
|
||||
}
|
||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
||||
|
||||
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
|
||||
|
||||
bool onIsEqual(const GrFragmentProcessor& other) const override { return true; }
|
||||
|
||||
void onGetGLSLProcessorKey(const GrShaderCaps&,GrProcessorKeyBuilder*) const override;
|
||||
bool onIsEqual(const GrFragmentProcessor&) const override;
|
||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
|
||||
|
||||
typedef GrSingleTextureEffect INHERITED;
|
||||
TextureSampler fImage;
|
||||
sk_sp<GrColorSpaceXform> fColorXform;
|
||||
SkMatrix44 fMatrix;
|
||||
GrCoordTransform fImageCoordTransform;
|
||||
typedef GrFragmentProcessor INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -89,6 +89,11 @@ Within an '.fp' fragment processor file:
|
||||
the name of the GrGLSLProgramDataManager)
|
||||
@test(<testData>) (the body of the TestCreate function, where <testData> is
|
||||
the name of the GrProcessorTestData* parameter)
|
||||
@coordTransform(<sampler>)
|
||||
(the matrix to attach to the named sampler2D's
|
||||
GrCoordTransform)
|
||||
@samplerParams(<sampler>)
|
||||
(the sampler params to attach to the named sampler2D)
|
||||
* global 'in' variables represent data passed to the fragment processor at
|
||||
construction time. These variables become constructor parameters and are
|
||||
stored in fragment processor fields. vec2s map to SkPoints, and vec4s map to
|
||||
|
@ -163,7 +163,7 @@ void CPPCodeGenerator::writeVarInitializer(const Variable& var, const Expression
|
||||
|
||||
String CPPCodeGenerator::getSamplerHandle(const Variable& var) {
|
||||
int samplerCount = 0;
|
||||
for (const auto param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto param : fSectionAndParameterHelper.getParameters()) {
|
||||
if (&var == param) {
|
||||
return "args.fTexSamplers[" + to_string(samplerCount) + "]";
|
||||
}
|
||||
@ -226,6 +226,20 @@ void CPPCodeGenerator::writeVariableReference(const VariableReference& ref) {
|
||||
}
|
||||
|
||||
void CPPCodeGenerator::writeFunctionCall(const FunctionCall& c) {
|
||||
if (c.fFunction.fBuiltin && c.fFunction.fName == "COLORSPACE") {
|
||||
String tmpVar = "_tmpVar" + to_string(++fVarCount);
|
||||
fFunctionHeader += "vec4 " + tmpVar + ";";
|
||||
ASSERT(c.fArguments.size() == 2);
|
||||
this->write("%s");
|
||||
fFormatArgs.push_back("fColorSpaceHelper.isValid() ? \"(" + tmpVar + " = \" : \"\"");
|
||||
this->writeExpression(*c.fArguments[0], kTopLevel_Precedence);
|
||||
ASSERT(c.fArguments[1]->fKind == Expression::kVariableReference_Kind);
|
||||
String xform("args.fUniformHandler->getUniformCStr(fColorSpaceHelper.gamutXformUniform())");
|
||||
this->write("%s");
|
||||
fFormatArgs.push_back("fColorSpaceHelper.isValid() ? SkStringPrintf(\", vec4(clamp((%s * vec4(" + tmpVar + ".rgb, 1.0)).rgb, 0.0, " + tmpVar +
|
||||
".a), " + tmpVar + ".a))\", " + xform + ").c_str() : \"\"");
|
||||
return;
|
||||
}
|
||||
INHERITED::writeFunctionCall(c);
|
||||
if (c.fFunction.fBuiltin && c.fFunction.fName == "texture") {
|
||||
this->write(".%s");
|
||||
@ -267,9 +281,9 @@ void CPPCodeGenerator::writeSetting(const Setting& s) {
|
||||
}
|
||||
|
||||
void CPPCodeGenerator::writeSection(const char* name, const char* prefix) {
|
||||
const auto found = fSectionAndParameterHelper.fSections.find(String(name));
|
||||
if (found != fSectionAndParameterHelper.fSections.end()) {
|
||||
this->writef("%s%s", prefix, found->second->fText.c_str());
|
||||
const Section* s = fSectionAndParameterHelper.getSection(name);
|
||||
if (s) {
|
||||
this->writef("%s%s", prefix, s->fText.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -398,10 +412,8 @@ bool CPPCodeGenerator::writeEmitCode(std::vector<const Variable*>& uniforms) {
|
||||
|
||||
void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
|
||||
const char* fullName = fFullName.c_str();
|
||||
auto section = fSectionAndParameterHelper.fSections.find(String(SET_DATA_SECTION));
|
||||
const char* pdman = section != fSectionAndParameterHelper.fSections.end() ?
|
||||
section->second->fArgument.c_str() :
|
||||
"pdman";
|
||||
const Section* section = fSectionAndParameterHelper.getSection(SET_DATA_SECTION);
|
||||
const char* pdman = section ? section->fArgument.c_str() : "pdman";
|
||||
this->writef(" void onSetData(const GrGLSLProgramDataManager& %s, "
|
||||
"const GrFragmentProcessor& _proc) override {\n",
|
||||
pdman);
|
||||
@ -439,7 +451,7 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
|
||||
if (wroteProcessor) {
|
||||
this->writef(" }\n");
|
||||
}
|
||||
if (section != fSectionAndParameterHelper.fSections.end()) {
|
||||
if (section) {
|
||||
for (const auto& p : fProgram.fElements) {
|
||||
if (ProgramElement::kVar_Kind == p->fKind) {
|
||||
const VarDeclarations* decls = (const VarDeclarations*) p.get();
|
||||
@ -470,27 +482,25 @@ void CPPCodeGenerator::writeSetData(std::vector<const Variable*>& uniforms) {
|
||||
}
|
||||
|
||||
void CPPCodeGenerator::writeTest() {
|
||||
const auto found = fSectionAndParameterHelper.fSections.find(TEST_CODE_SECTION);
|
||||
if (found == fSectionAndParameterHelper.fSections.end()) {
|
||||
return;
|
||||
const Section* test = fSectionAndParameterHelper.getSection(TEST_CODE_SECTION);
|
||||
if (test) {
|
||||
this->writef("GR_DEFINE_FRAGMENT_PROCESSOR_TEST(%s);\n"
|
||||
"#if GR_TEST_UTILS\n"
|
||||
"sk_sp<GrFragmentProcessor> %s::TestCreate(GrProcessorTestData* %s) {\n",
|
||||
fFullName.c_str(),
|
||||
fFullName.c_str(),
|
||||
test->fArgument.c_str());
|
||||
this->writeSection(TEST_CODE_SECTION);
|
||||
this->write("}\n"
|
||||
"#endif\n");
|
||||
}
|
||||
const Section* test = found->second;
|
||||
this->writef("GR_DEFINE_FRAGMENT_PROCESSOR_TEST(%s);\n"
|
||||
"#if GR_TEST_UTILS\n"
|
||||
"sk_sp<GrFragmentProcessor> %s::TestCreate(GrProcessorTestData* %s) {\n",
|
||||
fFullName.c_str(),
|
||||
fFullName.c_str(),
|
||||
test->fArgument.c_str());
|
||||
this->writeSection(TEST_CODE_SECTION);
|
||||
this->write("}\n"
|
||||
"#endif\n");
|
||||
}
|
||||
|
||||
void CPPCodeGenerator::writeGetKey() {
|
||||
this->writef("void %s::onGetGLSLProcessorKey(const GrShaderCaps& caps, "
|
||||
"GrProcessorKeyBuilder* b) const {\n",
|
||||
fFullName.c_str());
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
if (param->fType == *fContext.fColorSpaceXform_Type) {
|
||||
this->writef(" b->add32(GrColorSpaceXform::XformKey(%s.get()));\n",
|
||||
@ -580,7 +590,7 @@ bool CPPCodeGenerator::generateCode() {
|
||||
this->writef(" UniformHandle %sVar;\n", HCodeGenerator::FieldName(name).c_str());
|
||||
}
|
||||
}
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
if (needs_uniform_var(*param)) {
|
||||
this->writef(" UniformHandle %sVar;\n", HCodeGenerator::FieldName(name).c_str());
|
||||
@ -599,7 +609,7 @@ bool CPPCodeGenerator::generateCode() {
|
||||
" const %s& that = other.cast<%s>();\n"
|
||||
" (void) that;\n",
|
||||
fullName, fullName, fullName);
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
this->writef(" if (%s != that.%s) return false;\n",
|
||||
HCodeGenerator::FieldName(name).c_str(),
|
||||
|
@ -69,9 +69,9 @@ void HCodeGenerator::writef(const char* s, ...) {
|
||||
}
|
||||
|
||||
bool HCodeGenerator::writeSection(const char* name, const char* prefix) {
|
||||
const auto found = fSectionAndParameterHelper.fSections.find(String(name));
|
||||
if (found != fSectionAndParameterHelper.fSections.end()) {
|
||||
this->writef("%s%s", prefix, found->second->fText.c_str());
|
||||
const Section* s = fSectionAndParameterHelper.getSection(name);
|
||||
if (s) {
|
||||
this->writef("%s%s", prefix, s->fText.c_str());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -81,10 +81,9 @@ void HCodeGenerator::writeExtraConstructorParams(const char* separator) {
|
||||
// super-simple parse, just assume the last token before a comma is the name of a parameter
|
||||
// (which is true as long as there are no multi-parameter template types involved). Will replace
|
||||
// this with something more robust if the need arises.
|
||||
const auto found = fSectionAndParameterHelper.fSections.find(
|
||||
String(CONSTRUCTOR_PARAMS_SECTION));
|
||||
if (found != fSectionAndParameterHelper.fSections.end()) {
|
||||
const char* s = found->second->fText.c_str();
|
||||
const Section* section = fSectionAndParameterHelper.getSection(CONSTRUCTOR_PARAMS_SECTION);
|
||||
if (section) {
|
||||
const char* s = section->fText.c_str();
|
||||
#define BUFFER_SIZE 64
|
||||
char lastIdentifier[BUFFER_SIZE];
|
||||
int lastIdentifierLength = 0;
|
||||
@ -126,7 +125,7 @@ void HCodeGenerator::writeMake() {
|
||||
if (!this->writeSection(MAKE_SECTION)) {
|
||||
this->writef(" static sk_sp<GrFragmentProcessor> Make(");
|
||||
separator = "";
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
this->writef("%s%s %s", separator, ParameterType(param->fType).c_str(),
|
||||
param->fName.c_str());
|
||||
separator = ", ";
|
||||
@ -136,7 +135,7 @@ void HCodeGenerator::writeMake() {
|
||||
" return sk_sp<GrFragmentProcessor>(new %s(",
|
||||
fFullName.c_str());
|
||||
separator = "";
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
this->writef("%s%s", separator, param->fName.c_str());
|
||||
separator = ", ";
|
||||
}
|
||||
@ -146,13 +145,25 @@ void HCodeGenerator::writeMake() {
|
||||
}
|
||||
}
|
||||
|
||||
void HCodeGenerator::failOnSection(const char* section, const char* msg) {
|
||||
std::vector<const Section*> s = fSectionAndParameterHelper.getSections(section);
|
||||
if (s.size()) {
|
||||
fErrors.error(s[0]->fPosition, String("@") + section + " " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
void HCodeGenerator::writeConstructor() {
|
||||
if (this->writeSection(CONSTRUCTOR_SECTION)) {
|
||||
return;
|
||||
const char* msg = "may not be present when constructor is overridden";
|
||||
this->failOnSection(CONSTRUCTOR_CODE_SECTION, msg);
|
||||
this->failOnSection(CONSTRUCTOR_PARAMS_SECTION, msg);
|
||||
this->failOnSection(COORD_TRANSFORM_SECTION, msg);
|
||||
this->failOnSection(INITIALIZERS_SECTION, msg);
|
||||
this->failOnSection(OPTIMIZATION_FLAGS_SECTION, msg);
|
||||
}
|
||||
this->writef(" %s(", fFullName.c_str());
|
||||
const char* separator = "";
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
this->writef("%s%s %s", separator, ParameterType(param->fType).c_str(),
|
||||
param->fName.c_str());
|
||||
separator = ", ";
|
||||
@ -165,23 +176,38 @@ void HCodeGenerator::writeConstructor() {
|
||||
}
|
||||
this->writef(")");
|
||||
this->writeSection(INITIALIZERS_SECTION, "\n , ");
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
if (param->fType.kind() == Type::kSampler_Kind) {
|
||||
this->writef("\n , %s(std::move(%s))", FieldName(name).c_str(),
|
||||
name);
|
||||
this->writef("\n , %s(std::move(%s)", FieldName(name).c_str(), name);
|
||||
for (const Section* s : fSectionAndParameterHelper.getSections(
|
||||
SAMPLER_PARAMS_SECTION)) {
|
||||
if (s->fArgument == name) {
|
||||
this->writef(", %s", s->fText.c_str());
|
||||
}
|
||||
}
|
||||
this->writef(")");
|
||||
} else {
|
||||
this->writef("\n , %s(%s)", FieldName(name).c_str(), name);
|
||||
}
|
||||
}
|
||||
for (const Section* s : fSectionAndParameterHelper.getSections(COORD_TRANSFORM_SECTION)) {
|
||||
String field = FieldName(s->fArgument.c_str());
|
||||
this->writef("\n , %sCoordTransform(%s, %s.proxy())", field.c_str(), s->fText.c_str(),
|
||||
field.c_str());
|
||||
}
|
||||
this->writef(" {\n");
|
||||
this->writeSection(CONSTRUCTOR_CODE_SECTION);
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
if (param->fType.kind() == Type::kSampler_Kind) {
|
||||
this->writef(" this->addTextureSampler(&%s);\n",
|
||||
FieldName(param->fName.c_str()).c_str());
|
||||
}
|
||||
}
|
||||
for (const Section* s : fSectionAndParameterHelper.getSections(COORD_TRANSFORM_SECTION)) {
|
||||
String field = FieldName(s->fArgument.c_str());
|
||||
this->writef(" this->addCoordTransform(&%sCoordTransform);\n", field.c_str());
|
||||
}
|
||||
this->writef(" this->initClassID<%s>();\n"
|
||||
" }\n",
|
||||
fFullName.c_str());
|
||||
@ -189,10 +215,14 @@ void HCodeGenerator::writeConstructor() {
|
||||
|
||||
void HCodeGenerator::writeFields() {
|
||||
this->writeSection(FIELDS_SECTION);
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
const char* name = param->fName.c_str();
|
||||
this->writef(" %s %s;\n", FieldType(param->fType).c_str(), FieldName(name).c_str());
|
||||
}
|
||||
for (const Section* s : fSectionAndParameterHelper.getSections(COORD_TRANSFORM_SECTION)) {
|
||||
this->writef(" GrCoordTransform %sCoordTransform;\n",
|
||||
FieldName(s->fArgument.c_str()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool HCodeGenerator::generateCode() {
|
||||
@ -206,12 +236,13 @@ bool HCodeGenerator::generateCode() {
|
||||
this->writeSection(HEADER_SECTION);
|
||||
this->writef("#include \"GrFragmentProcessor.h\"\n"
|
||||
"#include \"GrCoordTransform.h\"\n"
|
||||
"#include \"GrColorSpaceXform.h\"\n"
|
||||
"#include \"effects/GrProxyMove.h\"\n");
|
||||
this->writef("class %s : public GrFragmentProcessor {\n"
|
||||
"public:\n",
|
||||
fFullName.c_str());
|
||||
this->writeSection(CLASS_SECTION);
|
||||
for (const auto& param : fSectionAndParameterHelper.fParameters) {
|
||||
for (const auto& param : fSectionAndParameterHelper.getParameters()) {
|
||||
if (param->fType.kind() == Type::kSampler_Kind) {
|
||||
continue;
|
||||
}
|
||||
|
@ -61,6 +61,8 @@ private:
|
||||
|
||||
void writeFields();
|
||||
|
||||
void failOnSection(const char* section, const char* msg);
|
||||
|
||||
String fName;
|
||||
String fFullName;
|
||||
SectionAndParameterHelper fSectionAndParameterHelper;
|
||||
|
@ -1394,84 +1394,17 @@ bool IRGenerator::determineCallCost(const FunctionDeclaration& function,
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> IRGenerator::applyColorSpace(std::unique_ptr<Expression> texture,
|
||||
const Variable* xform) {
|
||||
// Before:
|
||||
// vec4 color = texture(img, coords, xform);
|
||||
// After:
|
||||
// vec4 tmp;
|
||||
// vec4 color = (tmp = texture(img, coords) ,
|
||||
// xform != mat4(1) ?
|
||||
// vec4(clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a), tmp.a) :
|
||||
// tmp);
|
||||
|
||||
// a few macros to keep line lengths manageable
|
||||
#define EXPR std::unique_ptr<Expression>
|
||||
#define REF(v) EXPR(new VariableReference(p, *v))
|
||||
#define FLOAT(x) EXPR(new FloatLiteral(fContext, p, x))
|
||||
using std::move;
|
||||
Position p = Position();
|
||||
// vec4 tmp;
|
||||
Variable* tmp = new Variable(p, Modifiers(), "_tmp" + to_string(fTmpCount++), texture->fType,
|
||||
Variable::kLocal_Storage);
|
||||
fRootSymbolTable->takeOwnership(tmp);
|
||||
std::vector<std::unique_ptr<VarDeclaration>> decls;
|
||||
decls.emplace_back(new VarDeclaration(tmp, std::vector<std::unique_ptr<Expression>>(),
|
||||
nullptr));
|
||||
const Type& type = texture->fType;
|
||||
fExtraVars.emplace_back(new VarDeclarationsStatement(std::unique_ptr<VarDeclarations>(
|
||||
new VarDeclarations(p, &type, move(decls)))));
|
||||
// tmp = texture
|
||||
EXPR assignment = EXPR(new BinaryExpression(p,
|
||||
EXPR(new VariableReference(p, *tmp,
|
||||
VariableReference::kWrite_RefKind)),
|
||||
Token::EQ,
|
||||
move(texture), type));
|
||||
// 1.0
|
||||
std::vector<EXPR> matArgs;
|
||||
matArgs.push_back(FLOAT(1.0));
|
||||
// mat4(1.0)
|
||||
EXPR mat = EXPR(new Constructor(p, *fContext.fMat4x4_Type, move(matArgs)));
|
||||
// <xform> != mat4(1.0)
|
||||
EXPR matNeq = EXPR(new BinaryExpression(p, REF(xform), Token::NEQ, move(mat),
|
||||
*fContext.fBool_Type));
|
||||
// tmp.rgb
|
||||
std::vector<int> rgb { 0, 1, 2 };
|
||||
EXPR tmpRgb = EXPR(new Swizzle(fContext, REF(tmp), rgb));
|
||||
// vec4(tmp.rgb, 1.0)
|
||||
std::vector<EXPR> tmpVecArgs;
|
||||
tmpVecArgs.push_back(move(tmpRgb));
|
||||
tmpVecArgs.push_back(FLOAT(1.0));
|
||||
EXPR tmpVec = EXPR(new Constructor(p, *fContext.fVec4_Type, move(tmpVecArgs)));
|
||||
// xform * vec4(tmp.rgb, 1.0)
|
||||
EXPR mul = EXPR(new BinaryExpression(p, REF(xform), Token::STAR, move(tmpVec),
|
||||
*fContext.fVec4_Type));
|
||||
// (xform * vec4(tmp.rgb, 1.0)).rgb
|
||||
EXPR mulRGB = EXPR(new Swizzle(fContext, std::move(mul), rgb));
|
||||
// tmp.a
|
||||
std::vector<int> a { 3 };
|
||||
EXPR tmpA = EXPR(new Swizzle(fContext, REF(tmp), a));
|
||||
// clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a)
|
||||
EXPR clamp = this->convertIdentifier(ASTIdentifier(p, "clamp"));
|
||||
std::vector<EXPR> clampArgs;
|
||||
clampArgs.push_back(move(mulRGB));
|
||||
clampArgs.push_back(FLOAT(0));
|
||||
clampArgs.push_back(move(tmpA));
|
||||
EXPR clampCall = this->call(p, move(clamp), move(clampArgs));
|
||||
// tmp.a
|
||||
tmpA = EXPR(new Swizzle(fContext, REF(tmp), a));
|
||||
// vec4(clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a), tmp.a)
|
||||
std::vector<EXPR> finalVecArgs;
|
||||
finalVecArgs.push_back(move(clampCall));
|
||||
finalVecArgs.push_back(move(tmpA));
|
||||
EXPR finalVec = EXPR(new Constructor(p, *fContext.fVec4_Type, move(finalVecArgs)));
|
||||
// xform != mat4(1) ? vec4(clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a), tmp.a) : tmp)
|
||||
EXPR ternary = EXPR(new TernaryExpression(p, move(matNeq), move(finalVec), REF(tmp)));
|
||||
// (tmp = texture ,
|
||||
// xform != mat4(1) ? vec4(clamp((xform * vec4(tmp.rgb, 1.0)).rgb, 0.0, tmp.a), tmp.a) : tmp))
|
||||
return EXPR(new BinaryExpression(p, move(assignment), Token::COMMA, move(ternary), type));
|
||||
#undef EXPR
|
||||
#undef REF
|
||||
#undef FLOAT
|
||||
std::unique_ptr<Expression> xform) {
|
||||
// Before: texture(img, coords, xform);
|
||||
// After: COLORSPACE(texture(img, coords), xform)
|
||||
Position p = texture->fPosition;
|
||||
std::vector<std::unique_ptr<Expression>> args;
|
||||
args.push_back(std::move(texture));
|
||||
args.push_back(std::move(xform));
|
||||
const Symbol* colorspaceSymbol = (*fSymbolTable)["COLORSPACE"];
|
||||
ASSERT(colorspaceSymbol->fKind == Symbol::kFunctionDeclaration_Kind);
|
||||
const FunctionDeclaration& colorspaceFunction = (FunctionDeclaration&) *colorspaceSymbol;
|
||||
return this->call(p, colorspaceFunction, std::move(args));
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> IRGenerator::call(Position position,
|
||||
@ -1490,12 +1423,11 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
|
||||
if (ref->fFunctions[0]->fName == "texture" &&
|
||||
arguments.back()->fType == *fContext.fColorSpaceXform_Type) {
|
||||
std::unique_ptr<Expression> colorspace = std::move(arguments.back());
|
||||
ASSERT(colorspace->fKind == Expression::kVariableReference_Kind);
|
||||
arguments.pop_back();
|
||||
return this->applyColorSpace(this->call(position,
|
||||
std::move(functionValue),
|
||||
std::move(arguments)),
|
||||
&((VariableReference&) *colorspace).fVariable);
|
||||
std::move(colorspace));
|
||||
}
|
||||
|
||||
int bestCost = INT_MAX;
|
||||
|
@ -161,7 +161,7 @@ private:
|
||||
* to implement texture(sampler, coord, colorSpaceXForm).
|
||||
*/
|
||||
std::unique_ptr<Expression> applyColorSpace(std::unique_ptr<Expression> texture,
|
||||
const Variable* xform);
|
||||
std::unique_ptr<Expression> xform);
|
||||
void fixRectSampling(std::vector<std::unique_ptr<Expression>>& arguments);
|
||||
void checkValid(const Expression& expr);
|
||||
void markWrittenTo(const Expression& expr, bool readWrite);
|
||||
|
@ -2035,6 +2035,40 @@ SpvId SPIRVCodeGenerator::foldToBool(SpvId id, const Type& operandType, OutputSt
|
||||
return id;
|
||||
}
|
||||
|
||||
SpvId SPIRVCodeGenerator::writeMatrixComparison(const Type& operandType, SpvId lhs, SpvId rhs,
|
||||
SpvOp_ floatOperator, SpvOp_ intOperator,
|
||||
OutputStream& out) {
|
||||
SpvOp_ compareOp = is_float(fContext, operandType) ? floatOperator : intOperator;
|
||||
ASSERT(operandType.kind() == Type::kMatrix_Kind);
|
||||
SpvId rowType = this->getType(operandType.componentType().toCompound(fContext,
|
||||
operandType.columns(),
|
||||
1));
|
||||
SpvId bvecType = this->getType(fContext.fBool_Type->toCompound(fContext,
|
||||
operandType.columns(),
|
||||
1));
|
||||
SpvId boolType = this->getType(*fContext.fBool_Type);
|
||||
SpvId result = 0;
|
||||
for (int i = 0; i < operandType.rows(); i++) {
|
||||
SpvId rowL = this->nextId();
|
||||
this->writeInstruction(SpvOpCompositeExtract, rowType, rowL, lhs, 0, out);
|
||||
SpvId rowR = this->nextId();
|
||||
this->writeInstruction(SpvOpCompositeExtract, rowType, rowR, rhs, 0, out);
|
||||
SpvId compare = this->nextId();
|
||||
this->writeInstruction(compareOp, bvecType, compare, rowL, rowR, out);
|
||||
SpvId all = this->nextId();
|
||||
this->writeInstruction(SpvOpAll, boolType, all, compare, out);
|
||||
if (result != 0) {
|
||||
SpvId next = this->nextId();
|
||||
this->writeInstruction(SpvOpLogicalAnd, boolType, next, result, all, out);
|
||||
result = next;
|
||||
}
|
||||
else {
|
||||
result = all;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, OutputStream& out) {
|
||||
// handle cases where we don't necessarily evaluate both LHS and RHS
|
||||
switch (b.fOperator) {
|
||||
@ -2139,6 +2173,10 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Outpu
|
||||
}
|
||||
switch (b.fOperator) {
|
||||
case Token::EQEQ: {
|
||||
if (operandType->kind() == Type::kMatrix_Kind) {
|
||||
return this->writeMatrixComparison(*operandType, lhs, rhs, SpvOpFOrdEqual,
|
||||
SpvOpIEqual, out);
|
||||
}
|
||||
ASSERT(resultType == *fContext.fBool_Type);
|
||||
return this->foldToBool(this->writeBinaryOperation(resultType, *operandType, lhs, rhs,
|
||||
SpvOpFOrdEqual, SpvOpIEqual,
|
||||
@ -2146,6 +2184,10 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Outpu
|
||||
*operandType, out);
|
||||
}
|
||||
case Token::NEQ:
|
||||
if (operandType->kind() == Type::kMatrix_Kind) {
|
||||
return this->writeMatrixComparison(*operandType, lhs, rhs, SpvOpFOrdNotEqual,
|
||||
SpvOpINotEqual, out);
|
||||
}
|
||||
ASSERT(resultType == *fContext.fBool_Type);
|
||||
return this->foldToBool(this->writeBinaryOperation(resultType, *operandType, lhs, rhs,
|
||||
SpvOpFOrdNotEqual, SpvOpINotEqual,
|
||||
|
@ -185,6 +185,9 @@ private:
|
||||
*/
|
||||
SpvId foldToBool(SpvId id, const Type& operandType, OutputStream& out);
|
||||
|
||||
SpvId writeMatrixComparison(const Type& operandType, SpvId lhs, SpvId rhs, SpvOp_ floatOperator,
|
||||
SpvOp_ intOperator, OutputStream& out);
|
||||
|
||||
SpvId writeBinaryOperation(const Type& resultType, const Type& operandType, SpvId lhs,
|
||||
SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt,
|
||||
SpvOp_ ifBool, OutputStream& out);
|
||||
|
@ -18,18 +18,20 @@
|
||||
namespace SkSL {
|
||||
|
||||
#define CLASS_SECTION "class"
|
||||
#define CONSTRUCTOR_SECTION "constructor"
|
||||
#define CONSTRUCTOR_CODE_SECTION "constructorCode"
|
||||
#define CONSTRUCTOR_PARAMS_SECTION "constructorParams"
|
||||
#define COORD_TRANSFORM_SECTION "coordTransform"
|
||||
#define CPP_SECTION "cpp"
|
||||
#define CPP_END_SECTION "cppEnd"
|
||||
#define HEADER_SECTION "header"
|
||||
#define HEADER_END_SECTION "headerEnd"
|
||||
#define CONSTRUCTOR_PARAMS_SECTION "constructorParams"
|
||||
#define CONSTRUCTOR_SECTION "constructor"
|
||||
#define CONSTRUCTOR_CODE_SECTION "constructorCode"
|
||||
#define INITIALIZERS_SECTION "initializers"
|
||||
#define EMIT_CODE_SECTION "emitCode"
|
||||
#define FIELDS_SECTION "fields"
|
||||
#define INITIALIZERS_SECTION "initializers"
|
||||
#define MAKE_SECTION "make"
|
||||
#define OPTIMIZATION_FLAGS_SECTION "optimizationFlags"
|
||||
#define SAMPLER_PARAMS_SECTION "samplerParams"
|
||||
#define SET_DATA_SECTION "setData"
|
||||
#define TEST_CODE_SECTION "test"
|
||||
|
||||
@ -65,11 +67,12 @@ public:
|
||||
errors.error(s->fPosition,
|
||||
("unsupported section '@" + s->fName + "'").c_str());
|
||||
}
|
||||
if (fSections.find(s->fName) != fSections.end()) {
|
||||
if (!SectionPermitsDuplicates(s->fName.c_str()) &&
|
||||
fSections.find(s->fName) != fSections.end()) {
|
||||
errors.error(s->fPosition,
|
||||
("duplicate section '@" + s->fName + "'").c_str());
|
||||
}
|
||||
fSections[s->fName] = s;
|
||||
fSections[s->fName].push_back(s);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -78,6 +81,28 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
const Section* getSection(const char* name) {
|
||||
ASSERT(!SectionPermitsDuplicates(name));
|
||||
auto found = fSections.find(name);
|
||||
if (found == fSections.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
ASSERT(found->second.size() == 1);
|
||||
return found->second[0];
|
||||
}
|
||||
|
||||
std::vector<const Section*> getSections(const char* name) {
|
||||
auto found = fSections.find(name);
|
||||
if (found == fSections.end()) {
|
||||
return std::vector<const Section*>();
|
||||
}
|
||||
return found->second;
|
||||
}
|
||||
|
||||
const std::vector<const Variable*>& getParameters() {
|
||||
return fParameters;
|
||||
}
|
||||
|
||||
static bool IsParameter(const Variable& var) {
|
||||
return (var.fModifiers.fFlags & Modifiers::kIn_Flag) &&
|
||||
-1 == var.fModifiers.fLayout.fBuiltin;
|
||||
@ -85,29 +110,39 @@ public:
|
||||
|
||||
static bool IsSupportedSection(const char* name) {
|
||||
return !strcmp(name, CLASS_SECTION) ||
|
||||
!strcmp(name, CPP_SECTION) ||
|
||||
!strcmp(name, CPP_END_SECTION) ||
|
||||
!strcmp(name, HEADER_SECTION) ||
|
||||
!strcmp(name, HEADER_END_SECTION) ||
|
||||
!strcmp(name, CONSTRUCTOR_SECTION) ||
|
||||
!strcmp(name, CONSTRUCTOR_CODE_SECTION) ||
|
||||
!strcmp(name, CONSTRUCTOR_PARAMS_SECTION) ||
|
||||
!strcmp(name, COORD_TRANSFORM_SECTION) ||
|
||||
!strcmp(name, CPP_SECTION) ||
|
||||
!strcmp(name, CPP_END_SECTION) ||
|
||||
!strcmp(name, EMIT_CODE_SECTION) ||
|
||||
!strcmp(name, FIELDS_SECTION) ||
|
||||
!strcmp(name, HEADER_SECTION) ||
|
||||
!strcmp(name, HEADER_END_SECTION) ||
|
||||
!strcmp(name, INITIALIZERS_SECTION) ||
|
||||
!strcmp(name, MAKE_SECTION) ||
|
||||
!strcmp(name, OPTIMIZATION_FLAGS_SECTION) ||
|
||||
!strcmp(name, SAMPLER_PARAMS_SECTION) ||
|
||||
!strcmp(name, SET_DATA_SECTION) ||
|
||||
!strcmp(name, TEST_CODE_SECTION);
|
||||
}
|
||||
|
||||
static bool SectionAcceptsArgument(const char* name) {
|
||||
return !strcmp(name, SET_DATA_SECTION) ||
|
||||
return !strcmp(name, COORD_TRANSFORM_SECTION) ||
|
||||
!strcmp(name, SAMPLER_PARAMS_SECTION) ||
|
||||
!strcmp(name, SET_DATA_SECTION) ||
|
||||
!strcmp(name, TEST_CODE_SECTION);
|
||||
}
|
||||
|
||||
static bool SectionPermitsDuplicates(const char* name) {
|
||||
return !strcmp(name, COORD_TRANSFORM_SECTION) ||
|
||||
!strcmp(name, SAMPLER_PARAMS_SECTION);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<const Variable*> fParameters;
|
||||
std::unordered_map<String, const Section*> fSections;
|
||||
std::unordered_map<String, std::vector<const Section*>> fSections;
|
||||
};
|
||||
|
||||
} // namespace SkSL
|
||||
|
@ -128,6 +128,17 @@ const Type& Type::toCompound(const Context& context, int columns, int rows) cons
|
||||
}
|
||||
default: ABORT("unsupported row count (%d)", rows);
|
||||
}
|
||||
} else if (*this == *context.fBool_Type) {
|
||||
switch (rows) {
|
||||
case 1:
|
||||
switch (columns) {
|
||||
case 2: return *context.fBVec2_Type;
|
||||
case 3: return *context.fBVec3_Type;
|
||||
case 4: return *context.fBVec4_Type;
|
||||
default: ABORT("unsupported vector column count (%d)", columns);
|
||||
}
|
||||
default: ABORT("unsupported row count (%d)", rows);
|
||||
}
|
||||
}
|
||||
ABORT("unsupported scalar_to_compound type %s", this->description().c_str());
|
||||
}
|
||||
|
@ -20,4 +20,6 @@ layout(builtin=10003) vec4 sk_InColor;
|
||||
layout(builtin=10004) out vec4 sk_OutColor;
|
||||
layout(builtin=10005) vec2[] sk_TransformedCoords2D;
|
||||
layout(builtin=10006) sampler2D[] sk_TextureSamplers;
|
||||
|
||||
vec4 COLORSPACE(vec4 color, colorSpaceXform colorSpace);
|
||||
)
|
||||
|
@ -82,6 +82,7 @@ DEF_TEST(SkSLFPHelloWorld, r) {
|
||||
"#if SK_SUPPORT_GPU\n"
|
||||
"#include \"GrFragmentProcessor.h\"\n"
|
||||
"#include \"GrCoordTransform.h\"\n"
|
||||
"#include \"GrColorSpaceXform.h\"\n"
|
||||
"#include \"effects/GrProxyMove.h\"\n"
|
||||
"class GrTest : public GrFragmentProcessor {\n"
|
||||
"public:\n"
|
||||
@ -353,16 +354,14 @@ DEF_TEST(SkSLFPColorSpaceXform, r) {
|
||||
"sk_sp<GrColorSpaceXform> fColorXform;"
|
||||
},
|
||||
{
|
||||
"fragBuilder->codeAppendf(\"vec4 _tmp0;\\n%s = %s * (_tmp0 = texture(%s, "
|
||||
"vec2(0.0, 0.0)).%s , %s != mat4(1.0) ? vec4(clamp((%s * vec4(_tmp0.xyz, 1.0)).xyz, "
|
||||
"0.0, _tmp0.w), _tmp0.w) : _tmp0);\\n\", args.fOutputColor, args.fInputColor ? "
|
||||
"args.fInputColor : \"vec4(1)\", fragBuilder->getProgramBuilder()->"
|
||||
"samplerVariable(args.fTexSamplers[0]).c_str(), "
|
||||
"fragBuilder->codeAppendf(\"vec4 _tmpVar1;%s = %s * %stexture(%s, "
|
||||
"vec2(0.0, 0.0)).%s%s;\\n\", args.fOutputColor, args.fInputColor ? args.fInputColor : "
|
||||
"\"vec4(1)\", fColorSpaceHelper.isValid() ? \"(_tmpVar1 = \" : \"\", "
|
||||
"fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(), "
|
||||
"fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str(), "
|
||||
"fColorSpaceHelper.isValid() ? args.fUniformHandler->getUniformCStr("
|
||||
"fColorSpaceHelper.gamutXformUniform()) : \"mat4(1.0)\", "
|
||||
"fColorSpaceHelper.isValid() ? args.fUniformHandler->getUniformCStr("
|
||||
"fColorSpaceHelper.gamutXformUniform()) : \"mat4(1.0)\");"
|
||||
"fColorSpaceHelper.isValid() ? SkStringPrintf(\", vec4(clamp((%s * vec4(_tmpVar1.rgb, "
|
||||
"1.0)).rgb, 0.0, _tmpVar1.a), _tmpVar1.a))\", args.fUniformHandler->getUniformCStr("
|
||||
"fColorSpaceHelper.gamutXformUniform())).c_str() : \"\");"
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user