• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrYUVtoRGBEffect_DEFINED
9 #define GrYUVtoRGBEffect_DEFINED
10 
11 #include "include/core/SkTypes.h"
12 
13 #include "src/gpu/GrCoordTransform.h"
14 #include "src/gpu/GrFragmentProcessor.h"
15 #include "src/gpu/effects/GrTextureDomain.h"
16 
17 #include "include/core/SkYUVAIndex.h"
18 
19 class GrYUVtoRGBEffect : public GrFragmentProcessor {
20 public:
21     // 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.
25     static std::unique_ptr<GrFragmentProcessor> Make(const sk_sp<GrTextureProxy> proxies[],
26                                                      const SkYUVAIndex indices[4],
27                                                      SkYUVColorSpace yuvColorSpace,
28                                                      GrSamplerState::Filter filterMode,
29                                                      const SkMatrix& localMatrix = SkMatrix::I(),
30                                                      const SkRect* domain = nullptr);
31 #ifdef SK_DEBUG
32     SkString dumpInfo() const override;
33 #endif
34 
yuvColorSpace()35     SkYUVColorSpace yuvColorSpace() const { return fYUVColorSpace; }
yuvaIndex(int i)36     const SkYUVAIndex& yuvaIndex(int i) const { return fYUVAIndices[i]; }
37 
38     GrYUVtoRGBEffect(const GrYUVtoRGBEffect& src);
39     std::unique_ptr<GrFragmentProcessor> clone() const override;
name()40     const char* name() const override { return "YUVtoRGBEffect"; }
41 
42 private:
GrYUVtoRGBEffect(const sk_sp<GrTextureProxy> proxies[],const SkSize scales[],const GrSamplerState::Filter filterModes[],int numPlanes,const SkYUVAIndex yuvaIndices[4],SkYUVColorSpace yuvColorSpace,const SkMatrix & localMatrix,const SkRect * domain)43     GrYUVtoRGBEffect(const sk_sp<GrTextureProxy> proxies[], const SkSize scales[],
44                      const GrSamplerState::Filter filterModes[], int numPlanes,
45                      const SkYUVAIndex yuvaIndices[4], SkYUVColorSpace yuvColorSpace,
46                      const SkMatrix& localMatrix, const SkRect* domain)
47             : INHERITED(kGrYUVtoRGBEffect_ClassID, kNone_OptimizationFlags)
48             , fDomains{GrTextureDomain::IgnoredDomain(), GrTextureDomain::IgnoredDomain(),
49                        GrTextureDomain::IgnoredDomain(), GrTextureDomain::IgnoredDomain()}
50             , fYUVColorSpace(yuvColorSpace) {
51         for (int i = 0; i < numPlanes; ++i) {
52             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.preConcat(localMatrix);
67             fSamplers[i].reset(std::move(proxies[i]),
68                                GrSamplerState(GrSamplerState::WrapMode::kClamp, filterModes[i]));
69             fSamplerTransforms[i] = planeMatrix;
70             fSamplerCoordTransforms[i] =
71                     GrCoordTransform(fSamplerTransforms[i], fSamplers[i].proxy());
72         }
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));
80     }
81     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
82     void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
83     bool onIsEqual(const GrFragmentProcessor&) const override;
84     const TextureSampler& onTextureSampler(int) const override;
85     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
86 
87     TextureSampler   fSamplers[4];
88     SkMatrix44       fSamplerTransforms[4];
89     GrCoordTransform fSamplerCoordTransforms[4];
90     GrTextureDomain  fDomains[4];
91     SkYUVAIndex      fYUVAIndices[4];
92     SkYUVColorSpace  fYUVColorSpace;
93 
94     typedef GrFragmentProcessor INHERITED;
95 };
96 #endif
97