1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2024 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PaintOptions.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileBlender.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileColorFilter.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileImageFilter.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileMaskFilter.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/precompile/PrecompileShader.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Caps.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ContextUtils.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/KeyContext.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/PaintParamsKey.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/PrecompileInternal.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/Renderer.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ShaderCodeDictionary.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PaintOption.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PaintOptionsPriv.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PrecompileBaseComplete.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PrecompileBasePriv.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PrecompileBlenderPriv.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PrecompileShaderPriv.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/precompile/PrecompileShadersPriv.h"
29*c8dee2aaSAndroid Build Coastguard Worker
30*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker PaintOptions::PaintOptions() = default;
33*c8dee2aaSAndroid Build Coastguard Worker PaintOptions::PaintOptions(const PaintOptions&) = default;
34*c8dee2aaSAndroid Build Coastguard Worker PaintOptions::~PaintOptions() = default;
35*c8dee2aaSAndroid Build Coastguard Worker PaintOptions& PaintOptions::operator=(const PaintOptions&) = default;
36*c8dee2aaSAndroid Build Coastguard Worker
setShaders(SkSpan<const sk_sp<PrecompileShader>> shaders)37*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::setShaders(SkSpan<const sk_sp<PrecompileShader>> shaders) {
38*c8dee2aaSAndroid Build Coastguard Worker fShaderOptions.clear();
39*c8dee2aaSAndroid Build Coastguard Worker fShaderOptions.push_back_n(shaders.size(), shaders.data());
40*c8dee2aaSAndroid Build Coastguard Worker }
41*c8dee2aaSAndroid Build Coastguard Worker
setImageFilters(SkSpan<const sk_sp<PrecompileImageFilter>> imageFilters)42*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::setImageFilters(SkSpan<const sk_sp<PrecompileImageFilter>> imageFilters) {
43*c8dee2aaSAndroid Build Coastguard Worker fImageFilterOptions.clear();
44*c8dee2aaSAndroid Build Coastguard Worker fImageFilterOptions.push_back_n(imageFilters.size(), imageFilters.data());
45*c8dee2aaSAndroid Build Coastguard Worker }
46*c8dee2aaSAndroid Build Coastguard Worker
setMaskFilters(SkSpan<const sk_sp<PrecompileMaskFilter>> maskFilters)47*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::setMaskFilters(SkSpan<const sk_sp<PrecompileMaskFilter>> maskFilters) {
48*c8dee2aaSAndroid Build Coastguard Worker fMaskFilterOptions.clear();
49*c8dee2aaSAndroid Build Coastguard Worker fMaskFilterOptions.push_back_n(maskFilters.size(), maskFilters.data());
50*c8dee2aaSAndroid Build Coastguard Worker }
51*c8dee2aaSAndroid Build Coastguard Worker
setColorFilters(SkSpan<const sk_sp<PrecompileColorFilter>> colorFilters)52*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::setColorFilters(SkSpan<const sk_sp<PrecompileColorFilter>> colorFilters) {
53*c8dee2aaSAndroid Build Coastguard Worker fColorFilterOptions.clear();
54*c8dee2aaSAndroid Build Coastguard Worker fColorFilterOptions.push_back_n(colorFilters.size(), colorFilters.data());
55*c8dee2aaSAndroid Build Coastguard Worker }
56*c8dee2aaSAndroid Build Coastguard Worker
addColorFilter(sk_sp<PrecompileColorFilter> cf)57*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::addColorFilter(sk_sp<PrecompileColorFilter> cf) {
58*c8dee2aaSAndroid Build Coastguard Worker fColorFilterOptions.push_back(std::move(cf));
59*c8dee2aaSAndroid Build Coastguard Worker }
60*c8dee2aaSAndroid Build Coastguard Worker
setBlendModes(SkSpan<const SkBlendMode> blendModes)61*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::setBlendModes(SkSpan<const SkBlendMode> blendModes) {
62*c8dee2aaSAndroid Build Coastguard Worker fBlendModeOptions.clear();
63*c8dee2aaSAndroid Build Coastguard Worker fBlendModeOptions.push_back_n(blendModes.size(), blendModes.data());
64*c8dee2aaSAndroid Build Coastguard Worker }
65*c8dee2aaSAndroid Build Coastguard Worker
setBlenders(SkSpan<const sk_sp<PrecompileBlender>> blenders)66*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::setBlenders(SkSpan<const sk_sp<PrecompileBlender>> blenders) {
67*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileBlender>& b: blenders) {
68*c8dee2aaSAndroid Build Coastguard Worker if (b->priv().asBlendMode().has_value()) {
69*c8dee2aaSAndroid Build Coastguard Worker fBlendModeOptions.push_back(b->priv().asBlendMode().value());
70*c8dee2aaSAndroid Build Coastguard Worker } else {
71*c8dee2aaSAndroid Build Coastguard Worker fBlenderOptions.push_back(b);
72*c8dee2aaSAndroid Build Coastguard Worker }
73*c8dee2aaSAndroid Build Coastguard Worker }
74*c8dee2aaSAndroid Build Coastguard Worker }
75*c8dee2aaSAndroid Build Coastguard Worker
setClipShaders(SkSpan<const sk_sp<PrecompileShader>> clipShaders)76*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::setClipShaders(SkSpan<const sk_sp<PrecompileShader>> clipShaders) {
77*c8dee2aaSAndroid Build Coastguard Worker // In the normal API this modification happens in SkDevice::clipShader()
78*c8dee2aaSAndroid Build Coastguard Worker fClipShaderOptions.reserve(2 * clipShaders.size());
79*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileShader>& cs : clipShaders) {
80*c8dee2aaSAndroid Build Coastguard Worker // All clipShaders get wrapped in a CTMShader ...
81*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PrecompileShader> withCTM = cs ? PrecompileShadersPriv::CTM({ cs }) : nullptr;
82*c8dee2aaSAndroid Build Coastguard Worker // and, if it is a SkClipOp::kDifference clip, an additional ColorFilterShader
83*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PrecompileShader> inverted =
84*c8dee2aaSAndroid Build Coastguard Worker withCTM ? withCTM->makeWithColorFilter(PrecompileColorFilters::Blend())
85*c8dee2aaSAndroid Build Coastguard Worker : nullptr;
86*c8dee2aaSAndroid Build Coastguard Worker
87*c8dee2aaSAndroid Build Coastguard Worker fClipShaderOptions.emplace_back(std::move(withCTM));
88*c8dee2aaSAndroid Build Coastguard Worker fClipShaderOptions.emplace_back(std::move(inverted));
89*c8dee2aaSAndroid Build Coastguard Worker }
90*c8dee2aaSAndroid Build Coastguard Worker }
91*c8dee2aaSAndroid Build Coastguard Worker
numShaderCombinations() const92*c8dee2aaSAndroid Build Coastguard Worker int PaintOptions::numShaderCombinations() const {
93*c8dee2aaSAndroid Build Coastguard Worker int numShaderCombinations = 0;
94*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileShader>& s : fShaderOptions) {
95*c8dee2aaSAndroid Build Coastguard Worker numShaderCombinations += s->numCombinations();
96*c8dee2aaSAndroid Build Coastguard Worker }
97*c8dee2aaSAndroid Build Coastguard Worker
98*c8dee2aaSAndroid Build Coastguard Worker // If no shader option is specified we will add a solid color shader option
99*c8dee2aaSAndroid Build Coastguard Worker return numShaderCombinations ? numShaderCombinations : 1;
100*c8dee2aaSAndroid Build Coastguard Worker }
101*c8dee2aaSAndroid Build Coastguard Worker
numColorFilterCombinations() const102*c8dee2aaSAndroid Build Coastguard Worker int PaintOptions::numColorFilterCombinations() const {
103*c8dee2aaSAndroid Build Coastguard Worker int numColorFilterCombinations = 0;
104*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileColorFilter>& cf : fColorFilterOptions) {
105*c8dee2aaSAndroid Build Coastguard Worker if (!cf) {
106*c8dee2aaSAndroid Build Coastguard Worker ++numColorFilterCombinations;
107*c8dee2aaSAndroid Build Coastguard Worker } else {
108*c8dee2aaSAndroid Build Coastguard Worker numColorFilterCombinations += cf->numCombinations();
109*c8dee2aaSAndroid Build Coastguard Worker }
110*c8dee2aaSAndroid Build Coastguard Worker }
111*c8dee2aaSAndroid Build Coastguard Worker
112*c8dee2aaSAndroid Build Coastguard Worker // If no color filter options are specified we will use the unmodified result color
113*c8dee2aaSAndroid Build Coastguard Worker return numColorFilterCombinations ? numColorFilterCombinations : 1;
114*c8dee2aaSAndroid Build Coastguard Worker }
115*c8dee2aaSAndroid Build Coastguard Worker
numBlendCombinations() const116*c8dee2aaSAndroid Build Coastguard Worker int PaintOptions::numBlendCombinations() const {
117*c8dee2aaSAndroid Build Coastguard Worker int numBlendCombos = fBlendModeOptions.size();
118*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileBlender>& b: fBlenderOptions) {
119*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!b->priv().asBlendMode().has_value());
120*c8dee2aaSAndroid Build Coastguard Worker numBlendCombos += b->priv().numChildCombinations();
121*c8dee2aaSAndroid Build Coastguard Worker }
122*c8dee2aaSAndroid Build Coastguard Worker
123*c8dee2aaSAndroid Build Coastguard Worker if (!numBlendCombos) {
124*c8dee2aaSAndroid Build Coastguard Worker // If the user didn't specify a blender we will fall back to kSrcOver blending
125*c8dee2aaSAndroid Build Coastguard Worker numBlendCombos = 1;
126*c8dee2aaSAndroid Build Coastguard Worker }
127*c8dee2aaSAndroid Build Coastguard Worker
128*c8dee2aaSAndroid Build Coastguard Worker return numBlendCombos;
129*c8dee2aaSAndroid Build Coastguard Worker }
130*c8dee2aaSAndroid Build Coastguard Worker
numClipShaderCombinations() const131*c8dee2aaSAndroid Build Coastguard Worker int PaintOptions::numClipShaderCombinations() const {
132*c8dee2aaSAndroid Build Coastguard Worker int numClipShaderCombos = 0;
133*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileShader>& cs: fClipShaderOptions) {
134*c8dee2aaSAndroid Build Coastguard Worker if (cs) {
135*c8dee2aaSAndroid Build Coastguard Worker numClipShaderCombos += cs->priv().numChildCombinations();
136*c8dee2aaSAndroid Build Coastguard Worker } else {
137*c8dee2aaSAndroid Build Coastguard Worker ++numClipShaderCombos;
138*c8dee2aaSAndroid Build Coastguard Worker }
139*c8dee2aaSAndroid Build Coastguard Worker }
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Worker // If no clipShader options are specified we will just have the unclipped options
142*c8dee2aaSAndroid Build Coastguard Worker return numClipShaderCombos ? numClipShaderCombos : 1;
143*c8dee2aaSAndroid Build Coastguard Worker }
144*c8dee2aaSAndroid Build Coastguard Worker
numCombinations() const145*c8dee2aaSAndroid Build Coastguard Worker int PaintOptions::numCombinations() const {
146*c8dee2aaSAndroid Build Coastguard Worker return this->numShaderCombinations() *
147*c8dee2aaSAndroid Build Coastguard Worker this->numColorFilterCombinations() *
148*c8dee2aaSAndroid Build Coastguard Worker this->numBlendCombinations() *
149*c8dee2aaSAndroid Build Coastguard Worker this->numClipShaderCombinations();
150*c8dee2aaSAndroid Build Coastguard Worker }
151*c8dee2aaSAndroid Build Coastguard Worker
152*c8dee2aaSAndroid Build Coastguard Worker namespace {
153*c8dee2aaSAndroid Build Coastguard Worker
get_dst_read_req(const Caps * caps,Coverage coverage,PrecompileBlender * blender)154*c8dee2aaSAndroid Build Coastguard Worker DstReadRequirement get_dst_read_req(const Caps* caps,
155*c8dee2aaSAndroid Build Coastguard Worker Coverage coverage,
156*c8dee2aaSAndroid Build Coastguard Worker PrecompileBlender* blender) {
157*c8dee2aaSAndroid Build Coastguard Worker if (blender) {
158*c8dee2aaSAndroid Build Coastguard Worker return GetDstReadRequirement(caps, blender->priv().asBlendMode(), coverage);
159*c8dee2aaSAndroid Build Coastguard Worker }
160*c8dee2aaSAndroid Build Coastguard Worker return GetDstReadRequirement(caps, SkBlendMode::kSrcOver, coverage);
161*c8dee2aaSAndroid Build Coastguard Worker }
162*c8dee2aaSAndroid Build Coastguard Worker
163*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
164*c8dee2aaSAndroid Build Coastguard Worker
createKey(const KeyContext & keyContext,PaintParamsKeyBuilder * keyBuilder,PipelineDataGatherer * gatherer,int desiredCombination,bool addPrimitiveBlender,Coverage coverage) const165*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::createKey(const KeyContext& keyContext,
166*c8dee2aaSAndroid Build Coastguard Worker PaintParamsKeyBuilder* keyBuilder,
167*c8dee2aaSAndroid Build Coastguard Worker PipelineDataGatherer* gatherer,
168*c8dee2aaSAndroid Build Coastguard Worker int desiredCombination,
169*c8dee2aaSAndroid Build Coastguard Worker bool addPrimitiveBlender,
170*c8dee2aaSAndroid Build Coastguard Worker Coverage coverage) const {
171*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGCODE(keyBuilder->checkReset();)
172*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(desiredCombination < this->numCombinations());
173*c8dee2aaSAndroid Build Coastguard Worker
174*c8dee2aaSAndroid Build Coastguard Worker const int numClipShaderCombos = this->numClipShaderCombinations();
175*c8dee2aaSAndroid Build Coastguard Worker const int numBlendModeCombos = this->numBlendCombinations();
176*c8dee2aaSAndroid Build Coastguard Worker const int numColorFilterCombinations = this->numColorFilterCombinations();
177*c8dee2aaSAndroid Build Coastguard Worker
178*c8dee2aaSAndroid Build Coastguard Worker const int desiredClipShaderCombination = desiredCombination % numClipShaderCombos;
179*c8dee2aaSAndroid Build Coastguard Worker int remainingCombinations = desiredCombination / numClipShaderCombos;
180*c8dee2aaSAndroid Build Coastguard Worker
181*c8dee2aaSAndroid Build Coastguard Worker const int desiredBlendCombination = remainingCombinations % numBlendModeCombos;
182*c8dee2aaSAndroid Build Coastguard Worker remainingCombinations /= numBlendModeCombos;
183*c8dee2aaSAndroid Build Coastguard Worker
184*c8dee2aaSAndroid Build Coastguard Worker const int desiredColorFilterCombination = remainingCombinations % numColorFilterCombinations;
185*c8dee2aaSAndroid Build Coastguard Worker remainingCombinations /= numColorFilterCombinations;
186*c8dee2aaSAndroid Build Coastguard Worker
187*c8dee2aaSAndroid Build Coastguard Worker const int desiredShaderCombination = remainingCombinations;
188*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(desiredShaderCombination < this->numShaderCombinations());
189*c8dee2aaSAndroid Build Coastguard Worker
190*c8dee2aaSAndroid Build Coastguard Worker // TODO: this probably needs to be passed in just like addPrimitiveBlender
191*c8dee2aaSAndroid Build Coastguard Worker const bool kOpaquePaintColor = true;
192*c8dee2aaSAndroid Build Coastguard Worker
193*c8dee2aaSAndroid Build Coastguard Worker auto clipShader = PrecompileBase::SelectOption(SkSpan(fClipShaderOptions),
194*c8dee2aaSAndroid Build Coastguard Worker desiredClipShaderCombination);
195*c8dee2aaSAndroid Build Coastguard Worker
196*c8dee2aaSAndroid Build Coastguard Worker std::pair<sk_sp<PrecompileBlender>, int> finalBlender;
197*c8dee2aaSAndroid Build Coastguard Worker if (desiredBlendCombination < fBlendModeOptions.size()) {
198*c8dee2aaSAndroid Build Coastguard Worker finalBlender = { PrecompileBlenders::Mode(fBlendModeOptions[desiredBlendCombination]), 0 };
199*c8dee2aaSAndroid Build Coastguard Worker } else {
200*c8dee2aaSAndroid Build Coastguard Worker finalBlender = PrecompileBase::SelectOption(
201*c8dee2aaSAndroid Build Coastguard Worker SkSpan(fBlenderOptions),
202*c8dee2aaSAndroid Build Coastguard Worker desiredBlendCombination - fBlendModeOptions.size());
203*c8dee2aaSAndroid Build Coastguard Worker }
204*c8dee2aaSAndroid Build Coastguard Worker if (!finalBlender.first) {
205*c8dee2aaSAndroid Build Coastguard Worker finalBlender = { PrecompileBlenders::Mode(SkBlendMode::kSrcOver), 0 };
206*c8dee2aaSAndroid Build Coastguard Worker }
207*c8dee2aaSAndroid Build Coastguard Worker DstReadRequirement dstReadReq = get_dst_read_req(keyContext.caps(), coverage,
208*c8dee2aaSAndroid Build Coastguard Worker finalBlender.first.get());
209*c8dee2aaSAndroid Build Coastguard Worker
210*c8dee2aaSAndroid Build Coastguard Worker PaintOption option(kOpaquePaintColor,
211*c8dee2aaSAndroid Build Coastguard Worker finalBlender,
212*c8dee2aaSAndroid Build Coastguard Worker PrecompileBase::SelectOption(SkSpan(fShaderOptions),
213*c8dee2aaSAndroid Build Coastguard Worker desiredShaderCombination),
214*c8dee2aaSAndroid Build Coastguard Worker PrecompileBase::SelectOption(SkSpan(fColorFilterOptions),
215*c8dee2aaSAndroid Build Coastguard Worker desiredColorFilterCombination),
216*c8dee2aaSAndroid Build Coastguard Worker addPrimitiveBlender,
217*c8dee2aaSAndroid Build Coastguard Worker clipShader,
218*c8dee2aaSAndroid Build Coastguard Worker dstReadReq,
219*c8dee2aaSAndroid Build Coastguard Worker fDither);
220*c8dee2aaSAndroid Build Coastguard Worker
221*c8dee2aaSAndroid Build Coastguard Worker option.toKey(keyContext, keyBuilder, gatherer);
222*c8dee2aaSAndroid Build Coastguard Worker }
223*c8dee2aaSAndroid Build Coastguard Worker
224*c8dee2aaSAndroid Build Coastguard Worker namespace {
225*c8dee2aaSAndroid Build Coastguard Worker
create_image_drawing_pipelines(const KeyContext & keyContext,PipelineDataGatherer * gatherer,const PaintOptions & orig,const RenderPassDesc & renderPassDesc,const PaintOptionsPriv::ProcessCombination & processCombination)226*c8dee2aaSAndroid Build Coastguard Worker void create_image_drawing_pipelines(const KeyContext& keyContext,
227*c8dee2aaSAndroid Build Coastguard Worker PipelineDataGatherer* gatherer,
228*c8dee2aaSAndroid Build Coastguard Worker const PaintOptions& orig,
229*c8dee2aaSAndroid Build Coastguard Worker const RenderPassDesc& renderPassDesc,
230*c8dee2aaSAndroid Build Coastguard Worker const PaintOptionsPriv::ProcessCombination& processCombination) {
231*c8dee2aaSAndroid Build Coastguard Worker PaintOptions imagePaintOptions;
232*c8dee2aaSAndroid Build Coastguard Worker
233*c8dee2aaSAndroid Build Coastguard Worker // For imagefilters we know we don't have alpha-only textures and don't need cubic filtering.
234*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PrecompileShader> imageShader = PrecompileShadersPriv::Image(
235*c8dee2aaSAndroid Build Coastguard Worker PrecompileImageShaderFlags::kExcludeAlpha | PrecompileImageShaderFlags::kExcludeCubic);
236*c8dee2aaSAndroid Build Coastguard Worker
237*c8dee2aaSAndroid Build Coastguard Worker imagePaintOptions.setShaders({ imageShader });
238*c8dee2aaSAndroid Build Coastguard Worker imagePaintOptions.setBlendModes(orig.getBlendModes());
239*c8dee2aaSAndroid Build Coastguard Worker imagePaintOptions.setBlenders(orig.getBlenders());
240*c8dee2aaSAndroid Build Coastguard Worker imagePaintOptions.setColorFilters(orig.getColorFilters());
241*c8dee2aaSAndroid Build Coastguard Worker imagePaintOptions.priv().addColorFilter(nullptr);
242*c8dee2aaSAndroid Build Coastguard Worker
243*c8dee2aaSAndroid Build Coastguard Worker imagePaintOptions.priv().buildCombinations(keyContext,
244*c8dee2aaSAndroid Build Coastguard Worker gatherer,
245*c8dee2aaSAndroid Build Coastguard Worker DrawTypeFlags::kSimpleShape,
246*c8dee2aaSAndroid Build Coastguard Worker /* withPrimitiveBlender= */ false,
247*c8dee2aaSAndroid Build Coastguard Worker Coverage::kSingleChannel,
248*c8dee2aaSAndroid Build Coastguard Worker renderPassDesc,
249*c8dee2aaSAndroid Build Coastguard Worker processCombination);
250*c8dee2aaSAndroid Build Coastguard Worker }
251*c8dee2aaSAndroid Build Coastguard Worker
252*c8dee2aaSAndroid Build Coastguard Worker } // anonymous namespace
253*c8dee2aaSAndroid Build Coastguard Worker
buildCombinations(const KeyContext & keyContext,PipelineDataGatherer * gatherer,DrawTypeFlags drawTypes,bool withPrimitiveBlender,Coverage coverage,const RenderPassDesc & renderPassDesc,const ProcessCombination & processCombination) const254*c8dee2aaSAndroid Build Coastguard Worker void PaintOptions::buildCombinations(
255*c8dee2aaSAndroid Build Coastguard Worker const KeyContext& keyContext,
256*c8dee2aaSAndroid Build Coastguard Worker PipelineDataGatherer* gatherer,
257*c8dee2aaSAndroid Build Coastguard Worker DrawTypeFlags drawTypes,
258*c8dee2aaSAndroid Build Coastguard Worker bool withPrimitiveBlender,
259*c8dee2aaSAndroid Build Coastguard Worker Coverage coverage,
260*c8dee2aaSAndroid Build Coastguard Worker const RenderPassDesc& renderPassDesc,
261*c8dee2aaSAndroid Build Coastguard Worker const ProcessCombination& processCombination) const {
262*c8dee2aaSAndroid Build Coastguard Worker
263*c8dee2aaSAndroid Build Coastguard Worker PaintParamsKeyBuilder builder(keyContext.dict());
264*c8dee2aaSAndroid Build Coastguard Worker
265*c8dee2aaSAndroid Build Coastguard Worker if (!fImageFilterOptions.empty() || !fMaskFilterOptions.empty()) {
266*c8dee2aaSAndroid Build Coastguard Worker // TODO: split this out into a create_restore_draw_pipelines method
267*c8dee2aaSAndroid Build Coastguard Worker PaintOptions tmp = *this;
268*c8dee2aaSAndroid Build Coastguard Worker
269*c8dee2aaSAndroid Build Coastguard Worker // When image filtering, the original blend mode is taken over by the restore paint
270*c8dee2aaSAndroid Build Coastguard Worker tmp.setImageFilters({});
271*c8dee2aaSAndroid Build Coastguard Worker tmp.setMaskFilters({});
272*c8dee2aaSAndroid Build Coastguard Worker tmp.addBlendMode(SkBlendMode::kSrcOver);
273*c8dee2aaSAndroid Build Coastguard Worker
274*c8dee2aaSAndroid Build Coastguard Worker if (!fImageFilterOptions.empty()) {
275*c8dee2aaSAndroid Build Coastguard Worker std::vector<sk_sp<PrecompileColorFilter>> newCFs(tmp.fColorFilterOptions.begin(),
276*c8dee2aaSAndroid Build Coastguard Worker tmp.fColorFilterOptions.end());
277*c8dee2aaSAndroid Build Coastguard Worker if (newCFs.empty()) {
278*c8dee2aaSAndroid Build Coastguard Worker // TODO: I (robertphillips) believe this is unnecessary and is just a result of the
279*c8dee2aaSAndroid Build Coastguard Worker // base SkPaint generated in the PaintParamsKeyTest not correctly taking CFIFs into
280*c8dee2aaSAndroid Build Coastguard Worker // account.
281*c8dee2aaSAndroid Build Coastguard Worker newCFs.push_back(nullptr);
282*c8dee2aaSAndroid Build Coastguard Worker }
283*c8dee2aaSAndroid Build Coastguard Worker
284*c8dee2aaSAndroid Build Coastguard Worker // As in SkCanvasPriv::ImageToColorFilter, we fuse CFIFs into the base draw's CFs.
285*c8dee2aaSAndroid Build Coastguard Worker // TODO: in SkCanvasPriv::ImageToColorFilter this fusing of CFIFs and CFs is skipped
286*c8dee2aaSAndroid Build Coastguard Worker // when there is a maskfilter. For now we over-generate.
287*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileImageFilter>& o : fImageFilterOptions) {
288*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PrecompileColorFilter> imageFiltersCF = o ? o->asAColorFilter() : nullptr;
289*c8dee2aaSAndroid Build Coastguard Worker if (imageFiltersCF) {
290*c8dee2aaSAndroid Build Coastguard Worker if (!tmp.fColorFilterOptions.empty()) {
291*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileColorFilter>& cf : tmp.fColorFilterOptions) {
292*c8dee2aaSAndroid Build Coastguard Worker // TODO: if a CFIF was fully handled here it should be removed from the
293*c8dee2aaSAndroid Build Coastguard Worker // later loop over fImageFilterOptions. For now we over-generate.
294*c8dee2aaSAndroid Build Coastguard Worker sk_sp<PrecompileColorFilter> newCF = imageFiltersCF->makeComposed(cf);
295*c8dee2aaSAndroid Build Coastguard Worker newCFs.push_back(std::move(newCF));
296*c8dee2aaSAndroid Build Coastguard Worker }
297*c8dee2aaSAndroid Build Coastguard Worker } else {
298*c8dee2aaSAndroid Build Coastguard Worker newCFs.push_back(imageFiltersCF);
299*c8dee2aaSAndroid Build Coastguard Worker }
300*c8dee2aaSAndroid Build Coastguard Worker }
301*c8dee2aaSAndroid Build Coastguard Worker }
302*c8dee2aaSAndroid Build Coastguard Worker
303*c8dee2aaSAndroid Build Coastguard Worker tmp.setColorFilters(newCFs);
304*c8dee2aaSAndroid Build Coastguard Worker }
305*c8dee2aaSAndroid Build Coastguard Worker
306*c8dee2aaSAndroid Build Coastguard Worker tmp.buildCombinations(keyContext, gatherer, drawTypes, withPrimitiveBlender, coverage,
307*c8dee2aaSAndroid Build Coastguard Worker renderPassDesc, processCombination);
308*c8dee2aaSAndroid Build Coastguard Worker
309*c8dee2aaSAndroid Build Coastguard Worker create_image_drawing_pipelines(keyContext, gatherer, *this,
310*c8dee2aaSAndroid Build Coastguard Worker renderPassDesc, processCombination);
311*c8dee2aaSAndroid Build Coastguard Worker
312*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileImageFilter>& o : fImageFilterOptions) {
313*c8dee2aaSAndroid Build Coastguard Worker o->createPipelines(keyContext, gatherer, renderPassDesc, processCombination);
314*c8dee2aaSAndroid Build Coastguard Worker }
315*c8dee2aaSAndroid Build Coastguard Worker for (const sk_sp<PrecompileMaskFilter>& o : fMaskFilterOptions) {
316*c8dee2aaSAndroid Build Coastguard Worker o->createPipelines(keyContext, gatherer, *this, renderPassDesc, processCombination);
317*c8dee2aaSAndroid Build Coastguard Worker }
318*c8dee2aaSAndroid Build Coastguard Worker } else {
319*c8dee2aaSAndroid Build Coastguard Worker int numCombinations = this->numCombinations();
320*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < numCombinations; ++i) {
321*c8dee2aaSAndroid Build Coastguard Worker // Since the precompilation path's uniforms aren't used and don't change the key,
322*c8dee2aaSAndroid Build Coastguard Worker // the exact layout doesn't matter
323*c8dee2aaSAndroid Build Coastguard Worker gatherer->resetWithNewLayout(Layout::kMetal);
324*c8dee2aaSAndroid Build Coastguard Worker
325*c8dee2aaSAndroid Build Coastguard Worker this->createKey(keyContext, &builder, gatherer, i, withPrimitiveBlender, coverage);
326*c8dee2aaSAndroid Build Coastguard Worker
327*c8dee2aaSAndroid Build Coastguard Worker // The 'findOrCreate' calls lockAsKey on builder and then destroys the returned
328*c8dee2aaSAndroid Build Coastguard Worker // PaintParamsKey. This serves to reset the builder.
329*c8dee2aaSAndroid Build Coastguard Worker UniquePaintParamsID paintID = keyContext.dict()->findOrCreate(&builder);
330*c8dee2aaSAndroid Build Coastguard Worker
331*c8dee2aaSAndroid Build Coastguard Worker processCombination(paintID, drawTypes, withPrimitiveBlender, coverage, renderPassDesc);
332*c8dee2aaSAndroid Build Coastguard Worker }
333*c8dee2aaSAndroid Build Coastguard Worker }
334*c8dee2aaSAndroid Build Coastguard Worker }
335*c8dee2aaSAndroid Build Coastguard Worker
addColorFilter(sk_sp<PrecompileColorFilter> cf)336*c8dee2aaSAndroid Build Coastguard Worker void PaintOptionsPriv::addColorFilter(sk_sp<PrecompileColorFilter> cf) {
337*c8dee2aaSAndroid Build Coastguard Worker fPaintOptions->addColorFilter(std::move(cf));
338*c8dee2aaSAndroid Build Coastguard Worker }
339*c8dee2aaSAndroid Build Coastguard Worker
340*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
341