1 /* 2 * Copyright 2016 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 #include "GrColorSpaceXform.h" 9 #include "GrImageTextureMaker.h" 10 #include "SkGr.h" 11 #include "SkImage_GpuYUVA.h" 12 #include "SkImage_Lazy.h" 13 #include "effects/GrYUVtoRGBEffect.h" 14 15 GrImageTextureMaker::GrImageTextureMaker(GrRecordingContext* context, const SkImage* client, 16 SkImage::CachingHint chint, bool useDecal) 17 : INHERITED(context, client->width(), client->height(), client->isAlphaOnly(), useDecal) 18 , fImage(static_cast<const SkImage_Lazy*>(client)) 19 , fCachingHint(chint) { 20 SkASSERT(client->isLazyGenerated()); 21 GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(), 22 SkIRect::MakeWH(this->width(), this->height())); 23 } 24 25 sk_sp<GrTextureProxy> GrImageTextureMaker::refOriginalTextureProxy(bool willBeMipped, 26 AllowedTexGenType onlyIfFast) { 27 return fImage->lockTextureProxy(this->context(), fOriginalKey, fCachingHint, 28 willBeMipped, onlyIfFast); 29 } 30 31 void GrImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) { 32 if (fOriginalKey.isValid() && SkImage::kAllow_CachingHint == fCachingHint) { 33 GrUniqueKey cacheKey; 34 fImage->makeCacheKeyFromOrigKey(fOriginalKey, &cacheKey); 35 MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey); 36 } 37 } 38 39 SkAlphaType GrImageTextureMaker::alphaType() const { 40 return fImage->alphaType(); 41 } 42 SkColorSpace* GrImageTextureMaker::colorSpace() const { 43 return fImage->colorSpace(); 44 } 45 46 ///////////////////////////////////////////////////////////////////////////////////////////////// 47 48 GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrContext* context, const SkImage* client, 49 bool useDecal) 50 : INHERITED(context, client->width(), client->height(), client->isAlphaOnly(), useDecal) 51 , fImage(static_cast<const SkImage_GpuYUVA*>(client)) { 52 SkASSERT(as_IB(client)->isYUVA()); 53 GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(), 54 SkIRect::MakeWH(this->width(), this->height())); 55 } 56 57 sk_sp<GrTextureProxy> GrYUVAImageTextureMaker::refOriginalTextureProxy(bool willBeMipped, 58 AllowedTexGenType onlyIfFast) { 59 if (AllowedTexGenType::kCheap == onlyIfFast) { 60 return nullptr; 61 } 62 63 if (willBeMipped) { 64 return fImage->asMippedTextureProxyRef(this->context()); 65 } else { 66 return fImage->asTextureProxyRef(this->context()); 67 } 68 } 69 70 void GrYUVAImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) { 71 // TODO: Do we ever want to disable caching? 72 if (fOriginalKey.isValid()) { 73 GrUniqueKey cacheKey; 74 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); 75 GrUniqueKey::Builder builder(&cacheKey, fOriginalKey, kDomain, 0, "Image"); 76 MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey); 77 } 78 } 79 80 SkAlphaType GrYUVAImageTextureMaker::alphaType() const { 81 return fImage->alphaType(); 82 } 83 SkColorSpace* GrYUVAImageTextureMaker::colorSpace() const { 84 return fImage->colorSpace(); 85 } 86 87 std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProcessor( 88 const SkMatrix& textureMatrix, 89 const SkRect& constraintRect, 90 FilterConstraint filterConstraint, 91 bool coordsLimitedToConstraintRect, 92 const GrSamplerState::Filter* filterOrNullForBicubic) { 93 94 // Check simple cases to see if we need to fall back to flattening the image 95 // TODO: See if we can relax this -- for example, if filterConstraint 96 // is kYes_FilterConstraint we still may not need a TextureDomain 97 // in some cases. Or allow YUVtoRGBEffect to take a wrap mode to 98 // handle ClampToBorder when a decal is needed. 99 if (!textureMatrix.isIdentity() || kNo_FilterConstraint != filterConstraint || 100 !coordsLimitedToConstraintRect || !filterOrNullForBicubic || 101 this->domainNeedsDecal()) { 102 return this->INHERITED::createFragmentProcessor(textureMatrix, constraintRect, 103 filterConstraint, 104 coordsLimitedToConstraintRect, 105 filterOrNullForBicubic); 106 } 107 108 // Check to see if the client has given us pre-mipped textures or we can generate them 109 // If not, fall back to bilerp 110 GrSamplerState::Filter filter = *filterOrNullForBicubic; 111 if (GrSamplerState::Filter::kMipMap == filter && 112 !fImage->setupMipmapsForPlanes(this->context())) { 113 filter = GrSamplerState::Filter::kBilerp; 114 } 115 116 auto fp = GrYUVtoRGBEffect::Make(fImage->fProxies, fImage->fYUVAIndices, 117 fImage->fYUVColorSpace, filter); 118 if (fImage->fTargetColorSpace) { 119 fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fColorSpace.get(), 120 fImage->alphaType(), fImage->fTargetColorSpace.get()); 121 } 122 return fp; 123 } 124