1 /*
2 * Copyright 2017 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 SkGr_DEFINED
9 #define SkGr_DEFINED
10
11 #include "include/core/SkBlendMode.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkColorPriv.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkSamplingOptions.h"
16 #include "include/core/SkTileMode.h"
17 #include "include/core/SkTypes.h"
18 #include "include/gpu/GpuTypes.h"
19 #include "include/private/SkColorData.h"
20 #include "src/gpu/Blend.h"
21 #include "src/gpu/ganesh/GrCaps.h"
22 #include "src/gpu/SkBackingFit.h"
23 #include "src/gpu/ganesh/GrColor.h"
24 #include "src/gpu/ganesh/GrSamplerState.h"
25
26 #include <cstdint>
27 #include <memory>
28 #include <string_view>
29 #include <tuple>
30
31 class GrCaps;
32 class GrColorInfo;
33 class GrFragmentProcessor;
34 class GrPaint;
35 class GrRecordingContext;
36 class GrSurfaceProxy;
37 class GrSurfaceProxyView;
38 class SkBitmap;
39 class SkBlender;
40 class SkIDChangeListener;
41 class SkMatrix;
42 class SkPaint;
43 class SkSurfaceProps;
44 enum class GrColorType;
45 enum GrSurfaceOrigin : int;
46 struct SkIRect;
47
48 namespace skgpu { class UniqueKey; }
49
50 ////////////////////////////////////////////////////////////////////////////////
51 // Color type conversions
52
SkColorToPremulGrColor(SkColor c)53 static inline GrColor SkColorToPremulGrColor(SkColor c) {
54 SkPMColor pm = SkPreMultiplyColor(c);
55 unsigned r = SkGetPackedR32(pm);
56 unsigned g = SkGetPackedG32(pm);
57 unsigned b = SkGetPackedB32(pm);
58 unsigned a = SkGetPackedA32(pm);
59 return GrColorPackRGBA(r, g, b, a);
60 }
61
SkColorToUnpremulGrColor(SkColor c)62 static inline GrColor SkColorToUnpremulGrColor(SkColor c) {
63 unsigned r = SkColorGetR(c);
64 unsigned g = SkColorGetG(c);
65 unsigned b = SkColorGetB(c);
66 unsigned a = SkColorGetA(c);
67 return GrColorPackRGBA(r, g, b, a);
68 }
69
70 /** Similar, but using SkPMColor4f. */
71 SkPMColor4f SkColorToPMColor4f(SkColor, const GrColorInfo&);
72
73 /** Converts an SkColor4f to the destination color space. */
74 SkColor4f SkColor4fPrepForDst(SkColor4f, const GrColorInfo&);
75
76 ////////////////////////////////////////////////////////////////////////////////
77 // SkTileMode conversion
78
SkTileModeToWrapMode(SkTileMode tileMode)79 static constexpr GrSamplerState::WrapMode SkTileModeToWrapMode(SkTileMode tileMode) {
80 switch (tileMode) {
81 case SkTileMode::kClamp: return GrSamplerState::WrapMode::kClamp;
82 case SkTileMode::kDecal: return GrSamplerState::WrapMode::kClampToBorder;
83 case SkTileMode::kMirror: return GrSamplerState::WrapMode::kMirrorRepeat;
84 case SkTileMode::kRepeat: return GrSamplerState::WrapMode::kRepeat;
85 }
86 SkUNREACHABLE;
87 }
88
89 ////////////////////////////////////////////////////////////////////////////////
90 // Paint conversion
91
92 /** Converts an SkPaint to a GrPaint for a given GrRecordingContext. The matrix is required in order
93 to convert the SkShader (if any) on the SkPaint. The primitive itself has no color. */
94 bool SkPaintToGrPaint(GrRecordingContext*,
95 const GrColorInfo& dstColorInfo,
96 const SkPaint& skPaint,
97 const SkMatrix& ctm,
98 const SkSurfaceProps& surfaceProps,
99 GrPaint* grPaint);
100
101 /** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor, if not null.
102 If null then it is assumed that the geometry processor is implementing a shader replacement.
103 The processor should expect an unpremul input color and produce a premultiplied output color. */
104 bool SkPaintToGrPaintReplaceShader(GrRecordingContext*,
105 const GrColorInfo& dstColorInfo,
106 const SkPaint& skPaint,
107 const SkMatrix& ctm,
108 std::unique_ptr<GrFragmentProcessor> shaderFP,
109 const SkSurfaceProps& surfaceProps,
110 GrPaint* grPaint);
111
112 /** Blends the SkPaint's shader (or color if no shader) with the color which specified via a
113 GrOp's GrPrimitiveProcesssor. */
114 bool SkPaintToGrPaintWithBlend(GrRecordingContext* context,
115 const GrColorInfo& dstColorInfo,
116 const SkPaint& skPaint,
117 const SkMatrix& ctm,
118 SkBlender* primColorBlender,
119 const SkSurfaceProps& surfaceProps,
120 GrPaint* grPaint);
121
122 ////////////////////////////////////////////////////////////////////////////////
123 // Misc Sk to Gr type conversions
124
125 static_assert((int)skgpu::BlendCoeff::kZero == (int)SkBlendModeCoeff::kZero);
126 static_assert((int)skgpu::BlendCoeff::kOne == (int)SkBlendModeCoeff::kOne);
127 static_assert((int)skgpu::BlendCoeff::kSC == (int)SkBlendModeCoeff::kSC);
128 static_assert((int)skgpu::BlendCoeff::kISC == (int)SkBlendModeCoeff::kISC);
129 static_assert((int)skgpu::BlendCoeff::kDC == (int)SkBlendModeCoeff::kDC);
130 static_assert((int)skgpu::BlendCoeff::kIDC == (int)SkBlendModeCoeff::kIDC);
131 static_assert((int)skgpu::BlendCoeff::kSA == (int)SkBlendModeCoeff::kSA);
132 static_assert((int)skgpu::BlendCoeff::kISA == (int)SkBlendModeCoeff::kISA);
133 static_assert((int)skgpu::BlendCoeff::kDA == (int)SkBlendModeCoeff::kDA);
134 static_assert((int)skgpu::BlendCoeff::kIDA == (int)SkBlendModeCoeff::kIDA);
135 static_assert((int)SkBlendModeCoeff::kCoeffCount == 10);
136
137 ////////////////////////////////////////////////////////////////////////////////
138 // Texture management
139
140 /**
141 * Policies for how to create textures for SkImages (and SkBitmaps).
142 */
143 enum class GrImageTexGenPolicy : int {
144 // Choose the cheapest way to generate the texture. Use GrResourceCache if appropriate.
145 kDraw,
146 // Always make a new texture that is uncached and unbudgeted.
147 kNew_Uncached_Unbudgeted,
148 // Always make a new texture that is uncached and budgeted.
149 kNew_Uncached_Budgeted
150 };
151
152 /**
153 * Creates a new texture with mipmap levels and copies the baseProxy into the base layer.
154 */
155 sk_sp<GrSurfaceProxy> GrCopyBaseMipMapToTextureProxy(GrRecordingContext*,
156 sk_sp<GrSurfaceProxy> baseProxy,
157 GrSurfaceOrigin origin,
158 std::string_view label,
159 skgpu::Budgeted = skgpu::Budgeted::kYes);
160 /**
161 * Same as GrCopyBaseMipMapToTextureProxy but takes the src as a view and returns a view with same
162 * origin and swizzle as the src view.
163 */
164 GrSurfaceProxyView GrCopyBaseMipMapToView(GrRecordingContext*,
165 GrSurfaceProxyView,
166 skgpu::Budgeted = skgpu::Budgeted::kYes);
167
168 /*
169 * Create a texture proxy from the provided bitmap and add it to the texture cache using the key
170 * also extracted from the bitmap. If skgpu::Mipmapped is kYes a non-mipmapped result may be
171 * returned if mipmapping isn't supported or for a 1x1 bitmap. If skgpu::Mipmapped is kNo it
172 * indicates mipmaps aren't required but a previously created mipmapped texture may still be
173 * returned. A color type is returned as color type conversion may be performed if there isn't a
174 * texture format equivalent of the bitmap's color type.
175 */
176 std::tuple<GrSurfaceProxyView, GrColorType> GrMakeCachedBitmapProxyView(
177 GrRecordingContext*,
178 const SkBitmap&,
179 std::string_view label,
180 skgpu::Mipmapped = skgpu::Mipmapped::kNo);
181
182 /**
183 * Like above but always uploads the bitmap and never inserts into the cache. Unlike above, the
184 * texture may be approx or scratch and budgeted or not.
185 */
186 std::tuple<GrSurfaceProxyView, GrColorType> GrMakeUncachedBitmapProxyView(
187 GrRecordingContext*,
188 const SkBitmap&,
189 skgpu::Mipmapped = skgpu::Mipmapped::kNo,
190 SkBackingFit = SkBackingFit::kExact,
191 skgpu::Budgeted = skgpu::Budgeted::kYes);
192
193 /**
194 * Our key includes the offset, width, and height so that bitmaps created by extractSubset()
195 * are unique.
196 *
197 * The imageID is in the shared namespace (see SkNextID::ImageID())
198 * - SkBitmap/SkPixelRef
199 * - SkImage
200 * - SkImageGenerator
201 */
202 void GrMakeKeyFromImageID(skgpu::UniqueKey* key, uint32_t imageID, const SkIRect& imageBounds);
203
204 /**
205 * Makes a SkIDChangeListener from a skgpu::UniqueKey. The key will be invalidated in the resource
206 * cache if the ID becomes invalid. This also modifies the key so that it will cause the listener
207 * to be deregistered if the key is destroyed (to prevent unbounded listener growth when resources
208 * are purged before listeners trigger).
209 */
210 sk_sp<SkIDChangeListener> GrMakeUniqueKeyInvalidationListener(skgpu::UniqueKey*,
211 uint32_t contextID);
212
GrValidCubicResampler(SkCubicResampler cubic)213 static inline bool GrValidCubicResampler(SkCubicResampler cubic) {
214 return cubic.B >= 0 && cubic.C >= 0;
215 }
216
217 #ifdef SKIA_OHOS
218 #ifndef SK_IGNORE_GPU_DITHER
219 std::unique_ptr<GrFragmentProcessor> make_dither_effect(GrRecordingContext* rContext,
220 std::unique_ptr<GrFragmentProcessor> inputFP, float range, const GrCaps* caps);
221 #endif
222 #endif // SKIA_OHOS
223
224 #endif
225