blob: 35cd843d963404ad04faad59f1dd659777768917 [file] [log] [blame]
reed@google.comac10a2d2010-12-22 21:39:39 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * 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.
reed@google.comac10a2d2010-12-22 21:39:39 +00006 */
7
reed@google.comac10a2d2010-12-22 21:39:39 +00008#include "SkGr.h"
egdaniel378092f2014-12-03 10:40:13 -08009
Brian Osman3b66ab62016-11-28 09:26:31 -050010#include "GrBitmapTextureMaker.h"
bsalomon76228632015-05-29 08:02:10 -070011#include "GrCaps.h"
bsalomonf276ac52015-10-09 13:36:42 -070012#include "GrContext.h"
bsalomon045802d2015-10-20 07:58:01 -070013#include "GrGpuResourcePriv.h"
Brian Osman3b66ab62016-11-28 09:26:31 -050014#include "GrRenderTargetContext.h"
Brian Osman32342f02017-03-04 08:12:46 -050015#include "GrResourceProvider.h"
Hal Canary6f6961e2017-01-31 13:50:44 -050016#include "GrTextureProxy.h"
cblume55f2d2d2016-02-26 13:20:48 -080017#include "GrTypes.h"
egdaniel378092f2014-12-03 10:40:13 -080018#include "GrXferProcessor.h"
reed43fe6182015-09-08 08:37:36 -070019
Hal Canary95e3c052017-01-11 12:44:43 -050020#include "SkAutoMalloc.h"
reed374772b2016-10-05 17:33:02 -070021#include "SkBlendModePriv.h"
Hal Canary95e3c052017-01-11 12:44:43 -050022#include "SkCanvas.h"
commit-bot@chromium.org8dcff642014-05-15 20:32:48 +000023#include "SkColorFilter.h"
Matt Sarett485c4992017-02-14 14:18:27 -050024#include "SkConvertPixels.h"
krajcevski9c0e6292014-06-02 07:38:14 -070025#include "SkData.h"
Brian Osman4075ec82017-01-17 16:41:03 +000026#include "SkImageInfoPriv.h"
Robert Phillipsa29a9562016-10-20 09:40:55 -040027#include "SkMaskFilter.h"
commit-bot@chromium.org50a30432013-10-24 17:44:27 +000028#include "SkMessageBus.h"
cblume55f2d2d2016-02-26 13:20:48 -080029#include "SkMipMap.h"
Kevin Lubickc456b732017-01-11 17:21:57 +000030#include "SkPM4fPriv.h"
Florin Malitad4a70ee2017-06-19 10:21:43 -040031#include "SkPaintPriv.h"
Hal Canary95e3c052017-01-11 12:44:43 -050032#include "SkPixelRef.h"
sugoi692135f2015-01-19 10:10:27 -080033#include "SkResourceCache.h"
Florin Malita4aed1382017-05-25 10:38:07 -040034#include "SkShaderBase.h"
cblume55f2d2d2016-02-26 13:20:48 -080035#include "SkTemplates.h"
joshualitt9bc39542015-08-12 12:57:54 -070036#include "effects/GrBicubicEffect.h"
bsalomonf1b7a1d2015-09-28 06:26:28 -070037#include "effects/GrConstColorProcessor.h"
krajcevskif461a8f2014-06-19 14:14:06 -070038#include "effects/GrDitherEffect.h"
egdaniel378092f2014-12-03 10:40:13 -080039#include "effects/GrPorterDuffXferProcessor.h"
bsalomonf1b7a1d2015-09-28 06:26:28 -070040#include "effects/GrXfermodeFragmentProcessor.h"
krajcevski9c0e6292014-06-02 07:38:14 -070041
brianosmana6359362016-03-21 06:55:37 -070042GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info, const GrCaps& caps) {
bsalomon466c2c42015-10-16 12:01:18 -070043 GrSurfaceDesc desc;
44 desc.fFlags = kNone_GrSurfaceFlags;
45 desc.fWidth = info.width();
46 desc.fHeight = info.height();
brianosmana6359362016-03-21 06:55:37 -070047 desc.fConfig = SkImageInfo2GrPixelConfig(info, caps);
bsalomon466c2c42015-10-16 12:01:18 -070048 desc.fSampleCnt = 0;
49 return desc;
50}
51
bsalomon045802d2015-10-20 07:58:01 -070052void 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);
bsalomon466c2c42015-10-16 12:01:18 -070058 builder[0] = imageID;
bsalomon045802d2015-10-20 07:58:01 -070059 builder[1] = imageBounds.fLeft;
60 builder[2] = imageBounds.fTop;
61 builder[3] = imageBounds.fRight;
62 builder[4] = imageBounds.fBottom;
bsalomon466c2c42015-10-16 12:01:18 -070063}
64
bsalomon045802d2015-10-20 07:58:01 -070065//////////////////////////////////////////////////////////////////////////////
Robert Phillips26c90e02017-03-14 14:39:29 -040066sk_sp<GrTextureProxy> GrUploadBitmapToTextureProxy(GrResourceProvider* resourceProvider,
Matt Sarettdedac852017-05-12 10:56:49 -040067 const SkBitmap& bitmap,
68 SkColorSpace* dstColorSpace) {
Robert Phillipsd3749482017-03-14 09:17:43 -040069 if (!bitmap.readyToDraw()) {
Brian Osman4075ec82017-01-17 16:41:03 +000070 return nullptr;
71 }
Robert Phillipsd3749482017-03-14 09:17:43 -040072 SkPixmap pixmap;
73 if (!bitmap.peekPixels(&pixmap)) {
74 return nullptr;
75 }
Matt Sarettdedac852017-05-12 10:56:49 -040076 return GrUploadPixmapToTextureProxy(resourceProvider, pixmap, SkBudgeted::kYes, dstColorSpace);
Robert Phillipsd3749482017-03-14 09:17:43 -040077}
Brian Osman4075ec82017-01-17 16:41:03 +000078
Robert Phillipsd3749482017-03-14 09:17:43 -040079static 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);
bsalomon@google.com5782d712011-01-21 21:03:59 +000085
Brian Osmand0be1ef2017-01-11 16:57:15 -050086 // 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.
Brian Osman47299142017-03-07 13:22:22 -050088 SkColorSpace* colorSpace = pixmap.colorSpace();
Brian Osmand0be1ef2017-01-11 16:57:15 -050089
Robert Phillipsd3749482017-03-14 09:17:43 -040090 if (caps.srgbSupport() &&
Matt Sarettf3880932017-03-24 10:06:03 -040091 colorSpace && colorSpace->gammaCloseToSRGB() && !GrPixelConfigIsSRGB(desc->fConfig)) {
brianosmanb109b8c2016-06-16 13:03:24 -070092 // We were supplied an sRGB-like color space, but we don't have a suitable pixel config.
brianosmana6359362016-03-21 06:55:37 -070093 // 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(), pixmap.ctable());
99
brianosmanb109b8c2016-06-16 13:03:24 -0700100 SkImageInfo dstInfo = SkImageInfo::Make(pixmap.width(), pixmap.height(),
101 kN32_SkColorType, kPremul_SkAlphaType,
Robert Phillips70b49fd2017-01-13 11:21:36 -0500102 pixmap.info().refColorSpace());
brianosmanb109b8c2016-06-16 13:03:24 -0700103
Robert Phillipsd3749482017-03-14 09:17:43 -0400104 tmpBitmap->allocPixels(dstInfo);
brianosmana6359362016-03-21 06:55:37 -0700105
106 SkImageInfo linDstInfo = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height());
Robert Phillipsd3749482017-03-14 09:17:43 -0400107 if (!linSrcPixmap.readPixels(linDstInfo, tmpBitmap->getPixels(), tmpBitmap->rowBytes())) {
brianosmana6359362016-03-21 06:55:37 -0700108 return nullptr;
109 }
Robert Phillipsd3749482017-03-14 09:17:43 -0400110 if (!tmpBitmap->peekPixels(tmpPixmap)) {
brianosmana6359362016-03-21 06:55:37 -0700111 return nullptr;
112 }
Robert Phillipsd3749482017-03-14 09:17:43 -0400113 pmap = tmpPixmap;
brianosmana6359362016-03-21 06:55:37 -0700114 // must rebuild desc, since we've forced the info to be N32
Robert Phillipsd3749482017-03-14 09:17:43 -0400115 *desc = GrImageInfoToSurfaceDesc(pmap->info(), caps);
brianosmana6359362016-03-21 06:55:37 -0700116 } else if (kIndex_8_SkColorType == pixmap.colorType()) {
Brian Osmand0be1ef2017-01-11 16:57:15 -0500117 SkImageInfo info = SkImageInfo::MakeN32Premul(pixmap.width(), pixmap.height());
Robert Phillipsd3749482017-03-14 09:17:43 -0400118 tmpBitmap->allocPixels(info);
119 if (!pixmap.readPixels(info, tmpBitmap->getPixels(), tmpBitmap->rowBytes())) {
Brian Osmand0be1ef2017-01-11 16:57:15 -0500120 return nullptr;
krajcevski9c0e6292014-06-02 07:38:14 -0700121 }
Robert Phillipsd3749482017-03-14 09:17:43 -0400122 if (!tmpBitmap->peekPixels(tmpPixmap)) {
Brian Osmand0be1ef2017-01-11 16:57:15 -0500123 return nullptr;
124 }
Robert Phillipsd3749482017-03-14 09:17:43 -0400125 pmap = tmpPixmap;
Brian Osmand0be1ef2017-01-11 16:57:15 -0500126 // must rebuild desc, since we've forced the info to be N32
Robert Phillipsd3749482017-03-14 09:17:43 -0400127 *desc = GrImageInfoToSurfaceDesc(pmap->info(), caps);
bsalomon@google.com5782d712011-01-21 21:03:59 +0000128 }
reed@google.comac10a2d2010-12-22 21:39:39 +0000129
Robert Phillipsd3749482017-03-14 09:17:43 -0400130 return pmap;
bsalomon37f9a262015-02-02 13:00:10 -0800131}
132
Matt Sarettdedac852017-05-12 10:56:49 -0400133sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider* resourceProvider,
134 const SkPixmap& pixmap,
135 SkBudgeted budgeted,
136 SkColorSpace* dstColorSpace) {
137 SkDestinationSurfaceColorMode colorMode = dstColorSpace
138 ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
139 : SkDestinationSurfaceColorMode::kLegacy;
140
141 if (!SkImageInfoIsValid(pixmap.info(), colorMode)) {
142 return nullptr;
143 }
144
Robert Phillipsd3749482017-03-14 09:17:43 -0400145 SkBitmap tmpBitmap;
146 SkPixmap tmpPixmap;
147 GrSurfaceDesc desc;
148
Robert Phillips26c90e02017-03-14 14:39:29 -0400149 if (const SkPixmap* pmap = compute_desc(*resourceProvider->caps(), pixmap, &desc,
150 &tmpBitmap, &tmpPixmap)) {
151 return GrSurfaceProxy::MakeDeferred(resourceProvider, desc,
Robert Phillipsd3749482017-03-14 09:17:43 -0400152 budgeted, pmap->addr(), pmap->rowBytes());
153 }
154
155 return nullptr;
156}
bsalomonb4d40ef2015-07-15 10:12:16 -0700157
bsalomon045802d2015-10-20 07:58:01 -0700158////////////////////////////////////////////////////////////////////////////////
159
bsalomonc55271f2015-11-09 11:55:57 -0800160void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
bsalomon89fe56b2015-10-29 10:49:28 -0700161 class Invalidator : public SkPixelRef::GenIDChangeListener {
162 public:
163 explicit Invalidator(const GrUniqueKey& key) : fMsg(key) {}
164 private:
165 GrUniqueKeyInvalidatedMessage fMsg;
166
167 void onChange() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
168 };
169
170 pixelRef->addGenIDChangeListener(new Invalidator(key));
171}
172
Robert Phillips78075802017-03-23 11:11:59 -0400173sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext* ctx,
174 const SkBitmap& bitmap,
175 SkColorSpace* dstColorSpace) {
Brian Osman61624f02016-12-09 14:51:59 -0500176 SkDestinationSurfaceColorMode colorMode = dstColorSpace
177 ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
178 : SkDestinationSurfaceColorMode::kLegacy;
179
Matt Sarettdedac852017-05-12 10:56:49 -0400180 if (!SkImageInfoIsValid(bitmap.info(), colorMode)) {
Brian Osman4075ec82017-01-17 16:41:03 +0000181 return nullptr;
182 }
183
brianosmana6359362016-03-21 06:55:37 -0700184 GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info(), *ctx->caps());
cblume55f2d2d2016-02-26 13:20:48 -0800185
Mike Reed4edb5d22017-04-17 11:02:51 -0400186 SkPixmap pixmap;
187 if (!bitmap.peekPixels(&pixmap)) {
cblume55f2d2d2016-02-26 13:20:48 -0800188 return nullptr;
189 }
cblume55f2d2d2016-02-26 13:20:48 -0800190
Brian Osman7b8400d2016-11-08 17:08:54 -0500191 std::unique_ptr<SkMipMap> mipmaps(SkMipMap::Build(pixmap, colorMode, nullptr));
cblume55f2d2d2016-02-26 13:20:48 -0800192 if (!mipmaps) {
193 return nullptr;
194 }
195
196 const int mipLevelCount = mipmaps->countLevels() + 1;
197 if (mipLevelCount < 1) {
198 return nullptr;
199 }
200
201 const bool isMipMapped = mipLevelCount > 1;
202 desc.fIsMipMapped = isMipMapped;
203
Ben Wagner7ecc5962016-11-02 17:07:33 -0400204 std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
cblume55f2d2d2016-02-26 13:20:48 -0800205
206 texels[0].fPixels = pixmap.addr();
207 texels[0].fRowBytes = pixmap.rowBytes();
208
209 for (int i = 1; i < mipLevelCount; ++i) {
210 SkMipMap::Level generatedMipLevel;
211 mipmaps->getLevel(i - 1, &generatedMipLevel);
212 texels[i].fPixels = generatedMipLevel.fPixmap.addr();
213 texels[i].fRowBytes = generatedMipLevel.fPixmap.rowBytes();
214 }
215
Robert Phillips8e8c7552017-07-10 12:06:05 -0400216 return GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
217 desc,
218 SkBudgeted::kYes,
219 texels.get(),
220 mipLevelCount,
221 colorMode);
Robert Phillips0c984a02017-03-16 07:51:56 -0400222}
223
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400224sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext* ctx, const SkImageInfo& info,
Robert Phillips590533f2017-07-11 14:22:35 -0400225 const GrMipLevel texels[],
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400226 int mipLevelCount,
227 SkDestinationSurfaceColorMode colorMode) {
Matt Sarettdedac852017-05-12 10:56:49 -0400228 if (!SkImageInfoIsValid(info, colorMode)) {
Robert Phillips78075802017-03-23 11:11:59 -0400229 return nullptr;
230 }
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400231
Robert Phillips8e8c7552017-07-10 12:06:05 -0400232 return GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
233 GrImageInfoToSurfaceDesc(info, *ctx->caps()),
234 SkBudgeted::kYes, texels,
235 mipLevelCount, colorMode);
Robert Phillips0ae6faa2017-03-21 16:22:00 -0400236}
237
Robert Phillipsbbd7a3b2017-03-21 08:48:40 -0400238sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext* ctx,
239 const SkBitmap& bitmap,
240 const GrSamplerParams& params,
241 SkScalar scaleAdjust[2]) {
242 // Caller doesn't care about the texture's color space (they can always get it from the bitmap)
Robert Phillips3798c862017-03-27 11:08:16 -0400243 return GrBitmapTextureMaker(ctx, bitmap).refTextureProxyForParams(params, nullptr,
244 nullptr, scaleAdjust);
Robert Phillipsbbd7a3b2017-03-21 08:48:40 -0400245}
246
Robert Phillips26c90e02017-03-14 14:39:29 -0400247sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrResourceProvider* resourceProvider,
248 const SkBitmap& bitmap) {
Robert Phillipse14d3052017-02-15 13:18:21 -0500249 GrUniqueKey originalKey;
250
251 if (!bitmap.isVolatile()) {
252 SkIPoint origin = bitmap.pixelRefOrigin();
253 SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(), bitmap.height());
254 GrMakeKeyFromImageID(&originalKey, bitmap.pixelRef()->getGenerationID(), subset);
255 }
256
Robert Phillipsd3749482017-03-14 09:17:43 -0400257 sk_sp<GrTextureProxy> proxy;
Robert Phillipse14d3052017-02-15 13:18:21 -0500258
259 if (originalKey.isValid()) {
Robert Phillips26c90e02017-03-14 14:39:29 -0400260 proxy = resourceProvider->findProxyByUniqueKey(originalKey);
Robert Phillipse14d3052017-02-15 13:18:21 -0500261 }
Robert Phillipsd3749482017-03-14 09:17:43 -0400262 if (!proxy) {
Matt Sarettdedac852017-05-12 10:56:49 -0400263 // Pass nullptr for |dstColorSpace|. This is lenient - we allow a wider range of
264 // color spaces in legacy mode. Unfortunately, we have to be lenient here, since
265 // we can't necessarily know the |dstColorSpace| at this time.
266 proxy = GrUploadBitmapToTextureProxy(resourceProvider, bitmap, nullptr);
Robert Phillipsd3749482017-03-14 09:17:43 -0400267 if (proxy && originalKey.isValid()) {
Robert Phillips26c90e02017-03-14 14:39:29 -0400268 resourceProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
Robert Phillipsd3749482017-03-14 09:17:43 -0400269 // MDB TODO (caching): this has to play nice with the GrSurfaceProxy's caching
Robert Phillipse14d3052017-02-15 13:18:21 -0500270 GrInstallBitmapUniqueKeyInvalidator(originalKey, bitmap.pixelRef());
271 }
272 }
273
Robert Phillipsd3749482017-03-14 09:17:43 -0400274 return proxy;
Robert Phillipse14d3052017-02-15 13:18:21 -0500275}
276
rileya@google.com24f3ad12012-07-18 21:47:40 +0000277///////////////////////////////////////////////////////////////////////////////
278
Brian Osman72ae4312016-10-20 16:53:45 -0400279GrColor4f SkColorToPremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace) {
280 // We want to premultiply after linearizing, so this is easy:
281 return SkColorToUnpremulGrColor4f(c, dstColorSpace).premul();
282}
283
284GrColor4f SkColorToUnpremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace) {
285 if (dstColorSpace) {
Matt Sarett77a7a1b2017-02-07 13:56:11 -0500286 auto srgbColorSpace = SkColorSpace::MakeSRGB();
Brian Osman72ae4312016-10-20 16:53:45 -0400287 auto gamutXform = GrColorSpaceXform::Make(srgbColorSpace.get(), dstColorSpace);
Brian Osman47299142017-03-07 13:22:22 -0500288 return SkColorToUnpremulGrColor4f(c, dstColorSpace, gamutXform.get());
Brian Osman72ae4312016-10-20 16:53:45 -0400289 } else {
Brian Osman47299142017-03-07 13:22:22 -0500290 return SkColorToUnpremulGrColor4f(c, nullptr, nullptr);
Brian Osman72ae4312016-10-20 16:53:45 -0400291 }
292}
293
Brian Osman47299142017-03-07 13:22:22 -0500294GrColor4f SkColorToPremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace,
295 GrColorSpaceXform* gamutXform) {
Brian Osmanc68d4aa2016-09-30 11:41:59 -0400296 // We want to premultiply after linearizing, so this is easy:
Brian Osman47299142017-03-07 13:22:22 -0500297 return SkColorToUnpremulGrColor4f(c, dstColorSpace, gamutXform).premul();
Brian Osmanc68d4aa2016-09-30 11:41:59 -0400298}
299
Brian Osman47299142017-03-07 13:22:22 -0500300GrColor4f SkColorToUnpremulGrColor4f(SkColor c, SkColorSpace* dstColorSpace,
301 GrColorSpaceXform* gamutXform) {
Brian Osmanc68d4aa2016-09-30 11:41:59 -0400302 // You can't be color-space aware in legacy mode
Brian Osman47299142017-03-07 13:22:22 -0500303 SkASSERT(dstColorSpace || !gamutXform);
Brian Osmanc68d4aa2016-09-30 11:41:59 -0400304
305 GrColor4f color;
Brian Osman47299142017-03-07 13:22:22 -0500306 if (dstColorSpace) {
Brian Osmanc68d4aa2016-09-30 11:41:59 -0400307 // SkColor4f::FromColor does sRGB -> Linear
308 color = GrColor4f::FromSkColor4f(SkColor4f::FromColor(c));
309 } else {
310 // GrColor4f::FromGrColor just multiplies by 1/255
311 color = GrColor4f::FromGrColor(SkColorToUnpremulGrColor(c));
312 }
313
314 if (gamutXform) {
315 color = gamutXform->apply(color);
316 }
317
318 return color;
319}
320
321///////////////////////////////////////////////////////////////////////////////
322
Brian Osman0c2997b2017-01-11 16:58:42 -0500323GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info, const GrCaps& caps) {
brianosmana6359362016-03-21 06:55:37 -0700324 // We intentionally ignore profile type for non-8888 formats. Anything we can't support
325 // in hardware will be expanded to sRGB 8888 in GrUploadPixmapToTexture.
Brian Osman0c2997b2017-01-11 16:58:42 -0500326 SkColorSpace* cs = info.colorSpace();
327 switch (info.colorType()) {
brianosmanc571c002016-03-17 13:01:26 -0700328 case kUnknown_SkColorType:
329 return kUnknown_GrPixelConfig;
330 case kAlpha_8_SkColorType:
331 return kAlpha_8_GrPixelConfig;
332 case kRGB_565_SkColorType:
333 return kRGB_565_GrPixelConfig;
334 case kARGB_4444_SkColorType:
335 return kRGBA_4444_GrPixelConfig;
336 case kRGBA_8888_SkColorType:
Matt Sarettf3880932017-03-24 10:06:03 -0400337 return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
brianosmana6359362016-03-21 06:55:37 -0700338 ? kSRGBA_8888_GrPixelConfig : kRGBA_8888_GrPixelConfig;
brianosmanc571c002016-03-17 13:01:26 -0700339 case kBGRA_8888_SkColorType:
Matt Sarettf3880932017-03-24 10:06:03 -0400340 return (caps.srgbSupport() && cs && cs->gammaCloseToSRGB())
brianosmana6359362016-03-21 06:55:37 -0700341 ? kSBGRA_8888_GrPixelConfig : kBGRA_8888_GrPixelConfig;
brianosmanc571c002016-03-17 13:01:26 -0700342 case kIndex_8_SkColorType:
Brian Osmand0be1ef2017-01-11 16:57:15 -0500343 return kSkia8888_GrPixelConfig;
brianosmanc571c002016-03-17 13:01:26 -0700344 case kGray_8_SkColorType:
Brian Osman986563b2017-01-10 14:20:02 -0500345 return kGray_8_GrPixelConfig;
brianosmanc571c002016-03-17 13:01:26 -0700346 case kRGBA_F16_SkColorType:
347 return kRGBA_half_GrPixelConfig;
commit-bot@chromium.org15a14052014-02-16 00:59:25 +0000348 }
349 SkASSERT(0); // shouldn't get here
350 return kUnknown_GrPixelConfig;
351}
352
brianosman396fcdb2016-07-22 06:26:11 -0700353bool GrPixelConfigToColorType(GrPixelConfig config, SkColorType* ctOut) {
reed@google.combf790232013-12-13 19:45:58 +0000354 SkColorType ct;
355 switch (config) {
356 case kAlpha_8_GrPixelConfig:
357 ct = kAlpha_8_SkColorType;
358 break;
Brian Osman986563b2017-01-10 14:20:02 -0500359 case kGray_8_GrPixelConfig:
360 ct = kGray_8_SkColorType;
361 break;
reed@google.combf790232013-12-13 19:45:58 +0000362 case kRGB_565_GrPixelConfig:
363 ct = kRGB_565_SkColorType;
364 break;
365 case kRGBA_4444_GrPixelConfig:
366 ct = kARGB_4444_SkColorType;
367 break;
368 case kRGBA_8888_GrPixelConfig:
369 ct = kRGBA_8888_SkColorType;
370 break;
371 case kBGRA_8888_GrPixelConfig:
372 ct = kBGRA_8888_SkColorType;
373 break;
jvanverthfa1e8a72014-12-22 08:31:49 -0800374 case kSRGBA_8888_GrPixelConfig:
375 ct = kRGBA_8888_SkColorType;
jvanverthfa1e8a72014-12-22 08:31:49 -0800376 break;
brianosmana6359362016-03-21 06:55:37 -0700377 case kSBGRA_8888_GrPixelConfig:
378 ct = kBGRA_8888_SkColorType;
brianosmana6359362016-03-21 06:55:37 -0700379 break;
brianosman9ac5b912016-04-12 13:49:53 -0700380 case kRGBA_half_GrPixelConfig:
381 ct = kRGBA_F16_SkColorType;
382 break;
reed@google.combf790232013-12-13 19:45:58 +0000383 default:
384 return false;
385 }
386 if (ctOut) {
387 *ctOut = ct;
388 }
389 return true;
390}
commit-bot@chromium.org8dcff642014-05-15 20:32:48 +0000391
brianosman27a3aa52016-09-23 07:11:34 -0700392GrPixelConfig GrRenderableConfigForColorSpace(const SkColorSpace* colorSpace) {
Matt Sarettf3880932017-03-24 10:06:03 -0400393 if (!colorSpace) {
brianosman2695eaa2016-09-21 06:45:09 -0700394 return kRGBA_8888_GrPixelConfig;
395 } else if (colorSpace->gammaIsLinear()) {
396 return kRGBA_half_GrPixelConfig;
397 } else if (colorSpace->gammaCloseToSRGB()) {
398 return kSRGBA_8888_GrPixelConfig;
399 } else {
400 SkDEBUGFAIL("No renderable config exists for color space with strange gamma");
401 return kUnknown_GrPixelConfig;
402 }
403}
404
bsalomonf1b7a1d2015-09-28 06:26:28 -0700405////////////////////////////////////////////////////////////////////////////////////////////////
commit-bot@chromium.org8dcff642014-05-15 20:32:48 +0000406
Mike Reed185ba212017-04-28 12:31:05 -0400407static inline bool blend_requires_shader(const SkBlendMode mode) {
408 return SkBlendMode::kDst != mode;
bsalomonaa48d362015-10-01 08:34:17 -0700409}
410
bsalomonf1b7a1d2015-09-28 06:26:28 -0700411static inline bool skpaint_to_grpaint_impl(GrContext* context,
Brian Osman11052242016-10-27 14:47:55 -0400412 GrRenderTargetContext* rtc,
bsalomonf1b7a1d2015-09-28 06:26:28 -0700413 const SkPaint& skPaint,
414 const SkMatrix& viewM,
bungeman06ca8ec2016-06-09 08:01:03 -0700415 sk_sp<GrFragmentProcessor>* shaderProcessor,
Mike Reed7d954ad2016-10-28 15:42:34 -0400416 SkBlendMode* primColorMode,
bsalomonf1b7a1d2015-09-28 06:26:28 -0700417 GrPaint* grPaint) {
Brian Osman11052242016-10-27 14:47:55 -0400418 grPaint->setAllowSRGBInputs(rtc->isGammaCorrect());
commit-bot@chromium.org8dcff642014-05-15 20:32:48 +0000419
Brian Osmanc68d4aa2016-09-30 11:41:59 -0400420 // Convert SkPaint color to 4f format, including optional linearizing and gamut conversion.
Brian Osman47299142017-03-07 13:22:22 -0500421 GrColor4f origColor = SkColorToUnpremulGrColor4f(skPaint.getColor(), rtc->getColorSpace(),
Brian Osman11052242016-10-27 14:47:55 -0400422 rtc->getColorXformFromSRGB());
brianosmana4535a32016-06-24 12:50:19 -0700423
bsalomonf1b7a1d2015-09-28 06:26:28 -0700424 // Setup the initial color considering the shader, the SkPaint color, and the presence or not
425 // of per-vertex colors.
bungeman06ca8ec2016-06-09 08:01:03 -0700426 sk_sp<GrFragmentProcessor> shaderFP;
Mike Reed185ba212017-04-28 12:31:05 -0400427 if (!primColorMode || blend_requires_shader(*primColorMode)) {
bsalomonaa48d362015-10-01 08:34:17 -0700428 if (shaderProcessor) {
429 shaderFP = *shaderProcessor;
Florin Malita4aed1382017-05-25 10:38:07 -0400430 } else if (const auto* shader = as_SB(skPaint.getShader())) {
431 shaderFP = shader->asFragmentProcessor(
432 SkShaderBase::AsFPArgs(context, &viewM, nullptr, skPaint.getFilterQuality(),
433 rtc->getColorSpace()));
bsalomonaa48d362015-10-01 08:34:17 -0700434 if (!shaderFP) {
435 return false;
436 }
bsalomonf1b7a1d2015-09-28 06:26:28 -0700437 }
438 }
439
440 // Set this in below cases if the output of the shader/paint-color/paint-alpha/primXfermode is
441 // a known constant value. In that case we can simply apply a color filter during this
442 // conversion without converting the color filter to a GrFragmentProcessor.
443 bool applyColorFilterToPaintColor = false;
444 if (shaderFP) {
445 if (primColorMode) {
446 // There is a blend between the primitive color and the shader color. The shader sees
447 // the opaque paint color. The shader's output is blended using the provided mode by
448 // the primitive color. The blended color is then modulated by the paint's alpha.
449
450 // The geometry processor will insert the primitive color to start the color chain, so
451 // the GrPaint color will be ignored.
452
brianosman4cea3b92016-09-08 09:33:50 -0700453 GrColor4f shaderInput = origColor.opaque();
bsalomonf1b7a1d2015-09-28 06:26:28 -0700454 shaderFP = GrFragmentProcessor::OverrideInput(shaderFP, shaderInput);
Mike Reed185ba212017-04-28 12:31:05 -0400455 shaderFP = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(shaderFP),
456 *primColorMode);
457
bsalomonf1b7a1d2015-09-28 06:26:28 -0700458 // The above may return null if compose results in a pass through of the prim color.
459 if (shaderFP) {
Robert Phillips1c9686b2017-06-30 08:40:28 -0400460 grPaint->addColorFragmentProcessor(std::move(shaderFP));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700461 }
462
brianosmana4535a32016-06-24 12:50:19 -0700463 // We can ignore origColor here - alpha is unchanged by gamma
bsalomonf1b7a1d2015-09-28 06:26:28 -0700464 GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
465 if (GrColor_WHITE != paintAlpha) {
Brian Osman618d3042016-10-25 10:51:28 -0400466 // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
467 // color channels. It's value should be treated as the same in ANY color space.
bungeman06ca8ec2016-06-09 08:01:03 -0700468 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
Brian Osman618d3042016-10-25 10:51:28 -0400469 GrColor4f::FromGrColor(paintAlpha),
470 GrConstColorProcessor::kModulateRGBA_InputMode));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700471 }
472 } else {
473 // The shader's FP sees the paint unpremul color
brianosmana4535a32016-06-24 12:50:19 -0700474 grPaint->setColor4f(origColor);
bungeman06ca8ec2016-06-09 08:01:03 -0700475 grPaint->addColorFragmentProcessor(std::move(shaderFP));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700476 }
477 } else {
478 if (primColorMode) {
479 // There is a blend between the primitive color and the paint color. The blend considers
480 // the opaque paint color. The paint's alpha is applied to the post-blended color.
bungeman06ca8ec2016-06-09 08:01:03 -0700481 sk_sp<GrFragmentProcessor> processor(
Brian Osman618d3042016-10-25 10:51:28 -0400482 GrConstColorProcessor::Make(origColor.opaque(),
483 GrConstColorProcessor::kIgnore_InputMode));
Mike Reed185ba212017-04-28 12:31:05 -0400484 processor = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(processor),
485 *primColorMode);
bsalomonf1b7a1d2015-09-28 06:26:28 -0700486 if (processor) {
bungeman06ca8ec2016-06-09 08:01:03 -0700487 grPaint->addColorFragmentProcessor(std::move(processor));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700488 }
489
brianosmana4535a32016-06-24 12:50:19 -0700490 grPaint->setColor4f(origColor.opaque());
bsalomonf1b7a1d2015-09-28 06:26:28 -0700491
brianosmana4535a32016-06-24 12:50:19 -0700492 // We can ignore origColor here - alpha is unchanged by gamma
bsalomonf1b7a1d2015-09-28 06:26:28 -0700493 GrColor paintAlpha = SkColorAlphaToGrColor(skPaint.getColor());
bsalomonaa48d362015-10-01 08:34:17 -0700494 if (GrColor_WHITE != paintAlpha) {
Brian Osman618d3042016-10-25 10:51:28 -0400495 // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
496 // color channels. It's value should be treated as the same in ANY color space.
bungeman06ca8ec2016-06-09 08:01:03 -0700497 grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
Brian Osman618d3042016-10-25 10:51:28 -0400498 GrColor4f::FromGrColor(paintAlpha),
499 GrConstColorProcessor::kModulateRGBA_InputMode));
bsalomonaa48d362015-10-01 08:34:17 -0700500 }
bsalomonf1b7a1d2015-09-28 06:26:28 -0700501 } else {
502 // No shader, no primitive color.
brianosmana4535a32016-06-24 12:50:19 -0700503 grPaint->setColor4f(origColor.premul());
bsalomonf1b7a1d2015-09-28 06:26:28 -0700504 applyColorFilterToPaintColor = true;
505 }
506 }
507
508 SkColorFilter* colorFilter = skPaint.getColorFilter();
509 if (colorFilter) {
510 if (applyColorFilterToPaintColor) {
Brian Osman8bf4e672016-10-17 16:54:49 -0400511 // If we're in legacy mode, we *must* avoid using the 4f version of the color filter,
512 // because that will combine with the linearized version of the stored color.
Brian Osman11052242016-10-27 14:47:55 -0400513 if (rtc->isGammaCorrect()) {
Brian Osman8bf4e672016-10-17 16:54:49 -0400514 grPaint->setColor4f(GrColor4f::FromSkColor4f(
515 colorFilter->filterColor4f(origColor.toSkColor4f())).premul());
516 } else {
517 grPaint->setColor4f(SkColorToPremulGrColor4f(
Brian Osman47299142017-03-07 13:22:22 -0500518 colorFilter->filterColor(skPaint.getColor()), nullptr, nullptr));
Brian Osman8bf4e672016-10-17 16:54:49 -0400519 }
bsalomonf1b7a1d2015-09-28 06:26:28 -0700520 } else {
Brian Osman618d3042016-10-25 10:51:28 -0400521 sk_sp<GrFragmentProcessor> cfFP(colorFilter->asFragmentProcessor(context,
Brian Osman11052242016-10-27 14:47:55 -0400522 rtc->getColorSpace()));
bsalomone25eea42015-09-29 06:38:55 -0700523 if (cfFP) {
bungeman06ca8ec2016-06-09 08:01:03 -0700524 grPaint->addColorFragmentProcessor(std::move(cfFP));
bsalomonf1b7a1d2015-09-28 06:26:28 -0700525 } else {
526 return false;
527 }
528 }
529 }
530
Robert Phillipsa29a9562016-10-20 09:40:55 -0400531 SkMaskFilter* maskFilter = skPaint.getMaskFilter();
532 if (maskFilter) {
533 GrFragmentProcessor* mfFP;
Robert Phillipsd9d84852017-06-09 10:48:29 -0400534 if (maskFilter->asFragmentProcessor(&mfFP)) {
Robert Phillipsa29a9562016-10-20 09:40:55 -0400535 grPaint->addCoverageFragmentProcessor(sk_sp<GrFragmentProcessor>(mfFP));
536 }
537 }
538
robertphillips4f037942016-02-09 05:09:27 -0800539 // When the xfermode is null on the SkPaint (meaning kSrcOver) we need the XPFactory field on
540 // the GrPaint to also be null (also kSrcOver).
541 SkASSERT(!grPaint->getXPFactory());
reed374772b2016-10-05 17:33:02 -0700542 if (!skPaint.isSrcOver()) {
543 grPaint->setXPFactory(SkBlendMode_AsXPFactory(skPaint.getBlendMode()));
robertphillips4f037942016-02-09 05:09:27 -0800544 }
mtklein775b8192014-12-02 09:11:25 -0800545
krajcevskif461a8f2014-06-19 14:14:06 -0700546#ifndef SK_IGNORE_GPU_DITHER
Florin Malitad4a70ee2017-06-19 10:21:43 -0400547 // Conservative default, in case GrPixelConfigToColorType() fails.
548 SkColorType ct = SkColorType::kRGB_565_SkColorType;
549 GrPixelConfigToColorType(rtc->config(), &ct);
550 if (SkPaintPriv::ShouldDither(skPaint, ct) && grPaint->numColorFragmentProcessors() > 0
551 && !rtc->isGammaCorrect()) {
bungeman06ca8ec2016-06-09 08:01:03 -0700552 grPaint->addColorFragmentProcessor(GrDitherEffect::Make());
krajcevskif461a8f2014-06-19 14:14:06 -0700553 }
554#endif
bsalomonbed83a62015-04-15 14:18:34 -0700555 return true;
commit-bot@chromium.org8dcff642014-05-15 20:32:48 +0000556}
557
Brian Osman11052242016-10-27 14:47:55 -0400558bool SkPaintToGrPaint(GrContext* context, GrRenderTargetContext* rtc, const SkPaint& skPaint,
brianosman8fe485b2016-07-25 12:31:51 -0700559 const SkMatrix& viewM, GrPaint* grPaint) {
Mike Reed185ba212017-04-28 12:31:05 -0400560 return skpaint_to_grpaint_impl(context, rtc, skPaint, viewM, nullptr, nullptr, grPaint);
bsalomonf1b7a1d2015-09-28 06:26:28 -0700561}
commit-bot@chromium.org8dcff642014-05-15 20:32:48 +0000562
bsalomonf1b7a1d2015-09-28 06:26:28 -0700563/** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. */
564bool SkPaintToGrPaintReplaceShader(GrContext* context,
Brian Osman11052242016-10-27 14:47:55 -0400565 GrRenderTargetContext* rtc,
bsalomonf1b7a1d2015-09-28 06:26:28 -0700566 const SkPaint& skPaint,
bungeman06ca8ec2016-06-09 08:01:03 -0700567 sk_sp<GrFragmentProcessor> shaderFP,
bsalomonf1b7a1d2015-09-28 06:26:28 -0700568 GrPaint* grPaint) {
569 if (!shaderFP) {
bsalomonc21b09e2015-08-28 18:46:56 -0700570 return false;
commit-bot@chromium.org8dcff642014-05-15 20:32:48 +0000571 }
Mike Reed185ba212017-04-28 12:31:05 -0400572 return skpaint_to_grpaint_impl(context, rtc, skPaint, SkMatrix::I(), &shaderFP, nullptr,
brianosman8fe485b2016-07-25 12:31:51 -0700573 grPaint);
commit-bot@chromium.org8dcff642014-05-15 20:32:48 +0000574}
reed8b26b992015-05-07 15:36:17 -0700575
bsalomonf1b7a1d2015-09-28 06:26:28 -0700576/** Ignores the SkShader (if any) on skPaint. */
577bool SkPaintToGrPaintNoShader(GrContext* context,
Brian Osman11052242016-10-27 14:47:55 -0400578 GrRenderTargetContext* rtc,
bsalomonf1b7a1d2015-09-28 06:26:28 -0700579 const SkPaint& skPaint,
580 GrPaint* grPaint) {
581 // Use a ptr to a nullptr to to indicate that the SkShader is ignored and not replaced.
bungeman06ca8ec2016-06-09 08:01:03 -0700582 static sk_sp<GrFragmentProcessor> kNullShaderFP(nullptr);
583 static sk_sp<GrFragmentProcessor>* kIgnoreShader = &kNullShaderFP;
Brian Osman11052242016-10-27 14:47:55 -0400584 return skpaint_to_grpaint_impl(context, rtc, skPaint, SkMatrix::I(), kIgnoreShader, nullptr,
Mike Reed185ba212017-04-28 12:31:05 -0400585 grPaint);
bsalomonf1b7a1d2015-09-28 06:26:28 -0700586}
587
588/** Blends the SkPaint's shader (or color if no shader) with a per-primitive color which must
Mike Reed7d954ad2016-10-28 15:42:34 -0400589be setup as a vertex attribute using the specified SkBlendMode. */
bsalomonf1b7a1d2015-09-28 06:26:28 -0700590bool SkPaintToGrPaintWithXfermode(GrContext* context,
Brian Osman11052242016-10-27 14:47:55 -0400591 GrRenderTargetContext* rtc,
bsalomonf1b7a1d2015-09-28 06:26:28 -0700592 const SkPaint& skPaint,
593 const SkMatrix& viewM,
Mike Reed7d954ad2016-10-28 15:42:34 -0400594 SkBlendMode primColorMode,
bsalomonf1b7a1d2015-09-28 06:26:28 -0700595 GrPaint* grPaint) {
Brian Osman11052242016-10-27 14:47:55 -0400596 return skpaint_to_grpaint_impl(context, rtc, skPaint, viewM, nullptr, &primColorMode,
Mike Reed185ba212017-04-28 12:31:05 -0400597 grPaint);
bsalomonf1b7a1d2015-09-28 06:26:28 -0700598}
599
joshualitt33a5fce2015-11-18 13:28:51 -0800600bool SkPaintToGrPaintWithTexture(GrContext* context,
Brian Osman11052242016-10-27 14:47:55 -0400601 GrRenderTargetContext* rtc,
joshualitt33a5fce2015-11-18 13:28:51 -0800602 const SkPaint& paint,
603 const SkMatrix& viewM,
bungeman06ca8ec2016-06-09 08:01:03 -0700604 sk_sp<GrFragmentProcessor> fp,
joshualitt33a5fce2015-11-18 13:28:51 -0800605 bool textureIsAlphaOnly,
606 GrPaint* grPaint) {
bungeman06ca8ec2016-06-09 08:01:03 -0700607 sk_sp<GrFragmentProcessor> shaderFP;
joshualitt33a5fce2015-11-18 13:28:51 -0800608 if (textureIsAlphaOnly) {
Florin Malita4aed1382017-05-25 10:38:07 -0400609 if (const auto* shader = as_SB(paint.getShader())) {
610 shaderFP = shader->asFragmentProcessor(
611 SkShaderBase::AsFPArgs(context, &viewM, nullptr, paint.getFilterQuality(),
612 rtc->getColorSpace()));
joshualitt33a5fce2015-11-18 13:28:51 -0800613 if (!shaderFP) {
614 return false;
615 }
bungeman06ca8ec2016-06-09 08:01:03 -0700616 sk_sp<GrFragmentProcessor> fpSeries[] = { std::move(shaderFP), std::move(fp) };
617 shaderFP = GrFragmentProcessor::RunInSeries(fpSeries, 2);
joshualitt33a5fce2015-11-18 13:28:51 -0800618 } else {
Brian Salomon22af73f2017-01-26 11:25:12 -0500619 shaderFP = GrFragmentProcessor::MakeInputPremulAndMulByOutput(fp);
joshualitt33a5fce2015-11-18 13:28:51 -0800620 }
621 } else {
bungeman06ca8ec2016-06-09 08:01:03 -0700622 shaderFP = GrFragmentProcessor::MulOutputByInputAlpha(fp);
joshualitt33a5fce2015-11-18 13:28:51 -0800623 }
624
Brian Osman11052242016-10-27 14:47:55 -0400625 return SkPaintToGrPaintReplaceShader(context, rtc, paint, std::move(shaderFP), grPaint);
joshualitt33a5fce2015-11-18 13:28:51 -0800626}
627
bsalomonf1b7a1d2015-09-28 06:26:28 -0700628
629////////////////////////////////////////////////////////////////////////////////////////////////
630
Brian Salomon514baff2016-11-17 15:17:07 -0500631GrSamplerParams::FilterMode GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,
joshualitt9bc39542015-08-12 12:57:54 -0700632 const SkMatrix& viewM,
633 const SkMatrix& localM,
634 bool* doBicubic) {
635 *doBicubic = false;
Brian Salomon514baff2016-11-17 15:17:07 -0500636 GrSamplerParams::FilterMode textureFilterMode;
joshualitt9bc39542015-08-12 12:57:54 -0700637 switch (paintFilterQuality) {
638 case kNone_SkFilterQuality:
Brian Salomon514baff2016-11-17 15:17:07 -0500639 textureFilterMode = GrSamplerParams::kNone_FilterMode;
joshualitt9bc39542015-08-12 12:57:54 -0700640 break;
641 case kLow_SkFilterQuality:
Brian Salomon514baff2016-11-17 15:17:07 -0500642 textureFilterMode = GrSamplerParams::kBilerp_FilterMode;
joshualitt9bc39542015-08-12 12:57:54 -0700643 break;
644 case kMedium_SkFilterQuality: {
645 SkMatrix matrix;
646 matrix.setConcat(viewM, localM);
647 if (matrix.getMinScale() < SK_Scalar1) {
Brian Salomon514baff2016-11-17 15:17:07 -0500648 textureFilterMode = GrSamplerParams::kMipMap_FilterMode;
joshualitt9bc39542015-08-12 12:57:54 -0700649 } else {
650 // Don't trigger MIP level generation unnecessarily.
Brian Salomon514baff2016-11-17 15:17:07 -0500651 textureFilterMode = GrSamplerParams::kBilerp_FilterMode;
joshualitt9bc39542015-08-12 12:57:54 -0700652 }
653 break;
654 }
655 case kHigh_SkFilterQuality: {
656 SkMatrix matrix;
657 matrix.setConcat(viewM, localM);
658 *doBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
659 break;
660 }
661 default:
Mike Kleine54c75f2016-10-13 14:18:09 -0400662 // Should be unreachable. If not, fall back to mipmaps.
Brian Salomon514baff2016-11-17 15:17:07 -0500663 textureFilterMode = GrSamplerParams::kMipMap_FilterMode;
joshualitt9bc39542015-08-12 12:57:54 -0700664 break;
665
666 }
667 return textureFilterMode;
668}