Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkShaderBase.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 Google LLC
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
9
18
19class SkWriteBuffer;
20
21namespace SkShaders {
22MatrixRec::MatrixRec(const SkMatrix& ctm) : fCTM(ctm) {}
23
24std::optional<MatrixRec> MatrixRec::apply(const SkStageRec& rec, const SkMatrix& postInv) const {
25 SkMatrix total = fPendingLocalMatrix;
26 if (!fCTMApplied) {
27 total = SkMatrix::Concat(fCTM, total);
28 }
29 if (!total.invert(&total)) {
30 return {};
31 }
32 total = SkMatrix::Concat(postInv, total);
33 if (!fCTMApplied) {
34 rec.fPipeline->append(SkRasterPipelineOp::seed_shader);
35 }
36 // appendMatrix is a no-op if total worked out to identity.
37 rec.fPipeline->appendMatrix(rec.fAlloc, total);
38 return MatrixRec{fCTM,
39 fTotalLocalMatrix,
40 /*pendingLocalMatrix=*/SkMatrix::I(),
41 fTotalMatrixIsValid,
42 /*ctmApplied=*/true};
43}
44
45std::tuple<SkMatrix, bool> MatrixRec::applyForFragmentProcessor(const SkMatrix& postInv) const {
46 SkASSERT(!fCTMApplied);
47 SkMatrix total;
48 if (!fPendingLocalMatrix.invert(&total)) {
49 return {SkMatrix::I(), false};
50 }
51 return {SkMatrix::Concat(postInv, total), true};
52}
53
55 // We mark the CTM as "not applied" because we *never* apply the CTM for FPs. Their starting
56 // coords are local, not device, coords.
57 return MatrixRec{fCTM,
58 fTotalLocalMatrix,
59 /*pendingLocalMatrix=*/SkMatrix::I(),
60 fTotalMatrixIsValid,
61 /*ctmApplied=*/false};
62}
63
65 return {fCTM,
66 SkShaderBase::ConcatLocalMatrices(fTotalLocalMatrix, m),
67 SkShaderBase::ConcatLocalMatrices(fPendingLocalMatrix, m),
68 fTotalMatrixIsValid,
69 fCTMApplied};
70}
71
72} // namespace SkShaders
73
74///////////////////////////////////////////////////////////////////////////////////////
75
77
79
81
83 SkColor4f storage;
84 if (nullptr == colorPtr) {
85 colorPtr = &storage;
86 }
87 if (this->onAsLuminanceColor(colorPtr)) {
88 colorPtr->fA = 1.0f; // we only return opaque
89 return true;
90 }
91 return false;
92}
93
95#ifdef SK_ENABLE_LEGACY_SHADERCONTEXT
96 // We always fall back to raster pipeline when perspective is present.
97 auto totalMatrix = rec.fMatrixRec.totalMatrix();
98 if (totalMatrix.hasPerspective() || !totalMatrix.invert(nullptr)) {
99 return nullptr;
100 }
101
102 return this->onMakeContext(rec, alloc);
103#else
104 return nullptr;
105#endif
106}
107
109 : fShader(shader) {
110 // We should never use a context with perspective.
112
113 // Because the context parameters must be valid at this point, we know that the matrix is
114 // invertible.
115 SkAssertResult(rec.fMatrixRec.totalInverse(&fTotalInverse));
116
117 fPaintAlpha = rec.fPaintAlpha;
118}
119
121
123 // In legacy pipelines, shaders always produce premul (or opaque) and the destination is also
124 // always premul (or opaque). (And those "or opaque" caveats won't make any difference here.)
126 return 0 ==
127 SkColorSpaceXformSteps{shaderColorSpace, shaderAT, fDstColorSpace, dstAT}.flags.mask();
128}
129
131
132bool SkShaderBase::appendRootStages(const SkStageRec& rec, const SkMatrix& ctm) const {
133 return this->appendStages(rec, SkShaders::MatrixRec(ctm));
134}
135
137 return sk_sp<SkShader>(new SkCTMShader(sk_ref_sp(this), postM));
138}
139
140// need a cheap way to invert the alpha channel of a shader (i.e. 1 - a)
SkAlphaType
Definition SkAlphaType.h:26
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkAssertResult(cond)
Definition SkAssert.h:123
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kSrcOut
r = s * (1-da)
sk_sp< T > sk_ref_sp(T *obj)
Definition SkRefCnt.h:381
static sk_sp< SkColorFilter > Blend(const SkColor4f &c, sk_sp< SkColorSpace >, SkBlendMode mode)
virtual void flatten(SkWriteBuffer &) const
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Definition SkMatrix.h:1775
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
static const SkMatrix & I()
bool hasPerspective() const
Definition SkMatrix.h:312
void append(SkRasterPipelineOp, void *=nullptr)
void appendMatrix(SkArenaAlloc *, const SkMatrix &)
Context(const SkShaderBase &shader, const ContextRec &)
virtual bool onAsLuminanceColor(SkColor4f *) const
sk_sp< SkShader > makeInvertAlpha() const
bool appendRootStages(const SkStageRec &rec, const SkMatrix &ctm) const
void flatten(SkWriteBuffer &) const override
bool asLuminanceColor(SkColor4f *) const
sk_sp< SkShader > makeWithCTM(const SkMatrix &) const
~SkShaderBase() override
static SkMatrix ConcatLocalMatrices(const SkMatrix &parentLM, const SkMatrix &childLM)
Context * makeContext(const ContextRec &, SkArenaAlloc *) const
virtual bool appendStages(const SkStageRec &, const SkShaders::MatrixRec &) const =0
virtual sk_sp< SkShader > makeAsALocalMatrixShader(SkMatrix *localMatrix) const
sk_sp< SkShader > makeWithColorFilter(sk_sp< SkColorFilter >) const
Definition SkShader.cpp:43
std::optional< MatrixRec > apply(const SkStageRec &rec, const SkMatrix &postInv={}) const
bool totalInverse(SkMatrix *out) const
MatrixRec applied() const
std::tuple< SkMatrix, bool > applyForFragmentProcessor(const SkMatrix &postInv) const
MatrixRec concat(const SkMatrix &m) const
SkMatrix totalMatrix() const
static const uint8_t buffer[]
const SkShaders::MatrixRec fMatrixRec
bool isLegacyCompatible(SkColorSpace *shadersColorSpace) const
SkRasterPipeline * fPipeline
SkArenaAlloc * fAlloc