Home | History | Annotate | Download | only in gpu
      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