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 "src/gpu/GrImageTextureMaker.h"
9
10 #include "src/gpu/GrColorSpaceXform.h"
11 #include "src/gpu/SkGr.h"
12 #include "src/gpu/effects/GrYUVtoRGBEffect.h"
13 #include "src/image/SkImage_GpuYUVA.h"
14 #include "src/image/SkImage_Lazy.h"
15
GrImageTextureMaker(GrRecordingContext * context,const SkImage * client,SkImage::CachingHint chint,bool useDecal)16 GrImageTextureMaker::GrImageTextureMaker(GrRecordingContext* context, const SkImage* client,
17 SkImage::CachingHint chint, bool useDecal)
18 : INHERITED(context, client->width(), client->height(), client->imageInfo().colorInfo(),
19 useDecal)
20 , fImage(static_cast<const SkImage_Lazy*>(client))
21 , fCachingHint(chint) {
22 SkASSERT(client->isLazyGenerated());
23 GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(),
24 SkIRect::MakeWH(this->width(), this->height()));
25 }
26
refOriginalTextureProxy(bool willBeMipped,AllowedTexGenType onlyIfFast)27 sk_sp<GrTextureProxy> GrImageTextureMaker::refOriginalTextureProxy(bool willBeMipped,
28 AllowedTexGenType onlyIfFast) {
29 return fImage->lockTextureProxy(this->context(), fOriginalKey, fCachingHint,
30 willBeMipped, onlyIfFast);
31 }
32
makeCopyKey(const CopyParams & stretch,GrUniqueKey * paramsCopyKey)33 void GrImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) {
34 if (fOriginalKey.isValid() && SkImage::kAllow_CachingHint == fCachingHint) {
35 GrUniqueKey cacheKey;
36 fImage->makeCacheKeyFromOrigKey(fOriginalKey, &cacheKey);
37 MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey);
38 }
39 }
40
41
42 /////////////////////////////////////////////////////////////////////////////////////////////////
43
GrYUVAImageTextureMaker(GrContext * context,const SkImage * client,bool useDecal)44 GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrContext* context, const SkImage* client,
45 bool useDecal)
46 : INHERITED(context, client->width(), client->height(), client->imageInfo().colorInfo(),
47 useDecal)
48 , fImage(static_cast<const SkImage_GpuYUVA*>(client)) {
49 SkASSERT(as_IB(client)->isYUVA());
50 GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(),
51 SkIRect::MakeWH(this->width(), this->height()));
52 }
53
refOriginalTextureProxy(bool willBeMipped,AllowedTexGenType onlyIfFast)54 sk_sp<GrTextureProxy> GrYUVAImageTextureMaker::refOriginalTextureProxy(bool willBeMipped,
55 AllowedTexGenType onlyIfFast) {
56 if (AllowedTexGenType::kCheap == onlyIfFast) {
57 return nullptr;
58 }
59
60 if (willBeMipped) {
61 return fImage->asMippedTextureProxyRef(this->context());
62 } else {
63 return fImage->asTextureProxyRef(this->context());
64 }
65 }
66
makeCopyKey(const CopyParams & stretch,GrUniqueKey * paramsCopyKey)67 void GrYUVAImageTextureMaker::makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) {
68 // TODO: Do we ever want to disable caching?
69 if (fOriginalKey.isValid()) {
70 GrUniqueKey cacheKey;
71 static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
72 GrUniqueKey::Builder builder(&cacheKey, fOriginalKey, kDomain, 0, "Image");
73 MakeCopyKeyFromOrigKey(cacheKey, stretch, paramsCopyKey);
74 }
75 }
76
createFragmentProcessor(const SkMatrix & textureMatrix,const SkRect & constraintRect,FilterConstraint filterConstraint,bool coordsLimitedToConstraintRect,const GrSamplerState::Filter * filterOrNullForBicubic)77 std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProcessor(
78 const SkMatrix& textureMatrix,
79 const SkRect& constraintRect,
80 FilterConstraint filterConstraint,
81 bool coordsLimitedToConstraintRect,
82 const GrSamplerState::Filter* filterOrNullForBicubic) {
83
84 // Check simple cases to see if we need to fall back to flattening the image (or whether it's
85 // already been flattened.)
86 if (!filterOrNullForBicubic || this->domainNeedsDecal() || fImage->fRGBProxy) {
87 return this->INHERITED::createFragmentProcessor(textureMatrix, constraintRect,
88 filterConstraint,
89 coordsLimitedToConstraintRect,
90 filterOrNullForBicubic);
91 }
92
93 // Check to see if the client has given us pre-mipped textures or we can generate them
94 // If not, fall back to bilerp. Also fall back to bilerp when a domain is requested
95 GrSamplerState::Filter filter = *filterOrNullForBicubic;
96 if (GrSamplerState::Filter::kMipMap == filter &&
97 (filterConstraint == GrTextureProducer::kYes_FilterConstraint ||
98 !fImage->setupMipmapsForPlanes(this->context()))) {
99 filter = GrSamplerState::Filter::kBilerp;
100 }
101
102 // Cannot rely on GrTextureProducer's domain infrastructure since we need to calculate domain's
103 // per plane, which may be different, so respect the filterConstraint without any additional
104 // analysis.
105 const SkRect* domain = nullptr;
106 if (filterConstraint == GrTextureProducer::kYes_FilterConstraint) {
107 domain = &constraintRect;
108 }
109
110 auto fp = GrYUVtoRGBEffect::Make(fImage->fProxies, fImage->fYUVAIndices,
111 fImage->fYUVColorSpace, filter, textureMatrix, domain);
112 if (fImage->fFromColorSpace) {
113 fp = GrColorSpaceXformEffect::Make(std::move(fp), fImage->fFromColorSpace.get(),
114 fImage->alphaType(), fImage->colorSpace());
115 }
116 return fp;
117 }
118