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