Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Public Member Functions | Static Public Member Functions | Private Member Functions | List of all members
GrYUVtoRGBEffect Class Reference

#include <GrYUVtoRGBEffect.h>

Inheritance diagram for GrYUVtoRGBEffect:
GrFragmentProcessor GrProcessor

Public Member Functions

std::unique_ptr< GrFragmentProcessorclone () const override
 
const char * name () const override
 
- Public Member Functions inherited from GrFragmentProcessor
const GrFragmentProcessorparent () const
 
std::unique_ptr< ProgramImplmakeProgramImpl () const
 
void addToKey (const GrShaderCaps &caps, skgpu::KeyBuilder *b) const
 
int numChildProcessors () const
 
int numNonNullChildProcessors () const
 
GrFragmentProcessorchildProcessor (int index)
 
const GrFragmentProcessorchildProcessor (int index) const
 
 SkDEBUGCODE (bool isInstantiated() const ;) bool willReadDstColor() const
 
bool isBlendFunction () const
 
bool usesSampleCoordsDirectly () const
 
bool usesSampleCoords () const
 
const SkSL::SampleUsagesampleUsage () const
 
bool compatibleWithCoverageAsAlpha () const
 
bool preservesOpaqueInput () const
 
bool hasConstantOutputForConstantInput (SkPMColor4f inputColor, SkPMColor4f *outputColor) const
 
bool hasConstantOutputForConstantInput () const
 
void clearConstantOutputForConstantInputFlag ()
 
bool isEqual (const GrFragmentProcessor &that) const
 
void visitProxies (const GrVisitProxyFunc &) const
 
void visitTextureEffects (const std::function< void(const GrTextureEffect &)> &) const
 
void visitWithImpls (const std::function< void(const GrFragmentProcessor &, ProgramImpl &)> &, ProgramImpl &) const
 
GrTextureEffectasTextureEffect ()
 
const GrTextureEffectasTextureEffect () const
 
- Public Member Functions inherited from GrProcessor
virtual ~GrProcessor ()=default
 
void * operator new (size_t size)
 
void * operator new (size_t object_size, size_t footer_size)
 
void operator delete (void *target)
 
void * operator new (size_t size, void *placement)
 
void operator delete (void *target, void *placement)
 
template<typename T >
const Tcast () const
 
ClassID classID () const
 

Static Public Member Functions

static std::unique_ptr< GrFragmentProcessorMake (const GrYUVATextureProxies &yuvaProxies, GrSamplerState samplerState, const GrCaps &, const SkMatrix &localMatrix=SkMatrix::I(), const SkRect *subset=nullptr, const SkRect *domain=nullptr)
 
- Static Public Member Functions inherited from GrFragmentProcessor
static std::unique_ptr< GrFragmentProcessorMakeColor (SkPMColor4f color)
 
static std::unique_ptr< GrFragmentProcessorMulInputByChildAlpha (std::unique_ptr< GrFragmentProcessor > child)
 
static std::unique_ptr< GrFragmentProcessorApplyPaintAlpha (std::unique_ptr< GrFragmentProcessor > child)
 
static std::unique_ptr< GrFragmentProcessorModulateRGBA (std::unique_ptr< GrFragmentProcessor > child, const SkPMColor4f &color)
 
static std::unique_ptr< GrFragmentProcessorOverrideInput (std::unique_ptr< GrFragmentProcessor >, const SkPMColor4f &)
 
static std::unique_ptr< GrFragmentProcessorDisableCoverageAsAlpha (std::unique_ptr< GrFragmentProcessor >)
 
static std::unique_ptr< GrFragmentProcessorDestColor ()
 
static std::unique_ptr< GrFragmentProcessorSwizzleOutput (std::unique_ptr< GrFragmentProcessor >, const skgpu::Swizzle &)
 
static std::unique_ptr< GrFragmentProcessorClampOutput (std::unique_ptr< GrFragmentProcessor >)
 
static std::unique_ptr< GrFragmentProcessorCompose (std::unique_ptr< GrFragmentProcessor > f, std::unique_ptr< GrFragmentProcessor > g)
 
static std::unique_ptr< GrFragmentProcessorColorMatrix (std::unique_ptr< GrFragmentProcessor > child, const float matrix[20], bool unpremulInput, bool clampRGBOutput, bool premulOutput)
 
static std::unique_ptr< GrFragmentProcessorSurfaceColor ()
 
static std::unique_ptr< GrFragmentProcessorDeviceSpace (std::unique_ptr< GrFragmentProcessor >)
 
static std::unique_ptr< GrFragmentProcessorRect (std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkRect)
 
static GrFPResult Circle (std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkPoint center, float radius)
 
static GrFPResult Ellipse (std::unique_ptr< GrFragmentProcessor >, GrClipEdgeType, SkPoint center, SkPoint radii, const GrShaderCaps &)
 
static std::unique_ptr< GrFragmentProcessorHighPrecision (std::unique_ptr< GrFragmentProcessor >)
 

Private Member Functions

std::unique_ptr< ProgramImplonMakeProgramImpl () const override
 
void onAddToKey (const GrShaderCaps &, skgpu::KeyBuilder *) const override
 
bool onIsEqual (const GrFragmentProcessor &) const override
 

Additional Inherited Members

- Public Types inherited from GrProcessor
enum  ClassID {
  kNull_ClassID , kAttributeTestProcessor_ClassID , kBigKeyProcessor_ClassID , kBlendFragmentProcessor_ClassID ,
  kBlockInputFragmentProcessor_ClassID , kButtCapStrokedCircleGeometryProcessor_ClassID , kCircleGeometryProcessor_ClassID , kCircularRRectEffect_ClassID ,
  kClockwiseTestProcessor_ClassID , kColorTableEffect_ClassID , kCoverageSetOpXP_ClassID , kCustomXP_ClassID ,
  kDashingCircleEffect_ClassID , kDashingLineEffect_ClassID , kDefaultGeoProc_ClassID , kDeviceSpace_ClassID ,
  kDIEllipseGeometryProcessor_ClassID , kDisableColorXP_ClassID , kDrawAtlasPathShader_ClassID , kEllipseGeometryProcessor_ClassID ,
  kEllipticalRRectEffect_ClassID , kFwidthSquircleTestProcessor_ClassID , kGP_ClassID , kGrBicubicEffect_ClassID ,
  kGrBitmapTextGeoProc_ClassID , kGrColorSpaceXformEffect_ClassID , kGrConicEffect_ClassID , kGrConvexPolyEffect_ClassID ,
  kGrDiffuseLightingEffect_ClassID , kGrDisplacementMapEffect_ClassID , kGrDistanceFieldA8TextGeoProc_ClassID , kGrDistanceFieldLCDTextGeoProc_ClassID ,
  kGrDistanceFieldPathGeoProc_ClassID , kGrFillRRectOp_Processor_ClassID , kGrGaussianConvolutionFragmentProcessor_ClassID , kGrMatrixConvolutionEffect_ClassID ,
  kGrMatrixEffect_ClassID , kGrMeshTestProcessor_ClassID , kGrMorphologyEffect_ClassID , kGrPerlinNoise2Effect_ClassID ,
  kGrPipelineDynamicStateTestProcessor_ClassID , kGrQuadEffect_ClassID , kGrRRectShadowGeoProc_ClassID , kGrSkSLFP_ClassID ,
  kGrSpecularLightingEffect_ClassID , kGrTextureEffect_ClassID , kGrUnrolledBinaryGradientColorizer_ClassID , kGrYUVtoRGBEffect_ClassID ,
  kHighPrecisionFragmentProcessor_ClassID , kLatticeGP_ClassID , kPDLCDXferProcessor_ClassID , kPorterDuffXferProcessor_ClassID ,
  kPremulFragmentProcessor_ClassID , kQuadEdgeEffect_ClassID , kQuadPerEdgeAAGeometryProcessor_ClassID , kSeriesFragmentProcessor_ClassID ,
  kShaderPDXferProcessor_ClassID , kSurfaceColorProcessor_ClassID , kSwizzleFragmentProcessor_ClassID , kTessellate_BoundingBoxShader_ClassID ,
  kTessellate_GrModulateAtlasCoverageEffect_ClassID , kTessellate_GrStrokeTessellationShader_ClassID , kTessellate_HullShader_ClassID , kTessellate_MiddleOutShader_ClassID ,
  kTessellate_SimpleTriangleShader_ClassID , kTessellationTestTriShader_ClassID , kTestFP_ClassID , kTestRectOp_ClassID ,
  kVertexColorSpaceBenchGP_ClassID , kVerticesGP_ClassID
}
 
- Protected Types inherited from GrFragmentProcessor
enum  OptimizationFlags : uint32_t {
  kNone_OptimizationFlags , kCompatibleWithCoverageAsAlpha_OptimizationFlag = 0x1 , kPreservesOpaqueInput_OptimizationFlag = 0x2 , kConstantOutputForConstantInput_OptimizationFlag = 0x4 ,
  kAll_OptimizationFlags
}
 
- Protected Member Functions inherited from GrFragmentProcessor
 GrFragmentProcessor (ClassID classID, OptimizationFlags optimizationFlags)
 
 GrFragmentProcessor (const GrFragmentProcessor &src)
 
OptimizationFlags optimizationFlags () const
 
void registerChild (std::unique_ptr< GrFragmentProcessor > child, SkSL::SampleUsage sampleUsage=SkSL::SampleUsage::PassThrough())
 
void cloneAndRegisterAllChildProcessors (const GrFragmentProcessor &src)
 
void setUsesSampleCoordsDirectly ()
 
void setWillReadDstColor ()
 
void setIsBlendFunction ()
 
void mergeOptimizationFlags (OptimizationFlags flags)
 
- Protected Member Functions inherited from GrProcessor
 GrProcessor (ClassID classID)
 
 GrProcessor (const GrProcessor &)=delete
 
GrProcessoroperator= (const GrProcessor &)=delete
 
- Static Protected Member Functions inherited from GrFragmentProcessor
static OptimizationFlags ModulateForSamplerOptFlags (SkAlphaType alphaType, bool samplingDecal)
 
static OptimizationFlags ModulateForClampedSamplerOptFlags (SkAlphaType alphaType)
 
static OptimizationFlags ProcessorOptimizationFlags (const GrFragmentProcessor *fp)
 
static SkPMColor4f ConstantOutputForConstantInput (const GrFragmentProcessor *fp, const SkPMColor4f &input)
 
- Protected Attributes inherited from GrProcessor
const ClassID fClassID
 

Detailed Description

Definition at line 28 of file GrYUVtoRGBEffect.h.

Member Function Documentation

◆ clone()

std::unique_ptr< GrFragmentProcessor > GrYUVtoRGBEffect::clone ( ) const
overridevirtual

Makes a copy of this fragment processor that draws equivalently to the original. If the processor has child processors they are cloned as well.

Implements GrFragmentProcessor.

Definition at line 403 of file GrYUVtoRGBEffect.cpp.

403 {
404 return std::unique_ptr<GrFragmentProcessor>(new GrYUVtoRGBEffect(*this));
405}

◆ Make()

std::unique_ptr< GrFragmentProcessor > GrYUVtoRGBEffect::Make ( const GrYUVATextureProxies yuvaProxies,
GrSamplerState  samplerState,
const GrCaps caps,
const SkMatrix localMatrix = SkMatrix::I(),
const SkRect subset = nullptr,
const SkRect domain = nullptr 
)
static

Definition at line 53 of file GrYUVtoRGBEffect.cpp.

58 {
59 SkASSERT(!subset || SkRect::Make(yuvaProxies.yuvaInfo().dimensions()).contains(*subset));
60
61 int numPlanes = yuvaProxies.yuvaInfo().numPlanes();
62 if (!yuvaProxies.isValid()) {
63 return nullptr;
64 }
65
66 bool usesBorder = samplerState.wrapModeX() == GrSamplerState::WrapMode::kClampToBorder ||
68 float planeBorders[4][4] = {};
69 if (usesBorder) {
70 border_colors(yuvaProxies, planeBorders);
71 }
72
73 bool snap[2] = {false, false};
74 std::unique_ptr<GrFragmentProcessor> planeFPs[SkYUVAInfo::kMaxPlanes];
75 for (int i = 0; i < numPlanes; ++i) {
76 bool useSubset = SkToBool(subset);
77 GrSurfaceProxyView view = yuvaProxies.makeView(i);
78 SkMatrix planeMatrix = yuvaProxies.yuvaInfo().originMatrix();
79 // The returned matrix is a view matrix but we need a local matrix.
80 SkAssertResult(planeMatrix.invert(&planeMatrix));
81 SkRect planeSubset;
82 SkRect planeDomain;
83 bool makeLinearWithSnap = false;
84 auto [ssx, ssy] = yuvaProxies.yuvaInfo().planeSubsamplingFactors(i);
85 SkASSERT(ssx > 0 && ssx <= 4);
86 SkASSERT(ssy > 0 && ssy <= 2);
87 float scaleX = 1.f;
88 float scaleY = 1.f;
89 if (ssx > 1 || ssy > 1) {
90 scaleX = 1.f/ssx;
91 scaleY = 1.f/ssy;
92 // We would want to add a translation to this matrix to handle other sitings.
95 planeMatrix.postConcat(SkMatrix::Scale(scaleX, scaleY));
96 if (subset) {
97 planeSubset = {subset->fLeft *scaleX,
98 subset->fTop *scaleY,
99 subset->fRight *scaleX,
100 subset->fBottom*scaleY};
101 } else {
102 planeSubset = SkRect::Make(view.dimensions());
103 }
104 if (domain) {
105 planeDomain = {domain->fLeft *scaleX,
106 domain->fTop *scaleY,
107 domain->fRight *scaleX,
108 domain->fBottom*scaleY};
109 }
110 // If the image is not a multiple of the subsampling then the subsampled plane needs to
111 // be tiled at less than its full width/height. This only matters when the mode is not
112 // clamp.
113 if (samplerState.wrapModeX() != GrSamplerState::WrapMode::kClamp) {
114 int dx = (ssx*view.width() - yuvaProxies.yuvaInfo().width());
115 float maxRight = view.width() - dx*scaleX;
116 if (planeSubset.fRight > maxRight) {
117 planeSubset.fRight = maxRight;
118 useSubset = true;
119 }
120 }
121 if (samplerState.wrapModeY() != GrSamplerState::WrapMode::kClamp) {
122 int dy = (ssy*view.height() - yuvaProxies.yuvaInfo().height());
123 float maxBottom = view.height() - dy*scaleY;
124 if (planeSubset.fBottom > maxBottom) {
125 planeSubset.fBottom = maxBottom;
126 useSubset = true;
127 }
128 }
129 // This promotion of nearest to linear filtering for UV planes exists to mimic
130 // libjpeg[-turbo]'s do_fancy_upsampling option. We will filter the subsampled plane,
131 // however we want to filter at a fixed point for each logical image pixel to simulate
132 // nearest neighbor.
133 if (samplerState.filter() == GrSamplerState::Filter::kNearest) {
134 bool snapX = (ssx != 1),
135 snapY = (ssy != 1);
136 makeLinearWithSnap = snapX || snapY;
137 snap[0] |= snapX;
138 snap[1] |= snapY;
139 if (domain) {
140 // The outer YUVToRGB effect will ensure sampling happens at pixel centers
141 // within this plane.
142 planeDomain = {std::floor(planeDomain.fLeft) + 0.5f,
143 std::floor(planeDomain.fTop) + 0.5f,
144 std::floor(planeDomain.fRight) + 0.5f,
145 std::floor(planeDomain.fBottom) + 0.5f};
146 }
147 }
148 } else {
149 if (subset) {
150 planeSubset = *subset;
151 }
152 if (domain) {
153 planeDomain = *domain;
154 }
155 }
156 if (useSubset) {
157 if (makeLinearWithSnap) {
158 // The plane is subsampled and we have an overall subset on the image. We're
159 // emulating do_fancy_upsampling using linear filtering but snapping look ups to the
160 // y-plane pixel centers. Consider a logical image pixel at the edge of the subset.
161 // When computing the logical pixel color value we should use a 50/50 blend of two
162 // values from the subsampled plane. Depending on where the subset edge falls in
163 // actual subsampled plane, one of those values may come from outside the subset.
164 // Hence, we use this custom inset factory which applies the wrap mode to
165 // planeSubset but allows linear filtering to read pixels from the plane that are
166 // just outside planeSubset.
167 SkRect* domainRect = domain ? &planeDomain : nullptr;
168 planeFPs[i] = GrTextureEffect::MakeCustomLinearFilterInset(std::move(view),
170 planeMatrix,
171 samplerState.wrapModeX(),
172 samplerState.wrapModeY(),
173 planeSubset,
174 domainRect,
175 {scaleX/2.f, scaleY/2.f},
176 caps,
177 planeBorders[i]);
178 } else if (domain) {
179 planeFPs[i] = GrTextureEffect::MakeSubset(std::move(view),
181 planeMatrix,
182 samplerState,
183 planeSubset,
184 planeDomain,
185 caps,
186 planeBorders[i]);
187 } else {
188 planeFPs[i] = GrTextureEffect::MakeSubset(std::move(view),
190 planeMatrix,
191 samplerState,
192 planeSubset,
193 caps,
194 planeBorders[i]);
195 }
196 } else {
197 GrSamplerState planeSampler = samplerState;
198 if (makeLinearWithSnap) {
199 planeSampler = GrSamplerState(samplerState.wrapModeX(),
200 samplerState.wrapModeY(),
201 GrSamplerState::Filter::kLinear,
202 samplerState.mipmapMode());
203 }
204 planeFPs[i] = GrTextureEffect::Make(std::move(view),
206 planeMatrix,
207 planeSampler,
208 caps,
209 planeBorders[i]);
210 }
211 }
212 std::unique_ptr<GrFragmentProcessor> fp(
213 new GrYUVtoRGBEffect(planeFPs,
214 numPlanes,
215 yuvaProxies.yuvaLocations(),
216 snap,
217 yuvaProxies.yuvaInfo().yuvColorSpace()));
218 return GrMatrixEffect::Make(localMatrix, std::move(fp));
219}
static void border_colors(const GrYUVATextureProxies &yuvaProxies, float planeBorders[4][4])
@ kUnknown_SkAlphaType
uninitialized
Definition SkAlphaType.h:27
#define SkAssertResult(cond)
Definition SkAssert.h:123
#define SkASSERT(cond)
Definition SkAssert.h:116
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
static std::unique_ptr< GrFragmentProcessor > Make(const SkMatrix &matrix, std::unique_ptr< GrFragmentProcessor > child)
constexpr WrapMode wrapModeX() const
constexpr Filter filter() const
constexpr MipmapMode mipmapMode() const
constexpr WrapMode wrapModeY() const
SkISize dimensions() const
static std::unique_ptr< GrFragmentProcessor > MakeCustomLinearFilterInset(GrSurfaceProxyView, SkAlphaType, const SkMatrix &, GrSamplerState::WrapMode wx, GrSamplerState::WrapMode wy, const SkRect &subset, const SkRect *domain, SkVector inset, const GrCaps &caps, const float border[4]=kDefaultBorder)
static std::unique_ptr< GrFragmentProcessor > MakeSubset(GrSurfaceProxyView, SkAlphaType, const SkMatrix &, GrSamplerState, const SkRect &subset, const GrCaps &caps, const float border[4]=kDefaultBorder, bool alwaysUseShaderTileMode=false)
static std::unique_ptr< GrFragmentProcessor > Make(GrSurfaceProxyView, SkAlphaType, const SkMatrix &=SkMatrix::I(), GrSamplerState::Filter=GrSamplerState::Filter::kNearest, GrSamplerState::MipmapMode mipmapMode=GrSamplerState::MipmapMode::kNone)
const SkYUVAInfo & yuvaInfo() const
GrSurfaceProxyView makeView(int i) const
const SkYUVAInfo::YUVALocations & yuvaLocations() const
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition SkMatrix.h:75
SkMatrix & postConcat(const SkMatrix &other)
Definition SkMatrix.cpp:683
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
int width() const
Definition SkYUVAInfo.h:172
Siting sitingY() const
Definition SkYUVAInfo.h:177
SkMatrix originMatrix() const
Definition SkYUVAInfo.h:181
SkYUVColorSpace yuvColorSpace() const
Definition SkYUVAInfo.h:175
int numPlanes() const
Definition SkYUVAInfo.h:204
static constexpr int kMaxPlanes
Definition SkYUVAInfo.h:98
int height() const
Definition SkYUVAInfo.h:173
std::tuple< int, int > planeSubsamplingFactors(int planeIdx) const
Definition SkYUVAInfo.h:163
SkISize dimensions() const
Definition SkYUVAInfo.h:171
Siting sitingX() const
Definition SkYUVAInfo.h:176
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition SkRecords.h:208
const uint32_t fp
static SkRect Make(const SkISize &size)
Definition SkRect.h:669
SkScalar fBottom
larger y-axis bounds
Definition extension.cpp:17
SkScalar fLeft
smaller x-axis bounds
Definition extension.cpp:14
SkScalar fRight
larger x-axis bounds
Definition extension.cpp:16
bool contains(SkScalar x, SkScalar y) const
Definition extension.cpp:19
SkScalar fTop
smaller y-axis bounds
Definition extension.cpp:15

◆ name()

const char * GrYUVtoRGBEffect::name ( ) const
inlineoverridevirtual

Human-meaningful string to identify this processor; may be embedded in generated shader code and must be a legal SkSL identifier prefix.

Implements GrProcessor.

Definition at line 38 of file GrYUVtoRGBEffect.h.

38{ return "YUVtoRGBEffect"; }

◆ onAddToKey()

void GrYUVtoRGBEffect::onAddToKey ( const GrShaderCaps caps,
skgpu::KeyBuilder b 
) const
overrideprivatevirtual

Implements GrFragmentProcessor.

Definition at line 362 of file GrYUVtoRGBEffect.cpp.

362 {
363 uint32_t packed = 0;
364 int i = 0;
365 for (auto [plane, channel] : fLocations) {
366 if (plane < 0) {
367 continue;
368 }
369
370 uint8_t chann = static_cast<int>(channel);
371
372 SkASSERT(plane < 4 && chann < 4);
373
374 packed |= (plane | (chann << 2)) << (i++ * 4);
375 }
376 if (fYUVColorSpace == kIdentity_SkYUVColorSpace) {
377 packed |= 1 << 16;
378 }
379 if (fSnap[0]) {
380 packed |= 1 << 17;
381 }
382 if (fSnap[1]) {
383 packed |= 1 << 18;
384 }
385 b->add32(packed);
386}
@ kIdentity_SkYUVColorSpace
maps Y->R, U->G, V->B
Definition SkImageInfo.h:93
static bool b

◆ onIsEqual()

bool GrYUVtoRGBEffect::onIsEqual ( const GrFragmentProcessor ) const
overrideprivatevirtual

Subclass implements this to support isEqual(). It will only be called if it is known that the two processors are of the same subclass (i.e. have the same ClassID).

Implements GrFragmentProcessor.

Definition at line 388 of file GrYUVtoRGBEffect.cpp.

388 {
389 const GrYUVtoRGBEffect& that = other.cast<GrYUVtoRGBEffect>();
390
391 return fLocations == that.fLocations &&
392 std::equal(fSnap, fSnap + 2, that.fSnap) &&
393 fYUVColorSpace == that.fYUVColorSpace;
394}
const T & cast() const

◆ onMakeProgramImpl()

std::unique_ptr< GrFragmentProcessor::ProgramImpl > GrYUVtoRGBEffect::onMakeProgramImpl ( ) const
overrideprivatevirtual

Returns a new instance of the appropriate ProgramImpl subclass for the given GrFragmentProcessor. It will emit the appropriate code and live with the cached program to setup uniform data for each draw that uses the program.

Implements GrFragmentProcessor.

Definition at line 263 of file GrYUVtoRGBEffect.cpp.

263 {
264 class Impl : public ProgramImpl {
265 public:
266 void emitCode(EmitArgs& args) override {
267 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
268 const GrYUVtoRGBEffect& yuvEffect = args.fFp.cast<GrYUVtoRGBEffect>();
269
270 int numPlanes = yuvEffect.numChildProcessors();
271
272 const char* sampleCoords = "";
273 if (yuvEffect.fSnap[0] || yuvEffect.fSnap[1]) {
274 fragBuilder->codeAppendf("float2 snappedCoords = %s;", args.fSampleCoord);
275 if (yuvEffect.fSnap[0]) {
276 fragBuilder->codeAppend("snappedCoords.x = floor(snappedCoords.x) + 0.5;");
277 }
278 if (yuvEffect.fSnap[1]) {
279 fragBuilder->codeAppend("snappedCoords.y = floor(snappedCoords.y) + 0.5;");
280 }
281 sampleCoords = "snappedCoords";
282 }
283
284 fragBuilder->codeAppendf("half4 color;");
285 const bool hasAlpha = yuvEffect.fLocations[SkYUVAInfo::YUVAChannels::kA].fPlane >= 0;
286
287 for (int planeIdx = 0; planeIdx < numPlanes; ++planeIdx) {
288 std::string colorChannel;
289 std::string planeChannel;
290 for (int locIdx = 0; locIdx < (hasAlpha ? 4 : 3); ++locIdx) {
291 auto [yuvPlane, yuvChannel] = yuvEffect.fLocations[locIdx];
292 if (yuvPlane == planeIdx) {
293 colorChannel.push_back("rgba"[locIdx]);
294 planeChannel.push_back("rgba"[static_cast<int>(yuvChannel)]);
295 }
296 }
297
298 SkASSERT(colorChannel.size() == planeChannel.size());
299 if (!colorChannel.empty()) {
300 fragBuilder->codeAppendf(
301 "color.%s = (%s).%s;",
302 colorChannel.c_str(),
303 this->invokeChild(planeIdx, args, sampleCoords).c_str(),
304 planeChannel.c_str());
305 }
306 }
307
308 if (!hasAlpha) {
309 fragBuilder->codeAppendf("color.a = 1;");
310 }
311
312 if (kIdentity_SkYUVColorSpace != yuvEffect.fYUVColorSpace) {
313 fColorSpaceMatrixVar = args.fUniformHandler->addUniform(&yuvEffect,
314 kFragment_GrShaderFlag, SkSLType::kHalf3x3, "colorSpaceMatrix");
315 fColorSpaceTranslateVar = args.fUniformHandler->addUniform(&yuvEffect,
316 kFragment_GrShaderFlag, SkSLType::kHalf3, "colorSpaceTranslate");
317 fragBuilder->codeAppendf(
318 "color.rgb = saturate(color.rgb * %s + %s);",
319 args.fUniformHandler->getUniformCStr(fColorSpaceMatrixVar),
320 args.fUniformHandler->getUniformCStr(fColorSpaceTranslateVar));
321 }
322 if (hasAlpha) {
323 // premultiply alpha
324 fragBuilder->codeAppendf("color.rgb *= color.a;");
325 }
326 fragBuilder->codeAppendf("return color;");
327 }
328
329 private:
330 void onSetData(const GrGLSLProgramDataManager& pdman,
331 const GrFragmentProcessor& proc) override {
332 const GrYUVtoRGBEffect& yuvEffect = proc.cast<GrYUVtoRGBEffect>();
333
334 if (yuvEffect.fYUVColorSpace != kIdentity_SkYUVColorSpace) {
335 SkASSERT(fColorSpaceMatrixVar.isValid());
336 float yuvM[20];
337 SkColorMatrix_YUV2RGB(yuvEffect.fYUVColorSpace, yuvM);
338 // We drop the fourth column entirely since the transformation
339 // should not depend on alpha. The fifth column is sent as a separate
340 // vector. The fourth row is also dropped entirely because alpha should
341 // never be modified.
342 SkASSERT(yuvM[3] == 0 && yuvM[8] == 0 && yuvM[13] == 0 && yuvM[18] == 1);
343 SkASSERT(yuvM[15] == 0 && yuvM[16] == 0 && yuvM[17] == 0 && yuvM[19] == 0);
344 float mtx[9] = {
345 yuvM[ 0], yuvM[ 1], yuvM[ 2],
346 yuvM[ 5], yuvM[ 6], yuvM[ 7],
347 yuvM[10], yuvM[11], yuvM[12],
348 };
349 float v[3] = {yuvM[4], yuvM[9], yuvM[14]};
350 pdman.setMatrix3f(fColorSpaceMatrixVar, mtx);
351 pdman.set3fv(fColorSpaceTranslateVar, 1, v);
352 }
353 }
354
355 UniformHandle fColorSpaceMatrixVar;
356 UniformHandle fColorSpaceTranslateVar;
357 };
358
359 return std::make_unique<Impl>();
360}
@ kFragment_GrShaderFlag
void SkColorMatrix_YUV2RGB(SkYUVColorSpace cs, float m[20])
virtual void set3fv(UniformHandle, int arrayCount, const float v[]) const =0
virtual void setMatrix3f(UniformHandle, const float matrix[]) const =0
void codeAppend(const char *str)
void codeAppendf(const char format[],...) SK_PRINTF_LIKE(2
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args

The documentation for this class was generated from the following files: