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