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
16class SkImageStageUpdater;
17
18class SkImageShader : public SkShaderBase {
19public:
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 SkFilterOptions&,
46 const SkMatrix* localMatrix);
47
48 static sk_sp<SkShader> Make(sk_sp<SkImage>,
49 SkTileMode tmx,
50 SkTileMode tmy,
51 SkImage::CubicResampler,
52 const SkMatrix* localMatrix);
53
54 bool isOpaque() const override;
55
56#if SK_SUPPORT_GPU
57 std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(const GrFPArgs&) const override;
58#endif
59
60 static SkM44 CubicResamplerMatrix(float B, float C);
61
62private:
63 SK_FLATTENABLE_HOOKS(SkImageShader)
64
65 SkImageShader(sk_sp<SkImage>,
66 SkTileMode tmx,
67 SkTileMode tmy,
68 const SkMatrix* localMatrix,
69 FilterEnum,
70 bool clampAsIfUnpremul);
71 SkImageShader(sk_sp<SkImage>,
72 SkTileMode tmx,
73 SkTileMode tmy,
74 const SkFilterOptions&,
75 const SkMatrix* localMatrix);
76 SkImageShader(sk_sp<SkImage>,
77 SkTileMode tmx,
78 SkTileMode tmy,
79 SkImage::CubicResampler,
80 const SkMatrix* localMatrix);
81
82 void flatten(SkWriteBuffer&) const override;
83#ifdef SK_ENABLE_LEGACY_SHADERCONTEXT
84 Context* onMakeContext(const ContextRec&, SkArenaAlloc* storage) const override;
85#endif
86 SkImage* onIsAImage(SkMatrix*, SkTileMode*) const override;
87
88 bool onAppendStages(const SkStageRec&) const override;
89 SkStageUpdater* onAppendUpdatableStages(const SkStageRec&) const override;
90
91 skvm::Color onProgram(skvm::Builder*, skvm::Coord device, skvm::Coord local, skvm::Color paint,
92 const SkMatrixProvider&, const SkMatrix* localM,
93 SkFilterQuality quality, const SkColorInfo& dst,
94 skvm::Uniforms* uniforms, SkArenaAlloc*) const override;
95
96 bool doStages(const SkStageRec&, SkImageStageUpdater* = nullptr) const;
97
98 SkFilterQuality resolveFiltering(SkFilterQuality paintQuality) const {
99 switch (fFilterEnum) {
100 case kUseCubicResampler: return kHigh_SkFilterQuality; // TODO: handle explicitly
101 case kUseFilterOptions: return kNone_SkFilterQuality; // TODO: handle explicitly
102 case kInheritFromPaint: return paintQuality;
103 default: break;
104 }
105 return (SkFilterQuality)fFilterEnum;
106 }
107
108 sk_sp<SkImage> fImage;
109 const SkTileMode fTileModeX;
110 const SkTileMode fTileModeY;
111 const FilterEnum fFilterEnum;
112 const bool fClampAsIfUnpremul;
113
114 // only use this if fFilterEnum == kUseFilterOptions
115 SkFilterOptions fFilterOptions;
116 // only use this if fFilterEnum == kUseCubicResampler or kHigh
117 SkImage::CubicResampler fCubic = {1/3.0f, 1/3.0f}; // Default to Mitchell-Netravali.
118
119 friend class SkShaderBase;
120 typedef SkShaderBase INHERITED;
121};
122
123#endif
124