diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 59228d96c8c24..20300dd074842 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -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 diff --git a/impeller/core/BUILD.gn b/impeller/core/BUILD.gn index bb7ef28cf15ca..f88f90c205faa 100644 --- a/impeller/core/BUILD.gn +++ b/impeller/core/BUILD.gn @@ -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", diff --git a/impeller/core/raw_ptr.cc b/impeller/core/raw_ptr.cc new file mode 100644 index 0000000000000..314c2e06a892d --- /dev/null +++ b/impeller/core/raw_ptr.cc @@ -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 { + +// + +} diff --git a/impeller/core/raw_ptr.h b/impeller/core/raw_ptr.h new file mode 100644 index 0000000000000..9348cfe27e330 --- /dev/null +++ b/impeller/core/raw_ptr.h @@ -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 + +namespace impeller { + +/// @brief A wrapper around a raw ptr that adds additional unopt mode only +/// checks. +template +class raw_ptr { + public: + explicit raw_ptr(const std::shared_ptr& 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 + inline bool operator==(raw_ptr const& other) const { + return ptr_ == other.ptr_; + } + + template + inline bool operator!=(raw_ptr const& other) const { + return !(*this == other); + } + + explicit operator bool() const { return !!ptr_; } + + private: + T* ptr_; +#if !NDEBUG + std::weak_ptr weak_ptr_; +#endif +}; + +} // namespace impeller + +#endif // FLUTTER_IMPELLER_CORE_RAW_PTR_H_ diff --git a/impeller/entity/contents/color_source_contents.h b/impeller/entity/contents/color_source_contents.h index 76a49ffe4a1db..17eba81f8930a 100644 --- a/impeller/entity/contents/color_source_contents.h +++ b/impeller/entity/contents/color_source_contents.h @@ -104,8 +104,7 @@ class ColorSourceContents : public Contents { using PipelineBuilderMethod = std::shared_ptr> ( impeller::ContentContext::*)(ContentContextOptions) const; using PipelineBuilderCallback = - std::function>( - ContentContextOptions)>; + std::function; using CreateGeometryCallback = std::function> -ContentContext::GetCachedRuntimeEffectPipeline( +PipelineRef ContentContext::GetCachedRuntimeEffectPipeline( const std::string& unique_entrypoint_name, const ContentContextOptions& options, const std::function>()>& @@ -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( diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 0cfb4a2623e3e..0a0aee36262b9 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -377,102 +377,93 @@ class ContentContext { Tessellator& GetTessellator() const; - std::shared_ptr> GetFastGradientPipeline( - ContentContextOptions opts) const { + PipelineRef GetFastGradientPipeline(ContentContextOptions opts) const { return GetPipeline(fast_gradient_pipelines_, opts); } - std::shared_ptr> GetLinearGradientFillPipeline( - ContentContextOptions opts) const { + PipelineRef GetLinearGradientFillPipeline(ContentContextOptions opts) const { return GetPipeline(linear_gradient_fill_pipelines_, opts); } - std::shared_ptr> - GetLinearGradientUniformFillPipeline(ContentContextOptions opts) const { + PipelineRef GetLinearGradientUniformFillPipeline( + ContentContextOptions opts) const { return GetPipeline(linear_gradient_uniform_fill_pipelines_, opts); } - std::shared_ptr> - GetRadialGradientUniformFillPipeline(ContentContextOptions opts) const { + PipelineRef GetRadialGradientUniformFillPipeline( + ContentContextOptions opts) const { return GetPipeline(radial_gradient_uniform_fill_pipelines_, opts); } - std::shared_ptr> - GetConicalGradientUniformFillPipeline(ContentContextOptions opts) const { + PipelineRef GetConicalGradientUniformFillPipeline( + ContentContextOptions opts) const { return GetPipeline(conical_gradient_uniform_fill_pipelines_, opts); } - std::shared_ptr> - GetSweepGradientUniformFillPipeline(ContentContextOptions opts) const { + PipelineRef GetSweepGradientUniformFillPipeline( + ContentContextOptions opts) const { return GetPipeline(sweep_gradient_uniform_fill_pipelines_, opts); } - std::shared_ptr> - GetLinearGradientSSBOFillPipeline(ContentContextOptions opts) const { + PipelineRef GetLinearGradientSSBOFillPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsSSBO()); return GetPipeline(linear_gradient_ssbo_fill_pipelines_, opts); } - std::shared_ptr> - GetRadialGradientSSBOFillPipeline(ContentContextOptions opts) const { + PipelineRef GetRadialGradientSSBOFillPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsSSBO()); return GetPipeline(radial_gradient_ssbo_fill_pipelines_, opts); } - std::shared_ptr> - GetConicalGradientSSBOFillPipeline(ContentContextOptions opts) const { + PipelineRef GetConicalGradientSSBOFillPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsSSBO()); return GetPipeline(conical_gradient_ssbo_fill_pipelines_, opts); } - std::shared_ptr> - GetSweepGradientSSBOFillPipeline(ContentContextOptions opts) const { + PipelineRef GetSweepGradientSSBOFillPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsSSBO()); return GetPipeline(sweep_gradient_ssbo_fill_pipelines_, opts); } - std::shared_ptr> GetRadialGradientFillPipeline( - ContentContextOptions opts) const { + PipelineRef GetRadialGradientFillPipeline(ContentContextOptions opts) const { return GetPipeline(radial_gradient_fill_pipelines_, opts); } - std::shared_ptr> GetConicalGradientFillPipeline( - ContentContextOptions opts) const { + PipelineRef GetConicalGradientFillPipeline(ContentContextOptions opts) const { return GetPipeline(conical_gradient_fill_pipelines_, opts); } - std::shared_ptr> GetRRectBlurPipeline( - ContentContextOptions opts) const { + PipelineRef GetRRectBlurPipeline(ContentContextOptions opts) const { return GetPipeline(rrect_blur_pipelines_, opts); } - std::shared_ptr> GetSweepGradientFillPipeline( - ContentContextOptions opts) const { + PipelineRef GetSweepGradientFillPipeline(ContentContextOptions opts) const { return GetPipeline(sweep_gradient_fill_pipelines_, opts); } - std::shared_ptr> GetSolidFillPipeline( - ContentContextOptions opts) const { + PipelineRef GetSolidFillPipeline(ContentContextOptions opts) const { return GetPipeline(solid_fill_pipelines_, opts); } - std::shared_ptr> GetTexturePipeline( - ContentContextOptions opts) const { + PipelineRef GetTexturePipeline(ContentContextOptions opts) const { return GetPipeline(texture_pipelines_, opts); } - std::shared_ptr> GetTextureStrictSrcPipeline( - ContentContextOptions opts) const { + PipelineRef GetTextureStrictSrcPipeline(ContentContextOptions opts) const { return GetPipeline(texture_strict_src_pipelines_, opts); } #ifdef IMPELLER_ENABLE_OPENGLES - std::shared_ptr> - GetDownsampleTextureGlesPipeline(ContentContextOptions opts) const { + PipelineRef GetDownsampleTextureGlesPipeline( + ContentContextOptions opts) const { return GetPipeline(texture_downsample_gles_pipelines_, opts); } - std::shared_ptr> 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> GetTiledTexturePipeline( - ContentContextOptions opts) const { + PipelineRef GetTiledTexturePipeline(ContentContextOptions opts) const { return GetPipeline(tiled_texture_pipelines_, opts); } - std::shared_ptr> GetGaussianBlurPipeline( - ContentContextOptions opts) const { + PipelineRef GetGaussianBlurPipeline(ContentContextOptions opts) const { return GetPipeline(gaussian_blur_pipelines_, opts); } - std::shared_ptr> GetBorderMaskBlurPipeline( - ContentContextOptions opts) const { + PipelineRef GetBorderMaskBlurPipeline(ContentContextOptions opts) const { return GetPipeline(border_mask_blur_pipelines_, opts); } - std::shared_ptr> GetMorphologyFilterPipeline( - ContentContextOptions opts) const { + PipelineRef GetMorphologyFilterPipeline(ContentContextOptions opts) const { return GetPipeline(morphology_filter_pipelines_, opts); } - std::shared_ptr> - GetColorMatrixColorFilterPipeline(ContentContextOptions opts) const { + PipelineRef GetColorMatrixColorFilterPipeline( + ContentContextOptions opts) const { return GetPipeline(color_matrix_color_filter_pipelines_, opts); } - std::shared_ptr> GetLinearToSrgbFilterPipeline( - ContentContextOptions opts) const { + PipelineRef GetLinearToSrgbFilterPipeline(ContentContextOptions opts) const { return GetPipeline(linear_to_srgb_filter_pipelines_, opts); } - std::shared_ptr> GetSrgbToLinearFilterPipeline( - ContentContextOptions opts) const { + PipelineRef GetSrgbToLinearFilterPipeline(ContentContextOptions opts) const { return GetPipeline(srgb_to_linear_filter_pipelines_, opts); } - std::shared_ptr> GetClipPipeline( - ContentContextOptions opts) const { + PipelineRef GetClipPipeline(ContentContextOptions opts) const { return GetPipeline(clip_pipelines_, opts); } - std::shared_ptr> GetGlyphAtlasPipeline( - ContentContextOptions opts) const { + PipelineRef GetGlyphAtlasPipeline(ContentContextOptions opts) const { return GetPipeline(glyph_atlas_pipelines_, opts); } - std::shared_ptr> GetYUVToRGBFilterPipeline( - ContentContextOptions opts) const { + PipelineRef GetYUVToRGBFilterPipeline(ContentContextOptions opts) const { return GetPipeline(yuv_to_rgb_filter_pipelines_, opts); } - std::shared_ptr> GetPorterDuffBlendPipeline( - ContentContextOptions opts) const { + PipelineRef GetPorterDuffBlendPipeline(ContentContextOptions opts) const { return GetPipeline(porter_duff_blend_pipelines_, opts); } // Advanced blends. - std::shared_ptr> GetBlendColorPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendColorPipeline(ContentContextOptions opts) const { return GetPipeline(blend_color_pipelines_, opts); } - std::shared_ptr> GetBlendColorBurnPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendColorBurnPipeline(ContentContextOptions opts) const { return GetPipeline(blend_colorburn_pipelines_, opts); } - std::shared_ptr> GetBlendColorDodgePipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendColorDodgePipeline(ContentContextOptions opts) const { return GetPipeline(blend_colordodge_pipelines_, opts); } - std::shared_ptr> GetBlendDarkenPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendDarkenPipeline(ContentContextOptions opts) const { return GetPipeline(blend_darken_pipelines_, opts); } - std::shared_ptr> GetBlendDifferencePipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendDifferencePipeline(ContentContextOptions opts) const { return GetPipeline(blend_difference_pipelines_, opts); } - std::shared_ptr> GetBlendExclusionPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendExclusionPipeline(ContentContextOptions opts) const { return GetPipeline(blend_exclusion_pipelines_, opts); } - std::shared_ptr> GetBlendHardLightPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendHardLightPipeline(ContentContextOptions opts) const { return GetPipeline(blend_hardlight_pipelines_, opts); } - std::shared_ptr> GetBlendHuePipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendHuePipeline(ContentContextOptions opts) const { return GetPipeline(blend_hue_pipelines_, opts); } - std::shared_ptr> GetBlendLightenPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendLightenPipeline(ContentContextOptions opts) const { return GetPipeline(blend_lighten_pipelines_, opts); } - std::shared_ptr> GetBlendLuminosityPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendLuminosityPipeline(ContentContextOptions opts) const { return GetPipeline(blend_luminosity_pipelines_, opts); } - std::shared_ptr> GetBlendMultiplyPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendMultiplyPipeline(ContentContextOptions opts) const { return GetPipeline(blend_multiply_pipelines_, opts); } - std::shared_ptr> GetBlendOverlayPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendOverlayPipeline(ContentContextOptions opts) const { return GetPipeline(blend_overlay_pipelines_, opts); } - std::shared_ptr> GetBlendSaturationPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendSaturationPipeline(ContentContextOptions opts) const { return GetPipeline(blend_saturation_pipelines_, opts); } - std::shared_ptr> GetBlendScreenPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendScreenPipeline(ContentContextOptions opts) const { return GetPipeline(blend_screen_pipelines_, opts); } - std::shared_ptr> GetBlendSoftLightPipeline( - ContentContextOptions opts) const { + PipelineRef GetBlendSoftLightPipeline(ContentContextOptions opts) const { return GetPipeline(blend_softlight_pipelines_, opts); } - std::shared_ptr> GetDownsamplePipeline( - ContentContextOptions opts) const { + PipelineRef GetDownsamplePipeline(ContentContextOptions opts) const { return GetPipeline(texture_downsample_pipelines_, opts); } // Framebuffer Advanced Blends - std::shared_ptr> - GetFramebufferBlendColorPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendColorPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_color_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendColorBurnPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendColorBurnPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_colorburn_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendColorDodgePipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendColorDodgePipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_colordodge_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendDarkenPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendDarkenPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_darken_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendDifferencePipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendDifferencePipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_difference_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendExclusionPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendExclusionPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_exclusion_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendHardLightPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendHardLightPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_hardlight_pipelines_, opts); } - std::shared_ptr> GetFramebufferBlendHuePipeline( - ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendHuePipeline(ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_hue_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendLightenPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendLightenPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_lighten_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendLuminosityPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendLuminosityPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_luminosity_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendMultiplyPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendMultiplyPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_multiply_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendOverlayPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendOverlayPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_overlay_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendSaturationPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendSaturationPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_saturation_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendScreenPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendScreenPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_screen_pipelines_, opts); } - std::shared_ptr> - GetFramebufferBlendSoftLightPipeline(ContentContextOptions opts) const { + PipelineRef GetFramebufferBlendSoftLightPipeline( + ContentContextOptions opts) const { FML_DCHECK(GetDeviceCapabilities().SupportsFramebufferFetch()); return GetPipeline(framebuffer_blend_softlight_pipelines_, opts); } - std::shared_ptr> 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> GetCachedRuntimeEffectPipeline( + PipelineRef GetCachedRuntimeEffectPipeline( const std::string& unique_entrypoint_name, const ContentContextOptions& options, const std::function>()>& @@ -992,14 +955,13 @@ class ContentContext { mutable Variants vertices_uber_shader_; template - std::shared_ptr> GetPipeline( - Variants& container, - ContentContextOptions opts) const { + PipelineRef GetPipeline(Variants& container, + ContentContextOptions opts) const { TypedPipeline* pipeline = CreateIfNeeded(container, opts); if (!pipeline) { - return nullptr; + return raw_ptr>(); } - return pipeline->WaitAndGet(); + return raw_ptr(pipeline->WaitAndGet()); } template @@ -1023,7 +985,7 @@ class ContentContext { // The default must always be initialized in the constructor. FML_CHECK(default_handle != nullptr); - std::shared_ptr> pipeline = + const std::shared_ptr>& pipeline = default_handle->WaitAndGet(); if (!pipeline) { return nullptr; diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index b427de9ab76e6..3f07150c3df3c 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -71,8 +71,8 @@ BlendFilterContents::BlendFilterContents() { BlendFilterContents::~BlendFilterContents() = default; -using PipelineProc = std::shared_ptr> ( - ContentContext::*)(ContentContextOptions) const; +using PipelineProc = + PipelineRef (ContentContext::*)(ContentContextOptions) const; template static std::optional AdvancedBlend( @@ -170,8 +170,7 @@ static std::optional AdvancedBlend( auto options = OptionsFromPass(pass); options.primitive_type = PrimitiveType::kTriangleStrip; options.blend_mode = BlendMode::kSource; - std::shared_ptr> pipeline = - std::invoke(pipeline_proc, renderer, options); + PipelineRef pipeline = std::invoke(pipeline_proc, renderer, options); #ifdef IMPELLER_DEBUG pass.SetCommandLabel( diff --git a/impeller/entity/contents/test/recording_render_pass.cc b/impeller/entity/contents/test/recording_render_pass.cc index 39a8f69b50c58..9c81b5b273b7d 100644 --- a/impeller/entity/contents/test/recording_render_pass.cc +++ b/impeller/entity/contents/test/recording_render_pass.cc @@ -15,8 +15,7 @@ RecordingRenderPass::RecordingRenderPass( : RenderPass(context, render_target), delegate_(std::move(delegate)) {} // |RenderPass| -void RecordingRenderPass::SetPipeline( - const std::shared_ptr>& pipeline) { +void RecordingRenderPass::SetPipeline(PipelineRef pipeline) { pending_.pipeline = pipeline; if (delegate_) { delegate_->SetPipeline(pipeline); diff --git a/impeller/entity/contents/test/recording_render_pass.h b/impeller/entity/contents/test/recording_render_pass.h index 3fb9b34d344e1..4172121c77104 100644 --- a/impeller/entity/contents/test/recording_render_pass.h +++ b/impeller/entity/contents/test/recording_render_pass.h @@ -20,8 +20,7 @@ class RecordingRenderPass : public RenderPass { const std::vector& GetCommands() const override { return commands_; } // |RenderPass| - void SetPipeline( - const std::shared_ptr>& pipeline) override; + void SetPipeline(PipelineRef pipeline) override; void SetCommandLabel(std::string_view label) override; diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index ed4af453c0c32..968536e32d4fa 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -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,8 @@ TEST_P(EntityTest, RuntimeEffect) { ASSERT_TRUE(runtime_stage->IsDirty()); bool expect_dirty = true; - Pipeline* first_pipeline; + + PipelineRef first_pipeline; std::unique_ptr geom = Geometry::MakeCover(); auto callback = [&](ContentContext& context, RenderPass& pass) -> bool { @@ -1723,12 +1725,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(); + 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; return result; }; diff --git a/impeller/playground/imgui/imgui_impl_impeller.cc b/impeller/playground/imgui/imgui_impl_impeller.cc index caf346c8bcf38..1eb7657f93751 100644 --- a/impeller/playground/imgui/imgui_impl_impeller.cc +++ b/impeller/playground/imgui/imgui_impl_impeller.cc @@ -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" diff --git a/impeller/renderer/backend/metal/render_pass_mtl.h b/impeller/renderer/backend/metal/render_pass_mtl.h index ee244ce1e92b6..6639de497c247 100644 --- a/impeller/renderer/backend/metal/render_pass_mtl.h +++ b/impeller/renderer/backend/metal/render_pass_mtl.h @@ -58,8 +58,7 @@ class RenderPassMTL final : public RenderPass { bool OnEncodeCommands(const Context& context) const override; // |RenderPass| - void SetPipeline( - const std::shared_ptr>& pipeline) override; + void SetPipeline(PipelineRef pipeline) override; // |RenderPass| void SetCommandLabel(std::string_view label) override; diff --git a/impeller/renderer/backend/metal/render_pass_mtl.mm b/impeller/renderer/backend/metal/render_pass_mtl.mm index 203e97e36ec90..73e20544006f4 100644 --- a/impeller/renderer/backend/metal/render_pass_mtl.mm +++ b/impeller/renderer/backend/metal/render_pass_mtl.mm @@ -233,8 +233,7 @@ static bool Bind(PassBindingsCacheMTL& pass, } // |RenderPass| -void RenderPassMTL::SetPipeline( - const std::shared_ptr>& pipeline) { +void RenderPassMTL::SetPipeline(PipelineRef pipeline) { const PipelineDescriptor& pipeline_desc = pipeline->GetDescriptor(); primitive_type_ = pipeline_desc.GetPrimitiveType(); pass_bindings_.SetRenderPipelineState( diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.cc b/impeller/renderer/backend/vulkan/render_pass_vk.cc index f8a169adfb670..46315ffe0b8fc 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.cc +++ b/impeller/renderer/backend/vulkan/render_pass_vk.cc @@ -293,9 +293,8 @@ SharedHandleVK RenderPassVK::CreateVKFramebuffer( } // |RenderPass| -void RenderPassVK::SetPipeline( - const std::shared_ptr>& 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 pipeline_variant = + std::shared_ptr> 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(); diff --git a/impeller/renderer/backend/vulkan/render_pass_vk.h b/impeller/renderer/backend/vulkan/render_pass_vk.h index d442e08882cd2..95219e5c0659a 100644 --- a/impeller/renderer/backend/vulkan/render_pass_vk.h +++ b/impeller/renderer/backend/vulkan/render_pass_vk.h @@ -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* pipeline_; + PipelineRef pipeline_ = PipelineRef(nullptr); bool pipeline_uses_input_attachments_ = false; std::shared_ptr immutable_sampler_; @@ -58,8 +58,7 @@ class RenderPassVK final : public RenderPass { std::shared_ptr command_buffer); // |RenderPass| - void SetPipeline( - const std::shared_ptr>& pipeline) override; + void SetPipeline(PipelineRef pipeline) override; // |RenderPass| void SetCommandLabel(std::string_view label) override; diff --git a/impeller/renderer/command.h b/impeller/renderer/command.h index 24b64716663cf..f23d6769a06d8 100644 --- a/impeller/renderer/command.h +++ b/impeller/renderer/command.h @@ -80,7 +80,7 @@ struct Command { //---------------------------------------------------------------------------- /// The pipeline to use for this command. /// - std::shared_ptr> pipeline; + PipelineRef pipeline; /// An offset into render pass storage where bound buffers/texture metadata is /// stored. diff --git a/impeller/renderer/pipeline.h b/impeller/renderer/pipeline.h index b3babc34a8537..5c191c19b5f04 100644 --- a/impeller/renderer/pipeline.h +++ b/impeller/renderer/pipeline.h @@ -8,6 +8,7 @@ #include #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>; + extern template class Pipeline; extern template class Pipeline; diff --git a/impeller/renderer/render_pass.cc b/impeller/renderer/render_pass.cc index a7f00ff286a4c..ecafb9013ba24 100644 --- a/impeller/renderer/render_pass.cc +++ b/impeller/renderer/render_pass.cc @@ -81,9 +81,13 @@ const std::shared_ptr& RenderPass::GetContext() const { return context_; } +void RenderPass::SetPipeline(PipelineRef pipeline) { + pending_.pipeline = pipeline; +} + void RenderPass::SetPipeline( const std::shared_ptr>& pipeline) { - pending_.pipeline = pipeline; + SetPipeline(PipelineRef(pipeline)); } void RenderPass::SetCommandLabel(std::string_view label) { diff --git a/impeller/renderer/render_pass.h b/impeller/renderer/render_pass.h index 20d85111d90fc..2c2c81080206f 100644 --- a/impeller/renderer/render_pass.h +++ b/impeller/renderer/render_pass.h @@ -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); //---------------------------------------------------------------------------- diff --git a/lib/gpu/render_pass.cc b/lib/gpu/render_pass.cc index b2f43bc2db187..3416ef1d0b8a1 100644 --- a/lib/gpu/render_pass.cc +++ b/lib/gpu/render_pass.cc @@ -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(