1 /*
2 * Copyright 2024 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
8 #include "include/gpu/graphite/precompile/PrecompileMaskFilter.h"
9
10 #include "include/gpu/graphite/precompile/PaintOptions.h"
11 #include "include/gpu/graphite/precompile/PrecompileColorFilter.h"
12 #include "include/gpu/graphite/precompile/PrecompileShader.h"
13 #include "src/gpu/graphite/Caps.h"
14 #include "src/gpu/graphite/InternalDrawTypeFlags.h"
15 #include "src/gpu/graphite/KeyContext.h"
16 #include "src/gpu/graphite/PrecompileInternal.h"
17 #include "src/gpu/graphite/RenderPassDesc.h"
18 #include "src/gpu/graphite/Renderer.h"
19 #include "src/gpu/graphite/precompile/PrecompileImageFiltersPriv.h"
20
21 namespace skgpu::graphite {
22
23 PrecompileMaskFilter::~PrecompileMaskFilter() = default;
24
25 // The PrecompileMaskFilter-derived classes do not use the PrecompileBase::addToKey virtual since
26 // they, in general, do not themselves contribute to a given SkPaint/Pipeline but, rather,
27 // create separate SkPaints/Pipelines from whole cloth (in createPipelines).
addToKey(const KeyContext & keyContext,PaintParamsKeyBuilder * builder,PipelineDataGatherer * gatherer,int desiredCombination) const28 void PrecompileMaskFilter::addToKey(const KeyContext& keyContext,
29 PaintParamsKeyBuilder* builder,
30 PipelineDataGatherer* gatherer,
31 int desiredCombination) const {
32 SkASSERT(false);
33 }
34
35 //--------------------------------------------------------------------------------------------------
36 // TODO(b/342413572): the analytic blurmasks are triggered off of the simple DrawType thus
37 // over-generate when a simple draw doesn't have a blur mask.
38 class PrecompileBlurMaskFilter : public PrecompileMaskFilter {
39 public:
PrecompileBlurMaskFilter()40 PrecompileBlurMaskFilter() {}
41
42 private:
createPipelines(const KeyContext & keyContext,PipelineDataGatherer * gatherer,const PaintOptions & paintOptions,const RenderPassDesc & renderPassDescIn,const PaintOptionsPriv::ProcessCombination & processCombination) const43 void createPipelines(
44 const KeyContext& keyContext,
45 PipelineDataGatherer* gatherer,
46 const PaintOptions& paintOptions,
47 const RenderPassDesc& renderPassDescIn,
48 const PaintOptionsPriv::ProcessCombination& processCombination) const override {
49 const Caps* caps = keyContext.caps();
50 // TODO: pull Protected-ness from 'renderPassDescIn'
51 TextureInfo info = caps->getDefaultSampledTextureInfo(kAlpha_8_SkColorType,
52 Mipmapped::kNo,
53 Protected::kNo,
54 Renderable::kYes);
55
56 RenderPassDesc coverageRenderPassDesc = RenderPassDesc::Make(caps,
57 info,
58 LoadOp::kClear,
59 StoreOp::kStore,
60 DepthStencilFlags::kDepth,
61 { 0.0f, 0.0f, 0.0f, 0.0f },
62 /* requiresMSAA= */ false,
63 skgpu::Swizzle("a000"));
64
65 PrecompileImageFiltersPriv::CreateBlurImageFilterPipelines(keyContext, gatherer,
66 coverageRenderPassDesc,
67 processCombination);
68
69 // c.f. AutoLayerForImageFilter::addMaskFilterLayer. The following PaintOptions handle
70 // the case where an explicit layer must be created.
71 {
72 // The restore draw takes over all the shading effects. The mask filter blur will have
73 // been converted to an image filter applied to the coverage layer. That coverage
74 // will then be used as the coverage mask for the restoreOptions.
75 PaintOptions restoreOptions = paintOptions;
76 restoreOptions.setMaskFilters({});
77 restoreOptions.priv().buildCombinations(
78 keyContext,
79 gatherer,
80 static_cast<DrawTypeFlags>(InternalDrawTypeFlags::kCoverageMask),
81 /* withPrimitiveBlender= */ false,
82 Coverage::kSingleChannel,
83 renderPassDescIn,
84 processCombination);
85 }
86
87 {
88 // The initial draw into the coverage layer is just a solid white kSrcOver SkPaint
89 // These options cover the case where the coverage draw can be done with the
90 // AnalyticRRect RenderStep.
91 // TODO: gate the inclusion of this option on the drawType being kSimple
92 PaintOptions coverageOptions;
93 coverageOptions.setShaders({ PrecompileShaders::Color() });
94 coverageOptions.setBlendModes({ SkBlendMode::kSrcOver });
95
96 coverageOptions.priv().buildCombinations(
97 keyContext,
98 gatherer,
99 static_cast<DrawTypeFlags>(InternalDrawTypeFlags::kAnalyticRRect),
100 /* withPrimitiveBlender= */ false,
101 Coverage::kSingleChannel,
102 coverageRenderPassDesc,
103 processCombination);
104 }
105 }
106 };
107
Blur()108 sk_sp<PrecompileMaskFilter> PrecompileMaskFilters::Blur() {
109 return sk_make_sp<PrecompileBlurMaskFilter>();
110 }
111
112 } // namespace skgpu::graphite
113