25#include "impeller/entity/texture_fill.frag.h"
26#include "impeller/entity/texture_fill.vert.h"
37#define _IMPELLER_BLEND_MODE_FILTER_NAME_LIST(blend_mode) \
38 "Blend Filter " #blend_mode,
40static constexpr const char* kBlendModeFilterNames[] = {
43const std::string_view BlendModeToFilterString(
BlendMode blend_mode) {
44 return kBlendModeFilterNames[
static_cast<std::underlying_type_t<BlendMode>
>(
95template <
typename TPipeline>
100 const Rect& coverage,
102 std::optional<Color> foreground_color,
105 std::optional<Scalar> alpha) {
106 using VS =
typename TPipeline::VertexShader;
107 using FS =
typename TPipeline::FragmentShader;
113 const size_t total_inputs =
114 inputs.size() + (foreground_color.has_value() ? 1 : 0);
115 if (total_inputs < 2) {
120 inputs[0]->GetSnapshot(
"AdvancedBlend(Dst)", renderer, entity);
121 if (!dst_snapshot.has_value()) {
124 auto maybe_dst_uvs = dst_snapshot->GetCoverageUVs(coverage);
125 if (!maybe_dst_uvs.has_value()) {
128 auto dst_uvs = maybe_dst_uvs.value();
130 std::optional<Snapshot> src_snapshot;
131 std::array<Point, 4> src_uvs;
132 if (!foreground_color.has_value()) {
134 inputs[1]->GetSnapshot(
"AdvancedBlend(Src)", renderer, entity);
135 if (!src_snapshot.has_value()) {
136 if (!dst_snapshot.has_value()) {
141 auto maybe_src_uvs = src_snapshot->GetCoverageUVs(coverage);
142 if (!maybe_src_uvs.has_value()) {
143 if (!dst_snapshot.has_value()) {
148 src_uvs = maybe_src_uvs.value();
151 Rect subpass_coverage = coverage;
153 auto coverage_hint = entity.
GetContents()->GetCoverageHint();
155 if (coverage_hint.has_value()) {
156 auto maybe_subpass_coverage =
158 if (!maybe_subpass_coverage.has_value()) {
162 subpass_coverage = *maybe_subpass_coverage;
174 auto size = pass.GetRenderTargetSize();
176 std::array<typename VS::PerVertexData, 4> vertices = {
177 typename VS::PerVertexData{
Point(0, 0), dst_uvs[0], src_uvs[0]},
178 typename VS::PerVertexData{
Point(size.width, 0), dst_uvs[1],
180 typename VS::PerVertexData{
Point(0, size.height), dst_uvs[2],
182 typename VS::PerVertexData{
Point(size.width, size.height), dst_uvs[3],
194 pass.SetCommandLabel(BlendModeToFilterString(blend_mode));
196 pass.SetVertexBuffer(std::move(vtx_buffer));
199 typename FS::BlendInfo blend_info;
200 typename VS::FrameInfo frame_info;
203 renderer.
GetContext()->GetSamplerLibrary()->GetSampler(
204 dst_snapshot->sampler_descriptor);
205 FS::BindTextureSamplerDst(pass, dst_snapshot->texture, dst_sampler);
206 blend_info.dst_input_alpha =
208 ? dst_snapshot->opacity
211 if (foreground_color.has_value()) {
212 blend_info.color_factor = 1;
213 blend_info.color = foreground_color.value();
217 FS::BindTextureSamplerSrc(pass, dst_snapshot->texture, dst_sampler);
220 renderer.
GetContext()->GetSamplerLibrary()->GetSampler(
221 src_snapshot->sampler_descriptor);
222 blend_info.color_factor = 0;
223 blend_info.src_input_alpha = src_snapshot->opacity;
224 FS::BindTextureSamplerSrc(pass, src_snapshot->texture, src_sampler);
226 auto blend_uniform = data_host_buffer.EmplaceUniform(blend_info);
227 FS::BindBlendInfo(pass, blend_uniform);
229 frame_info.mvp = pass.GetOrthographicTransform() *
233 auto uniform_view = data_host_buffer.EmplaceUniform(frame_info);
234 VS::BindFrameInfo(pass, uniform_view);
236 return pass.Draw().ok();
252 if (!render_target.
ok()) {
261 .
texture = render_target.
value().GetRenderTargetTexture(),
266 .sampler_descriptor = {},
269 : dst_snapshot->opacity) *
270 alpha.value_or(1.0)},
274std::optional<Entity> BlendFilterContents::CreateForegroundAdvancedBlend(
275 const std::shared_ptr<FilterInput>&
input,
276 const ContentContext& renderer,
277 const Entity& entity,
278 const Rect& coverage,
279 Color foreground_color,
281 std::optional<Scalar> alpha,
284 input->GetSnapshot(
"ForegroundAdvancedBlend", renderer, entity);
285 if (!dst_snapshot.has_value()) {
289 RenderProc render_proc = [foreground_color, dst_snapshot, blend_mode, alpha,
290 absorb_opacity](
const ContentContext& renderer,
291 const Entity& entity,
292 RenderPass& pass) ->
bool {
293 using VS = BlendScreenPipeline::VertexShader;
294 using FS = BlendScreenPipeline::FragmentShader;
296 auto& data_host_buffer = renderer.GetTransientsDataBuffer();
297 auto size = dst_snapshot->texture->GetSize();
299 std::array<VS::PerVertexData, 4> vertices = {
300 VS::PerVertexData{{0, 0}, {0, 0}, {0, 0}},
301 VS::PerVertexData{
Point(
size.width, 0), {1, 0}, {1, 0}},
302 VS::PerVertexData{
Point(0,
size.height), {0, 1}, {0, 1}},
303 VS::PerVertexData{
Point(
size.width,
size.height), {1, 1}, {1, 1}},
308 pass.SetCommandLabel(BlendModeToFilterString(blend_mode));
310 pass.SetVertexBuffer(std::move(vtx_buffer));
314 switch (blend_mode) {
316 pass.SetPipeline(renderer.GetBlendScreenPipeline(options));
319 pass.SetPipeline(renderer.GetBlendOverlayPipeline(options));
322 pass.SetPipeline(renderer.GetBlendDarkenPipeline(options));
325 pass.SetPipeline(renderer.GetBlendLightenPipeline(options));
328 pass.SetPipeline(renderer.GetBlendColorDodgePipeline(options));
331 pass.SetPipeline(renderer.GetBlendColorBurnPipeline(options));
334 pass.SetPipeline(renderer.GetBlendHardLightPipeline(options));
337 pass.SetPipeline(renderer.GetBlendSoftLightPipeline(options));
340 pass.SetPipeline(renderer.GetBlendDifferencePipeline(options));
343 pass.SetPipeline(renderer.GetBlendExclusionPipeline(options));
346 pass.SetPipeline(renderer.GetBlendMultiplyPipeline(options));
349 pass.SetPipeline(renderer.GetBlendHuePipeline(options));
352 pass.SetPipeline(renderer.GetBlendSaturationPipeline(options));
355 pass.SetPipeline(renderer.GetBlendColorPipeline(options));
358 pass.SetPipeline(renderer.GetBlendLuminosityPipeline(options));
364 FS::BlendInfo blend_info;
365 VS::FrameInfo frame_info;
367 raw_ptr<const Sampler> dst_sampler =
368 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
369 dst_snapshot->sampler_descriptor);
370 FS::BindTextureSamplerDst(pass, dst_snapshot->texture, dst_sampler);
373 entity.GetShaderClipDepth(), pass,
374 entity.GetTransform() * dst_snapshot->transform);
376 blend_info.dst_input_alpha =
378 ? dst_snapshot->opacity * alpha.value_or(1.0)
381 blend_info.color_factor = 1;
382 blend_info.color = foreground_color;
386 FS::BindTextureSamplerSrc(pass, dst_snapshot->texture, dst_sampler);
388 auto blend_uniform = data_host_buffer.EmplaceUniform(blend_info);
389 FS::BindBlendInfo(pass, blend_uniform);
391 auto uniform_view = data_host_buffer.EmplaceUniform(frame_info);
392 VS::BindFrameInfo(pass, uniform_view);
394 return pass.Draw().ok();
397 [coverage](
const Entity& entity) -> std::optional<Rect> {
398 return coverage.TransformBounds(entity.GetTransform());
404 sub_entity.SetContents(std::move(contents));
405 sub_entity.SetBlendMode(entity.GetBlendMode());
410std::optional<Entity> BlendFilterContents::CreateForegroundPorterDuffBlend(
411 const std::shared_ptr<FilterInput>&
input,
412 const ContentContext& renderer,
413 const Entity& entity,
414 const Rect& coverage,
415 Color foreground_color,
417 std::optional<Scalar> alpha,
424 input->GetSnapshot(
"ForegroundPorterDuffBlend", renderer, entity);
425 if (!dst_snapshot.has_value()) {
433 RenderProc render_proc = [foreground_color, dst_snapshot, blend_mode,
434 absorb_opacity, alpha](
435 const ContentContext& renderer,
436 const Entity& entity, RenderPass& pass) ->
bool {
437 using VS = PorterDuffBlendPipeline::VertexShader;
438 using FS = PorterDuffBlendPipeline::FragmentShader;
440 auto& data_host_buffer = renderer.GetTransientsDataBuffer();
441 auto size = dst_snapshot->texture->GetSize();
442 auto color = foreground_color.Premultiply();
444 std::array<VS::PerVertexData, 4> vertices = {
445 VS::PerVertexData{{0, 0}, {0, 0}, color},
446 VS::PerVertexData{
Point(
size.width, 0), {1, 0}, color},
447 VS::PerVertexData{
Point(0,
size.height), {0, 1}, color},
448 VS::PerVertexData{
Point(
size.width,
size.height), {1, 1}, color},
454 pass.SetCommandLabel(BlendModeToFilterString(blend_mode));
456 pass.SetVertexBuffer(std::move(vtx_buffer));
459 pass.SetPipeline(renderer.GetPorterDuffPipeline(blend_mode, options));
461 FS::FragInfo frag_info;
462 VS::FrameInfo frame_info;
465 entity.GetShaderClipDepth(), pass,
466 entity.GetTransform() * dst_snapshot->transform);
468 raw_ptr<const Sampler> dst_sampler =
469 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
470 dst_snapshot->sampler_descriptor);
471 FS::BindTextureSamplerDst(pass, dst_snapshot->texture, dst_sampler);
473 frag_info.input_alpha_output_alpha_tmx_tmy =
475 ? dst_snapshot->opacity * alpha.value_or(1.0)
478 frag_info.use_strict_source_rect = 0.0;
480 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
481 VS::BindFrameInfo(pass, data_host_buffer.EmplaceUniform(frame_info));
483 return pass.Draw().ok();
487 [coverage](
const Entity& entity) -> std::optional<Rect> {
488 return coverage.TransformBounds(entity.GetTransform());
494 sub_entity.SetContents(std::move(contents));
495 sub_entity.SetBlendMode(entity.GetBlendMode());
504 const Rect& coverage,
506 std::optional<Color> foreground_color,
508 std::optional<Scalar> alpha) {
509 using VS = TexturePipeline::VertexShader;
510 using FS = TexturePipeline::FragmentShader;
513 inputs[0]->GetSnapshot(
"PipelineBlend(Dst)", renderer, entity);
514 if (!dst_snapshot.has_value()) {
518 Rect subpass_coverage = coverage;
520 auto coverage_hint = entity.
GetContents()->GetCoverageHint();
522 if (coverage_hint.has_value()) {
523 auto maybe_subpass_coverage =
525 if (!maybe_subpass_coverage.has_value()) {
529 subpass_coverage = *maybe_subpass_coverage;
538 pass.SetCommandLabel(BlendModeToFilterString(blend_mode));
543 auto add_blend_command = [&](std::optional<Snapshot>
input) {
544 if (!
input.has_value()) {
547 auto input_coverage =
input->GetCoverage();
548 if (!input_coverage.has_value()) {
553 renderer.
GetContext()->GetSamplerLibrary()->GetSampler(
554 input->sampler_descriptor);
555 FS::BindTextureSampler(pass,
input->texture, sampler);
557 auto size =
input->texture->GetSize();
558 std::array<VS::PerVertexData, 4> vertices = {
560 VS::PerVertexData{
Point(size.width, 0),
Point(1, 0)},
561 VS::PerVertexData{
Point(0, size.height),
Point(0, 1)},
562 VS::PerVertexData{
Point(size.width, size.height),
Point(1, 1)},
564 pass.SetVertexBuffer(
567 VS::FrameInfo frame_info;
568 frame_info.mvp = pass.GetOrthographicTransform() *
572 FS::FragInfo frag_info;
577 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
578 VS::BindFrameInfo(pass, data_host_buffer.EmplaceUniform(frame_info));
580 return pass.Draw().ok();
586 if (!add_blend_command(dst_snapshot)) {
592 if (inputs.size() >= 2) {
593 options.blend_mode = blend_mode;
596 for (
auto texture_i = inputs.begin() + 1; texture_i < inputs.end();
598 auto src_input = texture_i->get()->GetSnapshot(
"PipelineBlend(Src)",
600 if (!add_blend_command(src_input)) {
608 if (foreground_color.has_value()) {
610 auto contents = std::make_shared<SolidColorContents>(&geom);
611 contents->SetColor(foreground_color.value());
616 if (!foreground_entity.
Render(renderer, pass)) {
639 if (!render_target.
ok()) {
648 .
texture = render_target.
value().GetRenderTargetTexture(),
653 .sampler_descriptor = {},
656 : dst_snapshot->opacity) *
657 alpha.value_or(1.0)},
661std::optional<Entity> BlendFilterContents::CreateFramebufferAdvancedBlend(
663 const ContentContext& renderer,
664 const Entity& entity,
665 const Rect& coverage,
666 std::optional<Color> foreground_color,
668 std::optional<Scalar> alpha,
672 (inputs.size() == 1u && foreground_color.has_value()));
675 inputs[0]->GetSnapshot(
"ForegroundAdvancedBlend", renderer, entity);
676 if (!dst_snapshot.has_value()) {
680 std::shared_ptr<Texture> foreground_texture;
687 HostBuffer& data_host_buffer = renderer.GetTransientsDataBuffer();
690 using FS = TextureFillFragmentShader;
691 using VS = TextureFillVertexShader;
693 pass.SetCommandLabel(
"Framebuffer Advanced Blend");
696 pass.SetPipeline(renderer.GetTexturePipeline(pipeline_options));
698 VS::FrameInfo frame_info;
701 FS::FragInfo frag_info;
702 frag_info.alpha = 1.0;
704 std::array<VS::PerVertexData, 4> vertices = {
705 VS::PerVertexData{{0, 0}, {0, 0}},
706 VS::PerVertexData{
Point(1, 0), {1, 0}},
707 VS::PerVertexData{
Point(0, 1), {0, 1}},
708 VS::PerVertexData{
Point(1, 1), {1, 1}},
710 pass.SetVertexBuffer(
713 VS::BindFrameInfo(pass, data_host_buffer.EmplaceUniform(frame_info));
714 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
715 FS::BindTextureSampler(
716 pass, dst_snapshot->texture,
717 renderer.GetContext()->GetSamplerLibrary()->GetSampler({}));
719 if (!pass.Draw().ok()) {
725 using VS = FramebufferBlendScreenPipeline::VertexShader;
726 using FS = FramebufferBlendScreenPipeline::FragmentShader;
730 std::shared_ptr<Texture> src_texture;
731 SamplerDescriptor src_sampler_descriptor = SamplerDescriptor{};
732 if (foreground_color.has_value()) {
733 src_texture = foreground_texture;
736 inputs[0]->GetSnapshot(
"ForegroundAdvancedBlend", renderer, entity);
737 if (!src_snapshot.has_value()) {
743 src_texture = src_snapshot->texture;
744 src_sampler_descriptor = src_snapshot->sampler_descriptor;
747 std::array<VS::PerVertexData, 4> vertices = {
758 pass.SetCommandLabel(
"Framebuffer Advanced Blend Filter");
759 pass.SetVertexBuffer(
762 switch (blend_mode) {
764 pass.SetPipeline(renderer.GetFramebufferBlendScreenPipeline(options));
768 renderer.GetFramebufferBlendOverlayPipeline(options));
771 pass.SetPipeline(renderer.GetFramebufferBlendDarkenPipeline(options));
775 renderer.GetFramebufferBlendLightenPipeline(options));
779 renderer.GetFramebufferBlendColorDodgePipeline(options));
783 renderer.GetFramebufferBlendColorBurnPipeline(options));
787 renderer.GetFramebufferBlendHardLightPipeline(options));
791 renderer.GetFramebufferBlendSoftLightPipeline(options));
795 renderer.GetFramebufferBlendDifferencePipeline(options));
799 renderer.GetFramebufferBlendExclusionPipeline(options));
803 renderer.GetFramebufferBlendMultiplyPipeline(options));
806 pass.SetPipeline(renderer.GetFramebufferBlendHuePipeline(options));
810 renderer.GetFramebufferBlendSaturationPipeline(options));
813 pass.SetPipeline(renderer.GetFramebufferBlendColorPipeline(options));
817 renderer.GetFramebufferBlendLuminosityPipeline(options));
823 VS::FrameInfo frame_info;
824 FS::FragInfo frag_info;
826 raw_ptr<const Sampler> src_sampler =
827 renderer.GetContext()->GetSamplerLibrary()->GetSampler(
828 src_sampler_descriptor);
829 FS::BindTextureSamplerSrc(pass, src_texture, src_sampler);
832 VS::BindFrameInfo(pass, data_host_buffer.EmplaceUniform(frame_info));
834 frag_info.src_input_alpha = 1.0;
835 frag_info.dst_input_alpha =
837 ? dst_snapshot->opacity
839 FS::BindFragInfo(pass, data_host_buffer.EmplaceUniform(frag_info));
841 return pass.Draw().ok();
845 std::shared_ptr<CommandBuffer> cmd_buffer =
846 renderer.GetContext()->CreateCommandBuffer();
849 if (foreground_color.has_value()) {
850 TextureDescriptor desc;
855 renderer.GetContext()->GetResourceAllocator()->CreateTexture(desc);
856 if (!foreground_texture) {
859 std::shared_ptr<BlitPass> blit_pass = cmd_buffer->CreateBlitPass();
860 auto buffer_view = renderer.GetTransientsDataBuffer().Emplace(
861 foreground_color->Premultiply().ToR8G8B8A8(), 4);
863 blit_pass->AddCopy(std::move(buffer_view), foreground_texture);
864 if (!blit_pass->EncodeCommands()) {
870 renderer.MakeSubpass(
"FramebufferBlend",
871 dst_snapshot->texture->GetSize(),
878 if (!render_target.
ok()) {
881 if (!renderer.GetContext()->EnqueueCommandBuffer(std::move(cmd_buffer))) {
887 .texture = render_target.
value().GetRenderTargetTexture(),
892 .sampler_descriptor = {},
895 : dst_snapshot->opacity) *
896 alpha.value_or(1.0)},
897 entity.GetBlendMode());
900#define BLEND_CASE(mode) \
901 case BlendMode::k##mode: \
902 advanced_blend_proc_ = \
903 [](const FilterInput::Vector& inputs, const ContentContext& renderer, \
904 const Entity& entity, const Rect& coverage, BlendMode blend_mode, \
905 std::optional<Color> fg_color, \
906 ColorFilterContents::AbsorbOpacity absorb_opacity, \
907 std::optional<Scalar> alpha) { \
908 PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \
909 return AdvancedBlend<Blend##mode##Pipeline>( \
910 inputs, renderer, entity, coverage, blend_mode, fg_color, \
911 absorb_opacity, p, alpha); \
917 VALIDATION_LOG <<
"Invalid blend mode " <<
static_cast<int>(blend_mode)
918 <<
" assigned to BlendFilterContents.";
921 blend_mode_ = blend_mode;
924 switch (blend_mode) {
947 foreground_color_ = color;
950std::optional<Entity> BlendFilterContents::RenderFilter(
954 const Matrix& effect_transform,
955 const Rect& coverage,
956 const std::optional<Rect>& coverage_hint)
const {
957 if (inputs.empty()) {
961 if (inputs.size() == 1 && !foreground_color_.has_value()) {
968 if (inputs.size() == 1 && foreground_color_.has_value() &&
970 return CreateForegroundPorterDuffBlend(
971 inputs[0], renderer, entity, coverage, foreground_color_.value(),
974 return PipelineBlend(inputs, renderer, entity, coverage, blend_mode_,
980 return CreateFramebufferAdvancedBlend(inputs, renderer, entity, coverage,
981 foreground_color_, blend_mode_,
984 if (inputs.size() == 1 && foreground_color_.has_value() &&
986 return CreateForegroundAdvancedBlend(
987 inputs[0], renderer, entity, coverage, foreground_color_.value(),
990 return advanced_blend_proc_(inputs, renderer, entity, coverage, blend_mode_,
static std::shared_ptr< Contents > Make(RenderProc render_proc, CoverageProc coverage_proc)
~BlendFilterContents() override
void SetBlendMode(BlendMode blend_mode)
void SetForegroundColor(std::optional< Color > color)
Sets a source color which is blended after all of the inputs have been blended.
virtual bool SupportsFramebufferFetch() const =0
Whether the context backend is able to support pipelines with shaders that read from the framebuffer ...
std::optional< Scalar > GetAlpha() const
AbsorbOpacity GetAbsorbOpacity() const
HostBuffer & GetTransientsDataBuffer() const
Retrieve the current host buffer for transient storage of other non-index data.
fml::StatusOr< RenderTarget > MakeSubpass(std::string_view label, ISize texture_size, const std::shared_ptr< CommandBuffer > &command_buffer, const SubpassCallback &subpass_callback, bool msaa_enabled=true, bool depth_stencil_enabled=false, int32_t mip_count=1) const
Creates a new texture of size texture_size and calls subpass_callback with a RenderPass for drawing t...
const Capabilities & GetDeviceCapabilities() const
PipelineRef GetTexturePipeline(ContentContextOptions opts) const
std::function< bool(const ContentContext &, RenderPass &)> SubpassCallback
std::shared_ptr< Context > GetContext() const
std::function< std::optional< Rect >(const Entity &entity)> CoverageProc
std::function< bool(const ContentContext &renderer, const Entity &entity, RenderPass &pass)> RenderProc
const std::shared_ptr< Contents > & GetContents() const
Matrix GetShaderTransform(const RenderPass &pass) const
BlendMode GetBlendMode() const
void SetContents(std::shared_ptr< Contents > contents)
void SetBlendMode(BlendMode blend_mode)
static constexpr BlendMode kLastAdvancedBlendMode
bool Render(const ContentContext &renderer, RenderPass &parent_pass) const
static constexpr BlendMode kLastPipelineBlendMode
static Entity FromSnapshot(const Snapshot &snapshot, BlendMode blend_mode=BlendMode::kSrcOver)
Create an entity that can be used to render a given snapshot.
Render passes encode render commands directed as one specific render target into an underlying comman...
#define IMPELLER_FOR_EACH_BLEND_MODE(V)
FlutterDesktopBinaryReply callback
#define FML_UNREACHABLE()
#define FML_DCHECK(condition)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
static constexpr Scalar Saturation(Vector3 color)
raw_ptr< Pipeline< PipelineDescriptor > > PipelineRef
A raw ptr to a pipeline object.
LinePipeline::FragmentShader FS
VertexBuffer CreateVertexBuffer(std::array< VertexType, size > input, HostBuffer &data_host_buffer)
Create an index-less vertex buffer from a fixed size array.
static std::optional< Entity > PipelineBlend(const FilterInput::Vector &inputs, const ContentContext &renderer, const Entity &entity, const Rect &coverage, BlendMode blend_mode, std::optional< Color > foreground_color, ColorFilterContents::AbsorbOpacity absorb_opacity, std::optional< Scalar > alpha)
std::optional< BlendMode > InvertPorterDuffBlend(BlendMode blend_mode)
LinePipeline::VertexShader VS
PipelineRef(ContentContext::*)(ContentContextOptions) const PipelineProc
static std::optional< Entity > AdvancedBlend(const FilterInput::Vector &inputs, const ContentContext &renderer, const Entity &entity, const Rect &coverage, BlendMode blend_mode, std::optional< Color > foreground_color, ColorFilterContents::AbsorbOpacity absorb_opacity, PipelineProc pipeline_proc, std::optional< Scalar > alpha)
ContentContextOptions OptionsFromPassAndEntity(const RenderPass &pass, const Entity &entity)
ContentContextOptions OptionsFromPass(const RenderPass &pass)
static constexpr Scalar Luminosity(Vector3 color)
std::shared_ptr< PipelineGLES > pipeline
std::shared_ptr< CommandBuffer > command_buffer
A 4x4 matrix using column-major storage.
static constexpr Matrix MakeOrthographic(TSize< T > size)
static constexpr Matrix MakeTranslation(const Vector3 &t)
Represents a texture and its intended draw transform/sampler configuration.
std::shared_ptr< Texture > texture
constexpr std::optional< TRect > Intersection(const TRect &o) const
constexpr TSize< Type > GetSize() const
Returns the size of the rectangle which may be negative in either width or height and may have been c...
static constexpr TRect MakeSize(const TSize< U > &size)
constexpr TPoint< Type > GetOrigin() const
Returns the upper left corner of the rectangle as specified by the left/top or x/y values when it was...