Revert "Fix handling of MaskFilter matrices"

This reverts commit 2097fd03ff.

Reason for revert: This is breaking a lot of Windows bots (esp. on the shadermaskfilter_localmatrix)

Original change's description:
> Fix handling of MaskFilter matrices
> 
> 1) extend GrFPArgs to track pre/post local matrices, add helpers for
>    creating pre/post wrapper args
> 
> 2) add a SkShaderBase helper (totalLocalMatrix) to centralize the LM
>    sandwich logic.
> 
> 3) update call sites to use the above
> 
> 4) rename SkMatrixFilter::makeWithLocalMatrix -> makeWithMatrix, to
>    disambiguate vs. SkShader::makeWithLocalMatrix.
> 
> BUG=skia:7744
> 
> Change-Id: Ib2b7b007e6924979b00649dde7c94ef4b34771f1
> Reviewed-on: https://skia-review.googlesource.com/119330
> Commit-Queue: Florin Malita <fmalita@chromium.org>
> Reviewed-by: Brian Salomon <bsalomon@google.com>

TBR=bsalomon@google.com,robertphillips@google.com,fmalita@chromium.org,reed@google.com

Change-Id: I918dbb95bf00b3122e6699b84566ec82dbb5fc5c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:7744
Reviewed-on: https://skia-review.googlesource.com/120340
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2018-04-11 12:38:41 +00:00 committed by Skia Commit-Bot
parent 90f09e7853
commit c64ee20e13
21 changed files with 148 additions and 263 deletions

View File

@ -11,7 +11,6 @@
#include "SkCanvas.h"
#include "SkImage.h"
#include "SkMaskFilter.h"
#include "SkPictureRecorder.h"
#include "SkShaderMaskFilter.h"
static void draw_masked_image(SkCanvas* canvas, const SkImage* image, SkScalar x, SkScalar y,
@ -221,92 +220,3 @@ DEF_SIMPLE_GM(savelayer_maskfilter, canvas, 450, 675) {
}
}
static void draw_mask(SkCanvas* canvas) {
SkPaint p;
p.setAntiAlias(true);
canvas->drawOval(SkRect::Make(canvas->imageInfo().bounds()), p);
}
DEF_SIMPLE_GM(shadermaskfilter_localmatrix, canvas, 1200, 800) {
static constexpr SkScalar kSize = 100;
using ShaderMakerT = sk_sp<SkShader>(*)(SkCanvas*, const SkMatrix& lm);
static const ShaderMakerT gShaderMakers[] = {
[](SkCanvas* canvas, const SkMatrix& lm) -> sk_sp<SkShader> {
auto surface = sk_tool_utils::makeSurface(canvas,
SkImageInfo::MakeN32Premul(kSize, kSize));
draw_mask(surface->getCanvas());
return surface->makeImageSnapshot()->makeShader(SkShader::kClamp_TileMode,
SkShader::kClamp_TileMode, &lm);
},
[](SkCanvas*, const SkMatrix& lm) -> sk_sp<SkShader> {
SkPictureRecorder recorder;
draw_mask(recorder.beginRecording(kSize, kSize));
return SkShader::MakePictureShader(recorder.finishRecordingAsPicture(),
SkShader::kClamp_TileMode,
SkShader::kClamp_TileMode,
&lm, nullptr);
},
};
struct Config {
SkMatrix fCanvasMatrix,
fMaskMatrix,
fShaderMatrix;
} gConfigs[] = {
{ SkMatrix::I(), SkMatrix::MakeScale(2, 2), SkMatrix::MakeTrans(10, 10) },
{ SkMatrix::MakeScale(2, 2), SkMatrix::I(), SkMatrix::MakeTrans(10, 10) },
{ SkMatrix::MakeScale(2, 2), SkMatrix::MakeTrans(10, 10), SkMatrix::I() },
{ SkMatrix::Concat(SkMatrix::MakeScale(2, 2), SkMatrix::MakeTrans(10, 10)),
SkMatrix::I(), SkMatrix::I() },
{ SkMatrix::I(),
SkMatrix::Concat(SkMatrix::MakeScale(2, 2), SkMatrix::MakeTrans(10, 10)),
SkMatrix::I() },
{ SkMatrix::I(), SkMatrix::I(),
SkMatrix::Concat(SkMatrix::MakeScale(2, 2), SkMatrix::MakeTrans(10, 10)) },
};
using DrawerT = void(*)(SkCanvas*, const SkRect&, const SkPaint&);
static const DrawerT gDrawers[] = {
[](SkCanvas* canvas, const SkRect& dest, const SkPaint& mask) {
canvas->drawRect(dest, mask);
},
[](SkCanvas* canvas, const SkRect& dest, const SkPaint& mask) {
canvas->saveLayer(&dest, &mask);
SkPaint p = mask;
p.setMaskFilter(nullptr);
canvas->drawPaint(p);
canvas->restore();
},
};
SkPaint paint, rectPaint;
paint.setColor(0xff00ff00);
rectPaint.setStyle(SkPaint::kStroke_Style);
rectPaint.setColor(0xffff0000);
for (const auto& sm : gShaderMakers) {
for (const auto& drawer : gDrawers) {
{
SkAutoCanvasRestore acr(canvas, true);
for (const auto& cfg : gConfigs) {
paint.setMaskFilter(SkShaderMaskFilter::Make(sm(canvas, cfg.fShaderMatrix))
->makeWithMatrix(cfg.fMaskMatrix));
auto dest = SkRect::MakeWH(kSize, kSize);
SkMatrix::Concat(cfg.fMaskMatrix, cfg.fShaderMatrix).mapRect(&dest);
{
SkAutoCanvasRestore acr(canvas, true);
canvas->concat(cfg.fCanvasMatrix);
drawer(canvas, dest, paint);
canvas->drawRect(dest, rectPaint);
}
canvas->translate(kSize * 2.5f, 0);
}
}
canvas->translate(0, kSize * 2.5f);
}
}
}

View File

@ -50,14 +50,7 @@ public:
static sk_sp<SkMaskFilter> MakeCombine(sk_sp<SkMaskFilter> filterA, sk_sp<SkMaskFilter> filterB,
SkCoverageMode mode);
/**
* Construct a maskfilter with an additional transform.
*
* Note: unlike shader local matrices, this transform composes next to the CTM.
*
* TotalMatrix = CTM x MaskFilterMatrix x (optional/downstream) ShaderLocalMatrix
*/
sk_sp<SkMaskFilter> makeWithMatrix(const SkMatrix&) const;
sk_sp<SkMaskFilter> makeWithLocalMatrix(const SkMatrix&) const;
virtual void toString(SkString* str) const = 0;
SK_DEFINE_FLATTENABLE_TYPE(SkMaskFilter)

View File

@ -487,7 +487,7 @@ void SkBitmapDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPain
// todo: can we unify with similar adjustment in SkGpuDevice?
SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
if (paint->getMaskFilter()) {
paint.writable()->setMaskFilter(paint->getMaskFilter()->makeWithMatrix(this->ctm()));
paint.writable()->setMaskFilter(paint->getMaskFilter()->makeWithLocalMatrix(this->ctm()));
}
this->drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, *paint);
}
@ -546,7 +546,7 @@ void SkBitmapDevice::drawSpecial(SkSpecialImage* src, int x, int y, const SkPain
}
if (paint->getMaskFilter()) {
paint.writable()->setMaskFilter(paint->getMaskFilter()->makeWithMatrix(this->ctm()));
paint.writable()->setMaskFilter(paint->getMaskFilter()->makeWithLocalMatrix(this->ctm()));
}
if (!clipImage) {

View File

@ -635,9 +635,9 @@ void SkCombineMF::toString(SkString* str) const {
///////////////////////////////////////////////////////////////////////////////////////////////////
class SkMatrixMF : public SkMaskFilterBase {
class SkLocalMatrixMF : public SkMaskFilterBase {
public:
SkMatrixMF(sk_sp<SkMaskFilter> filter, const SkMatrix& lm)
SkLocalMatrixMF(sk_sp<SkMaskFilter> filter, const SkMatrix& lm)
: fFilter(std::move(filter))
, fLM(lm)
{}
@ -657,7 +657,7 @@ public:
SkMask::Format getFormat() const override { return as_MFB(fFilter)->getFormat(); }
void toString(SkString* str) const override {
str->set("SkMatrixMF:");
str->set("SkLocalMatrixMF:");
}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLocalMatrixMF)
@ -665,7 +665,16 @@ public:
protected:
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(const GrFPArgs& args) const override{
return as_MFB(fFilter)->asFragmentProcessor(args.makeWithPostLocalMatrix(fLM));
GrFPArgs newArgs = args;
SkMatrix storage;
if (args.fLocalMatrix) {
storage.setConcat(*args.fLocalMatrix, fLM);
newArgs.fLocalMatrix = &storage;
} else {
newArgs.fLocalMatrix = &fLM;
}
return as_MFB(fFilter)->asFragmentProcessor(newArgs);
}
bool onHasFragmentProcessor() const override {
@ -686,11 +695,11 @@ private:
typedef SkMaskFilterBase INHERITED;
};
sk_sp<SkFlattenable> SkMatrixMF::CreateProc(SkReadBuffer& buffer) {
SkMatrix m;
buffer.readMatrix(&m);
sk_sp<SkFlattenable> SkLocalMatrixMF::CreateProc(SkReadBuffer& buffer) {
SkMatrix lm;
buffer.readMatrix(&lm);
auto filter = buffer.readMaskFilter();
return filter ? filter->makeWithMatrix(m) : nullptr;
return filter ? filter->makeWithLocalMatrix(lm) : nullptr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
@ -726,16 +735,16 @@ sk_sp<SkMaskFilter> SkMaskFilter::MakeCombine(sk_sp<SkMaskFilter> dst, sk_sp<SkM
return sk_sp<SkMaskFilter>(new SkCombineMF(std::move(dst), std::move(src), mode));
}
sk_sp<SkMaskFilter> SkMaskFilter::makeWithMatrix(const SkMatrix& lm) const {
sk_sp<SkMaskFilter> SkMaskFilter::makeWithLocalMatrix(const SkMatrix& lm) const {
sk_sp<SkMaskFilter> me = sk_ref_sp(const_cast<SkMaskFilter*>(this));
if (lm.isIdentity()) {
return me;
}
return sk_sp<SkMaskFilter>(new SkMatrixMF(std::move(me), lm));
return sk_sp<SkMaskFilter>(new SkLocalMatrixMF(std::move(me), lm));
}
void SkMaskFilter::InitializeFlattenables() {
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkMatrixMF)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLocalMatrixMF)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposeMF)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkCombineMF)
sk_register_blur_maskfilter_createproc();

View File

@ -9,84 +9,39 @@
#define GrFPArgs_DEFINED
#include "SkFilterQuality.h"
#include "SkMatrix.h"
class SkMatrix;
class GrContext;
class GrColorSpaceInfo;
struct GrFPArgs {
GrFPArgs(GrContext* context,
const SkMatrix* viewMatrix,
const SkMatrix* localMatrix,
SkFilterQuality filterQuality,
const GrColorSpaceInfo* dstColorSpaceInfo)
: fContext(context)
, fViewMatrix(viewMatrix)
, fLocalMatrix(localMatrix)
, fFilterQuality(filterQuality)
, fDstColorSpaceInfo(dstColorSpaceInfo) {}
GrFPArgs(GrContext* context,
const SkMatrix* viewMatrix,
SkFilterQuality filterQuality,
const GrColorSpaceInfo* dstColorSpaceInfo)
: fContext(context)
, fViewMatrix(viewMatrix)
, fLocalMatrix(nullptr)
, fFilterQuality(filterQuality)
, fDstColorSpaceInfo(dstColorSpaceInfo) {
SkASSERT(fContext);
SkASSERT(fViewMatrix);
}
class WithMatrixStorage;
WithMatrixStorage makeWithPreLocalMatrix(const SkMatrix&) const;
WithMatrixStorage makeWithPostLocalMatrix(const SkMatrix&) const;
, fDstColorSpaceInfo(dstColorSpaceInfo) {}
GrContext* fContext;
const SkMatrix* fViewMatrix;
// We track both pre and post local matrix adjustments. For a given FP:
//
// total_local_matrix = postLocalMatrix x FP_localMatrix x preLocalMatrix
//
// Use the helpers above to create pre/post GrFPArgs wrappers.
//
const SkMatrix* fPreLocalMatrix = nullptr;
const SkMatrix* fPostLocalMatrix = nullptr;
const SkMatrix* fLocalMatrix;
SkFilterQuality fFilterQuality;
const GrColorSpaceInfo* fDstColorSpaceInfo;
};
class GrFPArgs::WithMatrixStorage final : public GrFPArgs {
private:
explicit WithMatrixStorage(const GrFPArgs& args) : INHERITED(args) {}
friend struct GrFPArgs;
SkMatrix fStorage;
using INHERITED = GrFPArgs;
};
inline GrFPArgs::WithMatrixStorage GrFPArgs::makeWithPreLocalMatrix(const SkMatrix& lm) const {
WithMatrixStorage newArgs(*this);
if (!lm.isIdentity()) {
if (fPreLocalMatrix) {
newArgs.fStorage.setConcat(lm, *fPreLocalMatrix);
newArgs.fPreLocalMatrix = newArgs.fStorage.isIdentity() ? nullptr : &newArgs.fStorage;
} else {
newArgs.fPreLocalMatrix = &lm;
}
}
return newArgs;
}
inline GrFPArgs::WithMatrixStorage GrFPArgs::makeWithPostLocalMatrix(const SkMatrix& lm) const {
WithMatrixStorage newArgs(*this);
if (!lm.isIdentity()) {
if (fPostLocalMatrix) {
newArgs.fStorage.setConcat(*fPostLocalMatrix, lm);
newArgs.fPostLocalMatrix = newArgs.fStorage.isIdentity() ? nullptr : &newArgs.fStorage;
} else {
newArgs.fPostLocalMatrix = &lm;
}
}
return newArgs;
}
#endif

View File

@ -337,7 +337,8 @@ TestAsFPArgs::TestAsFPArgs(GrProcessorTestData* d)
: fViewMatrixStorage(TestMatrix(d->fRandom))
, fColorSpaceInfoStorage(skstd::make_unique<GrColorSpaceInfo>(TestColorSpace(d->fRandom),
kRGBA_8888_GrPixelConfig))
, fArgs(d->context(), &fViewMatrixStorage, kNone_SkFilterQuality, fColorSpaceInfoStorage.get())
, fArgs(d->context(), &fViewMatrixStorage, nullptr, kNone_SkFilterQuality,
fColorSpaceInfoStorage.get())
{}
TestAsFPArgs::~TestAsFPArgs() {}

View File

@ -1092,7 +1092,7 @@ void SkGpuDevice::drawSpecial(SkSpecialImage* special1, int left, int top, const
if (tmpUnfiltered.getMaskFilter()) {
SkMatrix ctm = this->ctm();
ctm.postTranslate(-SkIntToScalar(left + offset.fX), -SkIntToScalar(top + offset.fY));
tmpUnfiltered.setMaskFilter(tmpUnfiltered.getMaskFilter()->makeWithMatrix(ctm));
tmpUnfiltered.setMaskFilter(tmpUnfiltered.getMaskFilter()->makeWithLocalMatrix(ctm));
}
tmpUnfiltered.setImageFilter(nullptr);

View File

@ -514,7 +514,7 @@ bool SkPaintToGrPaintWithTexture(GrContext* context,
if (textureIsAlphaOnly) {
if (const auto* shader = as_SB(paint.getShader())) {
shaderFP = shader->asFragmentProcessor(GrFPArgs(
context, &viewM, paint.getFilterQuality(), &colorSpaceInfo));
context, &viewM, nullptr, paint.getFilterQuality(), &colorSpaceInfo));
if (!shaderFP) {
return false;
}

View File

@ -213,11 +213,19 @@ static GrSamplerState::WrapMode tile_mode_to_wrap_mode(const SkShader::TileMode
std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
const GrFPArgs& args) const {
const auto lm = this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix);
SkMatrix lm = this->getLocalMatrix();
SkMatrix lmInverse;
if (!lm->invert(&lmInverse)) {
if (!lm.invert(&lmInverse)) {
return nullptr;
}
if (args.fLocalMatrix) {
SkMatrix inv;
if (!args.fLocalMatrix->invert(&inv)) {
return nullptr;
}
lmInverse.postConcat(inv);
lm.preConcat(*args.fLocalMatrix);
}
GrSamplerState::WrapMode wrapModes[] = {tile_mode_to_wrap_mode(fTileModeX),
tile_mode_to_wrap_mode(fTileModeY)};
@ -228,7 +236,7 @@ std::unique_ptr<GrFragmentProcessor> SkImageShader::asFragmentProcessor(
// are provided by the caller.
bool doBicubic;
GrSamplerState::Filter textureFilterMode = GrSkFilterQualityToGrFilterMode(
args.fFilterQuality, *args.fViewMatrix, *lm,
args.fFilterQuality, *args.fViewMatrix, lm,
args.fContext->contextPriv().sharpenMipmappedTextures(), &doBicubic);
GrSamplerState samplerState(wrapModes, textureFilterMode);
sk_sp<SkColorSpace> texColorSpace;

View File

@ -15,8 +15,13 @@
#if SK_SUPPORT_GPU
std::unique_ptr<GrFragmentProcessor> SkLocalMatrixShader::asFragmentProcessor(
const GrFPArgs& args) const {
SkMatrix tmp = this->getLocalMatrix();
if (args.fLocalMatrix) {
tmp.preConcat(*args.fLocalMatrix);
}
return as_SB(fProxyShader)
->asFragmentProcessor(args.makeWithPreLocalMatrix(this->getLocalMatrix()));
->asFragmentProcessor(GrFPArgs(args.fContext, args.fViewMatrix, &tmp,
args.fFilterQuality, args.fDstColorSpaceInfo));
}
#endif

View File

@ -1394,8 +1394,13 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso
const GrFPArgs& args) const {
SkASSERT(args.fContext);
const auto localMatrix = this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix);
const auto matrix = SkMatrix::Concat(*args.fViewMatrix, *localMatrix);
SkMatrix localMatrix = this->getLocalMatrix();
if (args.fLocalMatrix) {
localMatrix.preConcat(*args.fLocalMatrix);
}
SkMatrix matrix = *args.fViewMatrix;
matrix.preConcat(localMatrix);
// Either we don't stitch tiles, either we have a valid tile size
SkASSERT(!fStitchTiles || !fTileSize.isEmpty());
@ -1408,8 +1413,8 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso
matrix);
SkMatrix m = *args.fViewMatrix;
m.setTranslateX(-localMatrix->getTranslateX() + SK_Scalar1);
m.setTranslateY(-localMatrix->getTranslateY() + SK_Scalar1);
m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1);
m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1);
auto proxyProvider = args.fContext->contextPriv().proxyProvider();
if (fType == kImprovedNoise_Type) {

View File

@ -175,20 +175,24 @@ void SkPictureShader::flatten(SkWriteBuffer& buffer) const {
//
// 1) a cached image shader, which wraps a single picture tile at the given CTM/local matrix
//
// 2) a tile scale adjustment, to be applied downstream when dispatching createContext(),
// 2) a "composite" local matrix, to be passed down when dispatching createContext(),
// appendStages() and asFragmentProcessor() in callers
//
// The composite local matrix includes the actual local matrix, any inherited/outer local matrix
// and a scale component (to mape the actual tile bitmap size -> fTile size).
//
sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix,
const SkMatrix& localMatrix,
const SkMatrix* outerLocalMatrix,
SkColorSpace* dstColorSpace,
SkVector* scaleAdjust,
SkMatrix* compositeLocalMatrix,
const int maxTextureSize) const {
SkASSERT(fPicture && !fPicture->cullRect().isEmpty());
const SkMatrix m = SkMatrix::Concat(viewMatrix, localMatrix);
*compositeLocalMatrix = this->getLocalMatrix();
if (outerLocalMatrix) {
compositeLocalMatrix->preConcat(*outerLocalMatrix);
}
const SkMatrix m = SkMatrix::Concat(viewMatrix, *compositeLocalMatrix);
// Use a rotation-invariant scale
SkPoint scale;
@ -270,52 +274,37 @@ sk_sp<SkShader> SkPictureShader::refBitmapShader(const SkMatrix& viewMatrix,
fAddedToCache.store(true);
}
scaleAdjust->set(1 / tileScale.width(), 1 / tileScale.height());
compositeLocalMatrix->preScale(1 / tileScale.width(), 1 / tileScale.height());
return tileShader;
}
bool SkPictureShader::onAppendStages(const StageRec& rec) const {
auto lm = this->totalLocalMatrix(rec.fLocalM);
SkVector scaleAdjust;
// Keep bitmapShader alive by using alloc instead of stack memory
auto& bitmapShader = *rec.fAlloc->make<sk_sp<SkShader>>();
bitmapShader = this->refBitmapShader(rec.fCTM, *lm, rec.fDstCS, &scaleAdjust);
if (!bitmapShader) {
return false;
}
if (scaleAdjust != SkVector::Make(1, 1)) {
lm.writable()->preScale(scaleAdjust.fX, scaleAdjust.fY);
}
SkMatrix compositeLocalMatrix;
bitmapShader = this->refBitmapShader(rec.fCTM, rec.fLocalM, rec.fDstCS, &compositeLocalMatrix);
StageRec localRec = rec;
localRec.fLocalM = lm->isIdentity() ? nullptr : &(*lm);
localRec.fLocalM = compositeLocalMatrix.isIdentity() ? nullptr : &compositeLocalMatrix;
return as_SB(bitmapShader)->appendStages(localRec);
return bitmapShader && as_SB(bitmapShader)->appendStages(localRec);
}
/////////////////////////////////////////////////////////////////////////////////////////
SkShaderBase::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc)
const {
auto lm = this->totalLocalMatrix(rec.fLocalMatrix);
SkVector scaleAdjust;
SkMatrix compositeLocalMatrix;
sk_sp<SkShader> bitmapShader = this->refBitmapShader(*rec.fMatrix,
*lm,
rec.fLocalMatrix,
rec.fDstColorSpace,
&scaleAdjust);
&compositeLocalMatrix);
if (!bitmapShader) {
return nullptr;
}
if (scaleAdjust != SkVector::Make(1, 1)) {
lm.writable()->preScale(scaleAdjust.fX, scaleAdjust.fY);
}
ContextRec localRec = rec;
localRec.fLocalMatrix = lm->isIdentity() ? nullptr : &(*lm);
localRec.fLocalMatrix = compositeLocalMatrix.isIdentity() ? nullptr : &compositeLocalMatrix;
PictureShaderContext* ctx =
alloc->make<PictureShaderContext>(*this, localRec, std::move(bitmapShader), alloc);
@ -380,22 +369,20 @@ std::unique_ptr<GrFragmentProcessor> SkPictureShader::asFragmentProcessor(
if (args.fContext) {
maxTextureSize = args.fContext->caps()->maxTextureSize();
}
auto lm = this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix);
SkVector scaleAdjust;
sk_sp<SkShader> bitmapShader(this->refBitmapShader(*args.fViewMatrix,*lm,
SkMatrix compositeLocalMatrix;
sk_sp<SkShader> bitmapShader(this->refBitmapShader(*args.fViewMatrix, args.fLocalMatrix,
args.fDstColorSpaceInfo->colorSpace(),
&scaleAdjust, maxTextureSize));
&compositeLocalMatrix,
maxTextureSize));
if (!bitmapShader) {
return nullptr;
}
if (scaleAdjust != SkVector::Make(1, 1)) {
lm.writable()->preScale(scaleAdjust.fX, scaleAdjust.fY);
}
GrFPArgs newArgs(args.fContext, args.fViewMatrix, args.fFilterQuality, args.fDstColorSpaceInfo);
return as_SB(bitmapShader)->asFragmentProcessor(newArgs.makeWithPreLocalMatrix(*lm));
return as_SB(bitmapShader)->asFragmentProcessor(
GrFPArgs(args.fContext,
args.fViewMatrix,
compositeLocalMatrix.isIdentity() ? nullptr : &compositeLocalMatrix,
args.fFilterQuality,
args.fDstColorSpaceInfo));
}
#endif

View File

@ -46,9 +46,9 @@ private:
SkPictureShader(sk_sp<SkPicture>, TileMode, TileMode, const SkMatrix*, const SkRect*,
sk_sp<SkColorSpace>);
sk_sp<SkShader> refBitmapShader(const SkMatrix&, const SkMatrix& localMatrix,
sk_sp<SkShader> refBitmapShader(const SkMatrix&, const SkMatrix* localMatrix,
SkColorSpace* dstColorSpace,
SkVector* scaleAdjust,
SkMatrix* compositeLocalMatrix,
const int maxTextureSize = 0) const;
class PictureShaderContext : public Context {

View File

@ -67,26 +67,15 @@ void SkShaderBase::flatten(SkWriteBuffer& buffer) const {
}
}
SkTCopyOnFirstWrite<SkMatrix>
SkShaderBase::totalLocalMatrix(const SkMatrix* preLocalMatrix,
const SkMatrix* postLocalMatrix) const {
SkTCopyOnFirstWrite<SkMatrix> m(fLocalMatrix);
if (preLocalMatrix) {
m.writable()->preConcat(*preLocalMatrix);
}
if (postLocalMatrix) {
m.writable()->postConcat(*postLocalMatrix);
}
return m;
}
bool SkShaderBase::computeTotalInverse(const SkMatrix& ctm,
const SkMatrix* outerLocalMatrix,
SkMatrix* totalInverse) const {
return SkMatrix::Concat(ctm, *this->totalLocalMatrix(outerLocalMatrix)).invert(totalInverse);
SkMatrix total = SkMatrix::Concat(ctm, fLocalMatrix);
if (outerLocalMatrix) {
total.preConcat(*outerLocalMatrix);
}
return total.invert(totalInverse);
}
bool SkShaderBase::asLuminanceColor(SkColor* colorPtr) const {

View File

@ -12,7 +12,6 @@
#include "SkMask.h"
#include "SkMatrix.h"
#include "SkShader.h"
#include "SkTLazy.h"
#if SK_SUPPORT_GPU
#include "GrFPArgs.h"
@ -186,16 +185,9 @@ public:
// If this returns false, then we draw nothing (do not fall back to shader context)
bool appendStages(const StageRec&) const;
bool SK_WARN_UNUSED_RESULT computeTotalInverse(const SkMatrix& ctm,
const SkMatrix* outerLocalMatrix,
SkMatrix* totalInverse) const;
// Returns the total local matrix for this shader:
//
// M = postLocalMatrix x shaderLocalMatrix x preLocalMatrix
//
SkTCopyOnFirstWrite<SkMatrix> totalLocalMatrix(const SkMatrix* preLocalMatrix,
const SkMatrix* postLocalMatrix = nullptr) const;
bool computeTotalInverse(const SkMatrix& ctm,
const SkMatrix* outerLocalMatrix,
SkMatrix* totalInverse) const;
#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const {

View File

@ -195,9 +195,16 @@ std::unique_ptr<GrFragmentProcessor> SkLinearGradient::asFragmentProcessor(
SkASSERT(args.fContext);
SkMatrix matrix;
if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
if (!this->getLocalMatrix().invert(&matrix)) {
return nullptr;
}
if (args.fLocalMatrix) {
SkMatrix inv;
if (!args.fLocalMatrix->invert(&inv)) {
return nullptr;
}
matrix.postConcat(inv);
}
matrix.postConcat(fPtsToUnit);
return GrLinearGradient::Make(GrGradientEffect::CreateArgs(

View File

@ -162,10 +162,19 @@ void GrRadialGradient::GLSLRadialProcessor::emitCode(EmitArgs& args) {
std::unique_ptr<GrFragmentProcessor> SkRadialGradient::asFragmentProcessor(
const GrFPArgs& args) const {
SkASSERT(args.fContext);
SkMatrix matrix;
if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
if (!this->getLocalMatrix().invert(&matrix)) {
return nullptr;
}
if (args.fLocalMatrix) {
SkMatrix inv;
if (!args.fLocalMatrix->invert(&inv)) {
return nullptr;
}
matrix.postConcat(inv);
}
matrix.postConcat(fPtsToUnit);
return GrRadialGradient::Make(GrGradientEffect::CreateArgs(

View File

@ -216,9 +216,16 @@ void GrSweepGradient::GLSLSweepProcessor::emitCode(EmitArgs& args) {
std::unique_ptr<GrFragmentProcessor> SkSweepGradient::asFragmentProcessor(
const GrFPArgs& args) const {
SkMatrix matrix;
if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
if (!this->getLocalMatrix().invert(&matrix)) {
return nullptr;
}
if (args.fLocalMatrix) {
SkMatrix inv;
if (!args.fLocalMatrix->invert(&inv)) {
return nullptr;
}
matrix.postConcat(inv);
}
matrix.postConcat(fPtsToUnit);
return GrSweepGradient::Make(

View File

@ -175,13 +175,9 @@ void SkTwoPointConicalGradient::flatten(SkWriteBuffer& buffer) const {
std::unique_ptr<GrFragmentProcessor> SkTwoPointConicalGradient::asFragmentProcessor(
const GrFPArgs& args) const {
SkMatrix matrix;
if (!this->totalLocalMatrix(args.fPreLocalMatrix, args.fPostLocalMatrix)->invert(&matrix)) {
return nullptr;
}
SkASSERT(args.fContext);
return Gr2PtConicalGradientEffect::Make(
GrGradientEffect::CreateArgs(args.fContext, this, &matrix, fTileMode,
GrGradientEffect::CreateArgs(args.fContext, this, args.fLocalMatrix, fTileMode,
args.fDstColorSpaceInfo->colorSpace()));
}

View File

@ -388,7 +388,18 @@ std::unique_ptr<GrFragmentProcessor> Gr2PtConicalGradientEffect::Make(
const SkTwoPointConicalGradient& shader =
*static_cast<const SkTwoPointConicalGradient*>(args.fShader);
SkMatrix matrix = *args.fMatrix;
SkMatrix matrix;
if (!shader.getLocalMatrix().invert(&matrix)) {
return nullptr;
}
if (args.fMatrix) {
SkMatrix inv;
if (!args.fMatrix->invert(&inv)) {
return nullptr;
}
matrix.postConcat(inv);
}
GrGradientEffect::CreateArgs newArgs(args.fContext, args.fShader, &matrix, args.fWrapMode,
args.fDstColorSpace);
// Data and matrix has to be prepared before constructing TwoPointConicalEffect so its parent

View File

@ -479,7 +479,8 @@ static std::unique_ptr<GrFragmentProcessor> create_linear_gradient_processor(GrC
sk_sp<SkShader> shader = SkGradientShader::MakeLinear(
pts, colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode);
GrColorSpaceInfo colorSpaceInfo(nullptr, kRGBA_8888_GrPixelConfig);
GrFPArgs args(ctx, &SkMatrix::I(), SkFilterQuality::kLow_SkFilterQuality, &colorSpaceInfo);
GrFPArgs args(ctx, &SkMatrix::I(), &SkMatrix::I(), SkFilterQuality::kLow_SkFilterQuality,
&colorSpaceInfo);
return as_SB(shader)->asFragmentProcessor(args);
}