[Impeller] switch Pipeline to use raw ptr instead of shared ptr for recorded references. (flutter/engine#57015)

Fixes https://github.com/flutter/flutter/issues/159566

We don't need recorded commands to keep pipelines alive as the context does that already.
This commit is contained in:
Jonah Williams 2024-12-09 12:42:03 -08:00 committed by GitHub
parent 5964dc2244
commit 81d3d7fbca
21 changed files with 235 additions and 166 deletions

View File

@ -43017,6 +43017,8 @@ ORIGIN: ../../../flutter/impeller/core/platform.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/platform.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/range.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/range.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/raw_ptr.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/raw_ptr.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/resource_binder.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/resource_binder.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/runtime_types.cc + ../../../flutter/LICENSE
@ -45946,6 +45948,8 @@ FILE: ../../../flutter/impeller/core/platform.cc
FILE: ../../../flutter/impeller/core/platform.h
FILE: ../../../flutter/impeller/core/range.cc
FILE: ../../../flutter/impeller/core/range.h
FILE: ../../../flutter/impeller/core/raw_ptr.cc
FILE: ../../../flutter/impeller/core/raw_ptr.h
FILE: ../../../flutter/impeller/core/resource_binder.cc
FILE: ../../../flutter/impeller/core/resource_binder.h
FILE: ../../../flutter/impeller/core/runtime_types.cc

View File

@ -23,6 +23,8 @@ impeller_component("core") {
"platform.h",
"range.cc",
"range.h",
"raw_ptr.cc",
"raw_ptr.h",
"resource_binder.cc",
"resource_binder.h",
"runtime_types.cc",

View File

@ -0,0 +1,11 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "impeller/core/raw_ptr.h"
namespace impeller {
//
}

View File

@ -0,0 +1,84 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_IMPELLER_CORE_RAW_PTR_H_
#define FLUTTER_IMPELLER_CORE_RAW_PTR_H_
#include <memory>
namespace impeller {
/// @brief A wrapper around a raw ptr that adds additional unopt mode only
/// checks.
template <typename T>
class raw_ptr {
public:
explicit raw_ptr(const std::shared_ptr<T>& ptr)
: ptr_(ptr.get())
#if !NDEBUG
,
weak_ptr_(ptr)
#endif
{
}
raw_ptr() : ptr_(nullptr) {}
T* operator->() {
#if !NDEBUG
FML_CHECK(weak_ptr_.lock());
#endif
return ptr_;
}
const T* operator->() const {
#if !NDEBUG
FML_CHECK(weak_ptr_.lock());
#endif
return ptr_;
}
T* get() {
#if !NDEBUG
FML_CHECK(weak_ptr_.lock());
#endif
return ptr_;
}
T& operator*() {
#if !NDEBUG
FML_CHECK(weak_ptr_.lock());
#endif
return *ptr_;
}
const T& operator*() const {
#if !NDEBUG
FML_CHECK(weak_ptr_.lock());
#endif
return *ptr_;
}
template <class U>
inline bool operator==(raw_ptr<U> const& other) const {
return ptr_ == other.ptr_;
}
template <class U>
inline bool operator!=(raw_ptr<U> const& other) const {
return !(*this == other);
}
explicit operator bool() const { return !!ptr_; }
private:
T* ptr_;
#if !NDEBUG
std::weak_ptr<T> weak_ptr_;
#endif
};
} // namespace impeller
#endif // FLUTTER_IMPELLER_CORE_RAW_PTR_H_

View File

@ -104,8 +104,7 @@ class ColorSourceContents : public Contents {
using PipelineBuilderMethod = std::shared_ptr<Pipeline<PipelineDescriptor>> (
impeller::ContentContext::*)(ContentContextOptions) const;
using PipelineBuilderCallback =
std::function<std::shared_ptr<Pipeline<PipelineDescriptor>>(
ContentContextOptions)>;
std::function<PipelineRef(ContentContextOptions)>;
using CreateGeometryCallback =
std::function<GeometryResult(const ContentContext& renderer,
const Entity& entity,

View File

@ -569,8 +569,7 @@ void ContentContext::SetWireframe(bool wireframe) {
wireframe_ = wireframe;
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
ContentContext::GetCachedRuntimeEffectPipeline(
PipelineRef ContentContext::GetCachedRuntimeEffectPipeline(
const std::string& unique_entrypoint_name,
const ContentContextOptions& options,
const std::function<std::shared_ptr<Pipeline<PipelineDescriptor>>()>&
@ -580,7 +579,7 @@ ContentContext::GetCachedRuntimeEffectPipeline(
if (it == runtime_effect_pipelines_.end()) {
it = runtime_effect_pipelines_.insert(it, {key, create_callback()});
}
return it->second;
return raw_ptr(it->second);
}
void ContentContext::ClearCachedRuntimeEffectPipeline(

View File

@ -377,102 +377,93 @@ class ContentContext {
Tessellator& GetTessellator() const;
std::shared_ptr<Pipeline<PipelineDescriptor>> GetFastGradientPipeline(
ContentContextOptions opts) const {
PipelineRef GetFastGradientPipeline(ContentContextOptions opts) const {
return GetPipeline(fast_gradient_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetLinearGradientFillPipeline(
ContentContextOptions opts) const {
PipelineRef GetLinearGradientFillPipeline(ContentContextOptions opts) const {
return GetPipeline(linear_gradient_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetLinearGradientUniformFillPipeline(ContentContextOptions opts) const {
PipelineRef GetLinearGradientUniformFillPipeline(
ContentContextOptions opts) const {
return GetPipeline(linear_gradient_uniform_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetRadialGradientUniformFillPipeline(ContentContextOptions opts) const {
PipelineRef GetRadialGradientUniformFillPipeline(
ContentContextOptions opts) const {
return GetPipeline(radial_gradient_uniform_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetConicalGradientUniformFillPipeline(ContentContextOptions opts) const {
PipelineRef GetConicalGradientUniformFillPipeline(
ContentContextOptions opts) const {
return GetPipeline(conical_gradient_uniform_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetSweepGradientUniformFillPipeline(ContentContextOptions opts) const {
PipelineRef GetSweepGradientUniformFillPipeline(
ContentContextOptions opts) const {
return GetPipeline(sweep_gradient_uniform_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetLinearGradientSSBOFillPipeline(ContentContextOptions opts) const {
PipelineRef GetLinearGradientSSBOFillPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
return GetPipeline(linear_gradient_ssbo_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetRadialGradientSSBOFillPipeline(ContentContextOptions opts) const {
PipelineRef GetRadialGradientSSBOFillPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
return GetPipeline(radial_gradient_ssbo_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetConicalGradientSSBOFillPipeline(ContentContextOptions opts) const {
PipelineRef GetConicalGradientSSBOFillPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
return GetPipeline(conical_gradient_ssbo_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetSweepGradientSSBOFillPipeline(ContentContextOptions opts) const {
PipelineRef GetSweepGradientSSBOFillPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsSSBO());
return GetPipeline(sweep_gradient_ssbo_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetRadialGradientFillPipeline(
ContentContextOptions opts) const {
PipelineRef GetRadialGradientFillPipeline(ContentContextOptions opts) const {
return GetPipeline(radial_gradient_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetConicalGradientFillPipeline(
ContentContextOptions opts) const {
PipelineRef GetConicalGradientFillPipeline(ContentContextOptions opts) const {
return GetPipeline(conical_gradient_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetRRectBlurPipeline(
ContentContextOptions opts) const {
PipelineRef GetRRectBlurPipeline(ContentContextOptions opts) const {
return GetPipeline(rrect_blur_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetSweepGradientFillPipeline(
ContentContextOptions opts) const {
PipelineRef GetSweepGradientFillPipeline(ContentContextOptions opts) const {
return GetPipeline(sweep_gradient_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetSolidFillPipeline(
ContentContextOptions opts) const {
PipelineRef GetSolidFillPipeline(ContentContextOptions opts) const {
return GetPipeline(solid_fill_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetTexturePipeline(
ContentContextOptions opts) const {
PipelineRef GetTexturePipeline(ContentContextOptions opts) const {
return GetPipeline(texture_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetTextureStrictSrcPipeline(
ContentContextOptions opts) const {
PipelineRef GetTextureStrictSrcPipeline(ContentContextOptions opts) const {
return GetPipeline(texture_strict_src_pipelines_, opts);
}
#ifdef IMPELLER_ENABLE_OPENGLES
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetDownsampleTextureGlesPipeline(ContentContextOptions opts) const {
PipelineRef GetDownsampleTextureGlesPipeline(
ContentContextOptions opts) const {
return GetPipeline(texture_downsample_gles_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetTiledTextureExternalPipeline(
PipelineRef GetTiledTextureExternalPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetContext()->GetBackendType() ==
Context::BackendType::kOpenGLES);
@ -480,236 +471,208 @@ class ContentContext {
}
#endif // IMPELLER_ENABLE_OPENGLES
std::shared_ptr<Pipeline<PipelineDescriptor>> GetTiledTexturePipeline(
ContentContextOptions opts) const {
PipelineRef GetTiledTexturePipeline(ContentContextOptions opts) const {
return GetPipeline(tiled_texture_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetGaussianBlurPipeline(
ContentContextOptions opts) const {
PipelineRef GetGaussianBlurPipeline(ContentContextOptions opts) const {
return GetPipeline(gaussian_blur_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBorderMaskBlurPipeline(
ContentContextOptions opts) const {
PipelineRef GetBorderMaskBlurPipeline(ContentContextOptions opts) const {
return GetPipeline(border_mask_blur_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetMorphologyFilterPipeline(
ContentContextOptions opts) const {
PipelineRef GetMorphologyFilterPipeline(ContentContextOptions opts) const {
return GetPipeline(morphology_filter_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetColorMatrixColorFilterPipeline(ContentContextOptions opts) const {
PipelineRef GetColorMatrixColorFilterPipeline(
ContentContextOptions opts) const {
return GetPipeline(color_matrix_color_filter_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetLinearToSrgbFilterPipeline(
ContentContextOptions opts) const {
PipelineRef GetLinearToSrgbFilterPipeline(ContentContextOptions opts) const {
return GetPipeline(linear_to_srgb_filter_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetSrgbToLinearFilterPipeline(
ContentContextOptions opts) const {
PipelineRef GetSrgbToLinearFilterPipeline(ContentContextOptions opts) const {
return GetPipeline(srgb_to_linear_filter_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetClipPipeline(
ContentContextOptions opts) const {
PipelineRef GetClipPipeline(ContentContextOptions opts) const {
return GetPipeline(clip_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetGlyphAtlasPipeline(
ContentContextOptions opts) const {
PipelineRef GetGlyphAtlasPipeline(ContentContextOptions opts) const {
return GetPipeline(glyph_atlas_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetYUVToRGBFilterPipeline(
ContentContextOptions opts) const {
PipelineRef GetYUVToRGBFilterPipeline(ContentContextOptions opts) const {
return GetPipeline(yuv_to_rgb_filter_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPorterDuffBlendPipeline(
ContentContextOptions opts) const {
PipelineRef GetPorterDuffBlendPipeline(ContentContextOptions opts) const {
return GetPipeline(porter_duff_blend_pipelines_, opts);
}
// Advanced blends.
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendColorPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendColorPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_color_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendColorBurnPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendColorBurnPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_colorburn_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendColorDodgePipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendColorDodgePipeline(ContentContextOptions opts) const {
return GetPipeline(blend_colordodge_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendDarkenPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendDarkenPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_darken_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendDifferencePipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendDifferencePipeline(ContentContextOptions opts) const {
return GetPipeline(blend_difference_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendExclusionPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendExclusionPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_exclusion_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendHardLightPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendHardLightPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_hardlight_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendHuePipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendHuePipeline(ContentContextOptions opts) const {
return GetPipeline(blend_hue_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendLightenPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendLightenPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_lighten_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendLuminosityPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendLuminosityPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_luminosity_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendMultiplyPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendMultiplyPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_multiply_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendOverlayPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendOverlayPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_overlay_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendSaturationPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendSaturationPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_saturation_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendScreenPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendScreenPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_screen_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetBlendSoftLightPipeline(
ContentContextOptions opts) const {
PipelineRef GetBlendSoftLightPipeline(ContentContextOptions opts) const {
return GetPipeline(blend_softlight_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetDownsamplePipeline(
ContentContextOptions opts) const {
PipelineRef GetDownsamplePipeline(ContentContextOptions opts) const {
return GetPipeline(texture_downsample_pipelines_, opts);
}
// Framebuffer Advanced Blends
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendColorPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendColorPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_color_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendColorBurnPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendColorDodgePipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendDarkenPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_darken_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendDifferencePipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_difference_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendExclusionPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendHardLightPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetFramebufferBlendHuePipeline(
ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendHuePipeline(ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_hue_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendLightenPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_lighten_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendLuminosityPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendMultiplyPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_multiply_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendOverlayPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_overlay_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendSaturationPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_saturation_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendScreenPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_screen_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>>
GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const {
PipelineRef GetFramebufferBlendSoftLightPipeline(
ContentContextOptions opts) const {
FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch());
return GetPipeline(framebuffer_blend_softlight_pipelines_, opts);
}
std::shared_ptr<Pipeline<PipelineDescriptor>> GetDrawVerticesUberShader(
ContentContextOptions opts) const {
PipelineRef GetDrawVerticesUberShader(ContentContextOptions opts) const {
return GetPipeline(vertices_uber_shader_, opts);
}
@ -761,7 +724,7 @@ class ContentContext {
///
/// The create_callback is synchronously invoked exactly once if a cached
/// pipeline is not found.
std::shared_ptr<Pipeline<PipelineDescriptor>> GetCachedRuntimeEffectPipeline(
PipelineRef GetCachedRuntimeEffectPipeline(
const std::string& unique_entrypoint_name,
const ContentContextOptions& options,
const std::function<std::shared_ptr<Pipeline<PipelineDescriptor>>()>&
@ -992,14 +955,13 @@ class ContentContext {
mutable Variants<VerticesUberShader> vertices_uber_shader_;
template <class TypedPipeline>
std::shared_ptr<Pipeline<PipelineDescriptor>> GetPipeline(
Variants<TypedPipeline>& container,
ContentContextOptions opts) const {
PipelineRef GetPipeline(Variants<TypedPipeline>& container,
ContentContextOptions opts) const {
TypedPipeline* pipeline = CreateIfNeeded(container, opts);
if (!pipeline) {
return nullptr;
return raw_ptr<Pipeline<PipelineDescriptor>>();
}
return pipeline->WaitAndGet();
return raw_ptr(pipeline->WaitAndGet());
}
template <class RenderPipelineHandleT>
@ -1023,7 +985,7 @@ class ContentContext {
// The default must always be initialized in the constructor.
FML_CHECK(default_handle != nullptr);
std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline =
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline =
default_handle->WaitAndGet();
if (!pipeline) {
return nullptr;

View File

@ -71,8 +71,8 @@ BlendFilterContents::BlendFilterContents() {
BlendFilterContents::~BlendFilterContents() = default;
using PipelineProc = std::shared_ptr<Pipeline<PipelineDescriptor>> (
ContentContext::*)(ContentContextOptions) const;
using PipelineProc =
PipelineRef (ContentContext::*)(ContentContextOptions) const;
template <typename TPipeline>
static std::optional<Entity> AdvancedBlend(
@ -170,8 +170,7 @@ static std::optional<Entity> AdvancedBlend(
auto options = OptionsFromPass(pass);
options.primitive_type = PrimitiveType::kTriangleStrip;
options.blend_mode = BlendMode::kSource;
std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline =
std::invoke(pipeline_proc, renderer, options);
PipelineRef pipeline = std::invoke(pipeline_proc, renderer, options);
#ifdef IMPELLER_DEBUG
pass.SetCommandLabel(

View File

@ -15,8 +15,7 @@ RecordingRenderPass::RecordingRenderPass(
: RenderPass(context, render_target), delegate_(std::move(delegate)) {}
// |RenderPass|
void RecordingRenderPass::SetPipeline(
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) {
void RecordingRenderPass::SetPipeline(PipelineRef pipeline) {
pending_.pipeline = pipeline;
if (delegate_) {
delegate_->SetPipeline(pipeline);

View File

@ -20,8 +20,7 @@ class RecordingRenderPass : public RenderPass {
const std::vector<Command>& GetCommands() const override { return commands_; }
// |RenderPass|
void SetPipeline(
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) override;
void SetPipeline(PipelineRef pipeline) override;
void SetCommandLabel(std::string_view label) override;

View File

@ -15,6 +15,7 @@
#include "impeller/core/device_buffer.h"
#include "impeller/core/formats.h"
#include "impeller/core/host_buffer.h"
#include "impeller/core/raw_ptr.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/conical_gradient_contents.h"
@ -1696,7 +1697,7 @@ TEST_P(EntityTest, RuntimeEffect) {
ASSERT_TRUE(runtime_stage->IsDirty());
bool expect_dirty = true;
Pipeline<PipelineDescriptor>* first_pipeline;
PipelineRef first_pipeline;
std::unique_ptr<Geometry> geom = Geometry::MakeCover();
auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
@ -1723,10 +1724,10 @@ TEST_P(EntityTest, RuntimeEffect) {
bool result = contents->Render(context, entity, pass);
if (expect_dirty) {
EXPECT_NE(first_pipeline, pass.GetCommands().back().pipeline.get());
first_pipeline = pass.GetCommands().back().pipeline.get();
EXPECT_NE(first_pipeline, pass.GetCommands().back().pipeline);
first_pipeline = pass.GetCommands().back().pipeline;
} else {
EXPECT_EQ(pass.GetCommands().back().pipeline.get(), first_pipeline);
EXPECT_EQ(pass.GetCommands().back().pipeline, first_pipeline);
}
expect_dirty = false;

View File

@ -30,7 +30,6 @@
#include "impeller/geometry/point.h"
#include "impeller/geometry/rect.h"
#include "impeller/geometry/size.h"
#include "impeller/renderer/command.h"
#include "impeller/renderer/context.h"
#include "impeller/renderer/pipeline_builder.h"
#include "impeller/renderer/pipeline_descriptor.h"

View File

@ -58,8 +58,7 @@ class RenderPassMTL final : public RenderPass {
bool OnEncodeCommands(const Context& context) const override;
// |RenderPass|
void SetPipeline(
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) override;
void SetPipeline(PipelineRef pipeline) override;
// |RenderPass|
void SetCommandLabel(std::string_view label) override;

View File

@ -233,8 +233,7 @@ static bool Bind(PassBindingsCacheMTL& pass,
}
// |RenderPass|
void RenderPassMTL::SetPipeline(
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) {
void RenderPassMTL::SetPipeline(PipelineRef pipeline) {
const PipelineDescriptor& pipeline_desc = pipeline->GetDescriptor();
primitive_type_ = pipeline_desc.GetPrimitiveType();
pass_bindings_.SetRenderPipelineState(

View File

@ -293,9 +293,8 @@ SharedHandleVK<vk::Framebuffer> RenderPassVK::CreateVKFramebuffer(
}
// |RenderPass|
void RenderPassVK::SetPipeline(
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) {
pipeline_ = pipeline.get();
void RenderPassVK::SetPipeline(PipelineRef pipeline) {
pipeline_ = pipeline;
if (!pipeline_) {
return;
}
@ -305,7 +304,7 @@ void RenderPassVK::SetPipeline(
if (pipeline_uses_input_attachments_) {
if (bound_image_offset_ >= kMaxBindings) {
pipeline_ = nullptr;
pipeline_ = PipelineRef(nullptr);
return;
}
vk::DescriptorImageInfo image_info;
@ -464,7 +463,7 @@ fml::Status RenderPassVK::Draw() {
/// Jank can be completely eliminated by pre-populating known YUV conversion
/// pipelines.
if (immutable_sampler_) {
std::shared_ptr<PipelineVK> pipeline_variant =
std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline_variant =
PipelineVK::Cast(*pipeline_)
.CreateVariantForImmutableSamplers(immutable_sampler_);
if (!pipeline_variant) {
@ -472,7 +471,7 @@ fml::Status RenderPassVK::Draw() {
fml::StatusCode::kAborted,
"Could not create pipeline variant with immutable sampler.");
}
pipeline_ = pipeline_variant.get();
pipeline_ = raw_ptr(pipeline_variant);
}
const auto& context_vk = ContextVK::Cast(*context_);
@ -539,7 +538,7 @@ fml::Status RenderPassVK::Draw() {
instance_count_ = 1u;
base_vertex_ = 0u;
element_count_ = 0u;
pipeline_ = nullptr;
pipeline_ = PipelineRef(nullptr);
pipeline_uses_input_attachments_ = false;
immutable_sampler_ = nullptr;
return fml::Status();

View File

@ -49,7 +49,7 @@ class RenderPassVK final : public RenderPass {
size_t element_count_ = 0u;
bool has_index_buffer_ = false;
bool has_label_ = false;
const Pipeline<PipelineDescriptor>* pipeline_;
PipelineRef pipeline_ = PipelineRef(nullptr);
bool pipeline_uses_input_attachments_ = false;
std::shared_ptr<SamplerVK> immutable_sampler_;
@ -58,8 +58,7 @@ class RenderPassVK final : public RenderPass {
std::shared_ptr<CommandBufferVK> command_buffer);
// |RenderPass|
void SetPipeline(
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) override;
void SetPipeline(PipelineRef pipeline) override;
// |RenderPass|
void SetCommandLabel(std::string_view label) override;

View File

@ -80,7 +80,7 @@ struct Command {
//----------------------------------------------------------------------------
/// The pipeline to use for this command.
///
std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
PipelineRef pipeline;
/// An offset into render pass storage where bound buffers/texture metadata is
/// stored.

View File

@ -8,6 +8,7 @@
#include <future>
#include "compute_pipeline_descriptor.h"
#include "impeller/core/raw_ptr.h"
#include "impeller/renderer/compute_pipeline_builder.h"
#include "impeller/renderer/compute_pipeline_descriptor.h"
#include "impeller/renderer/context.h"
@ -78,6 +79,12 @@ class Pipeline {
Pipeline& operator=(const Pipeline&) = delete;
};
/// @brief A raw ptr to a pipeline object.
///
/// These pipeline refs are safe to use as the context will keep the
/// pipelines alive throughout rendering.
using PipelineRef = raw_ptr<Pipeline<PipelineDescriptor>>;
extern template class Pipeline<PipelineDescriptor>;
extern template class Pipeline<ComputePipelineDescriptor>;

View File

@ -81,9 +81,13 @@ const std::shared_ptr<const Context>& RenderPass::GetContext() const {
return context_;
}
void RenderPass::SetPipeline(PipelineRef pipeline) {
pending_.pipeline = pipeline;
}
void RenderPass::SetPipeline(
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline) {
pending_.pipeline = pipeline;
SetPipeline(PipelineRef(pipeline));
}
void RenderPass::SetCommandLabel(std::string_view label) {

View File

@ -45,7 +45,11 @@ class RenderPass : public ResourceBinder {
//----------------------------------------------------------------------------
/// The pipeline to use for this command.
virtual void SetPipeline(
virtual void SetPipeline(PipelineRef pipeline);
//----------------------------------------------------------------------------
/// The pipeline to use for this command.
void SetPipeline(
const std::shared_ptr<Pipeline<PipelineDescriptor>>& pipeline);
//----------------------------------------------------------------------------

View File

@ -177,7 +177,7 @@ RenderPass::GetOrCreatePipeline() {
}
bool RenderPass::Draw() {
render_pass_->SetPipeline(GetOrCreatePipeline());
render_pass_->SetPipeline(impeller::PipelineRef(GetOrCreatePipeline()));
for (const auto& [_, buffer] : vertex_uniform_bindings) {
render_pass_->BindDynamicResource(