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