10 #include "flutter/fml/logging.h"
11 #include "flutter/fml/make_copyable.h"
18 #include "impeller/entity/runtime_effect.vert.h"
26 std::shared_ptr<RuntimeStage> runtime_stage) {
27 runtime_stage_ = std::move(runtime_stage);
31 std::shared_ptr<std::vector<uint8_t>> uniform_data) {
32 uniform_data_ = std::move(uniform_data);
36 std::vector<TextureInput> texture_inputs) {
37 texture_inputs_ = std::move(texture_inputs);
68 auto metadata = std::make_shared<ShaderMetadata>();
69 metadata->name = uniform.
name;
88 <<
"Fragment programs not supported on Vulkan. Content dropped.";
92 auto library = context->GetShaderLibrary();
100 std::shared_ptr<const ShaderFunction>
function = library->GetFunction(
103 if (
function && runtime_stage_->IsDirty()) {
104 context->GetPipelineLibrary()->RemovePipelinesWithEntryPoint(
function);
105 library->UnregisterFunction(runtime_stage_->GetEntrypoint(),
112 std::promise<bool> promise;
113 auto future = promise.get_future();
115 library->RegisterFunction(
116 runtime_stage_->GetEntrypoint(),
118 runtime_stage_->GetCodeMapping(),
119 fml::MakeCopyable([promise = std::move(promise)](
bool result)
mutable {
120 promise.set_value(result);
125 << runtime_stage_->GetEntrypoint() <<
")";
129 function = library->GetFunction(runtime_stage_->GetEntrypoint(),
133 <<
"Failed to fetch runtime effect function immediately after "
134 "registering it (entry point: "
135 << runtime_stage_->GetEntrypoint() <<
")";
139 runtime_stage_->SetClean();
146 auto geometry_result =
147 GetGeometry()->GetPositionBuffer(renderer, entity, pass);
153 const auto& caps = context->GetCapabilities();
154 const auto color_attachment_format = caps->GetDefaultColorFormat();
155 const auto stencil_attachment_format = caps->GetDefaultStencilFormat();
157 using VS = RuntimeEffectVertexShader;
164 auto vertex_descriptor = std::make_shared<VertexDescriptor>();
165 vertex_descriptor->SetStageInputs(VS::kAllShaderStageInputs,
166 VS::kInterleavedBufferLayout);
169 0u, {.format = color_attachment_format, .blending_enabled =
true});
177 if (geometry_result.prevent_overdraw) {
181 options.primitive_type = geometry_result.type;
182 options.ApplyToPipelineDescriptor(desc);
184 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
186 VALIDATION_LOG <<
"Failed to get or create runtime effect pipeline.";
194 cmd.
BindVertices(std::move(geometry_result.vertex_buffer));
200 VS::FrameInfo frame_info;
201 frame_info.mvp = geometry_result.transform;
208 size_t minimum_sampler_index = 100000000;
209 size_t buffer_index = 0;
210 size_t buffer_offset = 0;
211 for (
const auto& uniform : runtime_stage_->GetUniforms()) {
214 switch (uniform.type) {
224 minimum_sampler_index =
225 std::min(minimum_sampler_index, uniform.location);
232 uniform_data_->data() + buffer_offset, uniform.GetSize(),
236 uniform_slot.
name = uniform.name.c_str();
237 uniform_slot.
ext_res_0 = uniform.location;
241 buffer_offset += uniform.GetSize();
261 size_t sampler_index = 0;
262 for (
const auto& uniform : runtime_stage_->GetUniforms()) {
265 switch (uniform.type) {
267 FML_DCHECK(sampler_index < texture_inputs_.size());
268 auto& input = texture_inputs_[sampler_index];
271 context->GetSamplerLibrary()->GetSampler(input.sampler_descriptor);
274 image_slot.
name = uniform.name.c_str();
275 image_slot.
texture_index = uniform.location - minimum_sampler_index;
277 input.texture, sampler);
289 if (geometry_result.prevent_overdraw) {
292 return restore.Render(renderer, entity, pass);