diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc index 853db4b5288eb..3ecea0a0d83d0 100644 --- a/impeller/display_list/display_list_dispatcher.cc +++ b/impeller/display_list/display_list_dispatcher.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include "display_list/display_list_blend_mode.h" #include "display_list/display_list_color_filter.h" @@ -436,11 +437,28 @@ void DisplayListDispatcher::setColorSource( auto runtime_stage = runtime_effect_color_source->runtime_effect()->runtime_stage(); auto uniform_data = runtime_effect_color_source->uniform_data(); + auto samplers = runtime_effect_color_source->samplers(); - paint_.color_source = [runtime_stage, uniform_data]() { + std::vector texture_inputs; + + for (auto& sampler : samplers) { + auto* image = sampler->asImage(); + if (!sampler->asImage()) { + UNIMPLEMENTED; + return; + } + FML_DCHECK(image->image()->impeller_texture()); + texture_inputs.push_back({ + .sampler_descriptor = ToSamplerDescriptor(image->sampling()), + .texture = image->image()->impeller_texture(), + }); + } + + paint_.color_source = [runtime_stage, uniform_data, texture_inputs]() { auto contents = std::make_shared(); contents->SetRuntimeStage(runtime_stage); contents->SetUniformData(uniform_data); + contents->SetTextureInputs(texture_inputs); return contents; }; return; diff --git a/impeller/entity/contents/runtime_effect_contents.cc b/impeller/entity/contents/runtime_effect_contents.cc index e454b9fbc4eb5..0bce8521769bf 100644 --- a/impeller/entity/contents/runtime_effect_contents.cc +++ b/impeller/entity/contents/runtime_effect_contents.cc @@ -16,6 +16,7 @@ #include "impeller/renderer/formats.h" #include "impeller/renderer/pipeline_library.h" #include "impeller/renderer/render_pass.h" +#include "impeller/renderer/sampler_library.h" #include "impeller/renderer/shader_function.h" #include "impeller/renderer/shader_types.h" @@ -31,6 +32,11 @@ void RuntimeEffectContents::SetUniformData( uniform_data_ = std::move(uniform_data); } +void RuntimeEffectContents::SetTextureInputs( + std::vector texture_inputs) { + texture_inputs_ = std::move(texture_inputs); +} + bool RuntimeEffectContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { @@ -136,21 +142,59 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer, /// size_t buffer_index = 0; + size_t sampler_index = 0; for (auto uniform : runtime_stage_->GetUniforms()) { // TODO(113715): 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_->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); + switch (uniform.type) { + case kSampledImage: { + FML_DCHECK(sampler_index < texture_inputs_.size()); + auto& input = texture_inputs_[sampler_index]; + + auto sampler = + context->GetSamplerLibrary()->GetSampler(input.sampler_descriptor); + + SampledImageSlot image_slot; + image_slot.name = uniform.name.c_str(); + image_slot.texture_index = sampler_index; + image_slot.sampler_index = sampler_index; + cmd.BindResource(ShaderStage::kFragment, image_slot, metadata, + input.texture, sampler); + + sampler_index++; + break; + } + case kFloat: { + size_t alignment = + std::max(uniform.bit_width / 8, DefaultUniformAlignment()); + auto buffer_view = pass.GetTransientsBuffer().Emplace( + uniform_data_->data() + uniform.location * sizeof(float), + uniform.GetSize(), alignment); + + ShaderUniformSlot uniform_slot; + uniform_slot.name = uniform.name.c_str(); + uniform_slot.ext_res_0 = buffer_index; + cmd.BindResource(ShaderStage::kFragment, uniform_slot, metadata, + buffer_view); + break; + } + case kBoolean: + case kSignedByte: + case kUnsignedByte: + case kSignedShort: + case kUnsignedShort: + case kSignedInt: + case kUnsignedInt: + case kSignedInt64: + case kUnsignedInt64: + case kHalfFloat: + case kDouble: + VALIDATION_LOG << "Unsupported uniform type for " << uniform.name + << "."; + return true; + } buffer_index++; } diff --git a/impeller/entity/contents/runtime_effect_contents.h b/impeller/entity/contents/runtime_effect_contents.h index 3abcc16a1a312..bda791bc064f5 100644 --- a/impeller/entity/contents/runtime_effect_contents.h +++ b/impeller/entity/contents/runtime_effect_contents.h @@ -4,18 +4,27 @@ #include #include +#include #include "impeller/entity/contents/color_source_contents.h" +#include "impeller/renderer/sampler_descriptor.h" #include "impeller/runtime_stage/runtime_stage.h" namespace impeller { class RuntimeEffectContents final : public ColorSourceContents { public: + struct TextureInput { + SamplerDescriptor sampler_descriptor; + std::shared_ptr texture; + }; + void SetRuntimeStage(std::shared_ptr runtime_stage); void SetUniformData(std::shared_ptr> uniform_data); + void SetTextureInputs(std::vector texture_inputs); + // |Contents| bool Render(const ContentContext& renderer, const Entity& entity, @@ -24,6 +33,7 @@ class RuntimeEffectContents final : public ColorSourceContents { private: std::shared_ptr runtime_stage_; std::shared_ptr> uniform_data_; + std::vector texture_inputs_; }; } // namespace impeller