55 * found in the LICENSE file.
66 */
77
8+ #include " src/shaders/SkImageShader.h"
9+
810#include " src/core/SkArenaAlloc.h"
911#include " src/core/SkBitmapController.h"
1012#include " src/core/SkColorSpacePriv.h"
1315#include " src/core/SkOpts.h"
1416#include " src/core/SkRasterPipeline.h"
1517#include " src/core/SkReadBuffer.h"
18+ #include " src/core/SkScopeExit.h"
1619#include " src/core/SkVM.h"
1720#include " src/core/SkWriteBuffer.h"
1821#include " src/image/SkImage_Base.h"
1922#include " src/shaders/SkBitmapProcShader.h"
2023#include " src/shaders/SkEmptyShader.h"
21- #include " src/shaders/SkImageShader.h"
2224
2325/* *
2426 * We are faster in clamp, so always use that tiling when we can.
@@ -195,9 +197,12 @@ sk_sp<SkShader> SkImageShader::Make(sk_sp<SkImage> image,
195197#if SK_SUPPORT_GPU
196198
197199#include " include/private/GrRecordingContext.h"
200+ #include " src/gpu/GrBitmapTextureMaker.h"
198201#include " src/gpu/GrCaps.h"
199202#include " src/gpu/GrColorInfo.h"
203+ #include " src/gpu/GrImageTextureMaker.h"
200204#include " src/gpu/GrRecordingContextPriv.h"
205+ #include " src/gpu/GrTextureAdjuster.h"
201206#include " src/gpu/SkGr.h"
202207#include " src/gpu/effects/GrBicubicEffect.h"
203208#include " src/gpu/effects/GrTextureEffect.h"
@@ -210,51 +215,71 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
210215 return nullptr ;
211216 }
212217
218+ // This would all be much nicer with std::variant.
219+ static constexpr size_t kSize = std::max ({sizeof (GrYUVAImageTextureMaker),
220+ sizeof (GrTextureAdjuster ),
221+ sizeof (GrImageTextureMaker ),
222+ sizeof (GrBitmapTextureMaker )});
223+ static constexpr size_t kAlign = std::max ({alignof (GrYUVAImageTextureMaker),
224+ alignof (GrTextureAdjuster ),
225+ alignof (GrImageTextureMaker ),
226+ alignof (GrBitmapTextureMaker )});
227+ std::aligned_storage_t <kSize , kAlign > storage;
228+ GrTextureProducer* producer = nullptr ;
229+ SkScopeExit destroyProducer ([&producer]{ if (producer) { producer->~GrTextureProducer (); } });
230+
231+ uint32_t pinnedUniqueID;
232+ SkBitmap bm;
233+ if (as_IB (fImage )->isYUVA ()) {
234+ producer = new (&storage) GrYUVAImageTextureMaker (args.fContext , fImage .get ());
235+ } else if (GrSurfaceProxyView view =
236+ as_IB (fImage )->refPinnedView (args.fContext , &pinnedUniqueID)) {
237+ GrColorInfo colorInfo;
238+ if (args.fContext ->priv ().caps ()->isFormatSRGB (view.proxy ()->backendFormat ())) {
239+ SkASSERT (fImage ->colorType () == kRGBA_8888_SkColorType );
240+ colorInfo = GrColorInfo (GrColorType::kRGBA_8888_SRGB , fImage ->alphaType (),
241+ fImage ->refColorSpace ());
242+ } else {
243+ colorInfo = fImage ->imageInfo ().colorInfo ();
244+ }
245+ producer = new (&storage)
246+ GrTextureAdjuster (args.fContext , std::move (view), colorInfo, pinnedUniqueID);
247+ } else if (fImage ->isLazyGenerated ()) {
248+ producer = new (&storage)
249+ GrImageTextureMaker (args.fContext , fImage .get (), GrImageTexGenPolicy::kDraw );
250+ } else if (as_IB (fImage )->getROPixels (&bm)) {
251+ producer =
252+ new (&storage) GrBitmapTextureMaker (args.fContext , bm, GrImageTexGenPolicy::kDraw );
253+ } else {
254+ return nullptr ;
255+ }
213256 GrSamplerState::WrapMode wmX = SkTileModeToWrapMode (fTileModeX ),
214257 wmY = SkTileModeToWrapMode (fTileModeY );
215-
216- // Must set wrap and filter on the sampler before requesting a texture. In two places below
217- // we check the matrix scale factors to determine how to interpret the filter quality setting.
218- // This completely ignores the complexity of the drawVertices case where explicit local coords
219- // are provided by the caller.
258+ // Must set wrap and filter on the sampler before requesting a texture. In two places
259+ // below we check the matrix scale factors to determine how to interpret the filter
260+ // quality setting. This completely ignores the complexity of the drawVertices case
261+ // where explicit local coords are provided by the caller.
220262 bool doBicubic;
221263 GrSamplerState::Filter textureFilterMode = GrSkFilterQualityToGrFilterMode (
222264 fImage ->width (), fImage ->height (), this ->resolveFiltering (args.fFilterQuality ),
223265 args.fMatrixProvider .localToDevice (), *lm,
224266 args.fContext ->priv ().options ().fSharpenMipmappedTextures , &doBicubic);
225- GrMipMapped mipMapped = GrMipMapped::kNo ;
226- if (textureFilterMode == GrSamplerState::Filter::kMipMap ) {
227- mipMapped = GrMipMapped::kYes ;
228- }
229- GrSurfaceProxyView view = as_IB (fImage )->refView (args.fContext , mipMapped);
230- if (!view) {
231- return nullptr ;
232- }
233-
234- SkAlphaType srcAlphaType = fImage ->alphaType ();
267+ const GrSamplerState::Filter* filterOrNull = doBicubic ? nullptr : &textureFilterMode;
268+ auto fp = producer->createFragmentProcessor (lmInverse, SkRect::Make (fImage ->dimensions ()),
269+ GrTextureProducer::kNo_FilterConstraint , false , wmX,
270+ wmY, filterOrNull);
235271
236- const auto & caps = *args.fContext ->priv ().caps ();
237-
238- std::unique_ptr<GrFragmentProcessor> inner;
239- if (doBicubic) {
240- static constexpr auto kDir = GrBicubicEffect::Direction::kXY ;
241- static constexpr auto kKernel = GrBicubicEffect::Kernel::kMitchell ;
242- inner = GrBicubicEffect::Make (std::move (view), srcAlphaType, lmInverse, wmX, wmY, kKernel ,
243- kDir , caps);
244- } else {
245- GrSamplerState samplerState (wmX, wmY, textureFilterMode);
246- inner = GrTextureEffect::Make (std::move (view), srcAlphaType, lmInverse, samplerState, caps);
272+ if (!fp) {
273+ return nullptr ;
247274 }
248- inner = GrColorSpaceXformEffect::Make (std::move (inner), fImage ->colorSpace (), srcAlphaType,
249- args.fDstColorInfo ->colorSpace ());
250275
251276 bool isAlphaOnly = SkColorTypeIsAlphaOnly (fImage ->colorType ());
252277 if (isAlphaOnly) {
253- return inner ;
278+ return fp ;
254279 } else if (args.fInputColorIsOpaque ) {
255- return GrFragmentProcessor::OverrideInput (std::move (inner ), SK_PMColor4fWHITE, false );
280+ return GrFragmentProcessor::OverrideInput (std::move (fp ), SK_PMColor4fWHITE, false );
256281 }
257- return GrFragmentProcessor::MulChildByInputAlpha (std::move (inner ));
282+ return GrFragmentProcessor::MulChildByInputAlpha (std::move (fp ));
258283}
259284
260285#endif
@@ -888,4 +913,3 @@ skvm::Color SkImageShader::onProgram(skvm::Builder* p,
888913 SkColorSpaceXformSteps steps{cs,at, dst.colorSpace (),kPremul_SkAlphaType };
889914 return steps.program (p, uniforms, c);
890915}
891-
0 commit comments