• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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