Skip to content

Commit 318afe6

Browse files
bsalomonSkia Commit-Bot
authored andcommitted
Don't flatten images in SkImageShader
Bug: skia:9570 Change-Id: Idd4485b5c5814501fe98fbf2115d89a80a41f5c7 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/299139 Commit-Queue: Brian Salomon <[email protected]> Reviewed-by: Michael Ludwig <[email protected]>
1 parent c0ab92c commit 318afe6

File tree

3 files changed

+61
-36
lines changed

3 files changed

+61
-36
lines changed

src/gpu/GrImageTextureMaker.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ GrSurfaceProxyView GrImageTextureMaker::refOriginalTextureProxyView(GrMipMapped
4040

4141
/////////////////////////////////////////////////////////////////////////////////////////////////
4242

43-
GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrContext* context, const SkImage* client)
43+
GrYUVAImageTextureMaker::GrYUVAImageTextureMaker(GrRecordingContext* context, const SkImage* client)
4444
: INHERITED(context, client->imageInfo())
4545
, fImage(static_cast<const SkImage_GpuYUVA*>(client)) {
4646
SkASSERT(as_IB(client)->isYUVA());
@@ -94,8 +94,9 @@ std::unique_ptr<GrFragmentProcessor> GrYUVAImageTextureMaker::createFragmentProc
9494

9595
const auto& caps = *fImage->context()->priv().caps();
9696
const SkMatrix& m = filterOrNullForBicubic ? textureMatrix : SkMatrix::I();
97+
GrSamplerState sampler(wrapX, wrapY, filter);
9798
auto fp = GrYUVtoRGBEffect::Make(fImage->fViews, fImage->fYUVAIndices, fImage->fYUVColorSpace,
98-
filter, caps, m, domain);
99+
sampler, caps, m, domain);
99100
if (!filterOrNullForBicubic) {
100101
fp = GrBicubicEffect::Make(std::move(fp),
101102
fImage->alphaType(),

src/gpu/GrImageTextureMaker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class GrImageTextureMaker final : public GrTextureMaker {
3333
/** This class manages the conversion of generator-backed YUVA images to GrTextures. */
3434
class GrYUVAImageTextureMaker final : public GrTextureMaker {
3535
public:
36-
GrYUVAImageTextureMaker(GrContext* context, const SkImage* client);
36+
GrYUVAImageTextureMaker(GrRecordingContext* context, const SkImage* client);
3737

3838
std::unique_ptr<GrFragmentProcessor> createFragmentProcessor(
3939
const SkMatrix& textureMatrix,

src/shaders/SkImageShader.cpp

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
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"
@@ -13,12 +15,12 @@
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

Comments
 (0)