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