• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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