1 /*
2  * Copyright 2015 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 #ifndef SkImageShader_DEFINED
9 #define SkImageShader_DEFINED
10 
11 #include "include/core/SkImage.h"
12 #include "src/shaders/SkBitmapProcShader.h"
13 #include "src/shaders/SkShaderBase.h"
14 
15 // private subclass of SkStageUpdater
16 class SkImageStageUpdater;
17 
18 class SkImageShader : public SkShaderBase {
19 public:
20     enum FilterEnum {   // first 4 entries match SkFilterQuality
21         kNone,
22         kLow,
23         kMedium,
24         kHigh,
25         // this is the special value for backward compatibility
26         kInheritFromPaint,
27         // this signals we should use the new SkFilterOptions
28         kUseFilterOptions,
29         // use fCubic and ignore FilterOptions
30         kUseCubicResampler,
31 
32         kLast = kUseCubicResampler,
33     };
34 
35     static sk_sp<SkShader> Make(sk_sp<SkImage>,
36                                 SkTileMode tmx,
37                                 SkTileMode tmy,
38                                 const SkMatrix* localMatrix,
39                                 FilterEnum,
40                                 bool clampAsIfUnpremul = false);
41 
42     static sk_sp<SkShader> Make(sk_sp<SkImage>,
43                                 SkTileMode tmx,
44                                 SkTileMode tmy,
45                                 const SkSamplingOptions&,
46                                 const SkMatrix* localMatrix);
47 
48     bool isOpaque() const override;
49 
50 #if SK_SUPPORT_GPU
51     std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
52 #endif
53 
54     static SkM44 CubicResamplerMatrix(float B, float C);
55 
56 private:
57     SK_FLATTENABLE_HOOKS(SkImageShader)
58 
59     SkImageShader(sk_sp<SkImage>,
60                   SkTileMode tmx,
61                   SkTileMode tmy,
62                   const SkMatrix* localMatrix,
63                   FilterEnum,
64                   bool clampAsIfUnpremul);
65     SkImageShader(sk_sp<SkImage>,
66                   SkTileMode tmx,
67                   SkTileMode tmy,
68                   const SkSamplingOptions&,
69                   const SkMatrix* localMatrix);
70 
71     void flatten(SkWriteBuffer&) const override;
72 #ifdef SK_ENABLE_LEGACY_SHADERCONTEXT
73     Context* onMakeContext(const ContextRec&, SkArenaAlloc* storage) const override;
74 #endif
75     SkImage* onIsAImage(SkMatrix*, SkTileMode*) const override;
76 
77     bool onAppendStages(const SkStageRec&) const override;
78     SkStageUpdater* onAppendUpdatableStages(const SkStageRec&) const override;
79 
80     skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint,
81                           const SkMatrixProvider&, const SkMatrix* localM,
82                           SkFilterQuality quality, const SkColorInfo& dst,
83                           skvm::Uniforms* uniforms, SkArenaAlloc*) const override;
84 
85     bool doStages(const SkStageRec&, SkImageStageUpdater* = nullptr) const;
86 
resolveFiltering(SkFilterQuality paintQuality)87     SkFilterQuality resolveFiltering(SkFilterQuality paintQuality) const {
88         switch (fFilterEnum) {
89             case kUseCubicResampler: return kHigh_SkFilterQuality;   // TODO: handle explicitly
90             case kUseFilterOptions:  return kNone_SkFilterQuality;   // TODO: handle explicitly
91             case kInheritFromPaint:  return paintQuality;
92             default: break;
93         }
94         return (SkFilterQuality)fFilterEnum;
95     }
96 
97     sk_sp<SkImage>   fImage;
98     const SkTileMode fTileModeX;
99     const SkTileMode fTileModeY;
100     const FilterEnum fFilterEnum;
101     const bool       fClampAsIfUnpremul;
102 
103     // only use this if fFilterEnum == kUseFilterOptions
104     SkFilterOptions  fFilterOptions;
105     // only use this if fFilterEnum == kUseCubicResampler or kHigh
106     SkCubicResampler fCubic = {1/3.0f, 1/3.0f};  // Default to Mitchell-Netravali.
107 
108     friend class SkShaderBase;
109     using INHERITED = SkShaderBase;
110 };
111 
112 #endif
113