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 "GrBlend.h" 12 #include "GrColor.h" 13 #include "GrSamplerParams.h" 14 #include "GrTypes.h" 15 #include "SkCanvas.h" 16 #include "SkColor.h" 17 #include "SkColorPriv.h" 18 #include "SkFilterQuality.h" 19 #include "SkImageInfo.h" 20 #include "SkMatrix.h" 21 #include "SkPM4f.h" 22 #include "SkXfermodePriv.h" 23 24 class GrCaps; 25 class GrColorSpaceXform; 26 class GrContext; 27 class GrRenderTargetContext; 28 class GrFragmentProcessor; 29 class GrPaint; 30 class GrResourceProvider; 31 class GrTextureProxy; 32 class GrUniqueKey; 33 class SkBitmap; 34 class SkData; 35 class SkPaint; 36 class SkPixelRef; 37 class SkPixmap; 38 struct SkIRect; 39 40 //////////////////////////////////////////////////////////////////////////////// 41 // Color type conversions 42 43 static inline GrColor SkColorToPremulGrColor(SkColor c) { 44 SkPMColor pm = SkPreMultiplyColor(c); 45 unsigned r = SkGetPackedR32(pm); 46 unsigned g = SkGetPackedG32(pm); 47 unsigned b = SkGetPackedB32(pm); 48 unsigned a = SkGetPackedA32(pm); 49 return GrColorPackRGBA(r, g, b, a); 50 } 51 52 static inline GrColor SkColorToUnpremulGrColor(SkColor c) { 53 unsigned r = SkColorGetR(c); 54 unsigned g = SkColorGetG(c); 55 unsigned b = SkColorGetB(c); 56 unsigned a = SkColorGetA(c); 57 return GrColorPackRGBA(r, g, b, a); 58 } 59 60 /** Transform an SkColor (sRGB bytes) to GrColor4f for the specified color space. */ 61 GrColor4f SkColorToPremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace); 62 GrColor4f SkColorToUnpremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace); 63 64 /** 65 * As above, but with a caller-supplied color space xform object. Faster for the cases where we 66 * have that cached. 67 */ 68 GrColor4f SkColorToPremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace, 69 GrColorSpaceXform* gamutXform); 70 GrColor4f SkColorToUnpremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace, 71 GrColorSpaceXform* gamutXform); 72 73 /** Replicates the SkColor's alpha to all four channels of the GrColor. */ 74 static inline GrColor SkColorAlphaToGrColor(SkColor c) { 75 U8CPU a = SkColorGetA(c); 76 return GrColorPackRGBA(a, a, a, a); 77 } 78 79 ////////////////////////////////////////////////////////////////////////////// 80 81 static inline SkPM4f GrColor4fToSkPM4f(const GrColor4f& c) { 82 SkPM4f pm4f; 83 pm4f.fVec[SkPM4f::R] = c.fRGBA[0]; 84 pm4f.fVec[SkPM4f::G] = c.fRGBA[1]; 85 pm4f.fVec[SkPM4f::B] = c.fRGBA[2]; 86 pm4f.fVec[SkPM4f::A] = c.fRGBA[3]; 87 return pm4f; 88 } 89 90 static inline GrColor4f SkPM4fToGrColor4f(const SkPM4f& c) { 91 return GrColor4f{c.r(), c.g(), c.b(), c.a()}; 92 } 93 94 //////////////////////////////////////////////////////////////////////////////// 95 // Paint conversion 96 97 /** Converts an SkPaint to a GrPaint for a given GrContext. The matrix is required in order 98 to convert the SkShader (if any) on the SkPaint. The primitive itself has no color. */ 99 bool SkPaintToGrPaint(GrContext*, 100 GrRenderTargetContext*, 101 const SkPaint& skPaint, 102 const SkMatrix& viewM, 103 GrPaint* grPaint); 104 105 /** Same as above but ignores the SkShader (if any) on skPaint. */ 106 bool SkPaintToGrPaintNoShader(GrContext* context, 107 GrRenderTargetContext* rtc, 108 const SkPaint& skPaint, 109 GrPaint* grPaint); 110 111 /** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. The processor 112 should expect an unpremul input color and produce a premultiplied output color. There is 113 no primitive color. */ 114 bool SkPaintToGrPaintReplaceShader(GrContext*, 115 GrRenderTargetContext*, 116 const SkPaint& skPaint, 117 sk_sp<GrFragmentProcessor> shaderFP, 118 GrPaint* grPaint); 119 120 /** Blends the SkPaint's shader (or color if no shader) with the color which specified via a 121 GrOp's GrPrimitiveProcesssor. Currently there is a bool param to indicate whether the 122 primitive color is the dst or src color to the blend in order to work around differences between 123 drawVertices and drawAtlas. */ 124 bool SkPaintToGrPaintWithXfermode(GrContext* context, 125 GrRenderTargetContext* rtc, 126 const SkPaint& skPaint, 127 const SkMatrix& viewM, 128 SkBlendMode primColorMode, 129 bool primitiveIsSrc, 130 GrPaint* grPaint); 131 132 /** This is used when there is a primitive color, but the shader should be ignored. Currently, 133 the expectation is that the primitive color will be premultiplied, though it really should be 134 unpremultiplied so that interpolation is done in unpremul space. The paint's alpha will be 135 applied to the primitive color after interpolation. */ 136 inline bool SkPaintToGrPaintWithPrimitiveColor(GrContext* context, GrRenderTargetContext* rtc, 137 const SkPaint& skPaint, GrPaint* grPaint) { 138 return SkPaintToGrPaintWithXfermode(context, rtc, skPaint, SkMatrix::I(), SkBlendMode::kDst, 139 false, grPaint); 140 } 141 142 /** This is used when there may or may not be a shader, and the caller wants to plugin a texture 143 lookup. If there is a shader, then its output will only be used if the texture is alpha8. */ 144 bool SkPaintToGrPaintWithTexture(GrContext* context, 145 GrRenderTargetContext* rtc, 146 const SkPaint& paint, 147 const SkMatrix& viewM, 148 sk_sp<GrFragmentProcessor> fp, 149 bool textureIsAlphaOnly, 150 GrPaint* grPaint); 151 152 //////////////////////////////////////////////////////////////////////////////// 153 // Misc Sk to Gr type conversions 154 155 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo&, const GrCaps&); 156 GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps); 157 158 bool GrPixelConfigToColorType(GrPixelConfig, SkColorType*); 159 160 GrSamplerParams::FilterMode GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality, 161 const SkMatrix& viewM, 162 const SkMatrix& localM, 163 bool* doBicubic); 164 165 ////////////////////////////////////////////////////////////////////////////// 166 167 static inline GrPrimitiveType SkVertexModeToGrPrimitiveType(const SkCanvas::VertexMode mode) { 168 switch (mode) { 169 case SkCanvas::kTriangles_VertexMode: 170 return kTriangles_GrPrimitiveType; 171 case SkCanvas::kTriangleStrip_VertexMode: 172 return kTriangleStrip_GrPrimitiveType; 173 case SkCanvas::kTriangleFan_VertexMode: 174 return kTriangleFan_GrPrimitiveType; 175 } 176 SkFAIL("Invalid mode"); 177 return kPoints_GrPrimitiveType; 178 } 179 180 ////////////////////////////////////////////////////////////////////////////// 181 182 GR_STATIC_ASSERT((int)kZero_GrBlendCoeff == (int)SkXfermode::kZero_Coeff); 183 GR_STATIC_ASSERT((int)kOne_GrBlendCoeff == (int)SkXfermode::kOne_Coeff); 184 GR_STATIC_ASSERT((int)kSC_GrBlendCoeff == (int)SkXfermode::kSC_Coeff); 185 GR_STATIC_ASSERT((int)kISC_GrBlendCoeff == (int)SkXfermode::kISC_Coeff); 186 GR_STATIC_ASSERT((int)kDC_GrBlendCoeff == (int)SkXfermode::kDC_Coeff); 187 GR_STATIC_ASSERT((int)kIDC_GrBlendCoeff == (int)SkXfermode::kIDC_Coeff); 188 GR_STATIC_ASSERT((int)kSA_GrBlendCoeff == (int)SkXfermode::kSA_Coeff); 189 GR_STATIC_ASSERT((int)kISA_GrBlendCoeff == (int)SkXfermode::kISA_Coeff); 190 GR_STATIC_ASSERT((int)kDA_GrBlendCoeff == (int)SkXfermode::kDA_Coeff); 191 GR_STATIC_ASSERT((int)kIDA_GrBlendCoeff == (int)SkXfermode::kIDA_Coeff); 192 GR_STATIC_ASSERT(SkXfermode::kCoeffCount == 10); 193 194 #define SkXfermodeCoeffToGrBlendCoeff(X) ((GrBlendCoeff)(X)) 195 196 //////////////////////////////////////////////////////////////////////////////// 197 // Texture management 198 199 /** Returns a texture representing the bitmap that is compatible with the GrSamplerParams. The 200 * texture is inserted into the cache (unless the bitmap is marked volatile) and can be 201 * retrieved again via this function. 202 * The 'scaleAdjust' in/out parameter will be updated to hold any rescaling that needs to be 203 * performed on the absolute texture coordinates (e.g., if the texture is resized out to 204 * the next power of two). It can be null if the caller is sure the bitmap won't be resized. 205 */ 206 sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext*, 207 const SkBitmap&, 208 const GrSamplerParams&, 209 SkScalar scaleAdjust[2]); 210 211 /** 212 * Creates a new texture for the bitmap. Does not concern itself with cache keys or texture params. 213 * The bitmap must have CPU-accessible pixels. Attempts to take advantage of faster paths for 214 * compressed textures and yuv planes. 215 */ 216 sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrResourceProvider*, const SkBitmap&); 217 218 sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext*, const SkBitmap&, 219 SkColorSpace* dstColorSpace); 220 221 /** 222 * Creates a new texture for the pixmap. 223 */ 224 sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider*, 225 const SkPixmap&, SkBudgeted); 226 227 /** 228 * Creates a new texture populated with the mipmap levels. 229 */ 230 sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext*, const SkImageInfo&, 231 const GrMipLevel* texels, 232 int mipLevelCount, 233 SkDestinationSurfaceColorMode colorMode); 234 235 // This is intended to replace: 236 // SkAutoLockPixels alp(bitmap, true); 237 // if (!bitmap.readyToDraw()) { 238 // return nullptr; 239 // } 240 // sk_sp<GrTexture> texture = GrMakeCachedBitmapTexture(fContext.get(), bitmap, 241 // GrSamplerParams::ClampNoFilter(), 242 // nullptr); 243 // if (!texture) { 244 // return nullptr; 245 // } 246 sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrResourceProvider*, const SkBitmap& bitmap); 247 248 249 /** 250 * Our key includes the offset, width, and height so that bitmaps created by extractSubset() 251 * are unique. 252 * 253 * The imageID is in the shared namespace (see SkNextID::ImageID()) 254 * - SkBitmap/SkPixelRef 255 * - SkImage 256 * - SkImageGenerator 257 * 258 * Note: width/height must fit in 16bits for this impl. 259 */ 260 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& imageBounds); 261 262 /** Call this after installing a GrUniqueKey on texture. It will cause the texture's key to be 263 removed should the bitmap's contents change or be destroyed. */ 264 void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef); 265 266 ////////////////////////////////////////////////////////////////////////////// 267 268 /** When image filter code needs to construct a render target context to do intermediate rendering, 269 we need a renderable pixel config. The source (SkSpecialImage) may not be in a renderable 270 format, but we want to preserve the color space of that source. This picks an appropriate format 271 to use. */ 272 GrPixelConfig GrRenderableConfigForColorSpace(const SkColorSpace*); 273 274 /** 275 * If the compressed data in the SkData is supported (as a texture format, this returns 276 * the pixel-config that should be used, and sets outStartOfDataToUpload to the ptr into 277 * the data where the actual raw data starts (skipping any header bytes). 278 * 279 * If the compressed data is not supported, this returns kUnknown_GrPixelConfig, and 280 * ignores outStartOfDataToUpload. 281 */ 282 GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data, 283 int expectedW, int expectedH, 284 const void** outStartOfDataToUpload); 285 286 287 288 #endif 289