Some changes to GrYUVToRGBEffect.
Don't implement domains, use child effects instead. Don't do a 4x4 matrix mul. Do 3x3 + a translate. Undo some of effects of this effect's stint as .fp generated code. Specify optimization flags using resulting alpha type. Multiply computed color with input color (so this is more interchangeable with GrSimpleTextureEffect used for non-planar texture images) Change-Id: I9d3d0ff7aed9177cd32ab16e9ceb67d458c3d88c Reviewed-on: https://skia-review.googlesource.com/c/skia/+/257883 Reviewed-by: Michael Ludwig <michaelludwig@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
parent
fae46e4043
commit
fa9232ccfd
@ -31,30 +31,68 @@ std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::Make(const sk_sp<GrTextur
|
|||||||
GrSamplerState::Filter subsampledPlaneFilterMode = GrSamplerState::Filter::kMipMap == filterMode
|
GrSamplerState::Filter subsampledPlaneFilterMode = GrSamplerState::Filter::kMipMap == filterMode
|
||||||
? GrSamplerState::Filter::kMipMap
|
? GrSamplerState::Filter::kMipMap
|
||||||
: GrSamplerState::Filter::kBilerp;
|
: GrSamplerState::Filter::kBilerp;
|
||||||
|
std::unique_ptr<GrFragmentProcessor> planeFPs[4];
|
||||||
GrSamplerState::Filter filterModes[4];
|
|
||||||
SkSize scales[4];
|
|
||||||
for (int i = 0; i < numPlanes; ++i) {
|
for (int i = 0; i < numPlanes; ++i) {
|
||||||
SkISize dimensions = proxies[i]->dimensions();
|
SkISize dimensions = proxies[i]->dimensions();
|
||||||
// JPEG chroma subsampling of odd dimensions produces U and V planes with the ceiling of
|
SkTCopyOnFirstWrite<SkMatrix> planeMatrix(&localMatrix);
|
||||||
// the image size divided by the subsampling factor (2). Our API for creating YUVA doesn't
|
GrSamplerState::Filter planeFilter = filterMode;
|
||||||
// capture the intended subsampling (and we should fix that). This fixes up 2x subsampling
|
SkRect planeDomain;
|
||||||
// for images with odd widths/heights (e.g. JPEG 420 or 422).
|
if (dimensions != YDimensions) {
|
||||||
scales[i] = {dimensions.width() / SkIntToScalar(YDimensions.width()),
|
// JPEG chroma subsampling of odd dimensions produces U and V planes with the ceiling of
|
||||||
dimensions.height() / SkIntToScalar(YDimensions.height())};
|
// the image size divided by the subsampling factor (2). Our API for creating YUVA
|
||||||
if ((YDimensions.width() & 0b1) && dimensions.width() == YDimensions.width() / 2 + 1) {
|
// doesn't capture the intended subsampling (and we should fix that). This fixes up 2x
|
||||||
scales[i].fWidth = 0.5f;
|
// subsampling for images with odd widths/heights (e.g. JPEG 420 or 422).
|
||||||
|
float sx = (float)dimensions.width() / YDimensions.width();
|
||||||
|
float sy = (float)dimensions.height() / YDimensions.height();
|
||||||
|
if ((YDimensions.width() & 0b1) && dimensions.width() == YDimensions.width() / 2 + 1) {
|
||||||
|
sx = 0.5f;
|
||||||
|
}
|
||||||
|
if ((YDimensions.height() & 0b1) &&
|
||||||
|
dimensions.height() == YDimensions.height() / 2 + 1) {
|
||||||
|
sy = 0.5f;
|
||||||
|
}
|
||||||
|
*planeMatrix.writable() = SkMatrix::MakeScale(sx, sy);
|
||||||
|
planeMatrix.writable()->preConcat(localMatrix);
|
||||||
|
planeFilter = subsampledPlaneFilterMode;
|
||||||
|
if (domain) {
|
||||||
|
planeDomain = {domain->fLeft * sx,
|
||||||
|
domain->fTop * sy,
|
||||||
|
domain->fRight * sx,
|
||||||
|
domain->fBottom * sy};
|
||||||
|
}
|
||||||
|
} else if (domain) {
|
||||||
|
planeDomain = *domain;
|
||||||
}
|
}
|
||||||
if ((YDimensions.height() & 0b1) && dimensions.height() == YDimensions.height() / 2 + 1) {
|
planeFPs[i] = GrSimpleTextureEffect::Make(proxies[i], kUnknown_SkAlphaType, *planeMatrix,
|
||||||
scales[i].fHeight = 0.5f;
|
planeFilter);
|
||||||
|
if (domain) {
|
||||||
|
SkASSERT(planeFilter != GrSamplerState::Filter::kMipMap);
|
||||||
|
if (planeFilter != GrSamplerState::Filter::kNearest) {
|
||||||
|
// Inset by half a pixel for bilerp, after scaling to the size of the plane
|
||||||
|
planeDomain.inset(0.5f, 0.5f);
|
||||||
|
}
|
||||||
|
planeFPs[i] = GrDomainEffect::Make(std::move(planeFPs[i]), planeDomain,
|
||||||
|
GrTextureDomain::kClamp_Mode, false);
|
||||||
}
|
}
|
||||||
// It seems the assumption here is the plane dimensions are smaller than the Y plane.
|
|
||||||
filterModes[i] = (dimensions == YDimensions) ? filterMode : subsampledPlaneFilterMode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect(
|
return std::unique_ptr<GrFragmentProcessor>(
|
||||||
proxies, scales, filterModes, numPlanes, yuvaIndices, yuvColorSpace, localMatrix,
|
new GrYUVtoRGBEffect(planeFPs, numPlanes, yuvaIndices, yuvColorSpace));
|
||||||
domain));
|
}
|
||||||
|
|
||||||
|
static SkAlphaType alpha_type(const SkYUVAIndex yuvaIndices[4]) {
|
||||||
|
return yuvaIndices[3].fIndex >= 0 ? kPremul_SkAlphaType : kOpaque_SkAlphaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrYUVtoRGBEffect::GrYUVtoRGBEffect(std::unique_ptr<GrFragmentProcessor> planeFPs[4], int numPlanes,
|
||||||
|
const SkYUVAIndex yuvaIndices[4], SkYUVColorSpace yuvColorSpace)
|
||||||
|
: GrFragmentProcessor(kGrYUVtoRGBEffect_ClassID,
|
||||||
|
ModulateForClampedSamplerOptFlags(alpha_type(yuvaIndices)))
|
||||||
|
, fYUVColorSpace(yuvColorSpace) {
|
||||||
|
for (int i = 0; i < numPlanes; ++i) {
|
||||||
|
this->registerChildProcessor(std::move(planeFPs[i]));
|
||||||
|
}
|
||||||
|
std::copy_n(yuvaIndices, 4, fYUVAIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
@ -78,85 +116,77 @@ GrGLSLFragmentProcessor* GrYUVtoRGBEffect::onCreateGLSLInstance() const {
|
|||||||
|
|
||||||
void emitCode(EmitArgs& args) override {
|
void emitCode(EmitArgs& args) override {
|
||||||
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||||
const GrYUVtoRGBEffect& _outer = args.fFp.cast<GrYUVtoRGBEffect>();
|
const GrYUVtoRGBEffect& yuvEffect = args.fFp.cast<GrYUVtoRGBEffect>();
|
||||||
(void)_outer;
|
|
||||||
|
|
||||||
if (kIdentity_SkYUVColorSpace != _outer.yuvColorSpace()) {
|
int numPlanes = yuvEffect.numChildProcessors();
|
||||||
fColorSpaceMatrixVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag,
|
|
||||||
kHalf4x4_GrSLType,
|
|
||||||
"colorSpaceMatrix");
|
|
||||||
}
|
|
||||||
|
|
||||||
int numSamplers = args.fTexSamplers.count();
|
|
||||||
|
|
||||||
SkString coords[4];
|
SkString coords[4];
|
||||||
for (int i = 0; i < numSamplers; ++i) {
|
fragBuilder->codeAppendf("half4 planes[%d];", numPlanes);
|
||||||
coords[i] = fragBuilder->ensureCoords2D(args.fTransformedCoords[i].fVaryingPoint);
|
for (int i = 0; i < numPlanes; ++i) {
|
||||||
|
SkString tempVar;
|
||||||
|
tempVar.printf("tmp%d", i);
|
||||||
|
this->invokeChild(i, &tempVar, args);
|
||||||
|
fragBuilder->codeAppendf("planes[%d] = %s;", i, tempVar.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < numSamplers; ++i) {
|
bool hasAlpha = yuvEffect.fYUVAIndices[3].fIndex >= 0;
|
||||||
SkString sampleVar;
|
SkString rgba[4];
|
||||||
sampleVar.printf("tmp%d", i);
|
rgba[3] = "1";
|
||||||
fragBuilder->codeAppendf("half4 %s;", sampleVar.c_str());
|
for (int i = 0; i < (hasAlpha ? 4 : 3); ++i) {
|
||||||
fGLDomains[i].sampleTexture(fragBuilder, args.fUniformHandler, args.fShaderCaps,
|
auto info = yuvEffect.fYUVAIndices[i];
|
||||||
_outer.fDomains[i], sampleVar.c_str(), coords[i], args.fTexSamplers[i]);
|
auto letter = "rgba"[static_cast<int>(info.fChannel)];
|
||||||
|
rgba[i].printf("planes[%d].%c", info.fIndex, letter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char kChannelToChar[4] = { 'x', 'y', 'z', 'w' };
|
fragBuilder->codeAppendf("half4 color = half4(%s, %s, %s, %s);",
|
||||||
|
rgba[0].c_str(), rgba[1].c_str(), rgba[2].c_str(), rgba[3].c_str());
|
||||||
|
|
||||||
fragBuilder->codeAppendf(
|
if (kIdentity_SkYUVColorSpace != yuvEffect.fYUVColorSpace) {
|
||||||
"half4 yuvOne = half4(tmp%d.%c, tmp%d.%c, tmp%d.%c, 1.0);",
|
fColorSpaceMatrixVar = args.fUniformHandler->addUniform(
|
||||||
_outer.yuvaIndex(0).fIndex, kChannelToChar[(int)_outer.yuvaIndex(0).fChannel],
|
kFragment_GrShaderFlag, kHalf3x3_GrSLType, "colorSpaceMatrix");
|
||||||
_outer.yuvaIndex(1).fIndex, kChannelToChar[(int)_outer.yuvaIndex(1).fChannel],
|
fColorSpaceTranslateVar = args.fUniformHandler->addUniform(
|
||||||
_outer.yuvaIndex(2).fIndex, kChannelToChar[(int)_outer.yuvaIndex(2).fChannel]);
|
kFragment_GrShaderFlag, kHalf3_GrSLType, "colorSpaceTranslate");
|
||||||
|
|
||||||
if (kIdentity_SkYUVColorSpace != _outer.yuvColorSpace()) {
|
|
||||||
SkASSERT(fColorSpaceMatrixVar.isValid());
|
|
||||||
fragBuilder->codeAppendf(
|
fragBuilder->codeAppendf(
|
||||||
"yuvOne *= %s;", args.fUniformHandler->getUniformCStr(fColorSpaceMatrixVar));
|
"color.rgb = saturate(color.rgb * %s + %s);",
|
||||||
fragBuilder->codeAppend("yuvOne.xyz = clamp(yuvOne.xyz, 0, 1);");
|
args.fUniformHandler->getUniformCStr(fColorSpaceMatrixVar),
|
||||||
|
args.fUniformHandler->getUniformCStr(fColorSpaceTranslateVar));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_outer.yuvaIndex(3).fIndex >= 0) {
|
if (hasAlpha) {
|
||||||
fragBuilder->codeAppendf(
|
|
||||||
"half a = tmp%d.%c;", _outer.yuvaIndex(3).fIndex,
|
|
||||||
kChannelToChar[(int)_outer.yuvaIndex(3).fChannel]);
|
|
||||||
// premultiply alpha
|
// premultiply alpha
|
||||||
fragBuilder->codeAppend("yuvOne *= a;");
|
fragBuilder->codeAppendf("color.rgb *= color.a;");
|
||||||
} else {
|
|
||||||
fragBuilder->codeAppend("half a = 1.0;");
|
|
||||||
}
|
}
|
||||||
|
fragBuilder->codeAppendf("%s = color;", args.fOutputColor);
|
||||||
fragBuilder->codeAppendf("%s = half4(yuvOne.xyz, a);", args.fOutputColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onSetData(const GrGLSLProgramDataManager& pdman,
|
void onSetData(const GrGLSLProgramDataManager& pdman,
|
||||||
const GrFragmentProcessor& _proc) override {
|
const GrFragmentProcessor& proc) override {
|
||||||
const GrYUVtoRGBEffect& _outer = _proc.cast<GrYUVtoRGBEffect>();
|
const GrYUVtoRGBEffect& yuvEffect = proc.cast<GrYUVtoRGBEffect>();
|
||||||
|
|
||||||
if (_outer.yuvColorSpace() != kIdentity_SkYUVColorSpace) {
|
if (yuvEffect.fYUVColorSpace != kIdentity_SkYUVColorSpace) {
|
||||||
SkASSERT(fColorSpaceMatrixVar.isValid());
|
SkASSERT(fColorSpaceMatrixVar.isValid());
|
||||||
float yuvM[20];
|
float yuvM[20];
|
||||||
SkColorMatrix_YUV2RGB(_outer.yuvColorSpace(), yuvM);
|
SkColorMatrix_YUV2RGB(yuvEffect.fYUVColorSpace, yuvM);
|
||||||
// Need to drop the fourth column to go to 4x4
|
// We drop the fourth column entirely since the transformation
|
||||||
float mtx[16] = {
|
// should not depend on alpha. The fifth column is sent as a separate
|
||||||
yuvM[ 0], yuvM[ 1], yuvM[ 2], yuvM[ 4],
|
// vector. The fourth row is also dropped entirely because alpha should
|
||||||
yuvM[ 5], yuvM[ 6], yuvM[ 7], yuvM[ 9],
|
// never be modified.
|
||||||
yuvM[10], yuvM[11], yuvM[12], yuvM[14],
|
SkASSERT(yuvM[3] == 0 && yuvM[8] == 0 && yuvM[13] == 0 && yuvM[18] == 1);
|
||||||
yuvM[15], yuvM[16], yuvM[17], yuvM[19],
|
SkASSERT(yuvM[15] == 0 && yuvM[16] == 0 && yuvM[17] == 0 && yuvM[19] == 0);
|
||||||
|
float mtx[9] = {
|
||||||
|
yuvM[ 0], yuvM[ 1], yuvM[ 2],
|
||||||
|
yuvM[ 5], yuvM[ 6], yuvM[ 7],
|
||||||
|
yuvM[10], yuvM[11], yuvM[12],
|
||||||
};
|
};
|
||||||
pdman.setMatrix4f(fColorSpaceMatrixVar, mtx);
|
float v[3] = {yuvM[4], yuvM[9], yuvM[14]};
|
||||||
}
|
pdman.setMatrix3f(fColorSpaceMatrixVar, mtx);
|
||||||
|
pdman.set3fv(fColorSpaceTranslateVar, 1, v);
|
||||||
int numSamplers = _outer.numTextureSamplers();
|
|
||||||
for (int i = 0; i < numSamplers; ++i) {
|
|
||||||
fGLDomains[i].setData(pdman, _outer.fDomains[i],
|
|
||||||
_outer.textureSampler(i).proxy(), _outer.textureSampler(i).samplerState());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UniformHandle fColorSpaceMatrixVar;
|
UniformHandle fColorSpaceMatrixVar;
|
||||||
|
UniformHandle fColorSpaceTranslateVar;
|
||||||
GrTextureDomain::GLDomain fGLDomains[4];
|
GrTextureDomain::GLDomain fGLDomains[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -164,33 +194,25 @@ GrGLSLFragmentProcessor* GrYUVtoRGBEffect::onCreateGLSLInstance() const {
|
|||||||
}
|
}
|
||||||
void GrYUVtoRGBEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
void GrYUVtoRGBEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
||||||
GrProcessorKeyBuilder* b) const {
|
GrProcessorKeyBuilder* b) const {
|
||||||
using Domain = GrTextureDomain::GLDomain;
|
|
||||||
|
|
||||||
b->add32(this->numTextureSamplers());
|
|
||||||
|
|
||||||
uint32_t packed = 0;
|
uint32_t packed = 0;
|
||||||
uint32_t domain = 0;
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
if (this->yuvaIndex(i).fIndex < 0) {
|
if (fYUVAIndices[i].fIndex < 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t index = this->yuvaIndex(i).fIndex;
|
uint8_t index = fYUVAIndices[i].fIndex;
|
||||||
uint8_t chann = (uint8_t) this->yuvaIndex(i).fChannel;
|
uint8_t chann = static_cast<int>(fYUVAIndices[i].fChannel);
|
||||||
|
|
||||||
SkASSERT(index < 4 && chann < 4);
|
SkASSERT(index < 4 && chann < 4);
|
||||||
|
|
||||||
packed |= (index | (chann << 2)) << (i * 4);
|
packed |= (index | (chann << 2)) << (i * 4);
|
||||||
|
|
||||||
domain |= Domain::DomainKey(fDomains[i]) << (i * Domain::kDomainKeyBits);
|
|
||||||
}
|
}
|
||||||
if (kIdentity_SkYUVColorSpace == this->yuvColorSpace()) {
|
if (fYUVColorSpace == kIdentity_SkYUVColorSpace) {
|
||||||
packed |= 0x1 << 16;
|
packed |= 0x1 << 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
b->add32(packed);
|
b->add32(packed);
|
||||||
b->add32(domain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GrYUVtoRGBEffect::onIsEqual(const GrFragmentProcessor& other) const {
|
bool GrYUVtoRGBEffect::onIsEqual(const GrFragmentProcessor& other) const {
|
||||||
const GrYUVtoRGBEffect& that = other.cast<GrYUVtoRGBEffect>();
|
const GrYUVtoRGBEffect& that = other.cast<GrYUVtoRGBEffect>();
|
||||||
|
|
||||||
@ -200,44 +222,23 @@ bool GrYUVtoRGBEffect::onIsEqual(const GrFragmentProcessor& other) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < this->numTextureSamplers(); ++i) {
|
|
||||||
// 'fSamplers' is checked by the base class
|
|
||||||
if (fSamplerTransforms[i] != that.fSamplerTransforms[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!(fDomains[i] == that.fDomains[i])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fYUVColorSpace != that.fYUVColorSpace) {
|
if (fYUVColorSpace != that.fYUVColorSpace) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrYUVtoRGBEffect::GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src)
|
GrYUVtoRGBEffect::GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src)
|
||||||
: INHERITED(kGrYUVtoRGBEffect_ClassID, src.optimizationFlags())
|
: GrFragmentProcessor(kGrYUVtoRGBEffect_ClassID, src.optimizationFlags())
|
||||||
, fDomains{src.fDomains[0], src.fDomains[1], src.fDomains[2], src.fDomains[3]}
|
|
||||||
, fYUVColorSpace(src.fYUVColorSpace) {
|
, fYUVColorSpace(src.fYUVColorSpace) {
|
||||||
int numPlanes = src.numTextureSamplers();
|
int numPlanes = src.numChildProcessors();
|
||||||
for (int i = 0; i < numPlanes; ++i) {
|
for (int i = 0; i < numPlanes; ++i) {
|
||||||
fSamplers[i].reset(sk_ref_sp(src.fSamplers[i].proxy()), src.fSamplers[i].samplerState());
|
this->registerChildProcessor(this->childProcessor(i).clone());
|
||||||
fSamplerTransforms[i] = src.fSamplerTransforms[i];
|
|
||||||
fSamplerCoordTransforms[i] = src.fSamplerCoordTransforms[i];
|
|
||||||
}
|
}
|
||||||
|
std::copy_n(src.fYUVAIndices, this->numChildProcessors(), fYUVAIndices);
|
||||||
this->setTextureSamplerCnt(numPlanes);
|
|
||||||
for (int i = 0; i < numPlanes; ++i) {
|
|
||||||
this->addCoordTransform(&fSamplerCoordTransforms[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(fYUVAIndices, src.fYUVAIndices, sizeof(fYUVAIndices));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::clone() const {
|
std::unique_ptr<GrFragmentProcessor> GrYUVtoRGBEffect::clone() const {
|
||||||
return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect(*this));
|
return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect(*this));
|
||||||
}
|
}
|
||||||
const GrFragmentProcessor::TextureSampler& GrYUVtoRGBEffect::onTextureSampler(int index) const {
|
|
||||||
SkASSERT(index < this->numTextureSamplers());
|
|
||||||
return fSamplers[index];
|
|
||||||
}
|
|
||||||
|
@ -32,65 +32,25 @@ public:
|
|||||||
SkString dumpInfo() const override;
|
SkString dumpInfo() const override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SkYUVColorSpace yuvColorSpace() const { return fYUVColorSpace; }
|
|
||||||
const SkYUVAIndex& yuvaIndex(int i) const { return fYUVAIndices[i]; }
|
|
||||||
|
|
||||||
GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src);
|
|
||||||
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
||||||
|
|
||||||
const char* name() const override { return "YUVtoRGBEffect"; }
|
const char* name() const override { return "YUVtoRGBEffect"; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrYUVtoRGBEffect(const sk_sp<GrTextureProxy> proxies[], const SkSize scales[],
|
GrYUVtoRGBEffect(std::unique_ptr<GrFragmentProcessor> planeFPs[4], int numPlanes,
|
||||||
const GrSamplerState::Filter filterModes[], int numPlanes,
|
const SkYUVAIndex yuvaIndices[4], SkYUVColorSpace yuvColorSpace);
|
||||||
const SkYUVAIndex yuvaIndices[4], SkYUVColorSpace yuvColorSpace,
|
|
||||||
const SkMatrix& localMatrix, const SkRect* domain)
|
|
||||||
: INHERITED(kGrYUVtoRGBEffect_ClassID, kNone_OptimizationFlags)
|
|
||||||
, fDomains{GrTextureDomain::IgnoredDomain(), GrTextureDomain::IgnoredDomain(),
|
|
||||||
GrTextureDomain::IgnoredDomain(), GrTextureDomain::IgnoredDomain()}
|
|
||||||
, fYUVColorSpace(yuvColorSpace) {
|
|
||||||
for (int i = 0; i < numPlanes; ++i) {
|
|
||||||
SkMatrix planeMatrix = SkMatrix::MakeScale(scales[i].width(), scales[i].height());
|
|
||||||
if (domain) {
|
|
||||||
SkASSERT(filterModes[i] != GrSamplerState::Filter::kMipMap);
|
|
||||||
|
|
||||||
SkRect scaledDomain = planeMatrix.mapRect(*domain);
|
GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src);
|
||||||
if (filterModes[i] != GrSamplerState::Filter::kNearest) {
|
|
||||||
// Inset by half a pixel for bilerp, after scaling to the size of the plane
|
|
||||||
scaledDomain.inset(0.5f, 0.5f);
|
|
||||||
}
|
|
||||||
|
|
||||||
fDomains[i] = GrTextureDomain(proxies[i].get(), scaledDomain,
|
|
||||||
GrTextureDomain::kClamp_Mode, GrTextureDomain::kClamp_Mode, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
planeMatrix.preConcat(localMatrix);
|
|
||||||
fSamplers[i].reset(std::move(proxies[i]),
|
|
||||||
GrSamplerState(GrSamplerState::WrapMode::kClamp, filterModes[i]));
|
|
||||||
fSamplerTransforms[i] = planeMatrix;
|
|
||||||
fSamplerCoordTransforms[i] =
|
|
||||||
GrCoordTransform(fSamplerTransforms[i], fSamplers[i].proxy());
|
|
||||||
}
|
|
||||||
|
|
||||||
this->setTextureSamplerCnt(numPlanes);
|
|
||||||
for (int i = 0; i < numPlanes; ++i) {
|
|
||||||
this->addCoordTransform(&fSamplerCoordTransforms[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(fYUVAIndices, yuvaIndices, sizeof(fYUVAIndices));
|
|
||||||
}
|
|
||||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
||||||
|
|
||||||
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
|
void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
|
||||||
|
|
||||||
bool onIsEqual(const GrFragmentProcessor&) const override;
|
bool onIsEqual(const GrFragmentProcessor&) const override;
|
||||||
const TextureSampler& onTextureSampler(int) const override;
|
|
||||||
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
|
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
|
||||||
|
|
||||||
TextureSampler fSamplers[4];
|
|
||||||
SkMatrix44 fSamplerTransforms[4];
|
|
||||||
GrCoordTransform fSamplerCoordTransforms[4];
|
|
||||||
GrTextureDomain fDomains[4];
|
|
||||||
SkYUVAIndex fYUVAIndices[4];
|
SkYUVAIndex fYUVAIndices[4];
|
||||||
SkYUVColorSpace fYUVColorSpace;
|
SkYUVColorSpace fYUVColorSpace;
|
||||||
|
|
||||||
typedef GrFragmentProcessor INHERITED;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user