From 730474c43b46b4108f62913ddbd0ec1aa98a179d Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 10 Oct 2022 19:37:36 -0700 Subject: [PATCH 01/10] Add DlRuntimeEffect --- display_list/display_list_color_source_unittests.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/display_list/display_list_color_source_unittests.cc b/display_list/display_list_color_source_unittests.cc index e2d9cbd142b6e..e3b8d75245806 100644 --- a/display_list/display_list_color_source_unittests.cc +++ b/display_list/display_list_color_source_unittests.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "display_list/display_list_runtime_effect.h" #include "flutter/display_list/display_list_attributes_testing.h" #include "flutter/display_list/display_list_builder.h" #include "flutter/display_list/display_list_color_source.h" From 4f633ee9b38f546dc47c3d1e41142a9c0eae589a Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 10 Oct 2022 21:46:46 -0700 Subject: [PATCH 02/10] Include fix --- display_list/display_list_color_source_unittests.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/display_list/display_list_color_source_unittests.cc b/display_list/display_list_color_source_unittests.cc index e3b8d75245806..e2d9cbd142b6e 100644 --- a/display_list/display_list_color_source_unittests.cc +++ b/display_list/display_list_color_source_unittests.cc @@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "display_list/display_list_runtime_effect.h" #include "flutter/display_list/display_list_attributes_testing.h" #include "flutter/display_list/display_list_builder.h" #include "flutter/display_list/display_list_color_source.h" From 99a9b580609bf9aca2c2e15bafdba5e0ba04288c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Fri, 14 Oct 2022 13:27:26 -0700 Subject: [PATCH 03/10] Runtime effect --- ci/licenses_golden/licenses_flutter | 2 + .../display_list/display_list_dispatcher.cc | 8 +++- impeller/entity/BUILD.gn | 2 + .../contents/runtime_effect_contents.cc | 41 +++++++++++++++++++ .../entity/contents/runtime_effect_contents.h | 23 +++++++++++ 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 impeller/entity/contents/runtime_effect_contents.cc create mode 100644 impeller/entity/contents/runtime_effect_contents.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 627096d0d20fe..3aacc83578acb 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1214,6 +1214,8 @@ FILE: ../../../flutter/impeller/entity/contents/radial_gradient_contents.cc FILE: ../../../flutter/impeller/entity/contents/radial_gradient_contents.h FILE: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.cc FILE: ../../../flutter/impeller/entity/contents/rrect_shadow_contents.h +FILE: ../../../flutter/impeller/entity/contents/runtime_effect_contents.cc +FILE: ../../../flutter/impeller/entity/contents/runtime_effect_contents.h FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.cc FILE: ../../../flutter/impeller/entity/contents/solid_color_contents.h FILE: ../../../flutter/impeller/entity/contents/solid_stroke_contents.cc diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index 024a6e460bce0..e03914b30d247 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -10,6 +10,7 @@ #include "display_list/display_list_blend_mode.h" #include "display_list/display_list_color_filter.h" +#include "display_list/display_list_color_source.h" #include "display_list/display_list_path_effect.h" #include "display_list/display_list_tile_mode.h" #include "flutter/fml/logging.h" @@ -426,7 +427,12 @@ void DisplayListDispatcher::setColorSource( return; } case flutter::DlColorSourceType::kConicalGradient: - case flutter::DlColorSourceType::kRuntimeEffect: + case flutter::DlColorSourceType::kRuntimeEffect: { + const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source = + source->asRuntimeEffect(); + const auto effect = runtime_effect_color_source->runtime_effect(); + auto runtime_stage = effect->runtime_stage(); + } case flutter::DlColorSourceType::kUnknown: UNIMPLEMENTED; break; diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 8a417d30fbd7c..1aa89a3da03ff 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -113,6 +113,8 @@ impeller_component("entity") { "contents/radial_gradient_contents.h", "contents/rrect_shadow_contents.cc", "contents/rrect_shadow_contents.h", + "contents/runtime_effect_contents.cc", + "contents/runtime_effect_contents.h", "contents/solid_color_contents.cc", "contents/solid_color_contents.h", "contents/solid_stroke_contents.cc", diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc new file mode 100644 index 0000000000000..7d0cca4b61a71 --- /dev/null +++ b/impeller/entity/contents/runtime_effect_contents.cc @@ -0,0 +1,41 @@ +// 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/entity/contents/runtime_effect_contents.h" + +#include + +#include "flutter/fml/make_copyable.h" +#include "fml/logging.h" +#include "impeller/entity/contents/content_context.h" +#include "impeller/renderer/shader_types.h" + +namespace impeller { + +bool RuntimeEffectContents::Render(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + std::promise promise; + auto future = promise.get_future(); + + auto context = renderer.GetContext(); + auto library = context->GetShaderLibrary(); + library->RegisterFunction( + runtime_stage_->GetEntrypoint(), + ToShaderStage(runtime_stage_->GetShaderStage()), + runtime_stage_->GetCodeMapping(), + fml::MakeCopyable([promise = std::move(promise)](bool result) mutable { + promise.set_value(result); + })); + + if (!future.get()) { + FML_LOG(ERROR) << "Failed to build runtime stage (entry point:" + << runtime_stage_->GetEntrypoint() << ")"; + return false; + } + + return true; +} + +} // namespace impeller \ No newline at end of file diff --git a/impeller/entity/contents/runtime_effect_contents.h b/impeller/entity/contents/runtime_effect_contents.h new file mode 100644 index 0000000000000..d205d677d472d --- /dev/null +++ b/impeller/entity/contents/runtime_effect_contents.h @@ -0,0 +1,23 @@ +// 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 + +#include "impeller/entity/contents/color_source_contents.h" +#include "impeller/runtime_stage/runtime_stage.h" + +namespace impeller { + +class RuntimeEffectContents final : public ColorSourceContents { + public: + // |Contents| + bool Render(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const override; + + private: + std::shared_ptr runtime_stage_; +}; + +} // namespace impeller \ No newline at end of file From d6ddae3aae752a24cf4258c1cb371ad466bc8739 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 19 Oct 2022 03:40:49 -0700 Subject: [PATCH 04/10] Make RuntimeEffect work for Metal --- ci/licenses_golden/licenses_flutter | 2 + .../display_list/display_list_dispatcher.cc | 21 ++- impeller/entity/BUILD.gn | 7 +- .../contents/runtime_effect_contents.cc | 153 ++++++++++++++++-- .../entity/contents/runtime_effect_contents.h | 6 + impeller/entity/entity_unittests.cc | 48 ++++++ .../entity/shaders/position_no_color.vert | 17 ++ impeller/fixtures/BUILD.gn | 1 + impeller/fixtures/example.frag.metal.iplr | Bin 0 -> 760 bytes impeller/playground/playground.cc | 17 ++ impeller/playground/playground.h | 5 + .../backend/metal/shader_library_mtl.mm | 1 - impeller/renderer/host_buffer.h | 21 +++ impeller/runtime_stage/BUILD.gn | 1 + impeller/runtime_stage/runtime_types.cc | 17 ++ impeller/runtime_stage/runtime_types.h | 3 + lib/ui/painting/fragment_program.cc | 9 +- 17 files changed, 301 insertions(+), 28 deletions(-) create mode 100644 impeller/entity/shaders/position_no_color.vert create mode 100644 impeller/fixtures/example.frag.metal.iplr create mode 100644 impeller/runtime_stage/runtime_types.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 3aacc83578acb..848d5faccb5e7 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1282,6 +1282,7 @@ FILE: ../../../flutter/impeller/entity/shaders/morphology_filter.frag FILE: ../../../flutter/impeller/entity/shaders/morphology_filter.vert FILE: ../../../flutter/impeller/entity/shaders/position.vert FILE: ../../../flutter/impeller/entity/shaders/position_color.vert +FILE: ../../../flutter/impeller/entity/shaders/position_no_color.vert FILE: ../../../flutter/impeller/entity/shaders/position_uv.vert FILE: ../../../flutter/impeller/entity/shaders/radial_gradient_fill.frag FILE: ../../../flutter/impeller/entity/shaders/rrect_blur.frag @@ -1557,6 +1558,7 @@ FILE: ../../../flutter/impeller/runtime_stage/runtime_stage.h FILE: ../../../flutter/impeller/runtime_stage/runtime_stage_playground.cc FILE: ../../../flutter/impeller/runtime_stage/runtime_stage_playground.h FILE: ../../../flutter/impeller/runtime_stage/runtime_stage_unittests.cc +FILE: ../../../flutter/impeller/runtime_stage/runtime_types.cc FILE: ../../../flutter/impeller/runtime_stage/runtime_types.h FILE: ../../../flutter/impeller/tessellator/c/tessellator.cc FILE: ../../../flutter/impeller/tessellator/c/tessellator.h diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index e03914b30d247..41bea12633182 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -5,6 +5,8 @@ #include "impeller/display_list/display_list_dispatcher.h" #include +#include +#include #include #include @@ -22,6 +24,7 @@ #include "impeller/entity/contents/filters/inputs/filter_input.h" #include "impeller/entity/contents/linear_gradient_contents.h" #include "impeller/entity/contents/radial_gradient_contents.h" +#include "impeller/entity/contents/runtime_effect_contents.h" #include "impeller/entity/contents/solid_stroke_contents.h" #include "impeller/entity/contents/sweep_gradient_contents.h" #include "impeller/entity/contents/tiled_texture_contents.h" @@ -430,8 +433,22 @@ void DisplayListDispatcher::setColorSource( case flutter::DlColorSourceType::kRuntimeEffect: { const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source = source->asRuntimeEffect(); - const auto effect = runtime_effect_color_source->runtime_effect(); - auto runtime_stage = effect->runtime_stage(); + auto runtime_stage = + runtime_effect_color_source->runtime_effect()->runtime_stage(); + auto uniform_data_sk = runtime_effect_color_source->uniform_data(); + + paint_.color_source = [runtime_stage, uniform_data_sk]() { + // TODO(bdero): Get rid of the allocation + copy for uniform data. + std::vector uniform_data; + uniform_data.resize(uniform_data_sk->size()); + memcpy(uniform_data.data(), uniform_data_sk->bytes(), + uniform_data.size()); + + auto contents = std::make_shared(); + contents->SetRuntimeStage(runtime_stage); + contents->SetUniformData(std::move(uniform_data)); + return contents; + }; } case flutter::DlColorSourceType::kUnknown: UNIMPLEMENTED; diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 1aa89a3da03ff..3c6c42e07c09e 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -44,6 +44,10 @@ impeller_shaders("entity_shaders") { "shaders/linear_gradient_fill.frag", "shaders/morphology_filter.frag", "shaders/morphology_filter.vert", + "shaders/position_color.vert", + "shaders/position_no_color.vert", + "shaders/position_uv.vert", + "shaders/position.vert", "shaders/radial_gradient_fill.frag", "shaders/rrect_blur.vert", "shaders/rrect_blur.frag", @@ -57,9 +61,6 @@ impeller_shaders("entity_shaders") { "shaders/tiled_texture_fill.frag", "shaders/tiled_texture_fill.vert", "shaders/vertices.frag", - "shaders/position_color.vert", - "shaders/position.vert", - "shaders/position_uv.vert", ] } diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc index 7d0cca4b61a71..1f1b6e987582f 100644 --- a/impeller/entity/contents/runtime_effect_contents.cc +++ b/impeller/entity/contents/runtime_effect_contents.cc @@ -5,36 +5,159 @@ #include "impeller/entity/contents/runtime_effect_contents.h" #include +#include +#include "flutter/fml/logging.h" #include "flutter/fml/make_copyable.h" -#include "fml/logging.h" +#include "impeller/base/validation.h" +#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/content_context.h" +#include "impeller/entity/position_no_color.vert.h" +#include "impeller/renderer/formats.h" +#include "impeller/renderer/pipeline_library.h" +#include "impeller/renderer/render_pass.h" +#include "impeller/renderer/shader_function.h" #include "impeller/renderer/shader_types.h" namespace impeller { +void RuntimeEffectContents::SetRuntimeStage( + std::shared_ptr runtime_stage) { + runtime_stage_ = std::move(runtime_stage); +} + +void RuntimeEffectContents::SetUniformData(std::vector uniform_data) { + uniform_data_ = std::move(uniform_data); +} + bool RuntimeEffectContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - std::promise promise; - auto future = promise.get_future(); - auto context = renderer.GetContext(); auto library = context->GetShaderLibrary(); - library->RegisterFunction( - runtime_stage_->GetEntrypoint(), - ToShaderStage(runtime_stage_->GetShaderStage()), - runtime_stage_->GetCodeMapping(), - fml::MakeCopyable([promise = std::move(promise)](bool result) mutable { - promise.set_value(result); - })); - - if (!future.get()) { - FML_LOG(ERROR) << "Failed to build runtime stage (entry point:" - << runtime_stage_->GetEntrypoint() << ")"; + + //-------------------------------------------------------------------------- + /// Get or register shader. + /// + + std::shared_ptr function = library->GetFunction( + runtime_stage_->GetEntrypoint(), ShaderStage::kFragment); + + if (!function) { + std::promise promise; + auto future = promise.get_future(); + + library->RegisterFunction( + runtime_stage_->GetEntrypoint(), + ToShaderStage(runtime_stage_->GetShaderStage()), + runtime_stage_->GetCodeMapping(), + fml::MakeCopyable([promise = std::move(promise)](bool result) mutable { + promise.set_value(result); + })); + + if (!future.get()) { + VALIDATION_LOG << "Failed to build runtime effect (entry point: " + << runtime_stage_->GetEntrypoint() << ")"; + return false; + } + + function = library->GetFunction(runtime_stage_->GetEntrypoint(), + ShaderStage::kFragment); + if (!function) { + VALIDATION_LOG + << "Failed to fetch runtime effect function immediately after " + "registering it (entry point: " + << runtime_stage_->GetEntrypoint() << ")"; + return false; + } + } + + //-------------------------------------------------------------------------- + /// Resolve geometry. + /// + + auto geometry_result = GetGeometry()->GetPositionBuffer( + context->GetResourceAllocator(), pass.GetTransientsBuffer(), + renderer.GetTessellator(), pass.GetRenderTargetSize()); + + //-------------------------------------------------------------------------- + /// Get or create runtime stage pipeline. + /// + + using VS = PositionNoColorVertexShader; + PipelineDescriptor desc; + desc.SetLabel("Runtime Stage"); + desc.AddStageEntrypoint( + library->GetFunction(VS::kEntrypointName, ShaderStage::kVertex)); + desc.AddStageEntrypoint(library->GetFunction(runtime_stage_->GetEntrypoint(), + ShaderStage::kFragment)); + auto vertex_descriptor = std::make_shared(); + if (!vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs)) { + VALIDATION_LOG << "Failed to set stage inputs for runtime effect pipeline."; + } + desc.SetVertexDescriptor(std::move(vertex_descriptor)); + desc.SetColorAttachmentDescriptor(0u, {.format = PixelFormat::kDefaultColor}); + desc.SetStencilAttachmentDescriptors({}); + desc.SetStencilPixelFormat(PixelFormat::kDefaultStencil); + + auto options = OptionsFromPassAndEntity(pass, entity); + if (geometry_result.prevent_overdraw) { + options.stencil_compare = CompareFunction::kEqual; + options.stencil_operation = StencilOperation::kIncrementClamp; + } + options.ApplyToPipelineDescriptor(desc); + + auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).get(); + if (!pipeline) { + VALIDATION_LOG << "Failed to get or create runtime effect pipeline."; return false; } + Command cmd; + cmd.label = "RuntimeEffectContents"; + cmd.pipeline = pipeline; + cmd.stencil_reference = entity.GetStencilDepth(); + cmd.BindVertices(geometry_result.vertex_buffer); + cmd.primitive_type = geometry_result.type; + + //-------------------------------------------------------------------------- + /// Vertex stage uniforms. + /// + + VS::VertInfo frame_info; + frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(); + VS::BindVertInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frame_info)); + + //-------------------------------------------------------------------------- + /// Fragment stage uniforms. + /// + + size_t buffer_index = 0; + for (auto uniform : runtime_stage_->GetUniforms()) { + // TODO(bdero): Populate this metadata once GLES is able to handle + // non-struct uniform names. + ShaderMetadata metadata; + + size_t alignment = + std::max(uniform.bit_width / 8, DefaultUniformAlignment()); + auto buffer_view = pass.GetTransientsBuffer().Emplace( + &uniform_data_[uniform.location * sizeof(float)], uniform.GetSize(), + alignment); + + ShaderUniformSlot slot; + slot.name = uniform.name.c_str(); + slot.ext_res_0 = buffer_index; + cmd.BindResource(ShaderStage::kFragment, slot, metadata, buffer_view); + + buffer_index++; + } + + pass.AddCommand(std::move(cmd)); + + if (!geometry_result.prevent_overdraw) { + return ClipRestoreContents().Render(renderer, entity, pass); + } return true; } diff --git a/impeller/entity/contents/runtime_effect_contents.h b/impeller/entity/contents/runtime_effect_contents.h index d205d677d472d..f45703b44cd59 100644 --- a/impeller/entity/contents/runtime_effect_contents.h +++ b/impeller/entity/contents/runtime_effect_contents.h @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include #include #include "impeller/entity/contents/color_source_contents.h" @@ -11,6 +12,10 @@ namespace impeller { class RuntimeEffectContents final : public ColorSourceContents { public: + void SetRuntimeStage(std::shared_ptr runtime_stage); + + void SetUniformData(std::vector uniform_data); + // |Contents| bool Render(const ContentContext& renderer, const Entity& entity, @@ -18,6 +23,7 @@ class RuntimeEffectContents final : public ColorSourceContents { private: std::shared_ptr runtime_stage_; + std::vector uniform_data_; }; } // namespace impeller \ No newline at end of file diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index c56dba23e4afd..3ad8ac996d061 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include +#include #include #include #include @@ -10,6 +11,7 @@ #include "flutter/testing/testing.h" #include "fml/logging.h" +#include "fml/time/time_point.h" #include "gtest/gtest.h" #include "impeller/entity/contents/atlas_contents.h" #include "impeller/entity/contents/clip_contents.h" @@ -19,6 +21,7 @@ #include "impeller/entity/contents/filters/filter_contents.h" #include "impeller/entity/contents/filters/inputs/filter_input.h" #include "impeller/entity/contents/rrect_shadow_contents.h" +#include "impeller/entity/contents/runtime_effect_contents.h" #include "impeller/entity/contents/solid_color_contents.h" #include "impeller/entity/contents/solid_stroke_contents.h" #include "impeller/entity/contents/text_contents.h" @@ -37,6 +40,7 @@ #include "impeller/playground/widgets.h" #include "impeller/renderer/render_pass.h" #include "impeller/renderer/vertex_buffer_builder.h" +#include "impeller/runtime_stage/runtime_stage.h" #include "impeller/tessellator/tessellator.h" #include "impeller/typographer/backends/skia/text_frame_skia.h" #include "impeller/typographer/backends/skia/text_render_context_skia.h" @@ -2026,5 +2030,49 @@ TEST_P(EntityTest, SdfText) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } +TEST_P(EntityTest, RuntimeEffect) { + if (GetParam() != PlaygroundBackend::kMetal) { + GTEST_SKIP_("This test only has a Metal fixture at the moment."); + } + + auto callback = [&](ContentContext& context, RenderPass& pass) -> bool { + auto contents = std::make_shared(); + contents->SetGeometry(Geometry::MakeCover()); + + // layout(location = 0) uniform float iTime; + // layout(location = 1) uniform vec2 iResolution; + // + // layout(location = 0) out vec4 fragColor; + // + // void main() { + // // Normalized pixel coordinates (from 0 to 1) + // vec2 uv = gl_FragCoord.xy/iResolution; + // float t = 4 * iTime; + // vec3 col = 0.5 + 0.5*cos(t + uv.xyx + vec3(0,1,4)); + // fragColor = vec4(col,1.0); + // } + auto runtime_stage = LoadFixtureRuntimeStage("example.frag.metal.iplr"); + contents->SetRuntimeStage(runtime_stage); + + struct FragUniforms { + Scalar iTime; + Vector2 iResolution; + } frag_uniforms = { + .iTime = static_cast( + fml::TimePoint::Now().ToEpochDelta().ToSecondsF()), + .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height), + }; + std::vector uniform_data; + uniform_data.resize(sizeof(FragUniforms)); + memcpy(uniform_data.data(), &frag_uniforms, sizeof(FragUniforms)); + contents->SetUniformData(uniform_data); + + Entity entity; + entity.SetContents(contents); + return contents->Render(context, entity, pass); + }; + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + } // namespace testing } // namespace impeller diff --git a/impeller/entity/shaders/position_no_color.vert b/impeller/entity/shaders/position_no_color.vert new file mode 100644 index 0000000000000..16007d94bb6dd --- /dev/null +++ b/impeller/entity/shaders/position_no_color.vert @@ -0,0 +1,17 @@ +// 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 + +uniform VertInfo { + mat4 mvp; +} vert_info; + +in vec2 position; +out vec2 v_position; + +void main() { + gl_Position = vert_info.mvp * vec4(position, 0.0, 1.0); + v_position = IPVec2TransformPosition(vert_info.mvp, position); +} diff --git a/impeller/fixtures/BUILD.gn b/impeller/fixtures/BUILD.gn index 19e4f2de68bac..0715078956028 100644 --- a/impeller/fixtures/BUILD.gn +++ b/impeller/fixtures/BUILD.gn @@ -50,6 +50,7 @@ test_fixtures("file_fixtures") { "blue_noise.png", "boston.jpg", "embarcadero.jpg", + "example.frag.metal.iplr", "kalimba.jpg", "resources_limit.vert", "sample.comp", diff --git a/impeller/fixtures/example.frag.metal.iplr b/impeller/fixtures/example.frag.metal.iplr new file mode 100644 index 0000000000000000000000000000000000000000..1e02757f6610358a292dd7257a12198e76ad2b71 GIT binary patch literal 760 zcmZ`%O-nN|5FSNQVv!yycaT}XjezE+8L!D|pZz&}bCWiym~SxJ|d znRUZbyU>;D?XoIY zIx~$EAA&)n(&X-p{qv0}P0cSag~uq32ZIaoiAb&M@3DSu&v+saupHC7T z2ouK$p;)o9=J>UVMqM-^k@$<5rf4X0kq-|P>buhhd~0n nl)}G*?epII!M_i^_iybPcTYaAr&jOpTi~VtqaDaU&KdfDhBU&T literal 0 HcmV?d00001 diff --git a/impeller/playground/playground.cc b/impeller/playground/playground.cc index 1d71b4e020656..adfce380cc838 100644 --- a/impeller/playground/playground.cc +++ b/impeller/playground/playground.cc @@ -9,6 +9,7 @@ #include "impeller/image/decompressed_image.h" #include "impeller/renderer/command_buffer.h" +#include "impeller/runtime_stage/runtime_stage.h" #define GLFW_INCLUDE_NONE #include "third_party/glfw/include/GLFW/glfw3.h" @@ -436,6 +437,22 @@ std::shared_ptr Playground::CreateTextureCubeForFixture( return texture; } +std::shared_ptr Playground::LoadFixtureRuntimeStage( + const char* fixture_name) const { + if (fixture_name == nullptr) { + return nullptr; + } + + auto runtime_stage = + std::make_shared(OpenAssetAsMapping(fixture_name)); + + if (!runtime_stage->IsValid()) { + VALIDATION_LOG << "Could not load valid runtime stage."; + return nullptr; + } + return runtime_stage; +} + void Playground::SetWindowSize(ISize size) { window_size_ = size; } diff --git a/impeller/playground/playground.h b/impeller/playground/playground.h index d2feb0ef1df7f..255c87d7b4784 100644 --- a/impeller/playground/playground.h +++ b/impeller/playground/playground.h @@ -8,9 +8,11 @@ #include "flutter/fml/closure.h" #include "flutter/fml/macros.h" + #include "impeller/geometry/point.h" #include "impeller/renderer/renderer.h" #include "impeller/renderer/texture.h" +#include "impeller/runtime_stage/runtime_stage.h" namespace impeller { @@ -62,6 +64,9 @@ class Playground { std::shared_ptr CreateTextureCubeForFixture( std::array fixture_names) const; + std::shared_ptr LoadFixtureRuntimeStage( + const char* fixture_name) const; + static bool SupportsBackend(PlaygroundBackend backend); virtual std::unique_ptr OpenAssetAsMapping( diff --git a/impeller/renderer/backend/metal/shader_library_mtl.mm b/impeller/renderer/backend/metal/shader_library_mtl.mm index abb4d123b35f1..57ab6d9bec842 100644 --- a/impeller/renderer/backend/metal/shader_library_mtl.mm +++ b/impeller/renderer/backend/metal/shader_library_mtl.mm @@ -71,7 +71,6 @@ static MTLFunctionType ToMTLFunctionType(ShaderStage stage) { } if (function == nil) { - VALIDATION_LOG << "No library function found for name: " << name; return nullptr; } diff --git a/impeller/renderer/host_buffer.h b/impeller/renderer/host_buffer.h index 7895a38b87ae6..d445171b89f4f 100644 --- a/impeller/renderer/host_buffer.h +++ b/impeller/renderer/host_buffer.h @@ -91,6 +91,27 @@ class HostBuffer final : public std::enable_shared_from_this, ); } + //---------------------------------------------------------------------------- + /// @brief Emplace data onto the host buffer with a custom alignment. + /// + /// @param[in] buffer The buffer data. + /// + /// @tparam BufferType The type of the buffer data. + /// + /// @tparam size_t The byte alignment to use when emplacing the + /// data. + /// + /// @return The buffer view. + /// + template >> + [[nodiscard]] BufferView Emplace(const BufferType& buffer, size_t alignment) { + return Emplace(reinterpret_cast(&buffer), // buffer + sizeof(BufferType), // size + alignment // alignment + ); + } + [[nodiscard]] BufferView Emplace(const void* buffer, size_t length, size_t align); diff --git a/impeller/runtime_stage/BUILD.gn b/impeller/runtime_stage/BUILD.gn index b36a7f9017c88..5756887562edb 100644 --- a/impeller/runtime_stage/BUILD.gn +++ b/impeller/runtime_stage/BUILD.gn @@ -20,6 +20,7 @@ impeller_component("runtime_stage") { sources = [ "runtime_stage.cc", "runtime_stage.h", + "runtime_types.cc", "runtime_types.h", ] public_deps = [ diff --git a/impeller/runtime_stage/runtime_types.cc b/impeller/runtime_stage/runtime_types.cc new file mode 100644 index 0000000000000..4236eae89bbfc --- /dev/null +++ b/impeller/runtime_stage/runtime_types.cc @@ -0,0 +1,17 @@ +// 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/runtime_stage/runtime_types.h" + +namespace impeller { + +size_t RuntimeUniformDescription::GetSize() const { + size_t size = dimensions.rows * dimensions.cols * bit_width / 8u; + if (array_elements.value_or(0) > 0) { + size *= array_elements.value(); + } + return size; +} + +} // namespace impeller diff --git a/impeller/runtime_stage/runtime_types.h b/impeller/runtime_stage/runtime_types.h index 2ccf6ca3e0f24..2ef8512dbd8b4 100644 --- a/impeller/runtime_stage/runtime_types.h +++ b/impeller/runtime_stage/runtime_types.h @@ -46,6 +46,9 @@ struct RuntimeUniformDescription { RuntimeUniformDimensions dimensions; size_t bit_width; std::optional array_elements; + + /// @brief Computes the total number of bytes that this uniform requires. + size_t GetSize() const; }; } // namespace impeller diff --git a/lib/ui/painting/fragment_program.cc b/lib/ui/painting/fragment_program.cc index 21bbd83c70421..2cadcacd5eb0b 100644 --- a/lib/ui/painting/fragment_program.cc +++ b/lib/ui/painting/fragment_program.cc @@ -4,6 +4,7 @@ #include #include +#include #include "display_list/display_list_runtime_effect.h" #include "flutter/lib/ui/painting/fragment_program.h" @@ -51,13 +52,7 @@ std::string FragmentProgram::initFromAsset(const std::string& asset_name) { impeller::RuntimeUniformType::kSampledImage) { sampled_image_count++; } else { - size_t size = uniform_description.dimensions.rows * - uniform_description.dimensions.cols * - uniform_description.bit_width / 8u; - if (uniform_description.array_elements.value_or(0) > 0) { - size *= uniform_description.array_elements.value(); - } - other_uniforms_bytes += size; + other_uniforms_bytes += uniform_description.GetSize(); } } From c7fbde9864fe967a1d0bc8e2d867c07d54fd9681 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 19 Oct 2022 03:45:34 -0700 Subject: [PATCH 05/10] Newlines --- impeller/entity/contents/runtime_effect_contents.cc | 2 +- impeller/entity/contents/runtime_effect_contents.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc index 1f1b6e987582f..734f34cc14baf 100644 --- a/impeller/entity/contents/runtime_effect_contents.cc +++ b/impeller/entity/contents/runtime_effect_contents.cc @@ -161,4 +161,4 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, return true; } -} // namespace impeller \ No newline at end of file +} // namespace impeller diff --git a/impeller/entity/contents/runtime_effect_contents.h b/impeller/entity/contents/runtime_effect_contents.h index f45703b44cd59..7a53e7f138bd6 100644 --- a/impeller/entity/contents/runtime_effect_contents.h +++ b/impeller/entity/contents/runtime_effect_contents.h @@ -26,4 +26,4 @@ class RuntimeEffectContents final : public ColorSourceContents { std::vector uniform_data_; }; -} // namespace impeller \ No newline at end of file +} // namespace impeller From 08227c85837b106c3b417142b82900ee43fdea03 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 19 Oct 2022 11:37:01 -0700 Subject: [PATCH 06/10] Address comments --- impeller/display_list/display_list_dispatcher.cc | 3 ++- .../entity/contents/runtime_effect_contents.cc | 6 ++++-- impeller/entity/entity_unittests.cc | 15 ++------------- impeller/fixtures/BUILD.gn | 5 ++++- impeller/fixtures/example.frag.metal.iplr | Bin 760 -> 0 bytes impeller/fixtures/runtime_stage_example.frag | 15 +++++++++++++++ 6 files changed, 27 insertions(+), 17 deletions(-) delete mode 100644 impeller/fixtures/example.frag.metal.iplr create mode 100644 impeller/fixtures/runtime_stage_example.frag diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index 41bea12633182..e6d23ddfe938b 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -438,7 +438,7 @@ void DisplayListDispatcher::setColorSource( auto uniform_data_sk = runtime_effect_color_source->uniform_data(); paint_.color_source = [runtime_stage, uniform_data_sk]() { - // TODO(bdero): Get rid of the allocation + copy for uniform data. + // TODO(113714): Get rid of the allocation + copy for uniform data. std::vector uniform_data; uniform_data.resize(uniform_data_sk->size()); memcpy(uniform_data.data(), uniform_data_sk->bytes(), @@ -449,6 +449,7 @@ void DisplayListDispatcher::setColorSource( contents->SetUniformData(std::move(uniform_data)); return contents; }; + return; } case flutter::DlColorSourceType::kUnknown: UNIMPLEMENTED; diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc index 734f34cc14baf..14514276b550e 100644 --- a/impeller/entity/contents/runtime_effect_contents.cc +++ b/impeller/entity/contents/runtime_effect_contents.cc @@ -40,6 +40,8 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, /// Get or register shader. /// + // TODO(113719): Register the shader function earlier. + std::shared_ptr function = library->GetFunction( runtime_stage_->GetEntrypoint(), ShaderStage::kFragment); @@ -135,8 +137,8 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, size_t buffer_index = 0; for (auto uniform : runtime_stage_->GetUniforms()) { - // TODO(bdero): Populate this metadata once GLES is able to handle - // non-struct uniform names. + // TODO(113715): Populate this metadata once GLES is able to handle + // non-struct uniform names. ShaderMetadata metadata; size_t alignment = diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 3ad8ac996d061..e80cc19c2e225 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -2039,19 +2039,8 @@ TEST_P(EntityTest, RuntimeEffect) { auto contents = std::make_shared(); contents->SetGeometry(Geometry::MakeCover()); - // layout(location = 0) uniform float iTime; - // layout(location = 1) uniform vec2 iResolution; - // - // layout(location = 0) out vec4 fragColor; - // - // void main() { - // // Normalized pixel coordinates (from 0 to 1) - // vec2 uv = gl_FragCoord.xy/iResolution; - // float t = 4 * iTime; - // vec3 col = 0.5 + 0.5*cos(t + uv.xyx + vec3(0,1,4)); - // fragColor = vec4(col,1.0); - // } - auto runtime_stage = LoadFixtureRuntimeStage("example.frag.metal.iplr"); + auto runtime_stage = + LoadFixtureRuntimeStage("runtime_stage_example.frag.iplr"); contents->SetRuntimeStage(runtime_stage); struct FragUniforms { diff --git a/impeller/fixtures/BUILD.gn b/impeller/fixtures/BUILD.gn index 0715078956028..2e31045d6d599 100644 --- a/impeller/fixtures/BUILD.gn +++ b/impeller/fixtures/BUILD.gn @@ -34,7 +34,10 @@ impeller_shaders("shader_fixtures") { } impellerc("runtime_stages") { - shaders = [ "ink_sparkle.frag" ] + shaders = [ + "ink_sparkle.frag", + "runtime_stage_example.frag", + ] sl_file_extension = "iplr" shader_target_flag = "--runtime-stage-metal" iplr = true diff --git a/impeller/fixtures/example.frag.metal.iplr b/impeller/fixtures/example.frag.metal.iplr deleted file mode 100644 index 1e02757f6610358a292dd7257a12198e76ad2b71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 760 zcmZ`%O-nN|5FSNQVv!yycaT}XjezE+8L!D|pZz&}bCWiym~SxJ|d znRUZbyU>;D?XoIY zIx~$EAA&)n(&X-p{qv0}P0cSag~uq32ZIaoiAb&M@3DSu&v+saupHC7T z2ouK$p;)o9=J>UVMqM-^k@$<5rf4X0kq-|P>buhhd~0n nl)}G*?epII!M_i^_iybPcTYaAr&jOpTi~VtqaDaU&KdfDhBU&T diff --git a/impeller/fixtures/runtime_stage_example.frag b/impeller/fixtures/runtime_stage_example.frag new file mode 100644 index 0000000000000..678cb95c263be --- /dev/null +++ b/impeller/fixtures/runtime_stage_example.frag @@ -0,0 +1,15 @@ +// 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. + +layout(location = 0) uniform float iTime; +layout(location = 1) uniform vec2 iResolution; + +layout(location = 0) out vec4 fragColor; + +void main() { + vec2 uv = gl_FragCoord.xy/iResolution; + float t = 4 * iTime; + vec3 col = 0.5 + 0.5*cos(t + uv.xyx + vec3(0,1,4)); + fragColor = vec4(col,1.0); +} From cba75064460f787bef7a2f033938d3957a994fd7 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 19 Oct 2022 11:40:56 -0700 Subject: [PATCH 07/10] kConicalGradient unimplemented --- impeller/display_list/display_list_dispatcher.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index e6d23ddfe938b..7a8cb9906d6ab 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -429,7 +429,6 @@ void DisplayListDispatcher::setColorSource( }; return; } - case flutter::DlColorSourceType::kConicalGradient: case flutter::DlColorSourceType::kRuntimeEffect: { const flutter::DlRuntimeEffectColorSource* runtime_effect_color_source = source->asRuntimeEffect(); @@ -451,6 +450,7 @@ void DisplayListDispatcher::setColorSource( }; return; } + case flutter::DlColorSourceType::kConicalGradient: case flutter::DlColorSourceType::kUnknown: UNIMPLEMENTED; break; From ecf021a4436d91a1ddbfb72a962f5b6f42bbf724 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 19 Oct 2022 11:54:02 -0700 Subject: [PATCH 08/10] Correct prevent overdraw --- impeller/entity/contents/runtime_effect_contents.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc index 14514276b550e..2e55c90209861 100644 --- a/impeller/entity/contents/runtime_effect_contents.cc +++ b/impeller/entity/contents/runtime_effect_contents.cc @@ -157,7 +157,7 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, pass.AddCommand(std::move(cmd)); - if (!geometry_result.prevent_overdraw) { + if (geometry_result.prevent_overdraw) { return ClipRestoreContents().Render(renderer, entity, pass); } return true; From da4b6bcd35d50495d3bdc79b24f3a7e00012e8b5 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 19 Oct 2022 11:58:34 -0700 Subject: [PATCH 09/10] Remove example.frag.metal.iplr from fixture list --- impeller/fixtures/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/impeller/fixtures/BUILD.gn b/impeller/fixtures/BUILD.gn index 2e31045d6d599..ca6984e0f5b57 100644 --- a/impeller/fixtures/BUILD.gn +++ b/impeller/fixtures/BUILD.gn @@ -53,7 +53,6 @@ test_fixtures("file_fixtures") { "blue_noise.png", "boston.jpg", "embarcadero.jpg", - "example.frag.metal.iplr", "kalimba.jpg", "resources_limit.vert", "sample.comp", From 3310ce8b8e696af13e244f153ddfb9c41e347ab0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 19 Oct 2022 12:53:00 -0700 Subject: [PATCH 10/10] Remove unused emplace --- impeller/renderer/host_buffer.h | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/impeller/renderer/host_buffer.h b/impeller/renderer/host_buffer.h index d445171b89f4f..7895a38b87ae6 100644 --- a/impeller/renderer/host_buffer.h +++ b/impeller/renderer/host_buffer.h @@ -91,27 +91,6 @@ class HostBuffer final : public std::enable_shared_from_this, ); } - //---------------------------------------------------------------------------- - /// @brief Emplace data onto the host buffer with a custom alignment. - /// - /// @param[in] buffer The buffer data. - /// - /// @tparam BufferType The type of the buffer data. - /// - /// @tparam size_t The byte alignment to use when emplacing the - /// data. - /// - /// @return The buffer view. - /// - template >> - [[nodiscard]] BufferView Emplace(const BufferType& buffer, size_t alignment) { - return Emplace(reinterpret_cast(&buffer), // buffer - sizeof(BufferType), // size - alignment // alignment - ); - } - [[nodiscard]] BufferView Emplace(const void* buffer, size_t length, size_t align);