SkGr.cpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  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. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkColorFilter.h"
  9. #include "include/core/SkData.h"
  10. #include "include/core/SkPixelRef.h"
  11. #include "include/gpu/GrContext.h"
  12. #include "include/gpu/GrTypes.h"
  13. #include "include/private/GrRecordingContext.h"
  14. #include "include/private/SkImageInfoPriv.h"
  15. #include "include/private/SkTemplates.h"
  16. #include "src/core/SkAutoMalloc.h"
  17. #include "src/core/SkBlendModePriv.h"
  18. #include "src/core/SkImagePriv.h"
  19. #include "src/core/SkMaskFilterBase.h"
  20. #include "src/core/SkMessageBus.h"
  21. #include "src/core/SkMipMap.h"
  22. #include "src/core/SkPaintPriv.h"
  23. #include "src/core/SkResourceCache.h"
  24. #include "src/core/SkTraceEvent.h"
  25. #include "src/gpu/GrBitmapTextureMaker.h"
  26. #include "src/gpu/GrCaps.h"
  27. #include "src/gpu/GrColorSpaceXform.h"
  28. #include "src/gpu/GrContextPriv.h"
  29. #include "src/gpu/GrGpuResourcePriv.h"
  30. #include "src/gpu/GrPaint.h"
  31. #include "src/gpu/GrProxyProvider.h"
  32. #include "src/gpu/GrRecordingContextPriv.h"
  33. #include "src/gpu/GrTextureProxy.h"
  34. #include "src/gpu/GrXferProcessor.h"
  35. #include "src/gpu/SkGr.h"
  36. #include "src/gpu/effects/GrBicubicEffect.h"
  37. #include "src/gpu/effects/GrPorterDuffXferProcessor.h"
  38. #include "src/gpu/effects/GrSkSLFP.h"
  39. #include "src/gpu/effects/GrXfermodeFragmentProcessor.h"
  40. #include "src/gpu/effects/generated/GrConstColorProcessor.h"
  41. #include "src/image/SkImage_Base.h"
  42. #include "src/shaders/SkShaderBase.h"
  43. #if SK_SUPPORT_GPU
  44. GR_FP_SRC_STRING SKSL_DITHER_SRC = R"(
  45. // This controls the range of values added to color channels
  46. layout(key) in int rangeType;
  47. void main(float x, float y, inout half4 color) {
  48. half value;
  49. half range;
  50. @switch (rangeType) {
  51. case 0:
  52. range = 1.0 / 255.0;
  53. break;
  54. case 1:
  55. range = 1.0 / 63.0;
  56. break;
  57. default:
  58. // Experimentally this looks better than the expected value of 1/15.
  59. range = 1.0 / 15.0;
  60. break;
  61. }
  62. @if (sk_Caps.integerSupport) {
  63. // This ordered-dither code is lifted from the cpu backend.
  64. uint x = uint(x);
  65. uint y = uint(y);
  66. uint m = (y & 1) << 5 | (x & 1) << 4 |
  67. (y & 2) << 2 | (x & 2) << 1 |
  68. (y & 4) >> 1 | (x & 4) >> 2;
  69. value = half(m) * 1.0 / 64.0 - 63.0 / 128.0;
  70. } else {
  71. // Simulate the integer effect used above using step/mod. For speed, simulates a 4x4
  72. // dither pattern rather than an 8x8 one.
  73. half4 modValues = mod(half4(half(x), half(y), half(x), half(y)), half4(2.0, 2.0, 4.0, 4.0));
  74. half4 stepValues = step(modValues, half4(1.0, 1.0, 2.0, 2.0));
  75. value = dot(stepValues, half4(8.0 / 16.0, 4.0 / 16.0, 2.0 / 16.0, 1.0 / 16.0)) - 15.0 / 32.0;
  76. }
  77. // For each color channel, add the random offset to the channel value and then clamp
  78. // between 0 and alpha to keep the color premultiplied.
  79. color = half4(clamp(color.rgb + value * range, 0.0, color.a), color.a);
  80. }
  81. )";
  82. #endif
  83. GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) {
  84. GrSurfaceDesc desc;
  85. desc.fWidth = info.width();
  86. desc.fHeight = info.height();
  87. desc.fConfig = SkImageInfo2GrPixelConfig(info);
  88. return desc;
  89. }
  90. void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& imageBounds) {
  91. SkASSERT(key);
  92. SkASSERT(imageID);
  93. SkASSERT(!imageBounds.isEmpty());
  94. static const GrUniqueKey::Domain kImageIDDomain = GrUniqueKey::GenerateDomain();
  95. GrUniqueKey::Builder builder(key, kImageIDDomain, 5, "Image");
  96. builder[0] = imageID;
  97. builder[1] = imageBounds.fLeft;
  98. builder[2] = imageBounds.fTop;
  99. builder[3] = imageBounds.fRight;
  100. builder[4] = imageBounds.fBottom;
  101. }
  102. ////////////////////////////////////////////////////////////////////////////////
  103. void GrInstallBitmapUniqueKeyInvalidator(const GrUniqueKey& key, uint32_t contextUniqueID,
  104. SkPixelRef* pixelRef) {
  105. class Invalidator : public SkPixelRef::GenIDChangeListener {
  106. public:
  107. explicit Invalidator(const GrUniqueKey& key, uint32_t contextUniqueID)
  108. : fMsg(key, contextUniqueID) {}
  109. private:
  110. GrUniqueKeyInvalidatedMessage fMsg;
  111. void onChange() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
  112. };
  113. pixelRef->addGenIDChangeListener(new Invalidator(key, contextUniqueID));
  114. }
  115. sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrRecordingContext* ctx,
  116. GrTextureProxy* baseProxy) {
  117. SkASSERT(baseProxy);
  118. if (!ctx->priv().caps()->isConfigCopyable(baseProxy->config())) {
  119. return nullptr;
  120. }
  121. return GrSurfaceProxy::Copy(ctx, baseProxy, GrMipMapped::kYes, SkBackingFit::kExact,
  122. SkBudgeted::kYes);
  123. }
  124. sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrRecordingContext* ctx,
  125. const SkBitmap& bitmap,
  126. const GrSamplerState& params,
  127. SkScalar scaleAdjust[2]) {
  128. return GrBitmapTextureMaker(ctx, bitmap).refTextureProxyForParams(params, scaleAdjust);
  129. }
  130. sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider* proxyProvider,
  131. const SkBitmap& bitmap,
  132. SkBackingFit fit) {
  133. if (!bitmap.peekPixels(nullptr)) {
  134. return nullptr;
  135. }
  136. // In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
  137. // even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the
  138. // upload of the data to the gpu can happen at anytime and the bitmap may change by then.
  139. SkCopyPixelsMode cpyMode = proxyProvider->renderingDirectly() ? kNever_SkCopyPixelsMode
  140. : kIfMutable_SkCopyPixelsMode;
  141. sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, cpyMode);
  142. if (!image) {
  143. return nullptr;
  144. }
  145. return GrMakeCachedImageProxy(proxyProvider, std::move(image), fit);
  146. }
  147. static void create_unique_key_for_image(const SkImage* image, GrUniqueKey* result) {
  148. if (!image) {
  149. result->reset(); // will be invalid
  150. return;
  151. }
  152. if (const SkBitmap* bm = as_IB(image)->onPeekBitmap()) {
  153. if (!bm->isVolatile()) {
  154. SkIPoint origin = bm->pixelRefOrigin();
  155. SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bm->width(), bm->height());
  156. GrMakeKeyFromImageID(result, bm->getGenerationID(), subset);
  157. }
  158. return;
  159. }
  160. GrMakeKeyFromImageID(result, image->uniqueID(), image->bounds());
  161. }
  162. sk_sp<GrTextureProxy> GrMakeCachedImageProxy(GrProxyProvider* proxyProvider,
  163. sk_sp<SkImage> srcImage,
  164. SkBackingFit fit) {
  165. sk_sp<GrTextureProxy> proxy;
  166. GrUniqueKey originalKey;
  167. create_unique_key_for_image(srcImage.get(), &originalKey);
  168. if (originalKey.isValid()) {
  169. proxy = proxyProvider->findOrCreateProxyByUniqueKey(originalKey, kTopLeft_GrSurfaceOrigin);
  170. }
  171. if (!proxy) {
  172. proxy = proxyProvider->createTextureProxy(srcImage, GrRenderable::kNo, 1, SkBudgeted::kYes,
  173. fit);
  174. if (proxy && originalKey.isValid()) {
  175. proxyProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
  176. const SkBitmap* bm = as_IB(srcImage.get())->onPeekBitmap();
  177. // When recording DDLs we do not want to install change listeners because doing
  178. // so isn't threadsafe.
  179. if (bm && proxyProvider->renderingDirectly()) {
  180. GrInstallBitmapUniqueKeyInvalidator(originalKey, proxyProvider->contextID(),
  181. bm->pixelRef());
  182. }
  183. }
  184. }
  185. return proxy;
  186. }
  187. ///////////////////////////////////////////////////////////////////////////////
  188. SkPMColor4f SkColorToPMColor4f(SkColor c, const GrColorSpaceInfo& colorSpaceInfo) {
  189. SkColor4f color = SkColor4f::FromColor(c);
  190. if (auto* xform = colorSpaceInfo.colorSpaceXformFromSRGB()) {
  191. color = xform->apply(color);
  192. }
  193. return color.premul();
  194. }
  195. SkColor4f SkColor4fPrepForDst(SkColor4f color, const GrColorSpaceInfo& colorSpaceInfo) {
  196. if (auto* xform = colorSpaceInfo.colorSpaceXformFromSRGB()) {
  197. color = xform->apply(color);
  198. }
  199. return color;
  200. }
  201. ///////////////////////////////////////////////////////////////////////////////
  202. GrPixelConfig SkColorType2GrPixelConfig(const SkColorType type) {
  203. switch (type) {
  204. case kUnknown_SkColorType:
  205. return kUnknown_GrPixelConfig;
  206. case kAlpha_8_SkColorType:
  207. return kAlpha_8_GrPixelConfig;
  208. case kRGB_565_SkColorType:
  209. return kRGB_565_GrPixelConfig;
  210. case kARGB_4444_SkColorType:
  211. return kRGBA_4444_GrPixelConfig;
  212. case kRGBA_8888_SkColorType:
  213. return kRGBA_8888_GrPixelConfig;
  214. case kRGB_888x_SkColorType:
  215. return kRGB_888_GrPixelConfig;
  216. case kBGRA_8888_SkColorType:
  217. return kBGRA_8888_GrPixelConfig;
  218. case kRGBA_1010102_SkColorType:
  219. return kRGBA_1010102_GrPixelConfig;
  220. case kRGB_101010x_SkColorType:
  221. return kUnknown_GrPixelConfig;
  222. case kGray_8_SkColorType:
  223. return kGray_8_GrPixelConfig;
  224. case kRGBA_F16Norm_SkColorType:
  225. return kRGBA_half_Clamped_GrPixelConfig;
  226. case kRGBA_F16_SkColorType:
  227. return kRGBA_half_GrPixelConfig;
  228. case kRGBA_F32_SkColorType:
  229. return kRGBA_float_GrPixelConfig;
  230. }
  231. SkASSERT(0); // shouldn't get here
  232. return kUnknown_GrPixelConfig;
  233. }
  234. GrPixelConfig SkImageInfo2GrPixelConfig(const SkImageInfo& info) {
  235. return SkColorType2GrPixelConfig(info.colorType());
  236. }
  237. bool GrPixelConfigToColorType(GrPixelConfig config, SkColorType* ctOut) {
  238. SkColorType ct = GrColorTypeToSkColorType(GrPixelConfigToColorType(config));
  239. if (kUnknown_SkColorType != ct) {
  240. if (ctOut) {
  241. *ctOut = ct;
  242. }
  243. return true;
  244. }
  245. return false;
  246. }
  247. ////////////////////////////////////////////////////////////////////////////////////////////////
  248. static inline bool blend_requires_shader(const SkBlendMode mode) {
  249. return SkBlendMode::kDst != mode;
  250. }
  251. #ifndef SK_IGNORE_GPU_DITHER
  252. static inline int32_t dither_range_type_for_config(GrColorType dstColorType) {
  253. switch (dstColorType) {
  254. case GrColorType::kGray_8:
  255. case GrColorType::kRGBA_8888:
  256. case GrColorType::kRGB_888x:
  257. case GrColorType::kRG_88:
  258. case GrColorType::kBGRA_8888:
  259. case GrColorType::kR_16:
  260. case GrColorType::kRG_1616:
  261. // Experimental (for Y416 and mutant P016/P010)
  262. case GrColorType::kRGBA_16161616:
  263. case GrColorType::kRG_F16:
  264. return 0;
  265. case GrColorType::kBGR_565:
  266. return 1;
  267. case GrColorType::kABGR_4444:
  268. return 2;
  269. case GrColorType::kUnknown:
  270. case GrColorType::kRGBA_8888_SRGB:
  271. case GrColorType::kRGBA_1010102:
  272. case GrColorType::kAlpha_F16:
  273. case GrColorType::kRGBA_F32:
  274. case GrColorType::kRGBA_F16:
  275. case GrColorType::kRGBA_F16_Clamped:
  276. case GrColorType::kAlpha_8:
  277. return -1;
  278. }
  279. SkUNREACHABLE;
  280. }
  281. #endif
  282. static inline bool skpaint_to_grpaint_impl(GrRecordingContext* context,
  283. const GrColorSpaceInfo& colorSpaceInfo,
  284. const SkPaint& skPaint,
  285. const SkMatrix& viewM,
  286. std::unique_ptr<GrFragmentProcessor>* shaderProcessor,
  287. SkBlendMode* primColorMode,
  288. GrPaint* grPaint) {
  289. // Convert SkPaint color to 4f format in the destination color space
  290. SkColor4f origColor = SkColor4fPrepForDst(skPaint.getColor4f(), colorSpaceInfo);
  291. GrFPArgs fpArgs(context, &viewM, skPaint.getFilterQuality(), &colorSpaceInfo);
  292. // Setup the initial color considering the shader, the SkPaint color, and the presence or not
  293. // of per-vertex colors.
  294. std::unique_ptr<GrFragmentProcessor> shaderFP;
  295. if (!primColorMode || blend_requires_shader(*primColorMode)) {
  296. fpArgs.fInputColorIsOpaque = origColor.isOpaque();
  297. if (shaderProcessor) {
  298. shaderFP = std::move(*shaderProcessor);
  299. } else if (const auto* shader = as_SB(skPaint.getShader())) {
  300. shaderFP = shader->asFragmentProcessor(fpArgs);
  301. if (!shaderFP) {
  302. return false;
  303. }
  304. }
  305. }
  306. // Set this in below cases if the output of the shader/paint-color/paint-alpha/primXfermode is
  307. // a known constant value. In that case we can simply apply a color filter during this
  308. // conversion without converting the color filter to a GrFragmentProcessor.
  309. bool applyColorFilterToPaintColor = false;
  310. if (shaderFP) {
  311. if (primColorMode) {
  312. // There is a blend between the primitive color and the shader color. The shader sees
  313. // the opaque paint color. The shader's output is blended using the provided mode by
  314. // the primitive color. The blended color is then modulated by the paint's alpha.
  315. // The geometry processor will insert the primitive color to start the color chain, so
  316. // the GrPaint color will be ignored.
  317. SkPMColor4f shaderInput = origColor.makeOpaque().premul();
  318. shaderFP = GrFragmentProcessor::OverrideInput(std::move(shaderFP), shaderInput);
  319. shaderFP = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(shaderFP),
  320. *primColorMode);
  321. // The above may return null if compose results in a pass through of the prim color.
  322. if (shaderFP) {
  323. grPaint->addColorFragmentProcessor(std::move(shaderFP));
  324. }
  325. // We can ignore origColor here - alpha is unchanged by gamma
  326. float paintAlpha = skPaint.getColor4f().fA;
  327. if (1.0f != paintAlpha) {
  328. // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
  329. // color channels. It's value should be treated as the same in ANY color space.
  330. grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
  331. { paintAlpha, paintAlpha, paintAlpha, paintAlpha },
  332. GrConstColorProcessor::InputMode::kModulateRGBA));
  333. }
  334. } else {
  335. // The shader's FP sees the paint *unpremul* color
  336. SkPMColor4f origColorAsPM = { origColor.fR, origColor.fG, origColor.fB, origColor.fA };
  337. grPaint->setColor4f(origColorAsPM);
  338. grPaint->addColorFragmentProcessor(std::move(shaderFP));
  339. }
  340. } else {
  341. if (primColorMode) {
  342. // There is a blend between the primitive color and the paint color. The blend considers
  343. // the opaque paint color. The paint's alpha is applied to the post-blended color.
  344. SkPMColor4f opaqueColor = origColor.makeOpaque().premul();
  345. auto processor = GrConstColorProcessor::Make(opaqueColor,
  346. GrConstColorProcessor::InputMode::kIgnore);
  347. processor = GrXfermodeFragmentProcessor::MakeFromSrcProcessor(std::move(processor),
  348. *primColorMode);
  349. if (processor) {
  350. grPaint->addColorFragmentProcessor(std::move(processor));
  351. }
  352. grPaint->setColor4f(opaqueColor);
  353. // We can ignore origColor here - alpha is unchanged by gamma
  354. float paintAlpha = skPaint.getColor4f().fA;
  355. if (1.0f != paintAlpha) {
  356. // No gamut conversion - paintAlpha is a (linear) alpha value, splatted to all
  357. // color channels. It's value should be treated as the same in ANY color space.
  358. grPaint->addColorFragmentProcessor(GrConstColorProcessor::Make(
  359. { paintAlpha, paintAlpha, paintAlpha, paintAlpha },
  360. GrConstColorProcessor::InputMode::kModulateRGBA));
  361. }
  362. } else {
  363. // No shader, no primitive color.
  364. grPaint->setColor4f(origColor.premul());
  365. applyColorFilterToPaintColor = true;
  366. }
  367. }
  368. SkColorFilter* colorFilter = skPaint.getColorFilter();
  369. if (colorFilter) {
  370. if (applyColorFilterToPaintColor) {
  371. grPaint->setColor4f(
  372. colorFilter->filterColor4f(origColor, colorSpaceInfo.colorSpace()).premul());
  373. } else {
  374. auto cfFP = colorFilter->asFragmentProcessor(context, colorSpaceInfo);
  375. if (cfFP) {
  376. grPaint->addColorFragmentProcessor(std::move(cfFP));
  377. } else {
  378. return false;
  379. }
  380. }
  381. }
  382. SkMaskFilterBase* maskFilter = as_MFB(skPaint.getMaskFilter());
  383. if (maskFilter) {
  384. // We may have set this before passing to the SkShader.
  385. fpArgs.fInputColorIsOpaque = false;
  386. if (auto mfFP = maskFilter->asFragmentProcessor(fpArgs)) {
  387. grPaint->addCoverageFragmentProcessor(std::move(mfFP));
  388. }
  389. }
  390. // When the xfermode is null on the SkPaint (meaning kSrcOver) we need the XPFactory field on
  391. // the GrPaint to also be null (also kSrcOver).
  392. SkASSERT(!grPaint->getXPFactory());
  393. if (!skPaint.isSrcOver()) {
  394. grPaint->setXPFactory(SkBlendMode_AsXPFactory(skPaint.getBlendMode()));
  395. }
  396. #ifndef SK_IGNORE_GPU_DITHER
  397. // Conservative default, in case GrPixelConfigToColorType() fails.
  398. GrColorType ct = colorSpaceInfo.colorType();
  399. if (SkPaintPriv::ShouldDither(skPaint, GrColorTypeToSkColorType(ct)) &&
  400. grPaint->numColorFragmentProcessors() > 0) {
  401. int32_t ditherRange = dither_range_type_for_config(ct);
  402. if (ditherRange >= 0) {
  403. static int ditherIndex = GrSkSLFP::NewIndex();
  404. auto ditherFP = GrSkSLFP::Make(context, ditherIndex, "Dither", SKSL_DITHER_SRC,
  405. &ditherRange, sizeof(ditherRange));
  406. if (ditherFP) {
  407. grPaint->addColorFragmentProcessor(std::move(ditherFP));
  408. }
  409. }
  410. }
  411. #endif
  412. return true;
  413. }
  414. bool SkPaintToGrPaint(GrRecordingContext* context, const GrColorSpaceInfo& colorSpaceInfo,
  415. const SkPaint& skPaint, const SkMatrix& viewM, GrPaint* grPaint) {
  416. return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, viewM, nullptr, nullptr,
  417. grPaint);
  418. }
  419. /** Replaces the SkShader (if any) on skPaint with the passed in GrFragmentProcessor. */
  420. bool SkPaintToGrPaintReplaceShader(GrRecordingContext* context,
  421. const GrColorSpaceInfo& colorSpaceInfo,
  422. const SkPaint& skPaint,
  423. std::unique_ptr<GrFragmentProcessor> shaderFP,
  424. GrPaint* grPaint) {
  425. if (!shaderFP) {
  426. return false;
  427. }
  428. return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, SkMatrix::I(), &shaderFP,
  429. nullptr, grPaint);
  430. }
  431. /** Ignores the SkShader (if any) on skPaint. */
  432. bool SkPaintToGrPaintNoShader(GrRecordingContext* context,
  433. const GrColorSpaceInfo& colorSpaceInfo,
  434. const SkPaint& skPaint,
  435. GrPaint* grPaint) {
  436. // Use a ptr to a nullptr to to indicate that the SkShader is ignored and not replaced.
  437. std::unique_ptr<GrFragmentProcessor> nullShaderFP(nullptr);
  438. return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, SkMatrix::I(), &nullShaderFP,
  439. nullptr, grPaint);
  440. }
  441. /** Blends the SkPaint's shader (or color if no shader) with a per-primitive color which must
  442. be setup as a vertex attribute using the specified SkBlendMode. */
  443. bool SkPaintToGrPaintWithXfermode(GrRecordingContext* context,
  444. const GrColorSpaceInfo& colorSpaceInfo,
  445. const SkPaint& skPaint,
  446. const SkMatrix& viewM,
  447. SkBlendMode primColorMode,
  448. GrPaint* grPaint) {
  449. return skpaint_to_grpaint_impl(context, colorSpaceInfo, skPaint, viewM, nullptr, &primColorMode,
  450. grPaint);
  451. }
  452. bool SkPaintToGrPaintWithTexture(GrRecordingContext* context,
  453. const GrColorSpaceInfo& colorSpaceInfo,
  454. const SkPaint& paint,
  455. const SkMatrix& viewM,
  456. std::unique_ptr<GrFragmentProcessor> fp,
  457. bool textureIsAlphaOnly,
  458. GrPaint* grPaint) {
  459. std::unique_ptr<GrFragmentProcessor> shaderFP;
  460. if (textureIsAlphaOnly) {
  461. if (const auto* shader = as_SB(paint.getShader())) {
  462. shaderFP = shader->asFragmentProcessor(GrFPArgs(
  463. context, &viewM, paint.getFilterQuality(), &colorSpaceInfo));
  464. if (!shaderFP) {
  465. return false;
  466. }
  467. std::unique_ptr<GrFragmentProcessor> fpSeries[] = { std::move(shaderFP), std::move(fp) };
  468. shaderFP = GrFragmentProcessor::RunInSeries(fpSeries, 2);
  469. } else {
  470. shaderFP = GrFragmentProcessor::MakeInputPremulAndMulByOutput(std::move(fp));
  471. }
  472. } else {
  473. if (paint.getColor4f().isOpaque()) {
  474. shaderFP = GrFragmentProcessor::OverrideInput(std::move(fp), SK_PMColor4fWHITE, false);
  475. } else {
  476. shaderFP = GrFragmentProcessor::MulChildByInputAlpha(std::move(fp));
  477. }
  478. }
  479. return SkPaintToGrPaintReplaceShader(context, colorSpaceInfo, paint, std::move(shaderFP),
  480. grPaint);
  481. }
  482. ////////////////////////////////////////////////////////////////////////////////////////////////
  483. GrSamplerState::Filter GrSkFilterQualityToGrFilterMode(SkFilterQuality paintFilterQuality,
  484. const SkMatrix& viewM,
  485. const SkMatrix& localM,
  486. bool sharpenMipmappedTextures,
  487. bool* doBicubic) {
  488. *doBicubic = false;
  489. GrSamplerState::Filter textureFilterMode;
  490. switch (paintFilterQuality) {
  491. case kNone_SkFilterQuality:
  492. textureFilterMode = GrSamplerState::Filter::kNearest;
  493. break;
  494. case kLow_SkFilterQuality:
  495. textureFilterMode = GrSamplerState::Filter::kBilerp;
  496. break;
  497. case kMedium_SkFilterQuality: {
  498. SkMatrix matrix;
  499. matrix.setConcat(viewM, localM);
  500. // With sharp mips, we bias lookups by -0.5. That means our final LOD is >= 0 until the
  501. // computed LOD is >= 0.5. At what scale factor does a texture get an LOD of 0.5?
  502. //
  503. // Want: 0 = log2(1/s) - 0.5
  504. // 0.5 = log2(1/s)
  505. // 2^0.5 = 1/s
  506. // 1/2^0.5 = s
  507. // 2^0.5/2 = s
  508. SkScalar mipScale = sharpenMipmappedTextures ? SK_ScalarRoot2Over2 : SK_Scalar1;
  509. if (matrix.getMinScale() < mipScale) {
  510. textureFilterMode = GrSamplerState::Filter::kMipMap;
  511. } else {
  512. // Don't trigger MIP level generation unnecessarily.
  513. textureFilterMode = GrSamplerState::Filter::kBilerp;
  514. }
  515. break;
  516. }
  517. case kHigh_SkFilterQuality: {
  518. SkMatrix matrix;
  519. matrix.setConcat(viewM, localM);
  520. *doBicubic = GrBicubicEffect::ShouldUseBicubic(matrix, &textureFilterMode);
  521. break;
  522. }
  523. default:
  524. // Should be unreachable. If not, fall back to mipmaps.
  525. textureFilterMode = GrSamplerState::Filter::kMipMap;
  526. break;
  527. }
  528. return textureFilterMode;
  529. }