blob: 9e4a843e76d027632409d169a1d04663fe817530 [file] [log] [blame]
Ethan Nicholas7461a4a2017-12-21 14:18:01 -05001/*
Ethan Nicholas130fb3f2018-02-01 12:14:34 -05002 * Copyright 2018 Google Inc.
Ethan Nicholas7461a4a2017-12-21 14:18:01 -05003 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Ethan Nicholas7461a4a2017-12-21 14:18:01 -05008#ifndef GrYUVtoRGBEffect_DEFINED
9#define GrYUVtoRGBEffect_DEFINED
Robert Phillips94ade752018-10-09 12:32:31 -040010
Ethan Nicholas7461a4a2017-12-21 14:18:01 -050011#include "SkTypes.h"
Robert Phillips94ade752018-10-09 12:32:31 -040012
Ethan Nicholas7461a4a2017-12-21 14:18:01 -050013#include "GrFragmentProcessor.h"
14#include "GrCoordTransform.h"
Michael Ludwiga6a84002019-04-12 15:03:02 -040015#include "GrTextureDomain.h"
Robert Phillips94ade752018-10-09 12:32:31 -040016
17#include "SkYUVAIndex.h"
18
Ethan Nicholas7461a4a2017-12-21 14:18:01 -050019class GrYUVtoRGBEffect : public GrFragmentProcessor {
20public:
Michael Ludwiga6a84002019-04-12 15:03:02 -040021 // The domain supported by this effect is more limited than the general GrTextureDomain due
22 // to the multi-planar, varying resolution images that it has to sample. If 'domain' is provided
23 // it is the Y plane's domain. This will automatically inset for bilinear filtering, and only
24 // the clamp wrap mode is supported.
Robert Phillips94ade752018-10-09 12:32:31 -040025 static std::unique_ptr<GrFragmentProcessor> Make(const sk_sp<GrTextureProxy> proxies[],
26 const SkYUVAIndex indices[4],
Jim Van Verth30e0d7f2018-11-02 13:36:42 -040027 SkYUVColorSpace yuvColorSpace,
Michael Ludwiga6a84002019-04-12 15:03:02 -040028 GrSamplerState::Filter filterMode,
29 const SkMatrix& localMatrix = SkMatrix::I(),
30 const SkRect* domain = nullptr);
Brian Osman9a390ac2018-11-12 09:47:48 -050031#ifdef SK_DEBUG
Robert Phillipsba5c4392018-07-25 12:37:14 -040032 SkString dumpInfo() const override;
Brian Osman9a390ac2018-11-12 09:47:48 -050033#endif
Robert Phillips94ade752018-10-09 12:32:31 -040034
Robert Phillipsb651aac2019-03-15 12:18:49 -040035 SkYUVColorSpace yuvColorSpace() const { return fYUVColorSpace; }
Robert Phillips94ade752018-10-09 12:32:31 -040036 const SkYUVAIndex& yuvaIndex(int i) const { return fYUVAIndices[i]; }
37
Ethan Nicholas7461a4a2017-12-21 14:18:01 -050038 GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src);
39 std::unique_ptr<GrFragmentProcessor> clone() const override;
40 const char* name() const override { return "YUVtoRGBEffect"; }
41
42private:
Robert Phillips94ade752018-10-09 12:32:31 -040043 GrYUVtoRGBEffect(const sk_sp<GrTextureProxy> proxies[], const SkSize scales[],
44 const GrSamplerState::Filter filterModes[], int numPlanes,
Michael Ludwiga6a84002019-04-12 15:03:02 -040045 const SkYUVAIndex yuvaIndices[4], SkYUVColorSpace yuvColorSpace,
46 const SkMatrix& localMatrix, const SkRect* domain)
Ethan Nicholas7461a4a2017-12-21 14:18:01 -050047 : INHERITED(kGrYUVtoRGBEffect_ClassID, kNone_OptimizationFlags)
Michael Ludwiga6a84002019-04-12 15:03:02 -040048 , fDomains{GrTextureDomain::IgnoredDomain(), GrTextureDomain::IgnoredDomain(),
49 GrTextureDomain::IgnoredDomain(), GrTextureDomain::IgnoredDomain()}
Robert Phillipsb651aac2019-03-15 12:18:49 -040050 , fYUVColorSpace(yuvColorSpace) {
Robert Phillips94ade752018-10-09 12:32:31 -040051 for (int i = 0; i < numPlanes; ++i) {
Michael Ludwiga6a84002019-04-12 15:03:02 -040052 SkMatrix planeMatrix = SkMatrix::MakeScale(scales[i].width(), scales[i].height());
53 if (domain) {
54 SkASSERT(filterModes[i] != GrSamplerState::Filter::kMipMap);
55
56 SkRect scaledDomain = planeMatrix.mapRect(*domain);
57 if (filterModes[i] != GrSamplerState::Filter::kNearest) {
58 // Inset by half a pixel for bilerp, after scaling to the size of the plane
59 scaledDomain.inset(0.5f, 0.5f);
60 }
61
62 fDomains[i] = GrTextureDomain(proxies[i].get(), scaledDomain,
63 GrTextureDomain::kClamp_Mode, GrTextureDomain::kClamp_Mode, i);
64 }
65
66 planeMatrix.postConcat(localMatrix);
Robert Phillips94ade752018-10-09 12:32:31 -040067 fSamplers[i].reset(std::move(proxies[i]),
68 GrSamplerState(GrSamplerState::WrapMode::kClamp, filterModes[i]));
Michael Ludwiga6a84002019-04-12 15:03:02 -040069 fSamplerTransforms[i] = planeMatrix;
Brian Salomon246bc3d2018-12-06 15:33:02 -050070 fSamplerCoordTransforms[i] =
71 GrCoordTransform(fSamplerTransforms[i], fSamplers[i].proxy());
Robert Phillips94ade752018-10-09 12:32:31 -040072 }
73
74 this->setTextureSamplerCnt(numPlanes);
75 for (int i = 0; i < numPlanes; ++i) {
76 this->addCoordTransform(&fSamplerCoordTransforms[i]);
77 }
78
79 memcpy(fYUVAIndices, yuvaIndices, sizeof(fYUVAIndices));
Ethan Nicholas7461a4a2017-12-21 14:18:01 -050080 }
81 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
82 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
83 bool onIsEqual(const GrFragmentProcessor&) const override;
Brian Salomonf7dcd762018-07-30 14:48:15 -040084 const TextureSampler& onTextureSampler(int) const override;
Ethan Nicholas7461a4a2017-12-21 14:18:01 -050085 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
Robert Phillips94ade752018-10-09 12:32:31 -040086
87 TextureSampler fSamplers[4];
88 SkMatrix44 fSamplerTransforms[4];
89 GrCoordTransform fSamplerCoordTransforms[4];
Michael Ludwiga6a84002019-04-12 15:03:02 -040090 GrTextureDomain fDomains[4];
Robert Phillips94ade752018-10-09 12:32:31 -040091 SkYUVAIndex fYUVAIndices[4];
Robert Phillipsb651aac2019-03-15 12:18:49 -040092 SkYUVColorSpace fYUVColorSpace;
Robert Phillips94ade752018-10-09 12:32:31 -040093
Ethan Nicholas7461a4a2017-12-21 14:18:01 -050094 typedef GrFragmentProcessor INHERITED;
95};
96#endif