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