• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GrImageInfoToSurfaceDesc(const SkImageInfo & info,const GrCaps & caps)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 
GrMakeKeyFromImageID(GrUniqueKey * key,uint32_t imageID,const SkIRect & imageBounds)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 //////////////////////////////////////////////////////////////////////////////
GrUploadBitmapToTextureProxy(GrResourceProvider * resourceProvider,const SkBitmap & bitmap,SkColorSpace * dstColorSpace)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 
compute_desc(const GrCaps & caps,const SkPixmap & pixmap,GrSurfaceDesc * desc,SkBitmap * tmpBitmap,SkPixmap * tmpPixmap)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 
GrUploadPixmapToTextureProxy(GrResourceProvider * resourceProvider,const SkPixmap & pixmap,SkBudgeted budgeted,SkColorSpace * dstColorSpace)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 
GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey & key,SkPixelRef * pixelRef)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 
GrGenerateMipMapsAndUploadToTextureProxy(GrContext * ctx,const SkBitmap & bitmap,SkColorSpace * dstColorSpace)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 
GrUploadMipMapToTextureProxy(GrContext * ctx,const SkImageInfo & info,const GrMipLevel texels[],int mipLevelCount,SkDestinationSurfaceColorMode colorMode)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 
GrRefCachedBitmapTextureProxy(GrContext * ctx,const SkBitmap & bitmap,const GrSamplerParams & params,SkScalar scaleAdjust[2])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 
GrMakeCachedBitmapProxy(GrResourceProvider * resourceProvider,const SkBitmap & bitmap)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 
SkColorToPremulGrColor4f(SkColor c,SkColorSpace * dstColorSpace)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 
SkColorToUnpremulGrColor4f(SkColor c,SkColorSpace * dstColorSpace)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 
SkColorToPremulGrColor4f(SkColor c,SkColorSpace * dstColorSpace,GrColorSpaceXform * gamutXform)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 
SkColorToUnpremulGrColor4f(SkColor c,SkColorSpace * dstColorSpace,GrColorSpaceXform * gamutXform)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 
SkImageInfo2GrPixelConfig(const SkColorType type,SkColorSpace * cs,const GrCaps & caps)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 
SkImageInfo2GrPixelConfig(const SkImageInfo & info,const GrCaps & caps)339 GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps) {
340     return SkImageInfo2GrPixelConfig(info.colorType(), info.colorSpace(), caps);
341 }
342 
GrPixelConfigToColorType(GrPixelConfig config,SkColorType * ctOut)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 
GrRenderableConfigForColorSpace(const SkColorSpace * colorSpace)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 
blend_requires_shader(const SkBlendMode mode)397 static inline bool blend_requires_shader(const SkBlendMode mode) {
398     return SkBlendMode::kDst != mode;
399 }
400 
skpaint_to_grpaint_impl(GrContext * context,GrRenderTargetContext * rtc,const SkPaint & skPaint,const SkMatrix & viewM,sk_sp<GrFragmentProcessor> * shaderProcessor,SkBlendMode * primColorMode,GrPaint * grPaint)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 
SkPaintToGrPaint(GrContext * context,GrRenderTargetContext * rtc,const SkPaint & skPaint,const SkMatrix & viewM,GrPaint * grPaint)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. */
SkPaintToGrPaintReplaceShader(GrContext * context,GrRenderTargetContext * rtc,const SkPaint & skPaint,sk_sp<GrFragmentProcessor> shaderFP,GrPaint * grPaint)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. */
SkPaintToGrPaintNoShader(GrContext * context,GrRenderTargetContext * rtc,const SkPaint & skPaint,GrPaint * grPaint)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. */
SkPaintToGrPaintWithXfermode(GrContext * context,GrRenderTargetContext * rtc,const SkPaint & skPaint,const SkMatrix & viewM,SkBlendMode primColorMode,GrPaint * grPaint)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 
SkPaintToGrPaintWithTexture(GrContext * context,GrRenderTargetContext * rtc,const SkPaint & paint,const SkMatrix & viewM,sk_sp<GrFragmentProcessor> fp,bool textureIsAlphaOnly,GrPaint * grPaint)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 
GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,const SkMatrix & viewM,const SkMatrix & localM,bool * doBicubic)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