Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 142 additions & 111 deletions impeller/entity/contents/content_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,161 +96,178 @@ namespace impeller {

#ifdef IMPELLER_DEBUG
using CheckerboardPipeline =
RenderPipelineT<CheckerboardVertexShader, CheckerboardFragmentShader>;
RenderPipelineHandle<CheckerboardVertexShader, CheckerboardFragmentShader>;
#endif // IMPELLER_DEBUG

using LinearGradientFillPipeline =
RenderPipelineT<GradientFillVertexShader, LinearGradientFillFragmentShader>;
RenderPipelineHandle<GradientFillVertexShader,
LinearGradientFillFragmentShader>;
using SolidFillPipeline =
RenderPipelineT<SolidFillVertexShader, SolidFillFragmentShader>;
RenderPipelineHandle<SolidFillVertexShader, SolidFillFragmentShader>;
using RadialGradientFillPipeline =
RenderPipelineT<GradientFillVertexShader, RadialGradientFillFragmentShader>;
RenderPipelineHandle<GradientFillVertexShader,
RadialGradientFillFragmentShader>;
using ConicalGradientFillPipeline =
RenderPipelineT<GradientFillVertexShader,
ConicalGradientFillFragmentShader>;
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientFillFragmentShader>;
using SweepGradientFillPipeline =
RenderPipelineT<GradientFillVertexShader, SweepGradientFillFragmentShader>;
RenderPipelineHandle<GradientFillVertexShader,
SweepGradientFillFragmentShader>;
using LinearGradientSSBOFillPipeline =
RenderPipelineT<GradientFillVertexShader,
LinearGradientSsboFillFragmentShader>;
RenderPipelineHandle<GradientFillVertexShader,
LinearGradientSsboFillFragmentShader>;
using ConicalGradientSSBOFillPipeline =
RenderPipelineT<GradientFillVertexShader,
ConicalGradientSsboFillFragmentShader>;
RenderPipelineHandle<GradientFillVertexShader,
ConicalGradientSsboFillFragmentShader>;
using RadialGradientSSBOFillPipeline =
RenderPipelineT<GradientFillVertexShader,
RadialGradientSsboFillFragmentShader>;
RenderPipelineHandle<GradientFillVertexShader,
RadialGradientSsboFillFragmentShader>;
using SweepGradientSSBOFillPipeline =
RenderPipelineT<GradientFillVertexShader,
SweepGradientSsboFillFragmentShader>;
RenderPipelineHandle<GradientFillVertexShader,
SweepGradientSsboFillFragmentShader>;
using RRectBlurPipeline =
RenderPipelineT<RrectBlurVertexShader, RrectBlurFragmentShader>;
using BlendPipeline = RenderPipelineT<BlendVertexShader, BlendFragmentShader>;
RenderPipelineHandle<RrectBlurVertexShader, RrectBlurFragmentShader>;
using BlendPipeline =
RenderPipelineHandle<BlendVertexShader, BlendFragmentShader>;
using TexturePipeline =
RenderPipelineT<TextureFillVertexShader, TextureFillFragmentShader>;
RenderPipelineHandle<TextureFillVertexShader, TextureFillFragmentShader>;
using TextureStrictSrcPipeline =
RenderPipelineT<TextureFillVertexShader,
TextureFillStrictSrcFragmentShader>;
using PositionUVPipeline =
RenderPipelineT<TextureFillVertexShader, TiledTextureFillFragmentShader>;
RenderPipelineHandle<TextureFillVertexShader,
TextureFillStrictSrcFragmentShader>;
using PositionUVPipeline = RenderPipelineHandle<TextureFillVertexShader,
TiledTextureFillFragmentShader>;
using TiledTexturePipeline =
RenderPipelineT<TextureFillVertexShader, TiledTextureFillFragmentShader>;
RenderPipelineHandle<TextureFillVertexShader,
TiledTextureFillFragmentShader>;
using KernelDecalPipeline =
RenderPipelineT<KernelVertexShader, KernelDecalFragmentShader>;
RenderPipelineHandle<KernelVertexShader, KernelDecalFragmentShader>;
using KernelPipeline =
RenderPipelineT<KernelVertexShader, KernelNodecalFragmentShader>;
RenderPipelineHandle<KernelVertexShader, KernelNodecalFragmentShader>;
using BorderMaskBlurPipeline =
RenderPipelineT<BorderMaskBlurVertexShader, BorderMaskBlurFragmentShader>;
RenderPipelineHandle<BorderMaskBlurVertexShader,
BorderMaskBlurFragmentShader>;
using MorphologyFilterPipeline =
RenderPipelineT<MorphologyFilterVertexShader,
MorphologyFilterFragmentShader>;
RenderPipelineHandle<MorphologyFilterVertexShader,
MorphologyFilterFragmentShader>;
using ColorMatrixColorFilterPipeline =
RenderPipelineT<FilterVertexShader, ColorMatrixColorFilterFragmentShader>;
RenderPipelineHandle<FilterVertexShader,
ColorMatrixColorFilterFragmentShader>;
using LinearToSrgbFilterPipeline =
RenderPipelineT<FilterVertexShader, LinearToSrgbFilterFragmentShader>;
RenderPipelineHandle<FilterVertexShader, LinearToSrgbFilterFragmentShader>;
using SrgbToLinearFilterPipeline =
RenderPipelineT<FilterVertexShader, SrgbToLinearFilterFragmentShader>;
RenderPipelineHandle<FilterVertexShader, SrgbToLinearFilterFragmentShader>;
using GlyphAtlasPipeline =
RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasFragmentShader>;
RenderPipelineHandle<GlyphAtlasVertexShader, GlyphAtlasFragmentShader>;
using GlyphAtlasColorPipeline =
RenderPipelineT<GlyphAtlasVertexShader, GlyphAtlasColorFragmentShader>;
RenderPipelineHandle<GlyphAtlasVertexShader, GlyphAtlasColorFragmentShader>;
using PorterDuffBlendPipeline =
RenderPipelineT<PorterDuffBlendVertexShader, PorterDuffBlendFragmentShader>;
using ClipPipeline = RenderPipelineT<ClipVertexShader, ClipFragmentShader>;
RenderPipelineHandle<PorterDuffBlendVertexShader,
PorterDuffBlendFragmentShader>;
using ClipPipeline = RenderPipelineHandle<ClipVertexShader, ClipFragmentShader>;

using GeometryColorPipeline =
RenderPipelineT<PositionColorVertexShader, VerticesFragmentShader>;
RenderPipelineHandle<PositionColorVertexShader, VerticesFragmentShader>;
using YUVToRGBFilterPipeline =
RenderPipelineT<FilterVertexShader, YuvToRgbFilterFragmentShader>;
RenderPipelineHandle<FilterVertexShader, YuvToRgbFilterFragmentShader>;

// Advanced blends
using BlendColorPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendColorPipeline = RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendColorBurnPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendColorDodgePipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendDarkenPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendDarkenPipeline = RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendDifferencePipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendExclusionPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendHardLightPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendHuePipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendLightenPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendHuePipeline = RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendLightenPipeline = RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendLuminosityPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendMultiplyPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendOverlayPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendMultiplyPipeline = RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendOverlayPipeline = RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendSaturationPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
using BlendScreenPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendScreenPipeline = RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
using BlendSoftLightPipeline =
RenderPipelineT<AdvancedBlendVertexShader, AdvancedBlendFragmentShader>;
RenderPipelineHandle<AdvancedBlendVertexShader,
AdvancedBlendFragmentShader>;
// Framebuffer Advanced Blends
using FramebufferBlendColorPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendColorBurnPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendColorDodgePipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendDarkenPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendDifferencePipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendExclusionPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendHardLightPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendHuePipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendLightenPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendLuminosityPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendMultiplyPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendOverlayPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendSaturationPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendScreenPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
using FramebufferBlendSoftLightPipeline =
RenderPipelineT<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;
RenderPipelineHandle<FramebufferBlendVertexShader,
FramebufferBlendFragmentShader>;

/// Geometry Pipelines
using PointsComputeShaderPipeline = ComputePipelineBuilder<PointsComputeShader>;
using UvComputeShaderPipeline = ComputePipelineBuilder<UvComputeShader>;

#ifdef IMPELLER_ENABLE_OPENGLES
using TextureExternalPipeline =
RenderPipelineT<TextureFillVertexShader, TextureFillExternalFragmentShader>;
RenderPipelineHandle<TextureFillVertexShader,
TextureFillExternalFragmentShader>;

using TiledTextureExternalPipeline =
RenderPipelineT<TextureFillVertexShader,
TiledTextureFillExternalFragmentShader>;
RenderPipelineHandle<TextureFillVertexShader,
TiledTextureFillExternalFragmentShader>;
#endif // IMPELLER_ENABLE_OPENGLES

// A struct used to isolate command buffer storage from the content
Expand Down Expand Up @@ -836,43 +853,56 @@ class ContentContext {
RuntimeEffectPipelineKey::Equal>
runtime_effect_pipelines_;

template <class PipelineT>
/// Holds multiple Pipelines associated with the same PipelineHandle types.
///
/// For example, it may have multiple
/// RenderPipelineHandle<SolidFillVertexShader, SolidFillFragmentShader>
/// instances for different blend modes. From them you can access the
/// Pipeline.
///
/// See also:
/// - impeller::ContentContextOptions - options from which variants are
/// created.
/// - impeller::Pipeline::CreateVariant
/// - impeller::RenderPipelineHandle<> - The type of objects this typically
/// contains.
template <class PipelineHandleT>
class Variants {
public:
Variants() = default;

void Set(const ContentContextOptions& options,
std::unique_ptr<PipelineT> pipeline) {
std::unique_ptr<PipelineHandleT> pipeline) {
pipelines_[options] = std::move(pipeline);
}

void SetDefault(const ContentContextOptions& options,
std::unique_ptr<PipelineT> pipeline) {
std::unique_ptr<PipelineHandleT> pipeline) {
default_options_ = options;
Set(options, std::move(pipeline));
}

void CreateDefault(const Context& context,
const ContentContextOptions& options,
const std::initializer_list<Scalar>& constants = {}) {
auto desc =
PipelineT::Builder::MakeDefaultPipelineDescriptor(context, constants);
auto desc = PipelineHandleT::Builder::MakeDefaultPipelineDescriptor(
context, constants);
if (!desc.has_value()) {
VALIDATION_LOG << "Failed to create default pipeline.";
return;
}
options.ApplyToPipelineDescriptor(*desc);
SetDefault(options, std::make_unique<PipelineT>(context, desc));
SetDefault(options, std::make_unique<PipelineHandleT>(context, desc));
}

PipelineT* Get(const ContentContextOptions& options) const {
PipelineHandleT* Get(const ContentContextOptions& options) const {
if (auto found = pipelines_.find(options); found != pipelines_.end()) {
return found->second.get();
}
return nullptr;
}

PipelineT* GetDefault() const {
PipelineHandleT* GetDefault() const {
if (!default_options_.has_value()) {
return nullptr;
}
Expand All @@ -884,7 +914,7 @@ class ContentContext {
private:
std::optional<ContentContextOptions> default_options_;
std::unordered_map<ContentContextOptions,
std::unique_ptr<PipelineT>,
std::unique_ptr<PipelineHandleT>,
ContentContextOptions::Hash,
ContentContextOptions::Equal>
pipelines_;
Expand Down Expand Up @@ -1004,9 +1034,10 @@ class ContentContext {
return pipeline->WaitAndGet();
}

template <class TypedPipeline>
TypedPipeline* CreateIfNeeded(Variants<TypedPipeline>& container,
ContentContextOptions opts) const {
template <class RenderPipelineHandleT>
RenderPipelineHandleT* CreateIfNeeded(
Variants<RenderPipelineHandleT>& container,
ContentContextOptions opts) const {
if (!IsValid()) {
return nullptr;
}
Expand All @@ -1015,17 +1046,17 @@ class ContentContext {
opts.wireframe = true;
}

if (TypedPipeline* found = container.Get(opts)) {
if (RenderPipelineHandleT* found = container.Get(opts)) {
return found;
}

TypedPipeline* prototype = container.GetDefault();
RenderPipelineHandleT* default_handle = container.GetDefault();

// The prototype must always be initialized in the constructor.
FML_CHECK(prototype != nullptr);
// The default must always be initialized in the constructor.
FML_CHECK(default_handle != nullptr);

std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline =
prototype->WaitAndGet();
default_handle->WaitAndGet();
if (!pipeline) {
return nullptr;
}
Expand All @@ -1037,8 +1068,8 @@ class ContentContext {
desc.SetLabel(
SPrintF("%s V#%zu", desc.GetLabel().c_str(), variants_count));
});
std::unique_ptr<TypedPipeline> variant =
std::make_unique<TypedPipeline>(std::move(variant_future));
std::unique_ptr<RenderPipelineHandleT> variant =
std::make_unique<RenderPipelineHandleT>(std::move(variant_future));
container.Set(opts, std::move(variant));
return container.Get(opts);
}
Expand Down
Loading