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