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