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 /** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. The processor
93 should expect an unpremul input color and produce a premultiplied output color. There is
94 no primitive color. */
95 bool SkPaintToGrPaintReplaceShader(GrRecordingContext*,
96 const GrColorInfo& dstColorInfo,
97 const SkPaint& skPaint,
98 const SkMatrixProvider& matrixProvider,
99 std::unique_ptr<GrFragmentProcessor> shaderFP,
100 GrPaint* grPaint);
101
102 /** Blends the SkPaint's shader (or color if no shader) with the color which specified via a
103 GrOp's GrPrimitiveProcesssor. */
104 bool SkPaintToGrPaintWithBlend(GrRecordingContext*,
105 const GrColorInfo& dstColorInfo,
106 const SkPaint& skPaint,
107 const SkMatrixProvider& matrixProvider,
108 SkBlendMode primColorMode,
109 GrPaint* grPaint);
110
111 /** This is used when there is a primitive color, but the shader should be ignored. Currently,
112 the expectation is that the primitive color will be premultiplied, though it really should be
113 unpremultiplied so that interpolation is done in unpremul space. The paint's alpha will be
114 applied to the primitive color after interpolation. */
SkPaintToGrPaintWithPrimitiveColor(GrRecordingContext * context,const GrColorInfo & dstColorInfo,const SkPaint & skPaint,const SkMatrixProvider & matrixProvider,GrPaint * grPaint)115 inline bool SkPaintToGrPaintWithPrimitiveColor(GrRecordingContext* context,
116 const GrColorInfo& dstColorInfo,
117 const SkPaint& skPaint,
118 const SkMatrixProvider& matrixProvider,
119 GrPaint* grPaint) {
120 return SkPaintToGrPaintWithBlend(context, dstColorInfo, skPaint, matrixProvider,
121 SkBlendMode::kDst, grPaint);
122 }
123
124 ////////////////////////////////////////////////////////////////////////////////
125 // Misc Sk to Gr type conversions
126
127 static_assert((int)kZero_GrBlendCoeff == (int)SkBlendModeCoeff::kZero);
128 static_assert((int)kOne_GrBlendCoeff == (int)SkBlendModeCoeff::kOne);
129 static_assert((int)kSC_GrBlendCoeff == (int)SkBlendModeCoeff::kSC);
130 static_assert((int)kISC_GrBlendCoeff == (int)SkBlendModeCoeff::kISC);
131 static_assert((int)kDC_GrBlendCoeff == (int)SkBlendModeCoeff::kDC);
132 static_assert((int)kIDC_GrBlendCoeff == (int)SkBlendModeCoeff::kIDC);
133 static_assert((int)kSA_GrBlendCoeff == (int)SkBlendModeCoeff::kSA);
134 static_assert((int)kISA_GrBlendCoeff == (int)SkBlendModeCoeff::kISA);
135 static_assert((int)kDA_GrBlendCoeff == (int)SkBlendModeCoeff::kDA);
136 static_assert((int)kIDA_GrBlendCoeff == (int)SkBlendModeCoeff::kIDA);
137 // static_assert(SkXfermode::kCoeffCount == 10);
138
139 ////////////////////////////////////////////////////////////////////////////////
140 // Texture management
141
142 /**
143 * Policies for how to create textures for SkImages (and SkBitmaps).
144 */
145 enum class GrImageTexGenPolicy : int {
146 // Choose the cheapest way to generate the texture. Use GrResourceCache if appropriate.
147 kDraw,
148 // Always make a new texture that is uncached and unbudgeted.
149 kNew_Uncached_Unbudgeted,
150 // Always make a new texture that is uncached and budgeted.
151 kNew_Uncached_Budgeted
152 };
153
154 /**
155 * Creates a new texture with mipmap levels and copies the baseProxy into the base layer.
156 */
157 sk_sp<GrSurfaceProxy> GrCopyBaseMipMapToTextureProxy(GrRecordingContext*,
158 sk_sp<GrSurfaceProxy> baseProxy,
159 GrSurfaceOrigin origin,
160 SkBudgeted = SkBudgeted::kYes);
161 /**
162 * Same as GrCopyBaseMipMapToTextureProxy but takes the src as a view and returns a view with same
163 * origin and swizzle as the src view.
164 */
165 GrSurfaceProxyView GrCopyBaseMipMapToView(GrRecordingContext*,
166 GrSurfaceProxyView,
167 SkBudgeted = SkBudgeted::kYes);
168
169 /*
170 * Create a texture proxy from the provided bitmap and add it to the texture cache using the key
171 * also extracted from the bitmap. If GrMipmapped is kYes a non-mipmapped result may be returned
172 * if mipmapping isn't supported or for a 1x1 bitmap. If GrMipmapped is kNo it indicates mipmaps
173 * aren't required but a previously created mipmapped texture may still be returned. A color type is
174 * returned as color type conversion may be performed if there isn't a texture format equivalent of
175 * the bitmap's color type.
176 */
177 std::tuple<GrSurfaceProxyView, GrColorType>
178 GrMakeCachedBitmapProxyView(GrRecordingContext*,
179 const SkBitmap&,
180 GrMipmapped = GrMipmapped::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>
187 GrMakeUncachedBitmapProxyView(GrRecordingContext*,
188 const SkBitmap&,
189 GrMipmapped = GrMipmapped::kNo,
190 SkBackingFit = SkBackingFit::kExact,
191 SkBudgeted = SkBudgeted::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(GrUniqueKey* key, uint32_t imageID, const SkIRect& imageBounds);
203
204 /**
205 * Makes a SkIDChangeListener from a GrUniqueKey. 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(GrUniqueKey*, uint32_t contextID);
211
GrValidCubicResampler(SkCubicResampler cubic)212 static inline bool GrValidCubicResampler(SkCubicResampler cubic) {
213 return cubic.B >= 0 && cubic.C >= 0;
214 }
215
216 #endif
217