48 auto c =
static_cast<int>(channel);
49 planeBorders[plane][c] =
m[
i*5 + 4];
68 float planeBorders[4][4] = {};
73 bool snap[2] = {
false,
false};
75 for (
int i = 0;
i < numPlanes; ++
i) {
83 bool makeLinearWithSnap =
false;
89 if (ssx > 1 || ssy > 1) {
97 planeSubset = {subset->
fLeft *scaleX,
105 planeDomain = {domain->
fLeft *scaleX,
106 domain->
fTop *scaleY,
115 float maxRight = view.
width() -
dx*scaleX;
116 if (planeSubset.
fRight > maxRight) {
117 planeSubset.
fRight = maxRight;
123 float maxBottom = view.
height() - dy*scaleY;
124 if (planeSubset.
fBottom > maxBottom) {
125 planeSubset.
fBottom = maxBottom;
134 bool snapX = (ssx != 1),
136 makeLinearWithSnap = snapX || snapY;
150 planeSubset = *subset;
153 planeDomain = *domain;
157 if (makeLinearWithSnap) {
167 SkRect* domainRect = domain ? &planeDomain :
nullptr;
175 {scaleX/2.f, scaleY/2.f},
198 if (makeLinearWithSnap) {
212 std::unique_ptr<GrFragmentProcessor>
fp(
226GrYUVtoRGBEffect::GrYUVtoRGBEffect(std::unique_ptr<GrFragmentProcessor> planeFPs[4],
232 ModulateForClampedSamplerOptFlags(
alpha_type(locations)))
233 , fLocations(locations)
234 , fYUVColorSpace(yuvColorSpace) {
235 std::copy_n(snap, 2, fSnap);
237 if (fSnap[0] || fSnap[1]) {
239 this->setUsesSampleCoordsDirectly();
240 for (
int i = 0;
i < numPlanes; ++
i) {
244 for (
int i = 0;
i < numPlanes; ++
i) {
245 this->registerChild(std::move(planeFPs[
i]));
250#if defined(GR_TEST_UTILS)
251SkString GrYUVtoRGBEffect::onDumpInfo()
const {
254 str.appendf(
"Locations[%d]=%d %d, ",
255 i, fLocations[
i].fPlane,
static_cast<int>(fLocations[
i].fChannel));
257 str.appendf(
"YUVColorSpace=%d, snap=(%d, %d))",
258 static_cast<int>(fYUVColorSpace), fSnap[0], fSnap[1]);
263std::unique_ptr<GrFragmentProcessor::ProgramImpl> GrYUVtoRGBEffect::onMakeProgramImpl()
const {
266 void emitCode(EmitArgs&
args)
override {
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;");
278 if (yuvEffect.fSnap[1]) {
279 fragBuilder->
codeAppend(
"snappedCoords.y = floor(snappedCoords.y) + 0.5;");
281 sampleCoords =
"snappedCoords";
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)]);
298 SkASSERT(colorChannel.size() == planeChannel.size());
299 if (!colorChannel.empty()) {
301 "color.%s = (%s).%s;",
302 colorChannel.c_str(),
303 this->invokeChild(planeIdx,
args, sampleCoords).c_str(),
304 planeChannel.c_str());
313 fColorSpaceMatrixVar =
args.fUniformHandler->addUniform(&yuvEffect,
315 fColorSpaceTranslateVar =
args.fUniformHandler->addUniform(&yuvEffect,
318 "color.rgb = saturate(color.rgb * %s + %s);",
319 args.fUniformHandler->getUniformCStr(fColorSpaceMatrixVar),
320 args.fUniformHandler->getUniformCStr(fColorSpaceTranslateVar));
335 SkASSERT(fColorSpaceMatrixVar.isValid());
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);
345 yuvM[ 0], yuvM[ 1], yuvM[ 2],
346 yuvM[ 5], yuvM[ 6], yuvM[ 7],
347 yuvM[10], yuvM[11], yuvM[12],
349 float v[3] = {yuvM[4], yuvM[9], yuvM[14]};
351 pdman.
set3fv(fColorSpaceTranslateVar, 1, v);
355 UniformHandle fColorSpaceMatrixVar;
356 UniformHandle fColorSpaceTranslateVar;
359 return std::make_unique<Impl>();
365 for (
auto [plane, channel] : fLocations) {
370 uint8_t chann =
static_cast<int>(channel);
374 packed |= (plane | (chann << 2)) << (
i++ * 4);
391 return fLocations == that.fLocations &&
393 fYUVColorSpace == that.fYUVColorSpace;
398 , fLocations((
src.fLocations))
399 , fYUVColorSpace(
src.fYUVColorSpace) {
400 std::copy_n(
src.fSnap, 2, fSnap);
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static void border_colors(const GrYUVATextureProxies &yuvaProxies, float planeBorders[4][4])
static SkAlphaType alpha_type(const SkYUVAInfo::YUVALocations locations)
static bool equal(const SkBitmap &a, const SkBitmap &b)
@ kUnknown_SkAlphaType
uninitialized
@ kOpaque_SkAlphaType
pixel is opaque
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
@ kIdentity_SkYUVColorSpace
maps Y->R, U->G, V->B
static constexpr bool SkToBool(const T &x)
void SkColorMatrix_RGB2YUV(SkYUVColorSpace cs, float m[20])
void SkColorMatrix_YUV2RGB(SkYUVColorSpace cs, float m[20])
int numChildProcessors() const
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
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 std::unique_ptr< GrFragmentProcessor > Make(const GrYUVATextureProxies &yuvaProxies, GrSamplerState samplerState, const GrCaps &, const SkMatrix &localMatrix=SkMatrix::I(), const SkRect *subset=nullptr, const SkRect *domain=nullptr)
std::unique_ptr< GrFragmentProcessor > clone() const override
static SkMatrix Scale(SkScalar sx, SkScalar sy)
SkMatrix & postConcat(const SkMatrix &other)
bool invert(SkMatrix *inverse) const
static SampleUsage Explicit()
SkMatrix originMatrix() const
SkYUVColorSpace yuvColorSpace() const
static constexpr int kMaxPlanes
std::tuple< int, int > planeSubsamplingFactors(int planeIdx) const
std::array< YUVALocation, kYUVAChannelCount > YUVALocations
static constexpr int kYUVAChannelCount
SkISize dimensions() const
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
SIN Vec< N, float > floor(const Vec< N, float > &x)
static SkRect Make(const SkISize &size)
SkScalar fBottom
larger y-axis bounds
SkScalar fLeft
smaller x-axis bounds
SkScalar fRight
larger x-axis bounds
bool contains(SkScalar x, SkScalar y) const
SkScalar fTop
smaller y-axis bounds