Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2010 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 #include "SkGr.h"
      9 
     10 #include "GrBitmapTextureMaker.h"
     11 #include "GrCaps.h"
     12 #include "GrContext.h"
     13 #include "GrGpuResourcePriv.h"
     14 #include "GrRenderTargetContext.h"
     15 #include "GrResourceProvider.h"
     16 #include "GrTextureProxy.h"
     17 #include "GrTypes.h"
     18 #include "GrXferProcessor.h"
     19 
     20 #include "SkAutoMalloc.h"
     21 #include "SkBlendModePriv.h"
     22 #include "SkCanvas.h"
     23 #include "SkColorFilter.h"
     24 #include "SkConvertPixels.h"
     25 #include "SkData.h"
     26 #include "SkImageInfoPriv.h"
     27 #include "SkMaskFilter.h"
     28 #include "SkMessageBus.h"
     29 #include "SkMipMap.h"
     30 #include "SkPM4fPriv.h"
     31 #include "SkPaintPriv.h"
     32 #include "SkPixelRef.h"
     33 #include "SkResourceCache.h"
     34 #include "SkShaderBase.h"
     35 #include "SkTemplates.h"
     36 #include "effects/GrBicubicEffect.h"
     37 #include "effects/GrConstColorProcessor.h"
     38 #include "effects/GrDitherEffect.h"
     39 #include "effects/GrPorterDuffXferProcessor.h"
     40 #include "effects/GrXfermodeFragmentProcessor.h"
     41 
     42 GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info, const GrCaps& caps) {
     43     GrSurfaceDesc desc;
     44     desc.fFlags = kNone_GrSurfaceFlags;
     45     desc.fWidth = info.width();
     46     desc.fHeight = info.height();
     47     desc.fConfig = SkImageInfo2GrPixelConfig(info, caps);
     48     desc.fSampleCnt = 0;
     49     return desc;
     50 }
     51 
     52 void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& imageBounds) {
     53     SkASSERT(key);
     54     SkASSERT(imageID);
     55     SkASSERT(!imageBounds.isEmpty());
     56     static const GrUniqueKey::Domain kImageIDDomain = GrUniqueKey::GenerateDomain();
     57     GrUniqueKey::Builder builder(key, kImageIDDomain, 5);
     58     builder[0] = imageID;
     59     builder[1] = imageBounds.fLeft;
     60     builder[2] = imageBounds.fTop;
     61     builder[3] = imageBounds.fRight;
     62     builder[4] = imageBounds.fBottom;
     63 }
     64 
     65 //////////////////////////////////////////////////////////////////////////////
     66 sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrResourceProvider* resourceProvider,
     67                                                    const SkBitmap& bitmap,
     68                                                    SkColorSpace* dstColorSpace) {
     69     if (!bitmap.readyToDraw()) {
     70         return nullptr;
     71     }
     72     SkPixmap pixmap;
     73     if (!bitmap.peekPixels(&pixmap)) {
     74         return nullptr;
     75     }
     76     return GrUploadPixmapToTextureProxy(resourceProvider, pixmap, SkBudgeted::kYes, dstColorSpace);
     77 }
     78 
     79 static const SkPixmap* compute_desc(const GrCaps& caps, const SkPixmap& pixmap,
     80                                     GrSurfaceDesc* desc,
     81                                     SkBitmap* tmpBitmap, SkPixmap* tmpPixmap) {
     82     const SkPixmap* pmap = &pixmap;
     83 
     84     *desc = GrImageInfoToSurfaceDesc(pixmap.info(), caps);
     85 
     86     // TODO: We're checking for srgbSupport, but we can then end up picking sBGRA as our pixel
     87     // config (which may not be supported). We need better fallback management here.
     88     SkColorSpace* colorSpace = pixmap.colorSpace();
     89 
     90     if (caps.srgbSupport() &&
     91         colorSpace && colorSpace->gammaCloseToSRGB() && !GrPixelConfigIsSRGB(desc->fConfig)) {
     92         // We were supplied an sRGB-like color space, but we don't have a suitable pixel config.
     93         // Convert to 8888 sRGB so we can handle the data correctly. The raster backend doesn't
     94         // handle sRGB Index8 -> sRGB 8888 correctly (yet), so lie about both the source and
     95         // destination (claim they're linear):
     96         SkImageInfo linSrcInfo = SkImageInfo::Make(pixmap.width(), pixmap.height(),
     97                                                    pixmap.colorType(), pixmap.alphaType());
     98         SkPixmap linSrcPixmap(linSrcInfo, pixmap.addr(), pixmap.rowBytes());
     99 
    100         SkImageInfo dstInfo = SkImageInfo::Make(pixmap.width(), pixmap.height(),
    101                                                 kN32_SkColorType, kPremul_SkAlphaType,
    102                                                 pixmap.info().refColorSpace());
    103 
    104         tmpBitmap->allocPixels(dstInfo);
    105 
    106         SkImageInfo linDstInfo = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height());
    107         if (!linSrcPixmap.readPixels(linDstInfo, tmpBitmap->getPixels(), tmpBitmap->rowBytes())) {
    108             return nullptr;
    109         }
    110         if (!tmpBitmap->peekPixels(tmpPixmap)) {
    111             return nullptr;
    112         }
    113         pmap = tmpPixmap;
    114         // must rebuild desc, since we've forced the info to be N32
    115         *desc = GrImageInfoToSurfaceDesc(pmap->info(), caps);
    116     }
    117 
    118     return pmap;
    119 }
    120 
    121 sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider* resourceProvider,
    122                                                    const SkPixmap& pixmap,
    123                                                    SkBudgeted budgeted,
    124                                                    SkColorSpace* dstColorSpace) {
    125     SkDestinationSurfaceColorMode colorMode = dstColorSpace
    126         ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
    127         : SkDestinationSurfaceColorMode::kLegacy;
    128 
    129     if (!SkImageInfoIsValid(pixmap.info(), colorMode)) {
    130         return nullptr;
    131     }
    132 
    133     SkBitmap tmpBitmap;
    134     SkPixmap tmpPixmap;
    135     GrSurfaceDesc desc;
    136 
    137     if (const SkPixmap* pmap = compute_desc(*resourceProvider->caps(), pixmap, &desc,
    138                                             &tmpBitmap, &tmpPixmap)) {
    139         return GrSurfaceProxy::MakeDeferred(resourceProvider, desc,
    140                                             budgeted, pmap->addr(), pmap->rowBytes());
    141     }
    142 
    143     return nullptr;
    144 }
    145 
    146 ////////////////////////////////////////////////////////////////////////////////
    147 
    148 void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
    149     class Invalidator : public SkPixelRef::GenIDChangeListener {
    150     public:
    151         explicit Invalidator(const GrUniqueKey& key) : fMsg(key) {}
    152     private:
    153         GrUniqueKeyInvalidatedMessage fMsg;
    154 
    155         void onChange() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
    156     };
    157 
    158     pixelRef->addGenIDChangeListener(new Invalidator(key));
    159 }
    160 
    161 sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext* ctx,
    162                                                                const SkBitmap& bitmap,
    163                                                                SkColorSpace* dstColorSpace) {
    164     SkDestinationSurfaceColorMode colorMode = dstColorSpace
    165         ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
    166         : SkDestinationSurfaceColorMode::kLegacy;
    167 
    168     if (!SkImageInfoIsValid(bitmap.info(), colorMode)) {
    169         return nullptr;
    170     }
    171 
    172     GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info(), *ctx->caps());
    173 
    174     SkPixmap pixmap;
    175     if (!bitmap.peekPixels(&pixmap)) {
    176         return nullptr;
    177     }
    178 
    179     std::unique_ptr<SkMipMap> mipmaps(SkMipMap::Build(pixmap, colorMode, nullptr));
    180     if (!mipmaps) {
    181         return nullptr;
    182     }
    183 
    184     const int mipLevelCount = mipmaps->countLevels() + 1;
    185     if (mipLevelCount < 1) {
    186         return nullptr;
    187     }
    188 
    189     const bool isMipMapped = mipLevelCount > 1;
    190     desc.fIsMipMapped = isMipMapped;
    191 
    192     std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
    193 
    194     texels[0].fPixels = pixmap.addr();
    195     texels[0].fRowBytes = pixmap.rowBytes();
    196 
    197     for (int i = 1; i < mipLevelCount; ++i) {
    198         SkMipMap::Level generatedMipLevel;
    199         mipmaps->getLevel(i - 1, &generatedMipLevel);
    200         texels[i].fPixels = generatedMipLevel.fPixmap.addr();
    201         texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes();
    202     }
    203 
    204     return GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
    205                                               desc,
    206                                               SkBudgeted::kYes,
    207                                               texels.get(),
    208                                               mipLevelCount,
    209                                               colorMode);
    210 }
    211 
    212 sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext* ctx, const SkImageInfo& info,
    213                                                    const GrMipLevel texels[],
    214                                                    int mipLevelCount,
    215                                                    SkDestinationSurfaceColorMode colorMode) {
    216     if (!SkImageInfoIsValid(info, colorMode)) {
    217         return nullptr;
    218     }
    219 
    220     return GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
    221                                               GrImageInfoToSurfaceDesc(info, *ctx->caps()),
    222                                               SkBudgeted::kYes, texels,
    223                                               mipLevelCount, colorMode);
    224 }
    225 
    226 sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext* ctx,
    227                                                     const SkBitmap& bitmap,
    228                                                     const GrSamplerParams& params,
    229                                                     SkScalar scaleAdjust[2]) {
    230     // Caller doesn't care about the texture's color space (they can always get it from the bitmap)
    231     return GrBitmapTextureMaker(ctx, bitmap).refTextureProxyForParams(params, nullptr,
    232                                                                       nullptr, scaleAdjust);
    233 }
    234 
    235 sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrResourceProvider* resourceProvider,
    236                                               const SkBitmap& bitmap) {
    237     GrUniqueKey originalKey;
    238 
    239     if (!bitmap.isVolatile()) {
    240         SkIPoint origin = bitmap.pixelRefOrigin();
    241         SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(), bitmap.height());
    242         GrMakeKeyFromImageID(&originalKey, bitmap.pixelRef()->getGenerationID(), subset);
    243     }
    244 
    245     sk_sp<GrTextureProxy> proxy;
    246 
    247     if (originalKey.isValid()) {
    248         proxy = resourceProvider->findProxyByUniqueKey(originalKey);
    249     }
    250     if (!proxy) {
    251         // Pass nullptr for |dstColorSpace|.  This is lenient - we allow a wider range of
    252         // color spaces in legacy mode.  Unfortunately, we have to be lenient here, since
    253         // we can't necessarily know the |dstColorSpace| at this time.
    254         proxy = GrUploadBitmapToTextureProxy(resourceProvider, bitmap, nullptr);
    255         if (proxy && originalKey.isValid()) {
    256             resourceProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
    257             // MDB TODO (caching): this has to play nice with the GrSurfaceProxy's caching
    258             GrInstallBitmapUniqueKeyInvalidator(originalKey, bitmap.pixelRef());
    259         }
    260     }
    261 
    262     return proxy;
    263 }
    264 
    265 ///////////////////////////////////////////////////////////////////////////////
    266 
    267 GrColor4f SkColorToPremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace) {
    268     // We want to premultiply after linearizing, so this is easy:
    269     return SkColorToUnpremulGrColor4f(c, dstColorSpace).premul();
    270 }
    271 
    272 GrColor4f SkColorToUnpremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace) {
    273     if (dstColorSpace) {
    274         auto srgbColorSpace = SkColorSpace::MakeSRGB();
    275         auto gamutXform = GrColorSpaceXform::Make(srgbColorSpace.get(), dstColorSpace);
    276         return SkColorToUnpremulGrColor4f(c, dstColorSpace, gamutXform.get());
    277     } else {
    278         return SkColorToUnpremulGrColor4f(c, nullptr, nullptr);
    279     }
    280 }
    281 
    282 GrColor4f SkColorToPremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace,
    283                                    GrColorSpaceXform* gamutXform) {
    284     // We want to premultiply after linearizing, so this is easy:
    285     return SkColorToUnpremulGrColor4f(c, dstColorSpace, gamutXform).premul();
    286 }
    287 
    288 GrColor4f SkColorToUnpremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace,
    289                                      GrColorSpaceXform* gamutXform) {
    290     // You can't be color-space aware in legacy mode
    291     SkASSERT(dstColorSpace || !gamutXform);
    292 
    293     GrColor4f color;
    294     if (dstColorSpace) {
    295         // SkColor4f::FromColor does sRGB -> Linear
    296         color = GrColor4f::FromSkColor4f(SkColor4f::FromColor(c));
    297     } else {
    298         // GrColor4f::FromGrColor just multiplies by 1/255
    299         color = GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c));
    300     }
    301 
    302     if (gamutXform) {
    303         color = gamutXform->apply(color);
    304     }
    305 
    306     return color;
    307 }
    308 
    309 ///////////////////////////////////////////////////////////////////////////////
    310 
    311 GrPixelConfig SkImageInfo2GrPixelConfig(const SkColorType type, SkColorSpace* cs,
    312                                         const GrCaps& caps) {
    313     // We intentionally ignore profile type for non-8888 formats. Anything we can't support
    314     // in hardware will be expanded to sRGB 8888 in GrUploadPixmapToTexture.
    315     switch (type) {
    316         case kUnknown_SkColorType:
    317             return kUnknown_GrPixelConfig;
    318         case kAlpha_8_SkColorType:
    319             return kAlpha_8_GrPixelConfig;
    320         case kRGB_565_SkColorType:
    321             return kRGB_565_GrPixelConfig;
    322         case kARGB_4444_SkColorType:
    323             return kRGBA_4444_GrPixelConfig;
    324         case kRGBA_8888_SkColorType:
    325             return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
    326                    ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
    327         case kBGRA_8888_SkColorType:
    328             return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
    329                    ? kSBGRA_8888_GrPixelConfig : kBGRA_8888_GrPixelConfig;
    330         case kGray_8_SkColorType:
    331             return kGray_8_GrPixelConfig;
    332         case kRGBA_F16_SkColorType:
    333             return kRGBA_half_GrPixelConfig;
    334     }
    335     SkASSERT(0);    // shouldn't get here
    336     return kUnknown_GrPixelConfig;
    337 }
    338 
    339 GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps) {
    340     return SkImageInfo2GrPixelConfig(info.colorType(), info.colorSpace(), caps);
    341 }
    342 
    343 bool GrPixelConfigToColorType(GrPixelConfig config, SkColorType* ctOut) {
    344     SkColorType ct;
    345     switch (config) {
    346         case kAlpha_8_GrPixelConfig:
    347             ct = kAlpha_8_SkColorType;
    348             break;
    349         case kGray_8_GrPixelConfig:
    350             ct = kGray_8_SkColorType;
    351             break;
    352         case kRGB_565_GrPixelConfig:
    353             ct = kRGB_565_SkColorType;
    354             break;
    355         case kRGBA_4444_GrPixelConfig:
    356             ct = kARGB_4444_SkColorType;
    357             break;
    358         case kRGBA_8888_GrPixelConfig:
    359             ct = kRGBA_8888_SkColorType;
    360             break;
    361         case kBGRA_8888_GrPixelConfig:
    362             ct = kBGRA_8888_SkColorType;
    363             break;
    364         case kSRGBA_8888_GrPixelConfig:
    365             ct = kRGBA_8888_SkColorType;
    366             break;
    367         case kSBGRA_8888_GrPixelConfig:
    368             ct = kBGRA_8888_SkColorType;
    369             break;
    370         case kRGBA_half_GrPixelConfig:
    371             ct = kRGBA_F16_SkColorType;
    372             break;
    373         default:
    374             return false;
    375     }
    376     if (ctOut) {
    377         *ctOut = ct;
    378     }
    379     return true;
    380 }
    381 
    382 GrPixelConfig GrRenderableConfigForColorSpace(const SkColorSpace* colorSpace) {
    383     if (!colorSpace) {
    384         return kRGBA_8888_GrPixelConfig;
    385     } else if (colorSpace->gammaIsLinear()) {
    386         return kRGBA_half_GrPixelConfig;
    387     } else if (colorSpace->gammaCloseToSRGB()) {
    388         return kSRGBA_8888_GrPixelConfig;
    389     } else {
    390         SkDEBUGFAIL("No renderable config exists for color space with strange gamma");
    391         return kUnknown_GrPixelConfig;
    392     }
    393 }
    394 
    395 ////////////////////////////////////////////////////////////////////////////////////////////////
    396 
    397 static inline bool blend_requires_shader(const SkBlendMode mode) {
    398     return SkBlendMode::kDst != mode;
    399 }
    400 
    401 static inline bool skpaint_to_grpaint_impl(GrContext* context,
    402                                            GrRenderTargetContext* rtc,
    403                                            const SkPaint& skPaint,
    404                                            const SkMatrix& viewM,
    405                                            sk_sp<GrFragmentProcessor>* shaderProcessor,
    406                                            SkBlendMode* primColorMode,
    407                                            GrPaint* grPaint) {
    408     grPaint->setAllowSRGBInputs(rtc->isGammaCorrect());
    409 
    410     // Convert SkPaint color to 4f format, including optional linearizing and gamut conversion.
    411     GrColor4f origColor = SkColorToUnpremulGrColor4f(skPaint.getColor(), rtc->getColorSpace(),
    412                                                      rtc->getColorXformFromSRGB());
    413 
    414     // Setup the initial color considering the shader, the SkPaint color, and the presence or not
    415     // of per-vertex colors.
    416     sk_sp<GrFragmentProcessor> shaderFP;
    417     if (!primColorMode || blend_requires_shader(*primColorMode)) {
    418         if (shaderProcessor) {
    419             shaderFP = *shaderProcessor;
    420         } else if (const auto* shader = as_SB(skPaint.getShader())) {
    421             shaderFP = shader->asFragmentProcessor(
    422                 SkShaderBase::AsFPArgs(context, &viewM, nullptr, skPaint.getFilterQuality(),
    423                                        rtc->getColorSpace()));
    424             if (!shaderFP) {
    425                 return false;
    426             }
    427         }
    428     }
    429 
    430     // Set this in below cases if the output of the shader/paint-color/paint-alpha/primXfermode is
    431     // a known constant value. In that case we can simply apply a color filter during this
    432     // conversion without converting the color filter to a GrFragmentProcessor.
    433     bool applyColorFilterToPaintColor = false;
    434     if (shaderFP) {
    435         if (primColorMode) {
    436             // There is a blend between the primitive color and the shader color. The shader sees
    437             // the opaque paint color. The shader's output is blended using the provided mode by
    438             // the primitive color. The blended color is then modulated by the paint's alpha.
    439 
    440             // The geometry processor will insert the primitive color to start the color chain, so
    441             // the GrPaint color will be ignored.
    442 
    443             GrColor4f shaderInput = origColor.opaque();
    444             shaderFP = GrFragmentProcessor::OverrideInput(shaderFP, shaderInput);
    445             shaderFP = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(shaderFP),
    446                                                                          *primColorMode);
    447 
    448             // The above may return null if compose results in a pass through of the prim color.
    449             if (shaderFP) {
    450                 grPaint->addColorFragmentProcessor(std::move(shaderFP));
    451             }
    452 
    453             // We can ignore origColor here - alpha is unchanged by gamma
    454             GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
    455             if (GrColor_WHITE != paintAlpha) {
    456                 // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
    457                 // color channels. It's value should be treated as the same in ANY color space.
    458                 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
    459                     GrColor4f::FromGrColor(paintAlpha),
    460                     GrConstColorProcessor::kModulateRGBA_InputMode));
    461             }
    462         } else {
    463             // The shader's FP sees the paint unpremul color
    464             grPaint->setColor4f(origColor);
    465             grPaint->addColorFragmentProcessor(std::move(shaderFP));
    466         }
    467     } else {
    468         if (primColorMode) {
    469             // There is a blend between the primitive color and the paint color. The blend considers
    470             // the opaque paint color. The paint's alpha is applied to the post-blended color.
    471             sk_sp<GrFragmentProcessor> processor(
    472                 GrConstColorProcessor::Make(origColor.opaque(),
    473                                             GrConstColorProcessor::kIgnore_InputMode));
    474             processor = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(processor),
    475                                                                           *primColorMode);
    476             if (processor) {
    477                 grPaint->addColorFragmentProcessor(std::move(processor));
    478             }
    479 
    480             grPaint->setColor4f(origColor.opaque());
    481 
    482             // We can ignore origColor here - alpha is unchanged by gamma
    483             GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
    484             if (GrColor_WHITE != paintAlpha) {
    485                 // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
    486                 // color channels. It's value should be treated as the same in ANY color space.
    487                 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
    488                     GrColor4f::FromGrColor(paintAlpha),
    489                     GrConstColorProcessor::kModulateRGBA_InputMode));
    490             }
    491         } else {
    492             // No shader, no primitive color.
    493             grPaint->setColor4f(origColor.premul());
    494             applyColorFilterToPaintColor = true;
    495         }
    496     }
    497 
    498     SkColorFilter* colorFilter = skPaint.getColorFilter();
    499     if (colorFilter) {
    500         if (applyColorFilterToPaintColor) {
    501             // If we're in legacy mode, we *must* avoid using the 4f version of the color filter,
    502             // because that will combine with the linearized version of the stored color.
    503             if (rtc->isGammaCorrect()) {
    504                 grPaint->setColor4f(GrColor4f::FromSkColor4f(
    505                     colorFilter->filterColor4f(origColor.toSkColor4f())).premul());
    506             } else {
    507                 grPaint->setColor4f(SkColorToPremulGrColor4f(
    508                     colorFilter->filterColor(skPaint.getColor()), nullptr, nullptr));
    509             }
    510         } else {
    511             sk_sp<GrFragmentProcessor> cfFP(colorFilter->asFragmentProcessor(context,
    512                                                                              rtc->getColorSpace()));
    513             if (cfFP) {
    514                 grPaint->addColorFragmentProcessor(std::move(cfFP));
    515             } else {
    516                 return false;
    517             }
    518         }
    519     }
    520 
    521     SkMaskFilter* maskFilter = skPaint.getMaskFilter();
    522     if (maskFilter) {
    523         GrFragmentProcessor* mfFP;
    524         if (maskFilter->asFragmentProcessor(&mfFP)) {
    525             grPaint->addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor>(mfFP));
    526         }
    527     }
    528 
    529     // When the xfermode is null on the SkPaint (meaning kSrcOver) we need the XPFactory field on
    530     // the GrPaint to also be null (also kSrcOver).
    531     SkASSERT(!grPaint->getXPFactory());
    532     if (!skPaint.isSrcOver()) {
    533         grPaint->setXPFactory(SkBlendMode_AsXPFactory(skPaint.getBlendMode()));
    534     }
    535 
    536 #ifndef SK_IGNORE_GPU_DITHER
    537     // Conservative default, in case GrPixelConfigToColorType() fails.
    538     SkColorType ct = SkColorType::kRGB_565_SkColorType;
    539     GrPixelConfigToColorType(rtc->config(), &ct);
    540     if (SkPaintPriv::ShouldDither(skPaint, ct) && grPaint->numColorFragmentProcessors() > 0
    541         && !rtc->isGammaCorrect()) {
    542         auto ditherFP = GrDitherEffect::Make(rtc->config());
    543         if (ditherFP) {
    544             grPaint->addColorFragmentProcessor(std::move(ditherFP));
    545         }
    546     }
    547 #endif
    548     return true;
    549 }
    550 
    551 bool SkPaintToGrPaint(GrContext* context, GrRenderTargetContext* rtc, const SkPaint& skPaint,
    552                       const SkMatrix& viewM, GrPaint* grPaint) {
    553     return skpaint_to_grpaint_impl(context, rtc, skPaint, viewM, nullptr, nullptr, grPaint);
    554 }
    555 
    556 /** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. */
    557 bool SkPaintToGrPaintReplaceShader(GrContext* context,
    558                                    GrRenderTargetContext* rtc,
    559                                    const SkPaint& skPaint,
    560                                    sk_sp<GrFragmentProcessor> shaderFP,
    561                                    GrPaint* grPaint) {
    562     if (!shaderFP) {
    563         return false;
    564     }
    565     return skpaint_to_grpaint_impl(context, rtc, skPaint, SkMatrix::I(), &shaderFP, nullptr,
    566                                    grPaint);
    567 }
    568 
    569 /** Ignores the SkShader (if any) on skPaint. */
    570 bool SkPaintToGrPaintNoShader(GrContext* context,
    571                               GrRenderTargetContext* rtc,
    572                               const SkPaint& skPaint,
    573                               GrPaint* grPaint) {
    574     // Use a ptr to a nullptr to to indicate that the SkShader is ignored and not replaced.
    575     static sk_sp<GrFragmentProcessor> kNullShaderFP(nullptr);
    576     static sk_sp<GrFragmentProcessor>* kIgnoreShader = &kNullShaderFP;
    577     return skpaint_to_grpaint_impl(context, rtc, skPaint, SkMatrix::I(), kIgnoreShader, nullptr,
    578                                    grPaint);
    579 }
    580 
    581 /** Blends the SkPaint's shader (or color if no shader) with a per-primitive color which must
    582 be setup as a vertex attribute using the specified SkBlendMode. */
    583 bool SkPaintToGrPaintWithXfermode(GrContext* context,
    584                                   GrRenderTargetContext* rtc,
    585                                   const SkPaint& skPaint,
    586                                   const SkMatrix& viewM,
    587                                   SkBlendMode primColorMode,
    588                                   GrPaint* grPaint) {
    589     return skpaint_to_grpaint_impl(context, rtc, skPaint, viewM, nullptr, &primColorMode,
    590                                    grPaint);
    591 }
    592 
    593 bool SkPaintToGrPaintWithTexture(GrContext* context,
    594                                  GrRenderTargetContext* rtc,
    595                                  const SkPaint& paint,
    596                                  const SkMatrix& viewM,
    597                                  sk_sp<GrFragmentProcessor> fp,
    598                                  bool textureIsAlphaOnly,
    599                                  GrPaint* grPaint) {
    600     sk_sp<GrFragmentProcessor> shaderFP;
    601     if (textureIsAlphaOnly) {
    602         if (const auto* shader = as_SB(paint.getShader())) {
    603             shaderFP = shader->asFragmentProcessor(
    604                 SkShaderBase::AsFPArgs(context, &viewM, nullptr, paint.getFilterQuality(),
    605                                        rtc->getColorSpace()));
    606             if (!shaderFP) {
    607                 return false;
    608             }
    609             sk_sp<GrFragmentProcessor> fpSeries[] = { std::move(shaderFP), std::move(fp) };
    610             shaderFP = GrFragmentProcessor::RunInSeries(fpSeries, 2);
    611         } else {
    612             shaderFP = GrFragmentProcessor::MakeInputPremulAndMulByOutput(fp);
    613         }
    614     } else {
    615         shaderFP = GrFragmentProcessor::MulOutputByInputAlpha(fp);
    616     }
    617 
    618     return SkPaintToGrPaintReplaceShader(context, rtc, paint, std::move(shaderFP), grPaint);
    619 }
    620 
    621 
    622 ////////////////////////////////////////////////////////////////////////////////////////////////
    623 
    624 GrSamplerParams::FilterMode GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,
    625                                                             const SkMatrix& viewM,
    626                                                             const SkMatrix& localM,
    627                                                             bool* doBicubic) {
    628     *doBicubic = false;
    629     GrSamplerParams::FilterMode textureFilterMode;
    630     switch (paintFilterQuality) {
    631         case kNone_SkFilterQuality:
    632             textureFilterMode = GrSamplerParams::kNone_FilterMode;
    633             break;
    634         case kLow_SkFilterQuality:
    635             textureFilterMode = GrSamplerParams::kBilerp_FilterMode;
    636             break;
    637         case kMedium_SkFilterQuality: {
    638             SkMatrix matrix;
    639             matrix.setConcat(viewM, localM);
    640             if (matrix.getMinScale() < SK_Scalar1) {
    641                 textureFilterMode = GrSamplerParams::kMipMap_FilterMode;
    642             } else {
    643                 // Don't trigger MIP level generation unnecessarily.
    644                 textureFilterMode = GrSamplerParams::kBilerp_FilterMode;
    645             }
    646             break;
    647         }
    648         case kHigh_SkFilterQuality: {
    649             SkMatrix matrix;
    650             matrix.setConcat(viewM, localM);
    651             *doBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
    652             break;
    653         }
    654         default:
    655             // Should be unreachable.  If not, fall back to mipmaps.
    656             textureFilterMode = GrSamplerParams::kMipMap_FilterMode;
    657             break;
    658 
    659     }
    660     return textureFilterMode;
    661 }
    662