From ff6f4de42ca558ce8c634df1ba6a4dd21b5f2bb4 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 15 Dec 2022 14:38:11 -0800 Subject: [PATCH 01/26] fill out drawAtlas --- .../shader_lib/impeller/blending.glsl | 51 ++++ impeller/entity/BUILD.gn | 27 ++ impeller/entity/contents/atlas_contents.cc | 139 +++++++++- impeller/entity/contents/content_context.cc | 56 ++++ impeller/entity/contents/content_context.h | 259 +++++++++++++++++- .../atlas_blending/atlas_advanced_blend.glsl | 34 +++ .../atlas_advanced_blend_color.frag | 11 + .../atlas_advanced_blend_colorburn.frag | 11 + .../atlas_advanced_blend_colordodge.frag | 11 + .../atlas_advanced_blend_darken.frag | 11 + .../atlas_advanced_blend_difference.frag | 11 + .../atlas_advanced_blend_exclusion.frag | 11 + .../atlas_advanced_blend_hardlight.frag | 11 + .../atlas_advanced_blend_hue.frag | 11 + .../atlas_advanced_blend_lighten.frag | 11 + .../atlas_advanced_blend_luminosity.frag | 11 + .../atlas_advanced_blend_multiply.frag | 11 + .../atlas_advanced_blend_overlay.frag | 11 + .../atlas_advanced_blend_saturation.frag | 11 + .../atlas_advanced_blend_screen.frag | 11 + .../atlas_advanced_blend_softlight.frag | 11 + .../shaders/atlas_blending/atlas_blend.glsl | 33 +++ .../shaders/atlas_blending/atlas_blend.vert | 23 ++ .../atlas_blending/atlas_blend_dst_a_top.frag | 11 + .../atlas_blending/atlas_blend_dst_in.frag | 11 + .../atlas_blending/atlas_blend_dst_out.frag | 11 + .../atlas_blending/atlas_blend_dst_over.frag | 11 + .../atlas_blending/atlas_blend_modulate.frag | 11 + .../atlas_blending/atlas_blend_plus.frag | 11 + .../atlas_blending/atlas_blend_src_a_top.frag | 11 + .../atlas_blending/atlas_blend_src_in.frag | 11 + .../atlas_blending/atlas_blend_src_out.frag | 11 + .../atlas_blending/atlas_blend_src_over.frag | 11 + .../atlas_blending/atlas_blend_xor.frag | 11 + impeller/entity/shaders/atlas_fill.frag | 21 +- impeller/entity/shaders/atlas_fill.vert | 20 +- .../shaders/blending/advanced_blend.glsl | 1 - 37 files changed, 911 insertions(+), 39 deletions(-) create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend.glsl create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend.vert create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag create mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag diff --git a/impeller/compiler/shader_lib/impeller/blending.glsl b/impeller/compiler/shader_lib/impeller/blending.glsl index f92e6bc4ab9a0..77ac61a5c4049 100644 --- a/impeller/compiler/shader_lib/impeller/blending.glsl +++ b/impeller/compiler/shader_lib/impeller/blending.glsl @@ -190,4 +190,55 @@ vec3 IPBlendLuminosity(vec3 dst, vec3 src) { return IPSetLuminosity(dst, IPLuminosity(src)); } +vec4 IPBlendSrcOver(vec4 dst, vec4 src) { + return src + dst * (1 - src.a); +} + +vec4 IPBlendSrcIn(vec4 dst, vec4 src) { + // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcin + return src * dst.a; +} + +vec4 IPBlendDstOver(vec4 dst, vec4 src) { + // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstout + return dst + src * (1 - dst.a); +} + +vec4 IPBlendDstIn(vec4 dst, vec4 src) { + // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstin + return dst * src.a; +} + +vec4 IPBlendDstOut(vec4 dst, vec4 src) { + return dst * (1 - src.a); +} + +vec4 IPBlendSrcOut(vec4 dst, vec4 src) { + // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcout + return src * (1 - dst.a); +} + +vec4 IPBlendSrcATop(vec4 dst, vec4 src) { + // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcatop + return src * dst.a + dst * (1 - src.a); +} + +vec4 IPBlendDstATop(vec4 dst, vec4 src) { + // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstatop + return dst * src.a + src * (1 - dst.a); +} + +vec4 IPBlendXor(vec4 dst, vec4 src) { + // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_xor + return src * (1 - dst.a) + dst * (1 - src.a); +} + +vec4 IPBlendPlus(vec4 dst, vec4 src) { + return min(src + dst, vec4(1)); +} + +vec4 IPBlendModulate(vec4 dst, vec4 src) { + return src * dst; +} + #endif diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index ecba665e6617a..fb6b05359bd5a 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -56,6 +56,33 @@ impeller_shaders("entity_shaders") { "shaders/srgb_to_linear_filter.frag", "shaders/srgb_to_linear_filter.vert", "shaders/sweep_gradient_fill.frag", + "shaders/atlas_blending/atlas_blend.vert", + "shaders/atlas_blending/atlas_advanced_blend_color.frag", + "shaders/atlas_blending/atlas_advanced_blend_colorburn.frag", + "shaders/atlas_blending/atlas_advanced_blend_colordodge.frag", + "shaders/atlas_blending/atlas_advanced_blend_darken.frag", + "shaders/atlas_blending/atlas_advanced_blend_difference.frag", + "shaders/atlas_blending/atlas_advanced_blend_exclusion.frag", + "shaders/atlas_blending/atlas_advanced_blend_hardlight.frag", + "shaders/atlas_blending/atlas_advanced_blend_hue.frag", + "shaders/atlas_blending/atlas_advanced_blend_lighten.frag", + "shaders/atlas_blending/atlas_advanced_blend_luminosity.frag", + "shaders/atlas_blending/atlas_advanced_blend_multiply.frag", + "shaders/atlas_blending/atlas_advanced_blend_overlay.frag", + "shaders/atlas_blending/atlas_advanced_blend_saturation.frag", + "shaders/atlas_blending/atlas_advanced_blend_screen.frag", + "shaders/atlas_blending/atlas_advanced_blend_softlight.frag", + "shaders/atlas_blending/atlas_blend_dst_a_top.frag", + "shaders/atlas_blending/atlas_blend_dst_in.frag", + "shaders/atlas_blending/atlas_blend_dst_out.frag", + "shaders/atlas_blending/atlas_blend_dst_over.frag", + "shaders/atlas_blending/atlas_blend_modulate.frag", + "shaders/atlas_blending/atlas_blend_plus.frag", + "shaders/atlas_blending/atlas_blend_src_a_top.frag", + "shaders/atlas_blending/atlas_blend_src_in.frag", + "shaders/atlas_blending/atlas_blend_src_out.frag", + "shaders/atlas_blending/atlas_blend_src_over.frag", + "shaders/atlas_blending/atlas_blend_xor.frag", "shaders/texture_fill.frag", "shaders/texture_fill.vert", "shaders/tiled_texture_fill.frag", diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index b983d29e9c261..29582aaad09f9 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -107,12 +107,12 @@ bool AtlasContents::Render(const ContentContext& renderer, for (size_t j = 0; j < 6; j++) { VS::PerVertexData data; - data.position = transformed_points[indices[j]]; - data.texture_coords = + data.vertices = transformed_points[indices[j]]; + data.src_texture_coords = (sample_rect.origin + Point(sample_rect.size.width * width[j], sample_rect.size.height * height[j])) / texture_size; - data.color = color.Premultiply(); + data.dst_color = color; vertex_builder.AppendVertex(data); } } @@ -123,26 +123,137 @@ bool AtlasContents::Render(const ContentContext& renderer, auto& host_buffer = pass.GetTransientsBuffer(); - VS::VertInfo vert_info; - vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * - entity.GetTransformation(); + VS::FrameInfo frame_info; + frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(); FS::FragInfo frag_info; - frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale(); - frag_info.has_vertex_color = colors_.size() > 0 ? 1.0 : 0.0; + frag_info.src_y_coord_scale = texture_->GetYCoordScale(); frag_info.alpha = alpha_; Command cmd; cmd.label = "DrawAtlas"; - cmd.pipeline = - renderer.GetAtlasPipeline(OptionsFromPassAndEntity(pass, entity)); + switch (blend_mode_) { + case BlendMode::kClear: + return true; + case BlendMode::kSource: + // Color only, just use vertices. + case BlendMode::kDestination: + // Image only, same as no color. + case BlendMode::kSourceOver: + cmd.pipeline = renderer.GetAtlasBlendSrcOverPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDestinationOver: + cmd.pipeline = renderer.GetAtlasBlendDstOverPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSourceIn: + cmd.pipeline = renderer.GetAtlasBlendSrcInPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDestinationIn: + cmd.pipeline = renderer.GetAtlasBlendDstInPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSourceOut: + cmd.pipeline = renderer.GetAtlasBlendSrcOutPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDestinationOut: + cmd.pipeline = renderer.GetAtlasBlendDstOutPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSourceATop: + cmd.pipeline = renderer.GetAtlasBlendSrcATopPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDestinationATop: + cmd.pipeline = renderer.GetAtlasBlendDstATopPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kXor: + cmd.pipeline = renderer.GetAtlasBlendXorPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kPlus: + cmd.pipeline = renderer.GetAtlasBlendPlusPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kModulate: + cmd.pipeline = renderer.GetAtlasBlendModulatePipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + // Advanced + case BlendMode::kScreen: + cmd.pipeline = renderer.GetAtlasBlendScreenPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kOverlay: + cmd.pipeline = renderer.GetAtlasBlendOverlayPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDarken: + cmd.pipeline = renderer.GetAtlasBlendDarkenPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kLighten: + cmd.pipeline = renderer.GetAtlasBlendLightenPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kColorDodge: + cmd.pipeline = renderer.GetAtlasBlendColorDodgePipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kColorBurn: + cmd.pipeline = renderer.GetAtlasBlendColorBurnPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kHardLight: + cmd.pipeline = renderer.GetAtlasBlendHardLightPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSoftLight: + cmd.pipeline = renderer.GetAtlasBlendSoftLightPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDifference: + cmd.pipeline = renderer.GetAtlasBlendDifferencePipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kExclusion: + cmd.pipeline = renderer.GetAtlasBlendExclusionPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kMultiply: + cmd.pipeline = renderer.GetAtlasBlendMultiplyPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kHue: + cmd.pipeline = renderer.GetAtlasBlendHuePipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSaturation: + cmd.pipeline = renderer.GetAtlasBlendSaturationPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kColor: + cmd.pipeline = renderer.GetAtlasBlendColorPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kLuminosity: + cmd.pipeline = renderer.GetAtlasBlendLuminosityPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + } cmd.stencil_reference = entity.GetStencilDepth(); cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); - VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); + VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); - FS::BindTextureSampler(cmd, texture_, - renderer.GetContext()->GetSamplerLibrary()->GetSampler( - sampler_descriptor_)); + FS::BindTextureSamplerSrc( + cmd, texture_, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + sampler_descriptor_)); pass.AddCommand(std::move(cmd)); return true; diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index fa6c6782f40cb..65acb462d2e6c 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -227,6 +227,62 @@ ContentContext::ContentContext(std::shared_ptr context) yuv_to_rgb_filter_pipelines_[{}] = CreateDefaultPipeline(*context_); + // Atlas/vertices advanced pipelines + atlas_blend_color_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_colorburn_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_colordodge_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_darken_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_difference_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_exclusion_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_hardlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_hue_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_lighten_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_luminosity_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_multiply_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_overlay_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_saturation_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_screen_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_softlight_pipelines_[{}] = + CreateDefaultPipeline(*context_); + + // Atlas/vertices normal pipelines + atlas_blend_dst_a_top_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_dst_in_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_dst_over_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_dst_out_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_modulate_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_plus_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_src_a_top_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_src_in_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_src_over_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_src_out_pipelines_[{}] = + CreateDefaultPipeline(*context_); + atlas_blend_xor_pipelines_[{}] = + CreateDefaultPipeline(*context_); + if (solid_fill_pipelines_[{}]->GetDescriptor().has_value()) { auto clip_pipeline_descriptor = solid_fill_pipelines_[{}]->GetDescriptor().value(); diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 661ac5a58a9d0..3dc3dc0bba272 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -27,6 +27,35 @@ #include "impeller/entity/advanced_blend_saturation.frag.h" #include "impeller/entity/advanced_blend_screen.frag.h" #include "impeller/entity/advanced_blend_softlight.frag.h" + +#include "impeller/entity/atlas_advanced_blend_color.frag.h" +#include "impeller/entity/atlas_advanced_blend_colorburn.frag.h" +#include "impeller/entity/atlas_advanced_blend_colordodge.frag.h" +#include "impeller/entity/atlas_advanced_blend_darken.frag.h" +#include "impeller/entity/atlas_advanced_blend_difference.frag.h" +#include "impeller/entity/atlas_advanced_blend_exclusion.frag.h" +#include "impeller/entity/atlas_advanced_blend_hardlight.frag.h" +#include "impeller/entity/atlas_advanced_blend_hue.frag.h" +#include "impeller/entity/atlas_advanced_blend_lighten.frag.h" +#include "impeller/entity/atlas_advanced_blend_luminosity.frag.h" +#include "impeller/entity/atlas_advanced_blend_multiply.frag.h" +#include "impeller/entity/atlas_advanced_blend_overlay.frag.h" +#include "impeller/entity/atlas_advanced_blend_saturation.frag.h" +#include "impeller/entity/atlas_advanced_blend_screen.frag.h" +#include "impeller/entity/atlas_advanced_blend_softlight.frag.h" +#include "impeller/entity/atlas_blend.vert.h" +#include "impeller/entity/atlas_blend_dst_a_top.frag.h" +#include "impeller/entity/atlas_blend_dst_in.frag.h" +#include "impeller/entity/atlas_blend_dst_out.frag.h" +#include "impeller/entity/atlas_blend_dst_over.frag.h" +#include "impeller/entity/atlas_blend_modulate.frag.h" +#include "impeller/entity/atlas_blend_plus.frag.h" +#include "impeller/entity/atlas_blend_src_a_top.frag.h" +#include "impeller/entity/atlas_blend_src_in.frag.h" +#include "impeller/entity/atlas_blend_src_out.frag.h" +#include "impeller/entity/atlas_blend_src_over.frag.h" +#include "impeller/entity/atlas_blend_xor.frag.h" + #include "impeller/entity/atlas_fill.frag.h" #include "impeller/entity/atlas_fill.vert.h" #include "impeller/entity/blend.frag.h" @@ -165,7 +194,7 @@ using GlyphAtlasPipeline = using GlyphAtlasSdfPipeline = RenderPipelineT; using AtlasPipeline = - RenderPipelineT; + RenderPipelineT; // Instead of requiring new shaders for clips, the solid fill stages are used // to redirect writing to the stencil instead of color attachments. using ClipPipeline = @@ -178,6 +207,75 @@ using GeometryColorPipeline = using YUVToRGBFilterPipeline = RenderPipelineT; +// Atlas/vertices specific shaders +using AtlasBlendColorPipeline = + RenderPipelineT; +using AtlasBlendColorBurnPipeline = + RenderPipelineT; +using AtlasBlendColorDodgePipeline = + RenderPipelineT; +using AtlasBlendDarkenPipeline = + RenderPipelineT; +using AtlasBlendDifferencePipeline = + RenderPipelineT; +using AtlasBlendExclusionPipeline = + RenderPipelineT; +using AtlasBlendHardLightPipeline = + RenderPipelineT; +using AtlasBlendHuePipeline = + RenderPipelineT; +using AtlasBlendLightenPipeline = + RenderPipelineT; +using AtlasBlendLuminosityPipeline = + RenderPipelineT; +using AtlasBlendMultiplyPipeline = + RenderPipelineT; +using AtlasBlendOverlayPipeline = + RenderPipelineT; +using AtlasBlendSaturationPipeline = + RenderPipelineT; +using AtlasBlendScreenPipeline = + RenderPipelineT; +using AtlasBlendSoftLightPipeline = + RenderPipelineT; +using AtlasBlendDstATopPipeline = + RenderPipelineT; +using AtlasBlendDstInPipeline = + RenderPipelineT; +using AtlasBlendDstOutPipeline = + RenderPipelineT; +using AtlasBlendDstOverPipeline = + RenderPipelineT; +using AtlasBlendModulatePipeline = + RenderPipelineT; +using AtlasBlendPlusPipeline = + RenderPipelineT; +using AtlasBlendSrcATopPipeline = + RenderPipelineT; +using AtlasBlendSrcInPipeline = + RenderPipelineT; +using AtlasBlendSrcOutPipeline = + RenderPipelineT; +using AtlasBlendSrcOverPipeline = + RenderPipelineT; +using AtlasBlendXorPipeline = + RenderPipelineT; + struct ContentContextOptions { SampleCount sample_count = SampleCount::kCount1; BlendMode blend_mode = BlendMode::kSourceOver; @@ -418,6 +516,129 @@ class ContentContext { return GetPipeline(blend_softlight_pipelines_, opts); } + // Atlas/Vertices advanced blends. + + std::shared_ptr> GetAtlasBlendColorPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_color_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendColorBurnPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_colorburn_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendColorDodgePipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_colordodge_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendDarkenPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_darken_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendDifferencePipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_difference_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendExclusionPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_exclusion_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendHardLightPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_hardlight_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendHuePipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_hue_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendLightenPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_lighten_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendLuminosityPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_luminosity_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendMultiplyPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_multiply_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendOverlayPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_overlay_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendSaturationPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_saturation_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendScreenPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_screen_pipelines_, opts); + } + + std::shared_ptr> GetAtlasBlendSoftLightPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_softlight_pipelines_, opts); + } + + // Atlas/Vertices Normal blend + std::shared_ptr> GetAtlasBlendDstATopPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_dst_a_top_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendDstInPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_dst_in_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendDstOverPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_dst_over_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendDstOutPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_dst_out_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendModulatePipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_modulate_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendPlusPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_plus_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendSrcATopPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_src_a_top_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendSrcInPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_src_in_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendSrcOverPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_src_over_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendSrcOutPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_src_out_pipelines_, opts); + } + std::shared_ptr> GetAtlasBlendXorPipeline( + ContentContextOptions opts) const { + return GetPipeline(atlas_blend_xor_pipelines_, opts); + } + std::shared_ptr GetContext() const; std::shared_ptr GetGlyphAtlasContext() const; @@ -489,6 +710,42 @@ class ContentContext { mutable Variants blend_saturation_pipelines_; mutable Variants blend_screen_pipelines_; mutable Variants blend_softlight_pipelines_; + // Atlas/Vertices advanced blends. + mutable Variants atlas_blend_color_pipelines_; + mutable Variants + atlas_blend_colorburn_pipelines_; + mutable Variants + atlas_blend_colordodge_pipelines_; + mutable Variants atlas_blend_darken_pipelines_; + mutable Variants + atlas_blend_difference_pipelines_; + mutable Variants + atlas_blend_exclusion_pipelines_; + mutable Variants + atlas_blend_hardlight_pipelines_; + mutable Variants atlas_blend_hue_pipelines_; + mutable Variants atlas_blend_lighten_pipelines_; + mutable Variants + atlas_blend_luminosity_pipelines_; + mutable Variants atlas_blend_multiply_pipelines_; + mutable Variants atlas_blend_overlay_pipelines_; + mutable Variants + atlas_blend_saturation_pipelines_; + mutable Variants atlas_blend_screen_pipelines_; + mutable Variants + atlas_blend_softlight_pipelines_; + // Atlas/Vertices normal blends. + mutable Variants atlas_blend_dst_a_top_pipelines_; + mutable Variants atlas_blend_dst_in_pipelines_; + mutable Variants atlas_blend_dst_over_pipelines_; + mutable Variants atlas_blend_dst_out_pipelines_; + mutable Variants atlas_blend_modulate_pipelines_; + mutable Variants atlas_blend_plus_pipelines_; + mutable Variants atlas_blend_src_a_top_pipelines_; + mutable Variants atlas_blend_src_in_pipelines_; + mutable Variants atlas_blend_src_over_pipelines_; + mutable Variants atlas_blend_src_out_pipelines_; + mutable Variants atlas_blend_xor_pipelines_; template std::shared_ptr> GetPipeline( diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl new file mode 100644 index 0000000000000..6d71fdfc9ad8b --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl @@ -0,0 +1,34 @@ +// 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 +#include +#include + +uniform FragInfo { + float src_y_coord_scale; + float alpha; +} +blend_info; + +uniform sampler2D texture_sampler_src; + +in vec2 v_src_texture_coords; +in vec4 v_dst_color; // This color input is expected to be unpremultiplied. + +out vec4 frag_color; + +void main() { + vec4 dst = v_dst_color; + vec4 src = IPUnpremultiply(IPSampleWithTileMode( + texture_sampler_src, // sampler + v_src_texture_coords, // texture coordinates + blend_info.src_y_coord_scale, // y coordinate scale + kTileModeDecal // tile mode + )); + + vec4 blended = vec4(Blend(dst.rgb, src.rgb), 1) * dst.a; + frag_color = mix(dst, blended, src.a) * blend_info.alpha; +} diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag new file mode 100644 index 0000000000000..849ee76c172b4 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendColor(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag new file mode 100644 index 0000000000000..78e34c22addb2 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendColorBurn(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag new file mode 100644 index 0000000000000..57e2b03b61baa --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendColorDodge(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag new file mode 100644 index 0000000000000..a0a2fa4e82f54 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendDarken(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag new file mode 100644 index 0000000000000..d0489cb9a6e5f --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendDifference(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag new file mode 100644 index 0000000000000..8879eac4fe47a --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendExclusion(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag new file mode 100644 index 0000000000000..776d03a0dddeb --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendHardLight(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag new file mode 100644 index 0000000000000..5153f4890b14b --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendHue(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag new file mode 100644 index 0000000000000..e1f134d783b57 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendLighten(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag new file mode 100644 index 0000000000000..e6990eb0ddc9d --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendLuminosity(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag new file mode 100644 index 0000000000000..ef9eec81fea1c --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendMultiply(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag new file mode 100644 index 0000000000000..b31ce6c1f4abb --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendOverlay(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag new file mode 100644 index 0000000000000..f00daeab4dc32 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendSaturation(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag new file mode 100644 index 0000000000000..9beeedd345538 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendScreen(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag new file mode 100644 index 0000000000000..70b6ad4300092 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag @@ -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 + +vec3 Blend(vec3 dst, vec3 src) { + return IPBlendSoftLight(dst, src); +} + +#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend.glsl b/impeller/entity/shaders/atlas_blending/atlas_blend.glsl new file mode 100644 index 0000000000000..b869cb79b7660 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend.glsl @@ -0,0 +1,33 @@ +// 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 +#include +#include + +uniform FragInfo { + float src_y_coord_scale; + float alpha; +} +blend_info; + +uniform sampler2D texture_sampler_src; + +in vec2 v_src_texture_coords; +in vec4 v_dst_color; // This color input is expected to be unpremultiplied. + +out vec4 frag_color; + +void main() { + vec4 dst = IPPremultiply(v_dst_color); + vec4 src = + IPSampleWithTileMode(texture_sampler_src, // sampler + v_src_texture_coords, // texture coordinates + blend_info.src_y_coord_scale, // y coordinate scale + kTileModeDecal // tile mode + ); + + frag_color = Blend(dst, src) * blend_info.alpha; +} diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend.vert b/impeller/entity/shaders/atlas_blending/atlas_blend.vert new file mode 100644 index 0000000000000..53bb320bb05bb --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend.vert @@ -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 + +uniform FrameInfo { + mat4 mvp; +} +frame_info; + +in vec2 vertices; +in vec4 dst_color; +in vec2 src_texture_coords; + +out vec2 v_src_texture_coords; +out vec4 v_dst_color; + +void main() { + gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0); + v_src_texture_coords = src_texture_coords; + v_dst_color = dst_color; +} diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag new file mode 100644 index 0000000000000..165a5aa9627f9 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendDstATop(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag new file mode 100644 index 0000000000000..837e01cf61787 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendDstIn(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag new file mode 100644 index 0000000000000..b1edb35c402b3 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendDstOut(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag new file mode 100644 index 0000000000000..c5d1be410d5c8 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendDstOver(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag new file mode 100644 index 0000000000000..0893836ea40c1 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendModulate(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag new file mode 100644 index 0000000000000..9857adc512638 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendPlus(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag new file mode 100644 index 0000000000000..c4e06d8f0fa10 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendSrcATop(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag new file mode 100644 index 0000000000000..fa5eccc6f6ca0 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendSrcIn(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag new file mode 100644 index 0000000000000..6e4a63570bc97 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendSrcOut(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag new file mode 100644 index 0000000000000..dbf179304f929 --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendSrcOver(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag new file mode 100644 index 0000000000000..a88653def3cba --- /dev/null +++ b/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag @@ -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 + +vec4 Blend(vec4 dst, vec4 src) { + return IPBlendXor(dst, src); +} + +#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_fill.frag b/impeller/entity/shaders/atlas_fill.frag index 4862343926a78..ab841efa56fff 100644 --- a/impeller/entity/shaders/atlas_fill.frag +++ b/impeller/entity/shaders/atlas_fill.frag @@ -5,26 +5,21 @@ #include #include -uniform sampler2D texture_sampler; - uniform FragInfo { - float texture_sampler_y_coord_scale; - float has_vertex_color; + float src_y_coord_scale; float alpha; } frag_info; -in vec2 v_texture_coords; -in vec4 v_color; +uniform sampler2D texture_sampler_src; + +in vec2 v_src_texture_coords; +in vec4 v_dst_color; // This color input is expected to be unpremultiplied. out vec4 frag_color; void main() { - vec4 sampled = IPSample(texture_sampler, v_texture_coords, - frag_info.texture_sampler_y_coord_scale); - if (frag_info.has_vertex_color == 1.0) { - frag_color = sampled.aaaa * v_color * frag_info.alpha; - } else { - frag_color = sampled * frag_info.alpha; - } + vec4 sampled = IPSample(texture_sampler_src, v_src_texture_coords, + frag_info.src_y_coord_scale); + frag_color = sampled * v_dst_color * frag_info.alpha; } diff --git a/impeller/entity/shaders/atlas_fill.vert b/impeller/entity/shaders/atlas_fill.vert index 6140ad98788a4..53bb320bb05bb 100644 --- a/impeller/entity/shaders/atlas_fill.vert +++ b/impeller/entity/shaders/atlas_fill.vert @@ -4,20 +4,20 @@ #include -uniform VertInfo { +uniform FrameInfo { mat4 mvp; } -vert_info; +frame_info; -in vec2 position; -in vec2 texture_coords; -in vec4 color; +in vec2 vertices; +in vec4 dst_color; +in vec2 src_texture_coords; -out vec2 v_texture_coords; -out vec4 v_color; +out vec2 v_src_texture_coords; +out vec4 v_dst_color; void main() { - gl_Position = vert_info.mvp * vec4(position, 0.0, 1.0); - v_texture_coords = texture_coords; - v_color = color; + gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0); + v_src_texture_coords = src_texture_coords; + v_dst_color = dst_color; } diff --git a/impeller/entity/shaders/blending/advanced_blend.glsl b/impeller/entity/shaders/blending/advanced_blend.glsl index 4fd47b059c0c8..c63f7ce541abb 100644 --- a/impeller/entity/shaders/blending/advanced_blend.glsl +++ b/impeller/entity/shaders/blending/advanced_blend.glsl @@ -46,5 +46,4 @@ void main() { vec4 blended = vec4(Blend(dst.rgb, src.rgb), 1) * dst.a; frag_color = mix(dst_sample, blended, src.a); - // frag_color = dst_sample; } From 56bf47dc442b9b601370e4c34501dd5133a76475 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 10 Jan 2023 19:12:42 -0800 Subject: [PATCH 02/26] ++ --- impeller/entity/BUILD.gn | 2 - impeller/entity/contents/atlas_contents.cc | 138 ++++++++++++++++++-- impeller/entity/contents/atlas_contents.h | 8 ++ impeller/entity/contents/content_context.cc | 1 - impeller/entity/contents/content_context.h | 10 -- impeller/entity/shaders/atlas_fill.frag | 25 ---- impeller/entity/shaders/atlas_fill.vert | 23 ---- 7 files changed, 134 insertions(+), 73 deletions(-) delete mode 100644 impeller/entity/shaders/atlas_fill.frag delete mode 100644 impeller/entity/shaders/atlas_fill.vert diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 1a4649446147c..3b1baad05a4b4 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -8,8 +8,6 @@ impeller_shaders("entity_shaders") { name = "entity" shaders = [ - "shaders/atlas_fill.frag", - "shaders/atlas_fill.vert", "shaders/blending/advanced_blend.vert", "shaders/blending/advanced_blend_color.frag", "shaders/blending/advanced_blend_colorburn.frag", diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 29582aaad09f9..bc0d8cd784846 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -9,11 +9,11 @@ #include "impeller/renderer/sampler_library.h" #include "impeller/renderer/vertex_buffer_builder.h" -#include "impeller/entity/atlas_fill.frag.h" -#include "impeller/entity/atlas_fill.vert.h" #include "impeller/entity/contents/atlas_contents.h" #include "impeller/entity/contents/content_context.h" #include "impeller/entity/entity.h" +#include "impeller/entity/texture_fill.frag.h" +#include "impeller/entity/texture_fill.vert.h" #include "impeller/renderer/render_pass.h" namespace impeller { @@ -47,7 +47,6 @@ void AtlasContents::SetAlpha(Scalar alpha) { } void AtlasContents::SetBlendMode(BlendMode blend_mode) { - // TODO(jonahwilliams): blending of colors with texture. blend_mode_ = blend_mode; } @@ -81,12 +80,19 @@ const SamplerDescriptor& AtlasContents::GetSamplerDescriptor() const { bool AtlasContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - if (texture_ == nullptr) { + if (texture_ == nullptr || blend_mode_ == BlendMode::kClear) { return true; } - using VS = AtlasFillVertexShader; - using FS = AtlasFillFragmentShader; + if (blend_mode_ == BlendMode::kSource || colors_.size() == 0) { + return RenderNoColor(renderer, entity, pass); + } + if (blend_mode_ == BlendMode::kDestination) { + return RenderOnlyColor(renderer, entity, pass); + } + + using VS = AtlasBlendSrcOverPipeline::VertexShader; + using FS = AtlasBlendSrcOverPipeline::FragmentShader; const auto texture_size = texture_->GetSize(); if (texture_size.IsEmpty()) { @@ -101,7 +107,7 @@ bool AtlasContents::Render(const ContentContext& renderer, for (size_t i = 0; i < texture_coords_.size(); i++) { auto sample_rect = texture_coords_[i]; auto matrix = transforms_[i]; - auto color = colors_.size() > 0 ? colors_[i] : Color::Black(); + auto color = colors_[i]; auto transformed_points = Rect::MakeSize(sample_rect.size).GetTransformedPoints(matrix); @@ -135,11 +141,10 @@ bool AtlasContents::Render(const ContentContext& renderer, cmd.label = "DrawAtlas"; switch (blend_mode_) { case BlendMode::kClear: - return true; case BlendMode::kSource: - // Color only, just use vertices. case BlendMode::kDestination: - // Image only, same as no color. + // All handled above. + return true; case BlendMode::kSourceOver: cmd.pipeline = renderer.GetAtlasBlendSrcOverPipeline( OptionsFromPassAndEntity(pass, entity)); @@ -254,9 +259,118 @@ bool AtlasContents::Render(const ContentContext& renderer, cmd, texture_, renderer.GetContext()->GetSamplerLibrary()->GetSampler( sampler_descriptor_)); - pass.AddCommand(std::move(cmd)); + return pass.AddCommand(std::move(cmd)); +} + +bool AtlasContents::RenderOnlyColor(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + using VS = GeometryColorPipeline::VertexShader; + ; + + const auto texture_size = texture_->GetSize(); + if (texture_size.IsEmpty()) { + return true; + } + + VertexBufferBuilder vertex_builder; + vertex_builder.Reserve(texture_coords_.size() * 6); + constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3}; + for (size_t i = 0; i < texture_coords_.size(); i++) { + auto sample_rect = texture_coords_[i]; + auto matrix = transforms_[i]; + auto transformed_points = + Rect::MakeSize(sample_rect.size).GetTransformedPoints(matrix); + + for (size_t j = 0; j < 6; j++) { + VS::PerVertexData data; + data.position = transformed_points[indices[j]]; + data.color = colors_[i].Premultiply(); + vertex_builder.AppendVertex(data); + } + } + + if (!vertex_builder.HasVertices()) { + return true; + } + + Command cmd; + cmd.label = "DrawAtlas"; + + auto& host_buffer = pass.GetTransientsBuffer(); + + VS::VertInfo vert_info; + vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(); + + cmd.pipeline = + renderer.GetGeometryColorPipeline(OptionsFromPassAndEntity(pass, entity)); + cmd.stencil_reference = entity.GetStencilDepth(); + cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); + VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); + return pass.AddCommand(std::move(cmd)); +} + +bool AtlasContents::RenderNoColor(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + using VS = TextureFillVertexShader; + using FS = TextureFillFragmentShader; - return true; + const auto texture_size = texture_->GetSize(); + if (texture_size.IsEmpty()) { + return true; + } + + VertexBufferBuilder vertex_builder; + vertex_builder.Reserve(texture_coords_.size() * 6); + constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3}; + constexpr Scalar width[6] = {0, 1, 0, 1, 0, 1}; + constexpr Scalar height[6] = {0, 0, 1, 0, 1, 1}; + for (size_t i = 0; i < texture_coords_.size(); i++) { + auto sample_rect = texture_coords_[i]; + auto matrix = transforms_[i]; + auto transformed_points = + Rect::MakeSize(sample_rect.size).GetTransformedPoints(matrix); + + for (size_t j = 0; j < 6; j++) { + VS::PerVertexData data; + data.position = transformed_points[indices[j]]; + data.texture_coords = + (sample_rect.origin + Point(sample_rect.size.width * width[j], + sample_rect.size.height * height[j])) / + texture_size; + vertex_builder.AppendVertex(data); + } + } + + if (!vertex_builder.HasVertices()) { + return true; + } + + Command cmd; + cmd.label = "DrawAtlas"; + + auto& host_buffer = pass.GetTransientsBuffer(); + + VS::VertInfo vert_info; + vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(); + + FS::FragInfo frag_info; + frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale(); + frag_info.alpha = alpha_; + + cmd.pipeline = + renderer.GetTexturePipeline(OptionsFromPassAndEntity(pass, entity)); + cmd.stencil_reference = entity.GetStencilDepth(); + cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); + VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); + FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); + FS::BindTextureSampler(cmd, texture_, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + sampler_descriptor_)); + return pass.AddCommand(std::move(cmd)); } } // namespace impeller diff --git a/impeller/entity/contents/atlas_contents.h b/impeller/entity/contents/atlas_contents.h index 7b879892da2a1..0c4a40f97ea39 100644 --- a/impeller/entity/contents/atlas_contents.h +++ b/impeller/entity/contents/atlas_contents.h @@ -50,6 +50,14 @@ class AtlasContents final : public Contents { RenderPass& pass) const override; private: + bool RenderNoColor(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const; + + bool RenderOnlyColor(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const; + std::shared_ptr texture_; std::vector texture_coords_; std::vector colors_; diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index 8e889602bee7a..d40caa826b5bb 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -225,7 +225,6 @@ ContentContext::ContentContext(std::shared_ptr context) CreateDefaultPipeline(*context_); geometry_position_pipelines_[{}] = CreateDefaultPipeline(*context_); - atlas_pipelines_[{}] = CreateDefaultPipeline(*context_); yuv_to_rgb_filter_pipelines_[{}] = CreateDefaultPipeline(*context_); diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index e6e3dd01301c2..7110689d26d60 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -56,8 +56,6 @@ #include "impeller/entity/atlas_blend_src_over.frag.h" #include "impeller/entity/atlas_blend_xor.frag.h" -#include "impeller/entity/atlas_fill.frag.h" -#include "impeller/entity/atlas_fill.vert.h" #include "impeller/entity/blend.frag.h" #include "impeller/entity/blend.vert.h" #include "impeller/entity/border_mask_blur.frag.h" @@ -195,8 +193,6 @@ using GlyphAtlasPipeline = RenderPipelineT; using GlyphAtlasSdfPipeline = RenderPipelineT; -using AtlasPipeline = - RenderPipelineT; // Instead of requiring new shaders for clips, the solid fill stages are used // to redirect writing to the stencil instead of color attachments. using ClipPipeline = @@ -433,11 +429,6 @@ class ContentContext { return GetPipeline(geometry_position_pipelines_, opts); } - std::shared_ptr> GetAtlasPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_pipelines_, opts); - } - std::shared_ptr> GetYUVToRGBFilterPipeline( ContentContextOptions opts) const { return GetPipeline(yuv_to_rgb_filter_pipelines_, opts); @@ -694,7 +685,6 @@ class ContentContext { mutable Variants clip_pipelines_; mutable Variants glyph_atlas_pipelines_; mutable Variants glyph_atlas_sdf_pipelines_; - mutable Variants atlas_pipelines_; mutable Variants geometry_position_pipelines_; mutable Variants geometry_color_pipelines_; mutable Variants yuv_to_rgb_filter_pipelines_; diff --git a/impeller/entity/shaders/atlas_fill.frag b/impeller/entity/shaders/atlas_fill.frag deleted file mode 100644 index ab841efa56fff..0000000000000 --- a/impeller/entity/shaders/atlas_fill.frag +++ /dev/null @@ -1,25 +0,0 @@ -// 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 - -uniform FragInfo { - float src_y_coord_scale; - float alpha; -} -frag_info; - -uniform sampler2D texture_sampler_src; - -in vec2 v_src_texture_coords; -in vec4 v_dst_color; // This color input is expected to be unpremultiplied. - -out vec4 frag_color; - -void main() { - vec4 sampled = IPSample(texture_sampler_src, v_src_texture_coords, - frag_info.src_y_coord_scale); - frag_color = sampled * v_dst_color * frag_info.alpha; -} diff --git a/impeller/entity/shaders/atlas_fill.vert b/impeller/entity/shaders/atlas_fill.vert deleted file mode 100644 index 53bb320bb05bb..0000000000000 --- a/impeller/entity/shaders/atlas_fill.vert +++ /dev/null @@ -1,23 +0,0 @@ -// 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 FrameInfo { - mat4 mvp; -} -frame_info; - -in vec2 vertices; -in vec4 dst_color; -in vec2 src_texture_coords; - -out vec2 v_src_texture_coords; -out vec4 v_dst_color; - -void main() { - gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0); - v_src_texture_coords = src_texture_coords; - v_dst_color = dst_color; -} From 683e3064eb04dd571bdd3da3b18185cef73be8b0 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 11 Jan 2023 11:57:54 -0800 Subject: [PATCH 03/26] add drawVertices uage --- impeller/aiks/canvas.cc | 32 +-- .../display_list_vertices_geometry.cc | 78 ++++++- .../display_list_vertices_geometry.h | 4 +- impeller/entity/contents/atlas_contents.cc | 1 - impeller/entity/contents/vertices_contents.cc | 218 +++++++++++++++--- impeller/entity/contents/vertices_contents.h | 7 + impeller/entity/geometry.h | 4 +- impeller/entity/shaders/vertices.frag | 7 +- 8 files changed, 281 insertions(+), 70 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 835748d0110d7..2364aa7b2eafa 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -380,26 +380,32 @@ void Canvas::DrawTextFrame(const TextFrame& text_frame, void Canvas::DrawVertices(std::unique_ptr vertices, BlendMode blend_mode, Paint paint) { + auto has_colors = vertices->GetVertexType() == GeometryVertexType::kColor; + auto rect = vertices->GetCoverage(GetCurrentTransformation()); + if ((has_colors && blend_mode == BlendMode::kClear) || !rect.has_value()) { + return; + } + Entity entity; entity.SetTransformation(GetCurrentTransformation()); entity.SetStencilDepth(GetStencilDepth()); entity.SetBlendMode(paint.blend_mode); - if (paint.color_source.has_value()) { - auto& source = paint.color_source.value(); - auto contents = source(); - contents->SetGeometry(std::move(vertices)); - contents->SetAlpha(paint.color.alpha); - entity.SetContents(paint.WithFilters(std::move(contents), true)); - } else { - std::shared_ptr contents = - std::make_shared(); - contents->SetColor(paint.color); - contents->SetBlendMode(blend_mode); - contents->SetGeometry(std::move(vertices)); - entity.SetContents(paint.WithFilters(std::move(contents), true)); + if (!has_colors || blend_mode == BlendMode::kSource) { + entity.SetContents(paint.WithFilters( + paint.CreateContentsForGeometry(std::move(vertices)))); + GetCurrentPass().AddEntity(entity); + return; } + auto contents = std::make_shared(); + contents->SetSrcContents(paint.CreateContentsForGeometry( + Geometry::MakeRect(rect.value()))); + contents->SetColor(paint.color); + contents->SetBlendMode(blend_mode); + contents->SetGeometry(std::move(vertices)); + entity.SetContents(paint.WithFilters(contents)); + GetCurrentPass().AddEntity(entity); } diff --git a/impeller/display_list/display_list_vertices_geometry.cc b/impeller/display_list/display_list_vertices_geometry.cc index 1cab24c1fb861..f9ba4f281fb2e 100644 --- a/impeller/display_list/display_list_vertices_geometry.cc +++ b/impeller/display_list/display_list_vertices_geometry.cc @@ -154,9 +154,7 @@ GeometryResult DLVerticesGeometry::GetPositionBuffer( GeometryResult DLVerticesGeometry::GetPositionColorBuffer( const ContentContext& renderer, const Entity& entity, - RenderPass& pass, - Color paint_color, - BlendMode blend_mode) { + RenderPass& pass) { using VS = GeometryColorPipeline::VertexShader; auto index_count = normalized_indices_.size() == 0 @@ -173,13 +171,12 @@ GeometryResult DLVerticesGeometry::GetPositionColorBuffer( { for (auto i = 0; i < vertex_count; i++) { auto dl_color = dl_colors[i]; - auto pre_color = Color(dl_color.getRedF(), dl_color.getGreenF(), - dl_color.getBlueF(), dl_color.getAlphaF()); - auto color = Color::BlendColor(paint_color, pre_color, blend_mode); + auto color = Color(dl_color.getRedF(), dl_color.getGreenF(), + dl_color.getBlueF(), dl_color.getAlphaF()); auto sk_point = dl_vertices[i]; vertex_data[i] = { .position = Point(sk_point.x(), sk_point.y()), - .color = color, + .color = color.Premultiply(), }; } } @@ -226,10 +223,69 @@ GeometryResult DLVerticesGeometry::GetPositionUVBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) { - // TODO(jonahwilliams): support texture coordinates in vertices - // https://github.com/flutter/flutter/issues/109956 - return {}; -} + using VS = AtlasBlendSrcOverPipeline::VertexShader; + + auto index_count = normalized_indices_.size() == 0 + ? vertices_->index_count() + : normalized_indices_.size(); + auto vertex_count = vertices_->vertex_count(); + auto* dl_indices = normalized_indices_.size() == 0 + ? vertices_->indices() + : normalized_indices_.data(); + auto* dl_vertices = vertices_->vertices(); + auto* dl_colors = vertices_->colors(); + + auto coverage = ToRect(vertices_->bounds()); + std::vector vertex_data(vertex_count); + for (auto i = 0; i < vertex_count; i++) { + auto dl_color = dl_colors[i]; + auto color = Color(dl_color.getRedF(), dl_color.getGreenF(), + dl_color.getBlueF(), dl_color.getAlphaF()); + auto sk_point = dl_vertices[i]; + vertex_data[i] = { + .vertices = Point(sk_point.x(), sk_point.y()), + .dst_color = color, + .src_texture_coords = Point(sk_point.x(), sk_point.y()) / coverage.size, + }; + } + + size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData); + size_t total_idx_bytes = index_count * sizeof(uint16_t); + + DeviceBufferDescriptor buffer_desc; + buffer_desc.size = total_vtx_bytes + total_idx_bytes; + buffer_desc.storage_mode = StorageMode::kHostVisible; + + auto buffer = + renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); + + if (!buffer->CopyHostBuffer(reinterpret_cast(vertex_data.data()), + Range{0, total_vtx_bytes}, 0)) { + return {}; + } + if (!buffer->CopyHostBuffer( + reinterpret_cast(const_cast(dl_indices)), + Range{0, total_idx_bytes}, total_vtx_bytes)) { + return {}; + } + + return GeometryResult{ + .type = GetPrimitiveType(vertices_), + .vertex_buffer = + { + .vertex_buffer = {.buffer = buffer, + .range = Range{0, total_vtx_bytes}}, + .index_buffer = {.buffer = buffer, + .range = + Range{total_vtx_bytes, total_idx_bytes}}, + .index_count = index_count, + .index_type = IndexType::k16bit, + }, + .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(), + .prevent_overdraw = false, + }; +} // namespace impeller GeometryVertexType DLVerticesGeometry::GetVertexType() const { auto* dl_colors = vertices_->colors(); diff --git a/impeller/display_list/display_list_vertices_geometry.h b/impeller/display_list/display_list_vertices_geometry.h index 510f496a30110..828d39ba85e13 100644 --- a/impeller/display_list/display_list_vertices_geometry.h +++ b/impeller/display_list/display_list_vertices_geometry.h @@ -29,9 +29,7 @@ class DLVerticesGeometry : public VerticesGeometry { // |VerticesGeometry| GeometryResult GetPositionColorBuffer(const ContentContext& renderer, const Entity& entity, - RenderPass& pass, - Color paint_color, - BlendMode blend_mode) override; + RenderPass& pass) override; // |VerticesGeometry| GeometryResult GetPositionUVBuffer(const ContentContext& renderer, diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index bc0d8cd784846..6e2b97f070aa0 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -266,7 +266,6 @@ bool AtlasContents::RenderOnlyColor(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { using VS = GeometryColorPipeline::VertexShader; - ; const auto texture_size = texture_->GetSize(); if (texture_size.IsEmpty()) { diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 3d0357ed9ae12..f6df95d5aa56e 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -30,62 +30,204 @@ void VerticesContents::SetGeometry(std::unique_ptr geometry) { } void VerticesContents::SetColor(Color color) { - color_ = color.Premultiply(); + color_ = color; } void VerticesContents::SetBlendMode(BlendMode blend_mode) { blend_mode_ = blend_mode; } +void VerticesContents::SetSrcContents(std::shared_ptr src_contents) { + src_contents_ = std::move(src_contents); +} + bool VerticesContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { + if (blend_mode_ == BlendMode::kDestination) { + return RenderDestination(renderer, entity, pass); + } + + using VS = AtlasBlendSrcOverPipeline::VertexShader; + using FS = AtlasBlendSrcOverPipeline::FragmentShader; + auto& host_buffer = pass.GetTransientsBuffer(); - auto vertex_type = geometry_->GetVertexType(); Command cmd; cmd.label = "Vertices"; cmd.stencil_reference = entity.GetStencilDepth(); auto opts = OptionsFromPassAndEntity(pass, entity); - - switch (vertex_type) { - case GeometryVertexType::kColor: { - using VS = GeometryColorPipeline::VertexShader; - - auto geometry_result = geometry_->GetPositionColorBuffer( - renderer, entity, pass, color_, blend_mode_); - opts.primitive_type = geometry_result.type; - cmd.pipeline = renderer.GetGeometryColorPipeline(opts); - cmd.BindVertices(geometry_result.vertex_buffer); - - VS::VertInfo vert_info; - vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * - entity.GetTransformation(); - VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); - break; - } - case GeometryVertexType::kUV: - case GeometryVertexType::kPosition: { - using VS = GeometryPositionPipeline::VertexShader; - - auto geometry_result = - geometry_->GetPositionBuffer(renderer, entity, pass); - opts.primitive_type = geometry_result.type; - cmd.pipeline = renderer.GetGeometryPositionPipeline(opts); - cmd.BindVertices(geometry_result.vertex_buffer); - - VS::VertInfo vert_info; - vert_info.mvp = geometry_result.transform; - vert_info.color = color_.Premultiply(); - VS::BindVertInfo(cmd, - pass.GetTransientsBuffer().EmplaceUniform(vert_info)); - break; - } + auto geometry_result = geometry_->GetPositionUVBuffer(renderer, entity, pass); + cmd.BindVertices(geometry_result.vertex_buffer); + opts.primitive_type = geometry_result.type; + + switch (blend_mode_) { + case BlendMode::kClear: + case BlendMode::kSource: + case BlendMode::kDestination: + // All handled above. + return true; + case BlendMode::kSourceOver: + cmd.pipeline = renderer.GetAtlasBlendSrcOverPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDestinationOver: + cmd.pipeline = renderer.GetAtlasBlendDstOverPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSourceIn: + cmd.pipeline = renderer.GetAtlasBlendSrcInPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDestinationIn: + cmd.pipeline = renderer.GetAtlasBlendDstInPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSourceOut: + cmd.pipeline = renderer.GetAtlasBlendSrcOutPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDestinationOut: + cmd.pipeline = renderer.GetAtlasBlendDstOutPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSourceATop: + cmd.pipeline = renderer.GetAtlasBlendSrcATopPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDestinationATop: + cmd.pipeline = renderer.GetAtlasBlendDstATopPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kXor: + cmd.pipeline = renderer.GetAtlasBlendXorPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kPlus: + cmd.pipeline = renderer.GetAtlasBlendPlusPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kModulate: + cmd.pipeline = renderer.GetAtlasBlendModulatePipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + // Advanced + case BlendMode::kScreen: + cmd.pipeline = renderer.GetAtlasBlendScreenPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kOverlay: + cmd.pipeline = renderer.GetAtlasBlendOverlayPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDarken: + cmd.pipeline = renderer.GetAtlasBlendDarkenPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kLighten: + cmd.pipeline = renderer.GetAtlasBlendLightenPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kColorDodge: + cmd.pipeline = renderer.GetAtlasBlendColorDodgePipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kColorBurn: + cmd.pipeline = renderer.GetAtlasBlendColorBurnPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kHardLight: + cmd.pipeline = renderer.GetAtlasBlendHardLightPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSoftLight: + cmd.pipeline = renderer.GetAtlasBlendSoftLightPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kDifference: + cmd.pipeline = renderer.GetAtlasBlendDifferencePipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kExclusion: + cmd.pipeline = renderer.GetAtlasBlendExclusionPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kMultiply: + cmd.pipeline = renderer.GetAtlasBlendMultiplyPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kHue: + cmd.pipeline = renderer.GetAtlasBlendHuePipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kSaturation: + cmd.pipeline = renderer.GetAtlasBlendSaturationPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kColor: + cmd.pipeline = renderer.GetAtlasBlendColorPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; + case BlendMode::kLuminosity: + cmd.pipeline = renderer.GetAtlasBlendLuminosityPipeline( + OptionsFromPassAndEntity(pass, entity)); + break; } - pass.AddCommand(std::move(cmd)); + auto src_texture = src_contents_->RenderToSnapshot(renderer, entity); + if (!src_texture.has_value()) { + return false; + } + + VS::FrameInfo frame_info; + frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(); + + FS::FragInfo frag_info; + frag_info.src_y_coord_scale = src_texture->texture->GetYCoordScale(); + frag_info.alpha = color_.alpha; + + cmd.stencil_reference = entity.GetStencilDepth(); + cmd.BindVertices(geometry_result.vertex_buffer); + VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); + FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); + FS::BindTextureSamplerSrc( + cmd, src_texture.value().texture, + renderer.GetContext()->GetSamplerLibrary()->GetSampler({})); + + return pass.AddCommand(std::move(cmd)); +} + +bool VerticesContents::RenderDestination(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + using VS = GeometryColorPipeline::VertexShader; + using FS = GeometryColorPipeline::FragmentShader; + + auto& host_buffer = pass.GetTransientsBuffer(); + + Command cmd; + cmd.label = "Vertices"; + cmd.stencil_reference = entity.GetStencilDepth(); + + auto opts = OptionsFromPassAndEntity(pass, entity); + + auto geometry_result = geometry_->GetPositionColorBuffer( + renderer, entity, pass); + opts.primitive_type = geometry_result.type; + cmd.pipeline = renderer.GetGeometryColorPipeline(opts); + cmd.BindVertices(geometry_result.vertex_buffer); + + VS::VertInfo vert_info; + vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(); + VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); + + FS::FragInfo frag_info; + frag_info.alpha = color_.alpha; + FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); - return true; + return pass.AddCommand(std::move(cmd)); } } // namespace impeller diff --git a/impeller/entity/contents/vertices_contents.h b/impeller/entity/contents/vertices_contents.h index 0f754c4c8ea25..df498470e938b 100644 --- a/impeller/entity/contents/vertices_contents.h +++ b/impeller/entity/contents/vertices_contents.h @@ -31,6 +31,8 @@ class VerticesContents final : public Contents { void SetBlendMode(BlendMode blend_mode); + void SetSrcContents(std::shared_ptr src_contents); + // |Contents| std::optional GetCoverage(const Entity& entity) const override; @@ -40,7 +42,12 @@ class VerticesContents final : public Contents { RenderPass& pass) const override; public: + bool RenderDestination(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const; + Color color_; + std::shared_ptr src_contents_; std::unique_ptr geometry_; BlendMode blend_mode_ = BlendMode::kSource; diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index dabab1d1dc42a..bd51bd2bfc495 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -75,9 +75,7 @@ class VerticesGeometry : public Geometry { public: virtual GeometryResult GetPositionColorBuffer(const ContentContext& renderer, const Entity& entity, - RenderPass& pass, - Color paint_color, - BlendMode blend_mode) = 0; + RenderPass& pass) = 0; virtual GeometryResult GetPositionUVBuffer(const ContentContext& renderer, const Entity& entity, diff --git a/impeller/entity/shaders/vertices.frag b/impeller/entity/shaders/vertices.frag index c42e809ecc14d..029d33da06ba9 100644 --- a/impeller/entity/shaders/vertices.frag +++ b/impeller/entity/shaders/vertices.frag @@ -4,10 +4,15 @@ #include +uniform FragInfo { + float alpha; +} +frag_info; + in vec4 v_color; out vec4 frag_color; void main() { - frag_color = v_color; + frag_color = v_color * frag_info.alpha; } From 8a1caa1f90ac9f8aa6e3d831c6423f12e7e6f21d Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 11 Jan 2023 11:58:23 -0800 Subject: [PATCH 04/26] ++ --- impeller/aiks/canvas.cc | 4 ++-- impeller/entity/contents/vertices_contents.cc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 2364aa7b2eafa..29eacd13c37e7 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -399,8 +399,8 @@ void Canvas::DrawVertices(std::unique_ptr vertices, } auto contents = std::make_shared(); - contents->SetSrcContents(paint.CreateContentsForGeometry( - Geometry::MakeRect(rect.value()))); + contents->SetSrcContents( + paint.CreateContentsForGeometry(Geometry::MakeRect(rect.value()))); contents->SetColor(paint.color); contents->SetBlendMode(blend_mode); contents->SetGeometry(std::move(vertices)); diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index f6df95d5aa56e..932548977554c 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -212,8 +212,8 @@ bool VerticesContents::RenderDestination(const ContentContext& renderer, auto opts = OptionsFromPassAndEntity(pass, entity); - auto geometry_result = geometry_->GetPositionColorBuffer( - renderer, entity, pass); + auto geometry_result = + geometry_->GetPositionColorBuffer(renderer, entity, pass); opts.primitive_type = geometry_result.type; cmd.pipeline = renderer.GetGeometryColorPipeline(opts); cmd.BindVertices(geometry_result.vertex_buffer); From 1a00d10a25a3a9a9ebc9257eb3121cf31cad933c Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 11 Jan 2023 12:39:11 -0800 Subject: [PATCH 05/26] test fixes --- impeller/aiks/canvas.cc | 5 +- .../display_list/display_list_unittests.cc | 100 ++++++++++++++++++ .../display_list_vertices_geometry.cc | 8 +- impeller/entity/contents/vertices_contents.cc | 6 +- 4 files changed, 109 insertions(+), 10 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 29eacd13c37e7..6e4ae06e979be 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -397,10 +397,9 @@ void Canvas::DrawVertices(std::unique_ptr vertices, GetCurrentPass().AddEntity(entity); return; } - auto contents = std::make_shared(); - contents->SetSrcContents( - paint.CreateContentsForGeometry(Geometry::MakeRect(rect.value()))); + contents->SetSrcContents(paint.CreateContentsForGeometry( + Geometry::MakeRect(Rect::MakeSize(rect.value().size)))); contents->SetColor(paint.color); contents->SetBlendMode(blend_mode); contents->SetGeometry(std::move(vertices)); diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc index 3ce405483022a..cd8980b7a25c4 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -34,6 +34,15 @@ namespace impeller { namespace testing { +flutter::DlColor toColor(const float* components) { + auto value = (((std::lround(components[3] * 255) & 0xff) << 24) | + ((std::lround(components[0] * 255) & 0xff) << 16) | + ((std::lround(components[1] * 255) & 0xff) << 8) | + ((std::lround(components[2] * 255) & 0xff) << 0)) & + 0xFFFFFFFF; + return flutter::DlColor(value); +} + using DisplayListTest = DisplayListPlayground; INSTANTIATE_PLAYGROUND_SUITE(DisplayListTest); @@ -1159,6 +1168,97 @@ TEST_P(DisplayListTest, DrawShapes) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +TEST_P(DisplayListTest, DrawVerticesBlendModes) { + std::vector blend_mode_names; + std::vector blend_mode_values; + { + const std::vector> blends = { + // Pipeline blends (Porter-Duff alpha compositing) + {"Clear", flutter::DlBlendMode::kClear}, + {"Source", flutter::DlBlendMode::kSrc}, + {"Destination", flutter::DlBlendMode::kDst}, + {"SourceOver", flutter::DlBlendMode::kSrcOver}, + {"DestinationOver", flutter::DlBlendMode::kDstOver}, + {"SourceIn", flutter::DlBlendMode::kSrcIn}, + {"DestinationIn", flutter::DlBlendMode::kDstIn}, + {"SourceOut", flutter::DlBlendMode::kSrcOut}, + {"DestinationOut", flutter::DlBlendMode::kDstOut}, + {"SourceATop", flutter::DlBlendMode::kSrcATop}, + {"DestinationATop", flutter::DlBlendMode::kDstATop}, + {"Xor", flutter::DlBlendMode::kXor}, + {"Plus", flutter::DlBlendMode::kPlus}, + {"Modulate", flutter::DlBlendMode::kModulate}, + // Advanced blends (color component blends) + {"Screen", flutter::DlBlendMode::kScreen}, + {"Overlay", flutter::DlBlendMode::kOverlay}, + {"Darken", flutter::DlBlendMode::kDarken}, + {"Lighten", flutter::DlBlendMode::kLighten}, + {"ColorDodge", flutter::DlBlendMode::kColorDodge}, + {"ColorBurn", flutter::DlBlendMode::kColorBurn}, + {"HardLight", flutter::DlBlendMode::kHardLight}, + {"SoftLight", flutter::DlBlendMode::kSoftLight}, + {"Difference", flutter::DlBlendMode::kDifference}, + {"Exclusion", flutter::DlBlendMode::kExclusion}, + {"Multiply", flutter::DlBlendMode::kMultiply}, + {"Hue", flutter::DlBlendMode::kHue}, + {"Saturation", flutter::DlBlendMode::kSaturation}, + {"Color", flutter::DlBlendMode::kColor}, + {"Luminosity", flutter::DlBlendMode::kLuminosity}, + }; + assert(blends.size() == + static_cast(flutter::DlBlendMode::kLastMode) + 1); + for (const auto& [name, mode] : blends) { + blend_mode_names.push_back(name); + blend_mode_values.push_back(mode); + } + } + + auto callback = [&]() { + static int current_blend_index = 3; + static float dst_alpha = 1; + static float src_alpha = 1; + static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f}; + static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f}; + static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f}; + static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + + ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize); + { + ImGui::ListBox("Blending mode", ¤t_blend_index, + blend_mode_names.data(), blend_mode_names.size()); + ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1); + ImGui::ColorEdit4("Color A", color0); + ImGui::ColorEdit4("Color B", color1); + ImGui::ColorEdit4("Color C", color2); + ImGui::ColorEdit4("Source Color", src_color); + ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1); + } + ImGui::End(); + + std::vector positions = {SkPoint::Make(100, 300), + SkPoint::Make(200, 100), + SkPoint::Make(300, 300)}; + std::vector colors = { + toColor(color0).modulateOpacity(dst_alpha), + toColor(color1).modulateOpacity(dst_alpha), + toColor(color2).modulateOpacity(dst_alpha)}; + + auto vertices = flutter::DlVertices::Make( + flutter::DlVertexMode::kTriangles, 3, positions.data(), + /*texture_coorindates=*/nullptr, colors.data()); + + flutter::DisplayListBuilder builder; + flutter::DlPaint paint; + + paint.setColor(toColor(src_color).modulateOpacity(src_alpha)); + builder.drawVertices(vertices, blend_mode_values[current_blend_index], + paint); + return builder.Build(); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + #ifdef IMPELLER_ENABLE_3D TEST_P(DisplayListTest, SceneColorSource) { // Load up the scene. diff --git a/impeller/display_list/display_list_vertices_geometry.cc b/impeller/display_list/display_list_vertices_geometry.cc index f9ba4f281fb2e..1961beed8c037 100644 --- a/impeller/display_list/display_list_vertices_geometry.cc +++ b/impeller/display_list/display_list_vertices_geometry.cc @@ -235,17 +235,19 @@ GeometryResult DLVerticesGeometry::GetPositionUVBuffer( auto* dl_vertices = vertices_->vertices(); auto* dl_colors = vertices_->colors(); - auto coverage = ToRect(vertices_->bounds()); + auto coverage_rect = ToRect(vertices_->bounds()); std::vector vertex_data(vertex_count); for (auto i = 0; i < vertex_count; i++) { auto dl_color = dl_colors[i]; auto color = Color(dl_color.getRedF(), dl_color.getGreenF(), dl_color.getBlueF(), dl_color.getAlphaF()); auto sk_point = dl_vertices[i]; + auto vertex = Point(sk_point.x(), sk_point.y()); + auto coverage_coords = (vertex - coverage_rect.origin) / coverage_rect.size; vertex_data[i] = { - .vertices = Point(sk_point.x(), sk_point.y()), + .vertices = vertex, .dst_color = color, - .src_texture_coords = Point(sk_point.x(), sk_point.y()) / coverage.size, + .src_texture_coords = coverage_coords / coverage_rect.size, }; } diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 932548977554c..2d8c0236d07cd 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -180,8 +180,7 @@ bool VerticesContents::Render(const ContentContext& renderer, } VS::FrameInfo frame_info; - frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * - entity.GetTransformation(); + frame_info.mvp = geometry_result.transform; FS::FragInfo frag_info; frag_info.src_y_coord_scale = src_texture->texture->GetYCoordScale(); @@ -219,8 +218,7 @@ bool VerticesContents::RenderDestination(const ContentContext& renderer, cmd.BindVertices(geometry_result.vertex_buffer); VS::VertInfo vert_info; - vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * - entity.GetTransformation(); + vert_info.mvp = geometry_result.transform; VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); FS::FragInfo frag_info; From 0c23ff48a6b0bef72d6323182bffd47c181468ae Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 11 Jan 2023 16:59:11 -0800 Subject: [PATCH 06/26] dont double divide --- impeller/display_list/display_list_vertices_geometry.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/impeller/display_list/display_list_vertices_geometry.cc b/impeller/display_list/display_list_vertices_geometry.cc index 1961beed8c037..40b08dcfd06c6 100644 --- a/impeller/display_list/display_list_vertices_geometry.cc +++ b/impeller/display_list/display_list_vertices_geometry.cc @@ -244,10 +244,11 @@ GeometryResult DLVerticesGeometry::GetPositionUVBuffer( auto sk_point = dl_vertices[i]; auto vertex = Point(sk_point.x(), sk_point.y()); auto coverage_coords = (vertex - coverage_rect.origin) / coverage_rect.size; + vertex_data[i] = { .vertices = vertex, .dst_color = color, - .src_texture_coords = coverage_coords / coverage_rect.size, + .src_texture_coords = coverage_coords, }; } From 2a27640ee026bab3e55d94da34c48151ddbfdc0f Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 11 Jan 2023 17:59:49 -0800 Subject: [PATCH 07/26] CI cleanups --- ci/licenses_golden/licenses_flutter | 62 +++++++++++++++++++++++++++-- impeller/aiks/canvas.cc | 2 +- impeller/aiks/canvas.h | 2 +- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index baecaa91972f5..18c0a9ebf2193 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1313,8 +1313,35 @@ ORIGIN: ../../../flutter/impeller/entity/geometry.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/inline_pass_context.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/inline_pass_context.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_fill.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_fill.vert + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend.glsl + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend.vert + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_color.frag + ../../../flutter/LICENSE @@ -3793,8 +3820,35 @@ FILE: ../../../flutter/impeller/entity/geometry.cc FILE: ../../../flutter/impeller/entity/geometry.h FILE: ../../../flutter/impeller/entity/inline_pass_context.cc FILE: ../../../flutter/impeller/entity/inline_pass_context.h -FILE: ../../../flutter/impeller/entity/shaders/atlas_fill.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_fill.vert +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend.glsl +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend.vert +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_color.frag diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 6e4ae06e979be..a97b2246ad2f7 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -379,7 +379,7 @@ void Canvas::DrawTextFrame(const TextFrame& text_frame, void Canvas::DrawVertices(std::unique_ptr vertices, BlendMode blend_mode, - Paint paint) { + const Paint& paint) { auto has_colors = vertices->GetVertexType() == GeometryVertexType::kColor; auto rect = vertices->GetCoverage(GetCurrentTransformation()); if ((has_colors && blend_mode == BlendMode::kClear) || !rect.has_value()) { diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index 456948b99139c..aacbe513b2e99 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -99,7 +99,7 @@ class Canvas { void DrawVertices(std::unique_ptr vertices, BlendMode blend_mode, - Paint paint); + const Paint& paint); void DrawAtlas(const std::shared_ptr& atlas, std::vector transforms, From 79c13e50cba5ecceed00fa57065db02075e8ce81 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 11 Jan 2023 20:05:10 -0800 Subject: [PATCH 08/26] some texture coordinates work --- impeller/aiks/canvas.cc | 6 ++-- .../display_list/display_list_unittests.cc | 32 +++++++++++++++++++ .../display_list_vertices_geometry.cc | 11 ++++++- impeller/entity/contents/vertices_contents.cc | 8 ++--- impeller/entity/contents/vertices_contents.h | 4 +-- 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index a97b2246ad2f7..7b00a779400db 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -398,9 +398,11 @@ void Canvas::DrawVertices(std::unique_ptr vertices, return; } auto contents = std::make_shared(); - contents->SetSrcContents(paint.CreateContentsForGeometry( + auto opaque_paint = paint; + opaque_paint.color = opaque_paint.color.WithAlpha(1.0); + contents->SetSrcContents(opaque_paint.CreateContentsForGeometry( Geometry::MakeRect(Rect::MakeSize(rect.value().size)))); - contents->SetColor(paint.color); + contents->SetAlpha(paint.color.alpha); contents->SetBlendMode(blend_mode); contents->SetGeometry(std::move(vertices)); entity.SetContents(paint.WithFilters(contents)); diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc index cd8980b7a25c4..6a8d49d0e3427 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -1111,6 +1111,38 @@ TEST_P(DisplayListTest, DrawVerticesLinearGradientWithoutIndices) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +TEST_P(DisplayListTest, DrawVerticesLinearGradientWithTextureCoordinates) { + std::vector positions = {SkPoint::Make(100, 300), + SkPoint::Make(200, 100), + SkPoint::Make(300, 300)}; + std::vector texture_coordinates = {SkPoint::Make(1.0, 1.0), + SkPoint::Make(0.0, 1.0), + SkPoint::Make(0.0, 0.0)}; + std::vector colors = {flutter::DlColor::kRed(), + flutter::DlColor::kGreen(), + flutter::DlColor::kBlue()}; + + auto vertices = flutter::DlVertices::Make( + flutter::DlVertexMode::kTriangles, 3, positions.data(), + texture_coordinates.data(), colors.data()); + + std::vector gradient_colors = {flutter::DlColor::kBlue(), + flutter::DlColor::kRed()}; + const float stops[2] = {0.0, 1.0}; + + auto linear = flutter::DlColorSource::MakeLinear( + {100.0, 100.0}, {300.0, 300.0}, 2, gradient_colors.data(), stops, + flutter::DlTileMode::kRepeat); + + flutter::DisplayListBuilder builder; + flutter::DlPaint paint; + + paint.setColorSource(linear); + builder.drawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + TEST_P(DisplayListTest, DrawVerticesSolidColorTrianglesWithIndices) { std::vector positions = { SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300), diff --git a/impeller/display_list/display_list_vertices_geometry.cc b/impeller/display_list/display_list_vertices_geometry.cc index 40b08dcfd06c6..b8fe95d9866f3 100644 --- a/impeller/display_list/display_list_vertices_geometry.cc +++ b/impeller/display_list/display_list_vertices_geometry.cc @@ -21,6 +21,10 @@ static Rect ToRect(const SkRect& rect) { return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); } +static Point ToPoint(const SkPoint& point) { + return Point::MakeXY(point.fX, point.fY); +} + // Fan mode isn't natively supported. Unroll into triangle mode by // manipulating the index array. // @@ -234,16 +238,21 @@ GeometryResult DLVerticesGeometry::GetPositionUVBuffer( : normalized_indices_.data(); auto* dl_vertices = vertices_->vertices(); auto* dl_colors = vertices_->colors(); + auto* dl_tex_coords = vertices_->texture_coordinates(); auto coverage_rect = ToRect(vertices_->bounds()); std::vector vertex_data(vertex_count); + for (auto i = 0; i < vertex_count; i++) { auto dl_color = dl_colors[i]; auto color = Color(dl_color.getRedF(), dl_color.getGreenF(), dl_color.getBlueF(), dl_color.getAlphaF()); auto sk_point = dl_vertices[i]; auto vertex = Point(sk_point.x(), sk_point.y()); - auto coverage_coords = (vertex - coverage_rect.origin) / coverage_rect.size; + auto coverage_coords = + (dl_tex_coords == nullptr) + ? (vertex - coverage_rect.origin) / coverage_rect.size + : ToPoint(dl_tex_coords[i]); vertex_data[i] = { .vertices = vertex, diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 2d8c0236d07cd..5669161e2cf31 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -29,8 +29,8 @@ void VerticesContents::SetGeometry(std::unique_ptr geometry) { geometry_ = std::move(geometry); } -void VerticesContents::SetColor(Color color) { - color_ = color; +void VerticesContents::SetAlpha(Scalar alpha) { + alpha_ = alpha; } void VerticesContents::SetBlendMode(BlendMode blend_mode) { @@ -184,7 +184,7 @@ bool VerticesContents::Render(const ContentContext& renderer, FS::FragInfo frag_info; frag_info.src_y_coord_scale = src_texture->texture->GetYCoordScale(); - frag_info.alpha = color_.alpha; + frag_info.alpha = alpha_; cmd.stencil_reference = entity.GetStencilDepth(); cmd.BindVertices(geometry_result.vertex_buffer); @@ -222,7 +222,7 @@ bool VerticesContents::RenderDestination(const ContentContext& renderer, VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); FS::FragInfo frag_info; - frag_info.alpha = color_.alpha; + frag_info.alpha = alpha_; FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); return pass.AddCommand(std::move(cmd)); diff --git a/impeller/entity/contents/vertices_contents.h b/impeller/entity/contents/vertices_contents.h index df498470e938b..175e8adc5ffa9 100644 --- a/impeller/entity/contents/vertices_contents.h +++ b/impeller/entity/contents/vertices_contents.h @@ -27,7 +27,7 @@ class VerticesContents final : public Contents { void SetGeometry(std::unique_ptr geometry); - void SetColor(Color color); + void SetAlpha(Scalar alpha); void SetBlendMode(BlendMode blend_mode); @@ -46,7 +46,7 @@ class VerticesContents final : public Contents { const Entity& entity, RenderPass& pass) const; - Color color_; + Scalar alpha_; std::shared_ptr src_contents_; std::unique_ptr geometry_; BlendMode blend_mode_ = BlendMode::kSource; From 785e18bdcb342b561545d00894d6b061a4bc66a6 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 11 Jan 2023 20:13:56 -0800 Subject: [PATCH 09/26] ++ --- impeller/display_list/display_list_unittests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc index 6a8d49d0e3427..08371f4019536 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -1127,7 +1127,7 @@ TEST_P(DisplayListTest, DrawVerticesLinearGradientWithTextureCoordinates) { texture_coordinates.data(), colors.data()); std::vector gradient_colors = {flutter::DlColor::kBlue(), - flutter::DlColor::kRed()}; + flutter::DlColor::kRed()}; const float stops[2] = {0.0, 1.0}; auto linear = flutter::DlColorSource::MakeLinear( From a3a94768ddb03c246b1c559d73ff4ca9219ff768 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 12 Jan 2023 16:35:02 -0800 Subject: [PATCH 10/26] basic texture coordiantes work --- impeller/aiks/canvas.cc | 25 ++- .../display_list_vertices_geometry.cc | 189 +++++++++--------- .../display_list_vertices_geometry.h | 11 + impeller/entity/contents/vertices_contents.cc | 52 ++++- impeller/entity/contents/vertices_contents.h | 4 + impeller/entity/geometry.h | 8 + 6 files changed, 196 insertions(+), 93 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 7b00a779400db..a00fef7e10e63 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -380,8 +380,21 @@ void Canvas::DrawTextFrame(const TextFrame& text_frame, void Canvas::DrawVertices(std::unique_ptr vertices, BlendMode blend_mode, const Paint& paint) { - auto has_colors = vertices->GetVertexType() == GeometryVertexType::kColor; + // drawVertices rendering: + // * If there are no per-vertex colors and no texture coordinates, use the + // color source and apply the vertex geometry to this. + // * If there are vertex colors or vertex colors and texture coordinates, then + // the blend_mode parameter applies: + // * The paint color, if any, is treated as fully opaque. The alpha is applied + // separately even to other paint sources. + // * If there are only texture coordinates and the paint source is not a solid + // color, then pretend this is per-vertex color with a source blend mode. + + auto has_colors = vertices->HasVertexColors(); + auto has_texture_coordinates = vertices->HasTextureCoordinates(); auto rect = vertices->GetCoverage(GetCurrentTransformation()); + + // Clear blend mode can be ignored entirely. if ((has_colors && blend_mode == BlendMode::kClear) || !rect.has_value()) { return; } @@ -391,15 +404,21 @@ void Canvas::DrawVertices(std::unique_ptr vertices, entity.SetStencilDepth(GetStencilDepth()); entity.SetBlendMode(paint.blend_mode); - if (!has_colors || blend_mode == BlendMode::kSource) { + // No vertex colors or texture coordinates, this can be treated as a regular paint + // op. + // TODO(jonahwilliams): optimization, texture coordinate + solid color contents + // should exit here too. + if (!has_texture_coordinates && (blend_mode == BlendMode::kSource || !has_colors)) { entity.SetContents(paint.WithFilters( paint.CreateContentsForGeometry(std::move(vertices)))); GetCurrentPass().AddEntity(entity); return; } - auto contents = std::make_shared(); + // The paint color, if present, should be treated as fully opaque. auto opaque_paint = paint; opaque_paint.color = opaque_paint.color.WithAlpha(1.0); + + auto contents = std::make_shared(); contents->SetSrcContents(opaque_paint.CreateContentsForGeometry( Geometry::MakeRect(Rect::MakeSize(rect.value().size)))); contents->SetAlpha(paint.color.alpha); diff --git a/impeller/display_list/display_list_vertices_geometry.cc b/impeller/display_list/display_list_vertices_geometry.cc index b8fe95d9866f3..dd73180b9ce1f 100644 --- a/impeller/display_list/display_list_vertices_geometry.cc +++ b/impeller/display_list/display_list_vertices_geometry.cc @@ -104,20 +104,21 @@ static PrimitiveType GetPrimitiveType(const flutter::DlVertices* vertices) { } } -GeometryResult DLVerticesGeometry::GetPositionBuffer( - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) { - auto index_count = normalized_indices_.size() == 0 - ? vertices_->index_count() - : normalized_indices_.size(); - auto vertex_count = vertices_->vertex_count(); - auto* dl_indices = normalized_indices_.size() == 0 - ? vertices_->indices() - : normalized_indices_.data(); - auto* dl_vertices = vertices_->vertices(); +bool DLVerticesGeometry::HasTextureCoordinates() const { + return vertices_->texture_coordinates() != nullptr; +} + +bool DLVerticesGeometry::HasVertexColors() const { + return vertices_->colors() != nullptr; +} - size_t total_vtx_bytes = vertex_count * sizeof(float) * 2; +static VertexBuffer CreateVertexBuffer(const ContentContext& renderer, + size_t vertex_count, + size_t index_count, + size_t vertex_size, + const uint8_t* vertex_data, + const uint8_t* index_data) { + size_t total_vtx_bytes = vertex_count * vertex_size; size_t total_idx_bytes = index_count * sizeof(uint16_t); DeviceBufferDescriptor buffer_desc; @@ -127,28 +128,41 @@ GeometryResult DLVerticesGeometry::GetPositionBuffer( auto buffer = renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); - if (!buffer->CopyHostBuffer(reinterpret_cast(dl_vertices), - Range{0, total_vtx_bytes}, 0)) { + if (!buffer->CopyHostBuffer(vertex_data, Range{0, total_vtx_bytes}, 0)) { return {}; } - if (!buffer->CopyHostBuffer( - reinterpret_cast(const_cast(dl_indices)), - Range{0, total_idx_bytes}, total_vtx_bytes)) { + if (!buffer->CopyHostBuffer(index_data, Range{0, total_idx_bytes}, + total_vtx_bytes)) { return {}; } + return { + .vertex_buffer = {.buffer = buffer, .range = Range{0, total_vtx_bytes}}, + .index_buffer = {.buffer = buffer, + .range = Range{total_vtx_bytes, total_idx_bytes}}, + .index_count = index_count, + .index_type = IndexType::k16bit, + }; +} + +GeometryResult DLVerticesGeometry::GetPositionBuffer( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + auto index_count = normalized_indices_.size() == 0 + ? vertices_->index_count() + : normalized_indices_.size(); + auto vertex_count = vertices_->vertex_count(); + auto* dl_indices = normalized_indices_.size() == 0 + ? vertices_->indices() + : normalized_indices_.data(); + auto* dl_vertices = vertices_->vertices(); return GeometryResult{ .type = GetPrimitiveType(vertices_), - .vertex_buffer = - { - .vertex_buffer = {.buffer = buffer, - .range = Range{0, total_vtx_bytes}}, - .index_buffer = {.buffer = buffer, - .range = - Range{total_vtx_bytes, total_idx_bytes}}, - .index_count = index_count, - .index_type = IndexType::k16bit, - }, + .vertex_buffer = CreateVertexBuffer( + renderer, vertex_count, index_count, sizeof(float) * 2, + reinterpret_cast(dl_vertices), + reinterpret_cast(dl_indices)), .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), .prevent_overdraw = false, @@ -185,45 +199,65 @@ GeometryResult DLVerticesGeometry::GetPositionColorBuffer( } } - size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData); - size_t total_idx_bytes = index_count * sizeof(uint16_t); + return GeometryResult{ + .type = GetPrimitiveType(vertices_), + .vertex_buffer = CreateVertexBuffer( + renderer, vertex_count, index_count, sizeof(VS::PerVertexData), + reinterpret_cast(vertex_data.data()), + reinterpret_cast(dl_indices)), + .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(), + .prevent_overdraw = false, + }; +} - DeviceBufferDescriptor buffer_desc; - buffer_desc.size = total_vtx_bytes + total_idx_bytes; - buffer_desc.storage_mode = StorageMode::kHostVisible; +GeometryResult DLVerticesGeometry::GetPositionUVBuffer( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + using VS = TexturePipeline::VertexShader; - auto buffer = - renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); + auto index_count = normalized_indices_.size() == 0 + ? vertices_->index_count() + : normalized_indices_.size(); + auto vertex_count = vertices_->vertex_count(); + auto* dl_indices = normalized_indices_.size() == 0 + ? vertices_->indices() + : normalized_indices_.data(); + auto* dl_vertices = vertices_->vertices(); + auto* dl_tex_coords = vertices_->texture_coordinates(); - if (!buffer->CopyHostBuffer(reinterpret_cast(vertex_data.data()), - Range{0, total_vtx_bytes}, 0)) { - return {}; - } - if (!buffer->CopyHostBuffer( - reinterpret_cast(const_cast(dl_indices)), - Range{0, total_idx_bytes}, total_vtx_bytes)) { - return {}; + auto coverage_rect = ToRect(vertices_->bounds()); + + std::vector vertex_data(vertex_count); + for (auto i = 0; i < vertex_count; i++) { + auto sk_point = dl_vertices[i]; + auto vertex = Point(sk_point.x(), sk_point.y()); + + // TODO(jonahwilliams): Instead of the coverage rect, this should use the size + // of what is being sampled, such as the image size or gradient bounds. + auto coverage_coords = ToPoint(dl_tex_coords[i]) / coverage_rect.size; + + vertex_data[i] = { + .position = vertex, + .texture_coords = coverage_coords, + }; } return GeometryResult{ .type = GetPrimitiveType(vertices_), - .vertex_buffer = - { - .vertex_buffer = {.buffer = buffer, - .range = Range{0, total_vtx_bytes}}, - .index_buffer = {.buffer = buffer, - .range = - Range{total_vtx_bytes, total_idx_bytes}}, - .index_count = index_count, - .index_type = IndexType::k16bit, - }, + .vertex_buffer = CreateVertexBuffer( + renderer, vertex_count, index_count, sizeof(VS::PerVertexData), + reinterpret_cast(vertex_data.data()), + reinterpret_cast(dl_indices)), .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), .prevent_overdraw = false, }; } -GeometryResult DLVerticesGeometry::GetPositionUVBuffer( +// This method is used even if there are no user-provided texture coordinates. +GeometryResult DLVerticesGeometry::GetPositionUVColorBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) { @@ -249,10 +283,13 @@ GeometryResult DLVerticesGeometry::GetPositionUVBuffer( dl_color.getBlueF(), dl_color.getAlphaF()); auto sk_point = dl_vertices[i]; auto vertex = Point(sk_point.x(), sk_point.y()); - auto coverage_coords = - (dl_tex_coords == nullptr) - ? (vertex - coverage_rect.origin) / coverage_rect.size - : ToPoint(dl_tex_coords[i]); + + // TODO(jonahwilliams): Instead of the coverage rect, this should use the size + // of what is being sampled, such as the image size or gradient bounds. + auto coverage_coords = (vertex - coverage_rect.origin) / coverage_rect.size; + if (dl_tex_coords != nullptr) { + coverage_coords = ToPoint(dl_tex_coords[i]) / coverage_rect.size; + } vertex_data[i] = { .vertices = vertex, @@ -261,43 +298,17 @@ GeometryResult DLVerticesGeometry::GetPositionUVBuffer( }; } - size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData); - size_t total_idx_bytes = index_count * sizeof(uint16_t); - - DeviceBufferDescriptor buffer_desc; - buffer_desc.size = total_vtx_bytes + total_idx_bytes; - buffer_desc.storage_mode = StorageMode::kHostVisible; - - auto buffer = - renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); - - if (!buffer->CopyHostBuffer(reinterpret_cast(vertex_data.data()), - Range{0, total_vtx_bytes}, 0)) { - return {}; - } - if (!buffer->CopyHostBuffer( - reinterpret_cast(const_cast(dl_indices)), - Range{0, total_idx_bytes}, total_vtx_bytes)) { - return {}; - } - return GeometryResult{ .type = GetPrimitiveType(vertices_), - .vertex_buffer = - { - .vertex_buffer = {.buffer = buffer, - .range = Range{0, total_vtx_bytes}}, - .index_buffer = {.buffer = buffer, - .range = - Range{total_vtx_bytes, total_idx_bytes}}, - .index_count = index_count, - .index_type = IndexType::k16bit, - }, + .vertex_buffer = CreateVertexBuffer( + renderer, vertex_count, index_count, sizeof(VS::PerVertexData), + reinterpret_cast(vertex_data.data()), + reinterpret_cast(dl_indices)), .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), .prevent_overdraw = false, }; -} // namespace impeller +} GeometryVertexType DLVerticesGeometry::GetVertexType() const { auto* dl_colors = vertices_->colors(); diff --git a/impeller/display_list/display_list_vertices_geometry.h b/impeller/display_list/display_list_vertices_geometry.h index 828d39ba85e13..8a56e5faf28a8 100644 --- a/impeller/display_list/display_list_vertices_geometry.h +++ b/impeller/display_list/display_list_vertices_geometry.h @@ -36,6 +36,17 @@ class DLVerticesGeometry : public VerticesGeometry { const Entity& entity, RenderPass& pass) override; + // |VerticesGeometry| + GeometryResult GetPositionUVColorBuffer(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) override; + + // |VerticesGeometry| + bool HasTextureCoordinates() const override; + + // |VerticesGeometry| + bool HasVertexColors() const override; + // |Geometry| GeometryResult GetPositionBuffer(const ContentContext& renderer, const Entity& entity, diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 5669161e2cf31..17d728aa75711 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -47,6 +47,10 @@ bool VerticesContents::Render(const ContentContext& renderer, if (blend_mode_ == BlendMode::kDestination) { return RenderDestination(renderer, entity, pass); } + if (blend_mode_ == BlendMode::kSource || + (geometry_->HasTextureCoordinates() && !geometry_->HasVertexColors())) { + return RenderSource(renderer, entity, pass); + } using VS = AtlasBlendSrcOverPipeline::VertexShader; using FS = AtlasBlendSrcOverPipeline::FragmentShader; @@ -58,7 +62,8 @@ bool VerticesContents::Render(const ContentContext& renderer, cmd.stencil_reference = entity.GetStencilDepth(); auto opts = OptionsFromPassAndEntity(pass, entity); - auto geometry_result = geometry_->GetPositionUVBuffer(renderer, entity, pass); + auto geometry_result = + geometry_->GetPositionUVColorBuffer(renderer, entity, pass); cmd.BindVertices(geometry_result.vertex_buffer); opts.primitive_type = geometry_result.type; @@ -174,6 +179,7 @@ bool VerticesContents::Render(const ContentContext& renderer, OptionsFromPassAndEntity(pass, entity)); break; } + // TODO: skip this step if we're given an image shader. auto src_texture = src_contents_->RenderToSnapshot(renderer, entity); if (!src_texture.has_value()) { return false; @@ -228,4 +234,48 @@ bool VerticesContents::RenderDestination(const ContentContext& renderer, return pass.AddCommand(std::move(cmd)); } +bool VerticesContents::RenderSource(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + using VS = TextureFillVertexShader; + using FS = TextureFillFragmentShader; + + // TODO: skip this step if we're given an image shader. + auto src_texture = src_contents_->RenderToSnapshot(renderer, entity); + if (!src_texture.has_value()) { + return false; + } + + auto& host_buffer = pass.GetTransientsBuffer(); + + Command cmd; + cmd.label = "Vertices"; + cmd.stencil_reference = entity.GetStencilDepth(); + + auto opts = OptionsFromPassAndEntity(pass, entity); + + auto geometry_result = geometry_->GetPositionUVBuffer(renderer, entity, pass); + opts.primitive_type = geometry_result.type; + cmd.pipeline = renderer.GetTexturePipeline(opts); + cmd.BindVertices(geometry_result.vertex_buffer); + + VS::VertInfo vert_info; + vert_info.mvp = geometry_result.transform; + + FS::FragInfo frag_info; + frag_info.texture_sampler_y_coord_scale = + src_texture->texture->GetYCoordScale(); + frag_info.alpha = alpha_; + + cmd.stencil_reference = entity.GetStencilDepth(); + cmd.BindVertices(geometry_result.vertex_buffer); + VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); + FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); + FS::BindTextureSampler( + cmd, src_texture.value().texture, + renderer.GetContext()->GetSamplerLibrary()->GetSampler({})); + + return pass.AddCommand(std::move(cmd)); +} + } // namespace impeller diff --git a/impeller/entity/contents/vertices_contents.h b/impeller/entity/contents/vertices_contents.h index 175e8adc5ffa9..b10c7c0b7c250 100644 --- a/impeller/entity/contents/vertices_contents.h +++ b/impeller/entity/contents/vertices_contents.h @@ -46,6 +46,10 @@ class VerticesContents final : public Contents { const Entity& entity, RenderPass& pass) const; + bool RenderSource(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const; + Scalar alpha_; std::shared_ptr src_contents_; std::unique_ptr geometry_; diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index bd51bd2bfc495..79c5db4b62f49 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -80,6 +80,14 @@ class VerticesGeometry : public Geometry { virtual GeometryResult GetPositionUVBuffer(const ContentContext& renderer, const Entity& entity, RenderPass& pass) = 0; + + virtual GeometryResult GetPositionUVColorBuffer(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) = 0; + + virtual bool HasTextureCoordinates() const; + + virtual bool HasVertexColors() const; }; /// @brief A geometry that is created from a filled path object. From ca273f4417adce0c71b1dc8f48360c50f68162b2 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 12 Jan 2023 16:35:40 -0800 Subject: [PATCH 11/26] ++ --- impeller/aiks/canvas.cc | 20 +++++++++++-------- .../display_list_vertices_geometry.cc | 8 ++++---- impeller/entity/geometry.h | 7 ++++--- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index a00fef7e10e63..8bc7fc6e3fbc6 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -383,11 +383,14 @@ void Canvas::DrawVertices(std::unique_ptr vertices, // drawVertices rendering: // * If there are no per-vertex colors and no texture coordinates, use the // color source and apply the vertex geometry to this. - // * If there are vertex colors or vertex colors and texture coordinates, then + // * If there are vertex colors or vertex colors and texture coordinates, + // then // the blend_mode parameter applies: - // * The paint color, if any, is treated as fully opaque. The alpha is applied + // * The paint color, if any, is treated as fully opaque. The alpha is + // applied // separately even to other paint sources. - // * If there are only texture coordinates and the paint source is not a solid + // * If there are only texture coordinates and the paint source is not a + // solid // color, then pretend this is per-vertex color with a source blend mode. auto has_colors = vertices->HasVertexColors(); @@ -404,11 +407,12 @@ void Canvas::DrawVertices(std::unique_ptr vertices, entity.SetStencilDepth(GetStencilDepth()); entity.SetBlendMode(paint.blend_mode); - // No vertex colors or texture coordinates, this can be treated as a regular paint - // op. - // TODO(jonahwilliams): optimization, texture coordinate + solid color contents - // should exit here too. - if (!has_texture_coordinates && (blend_mode == BlendMode::kSource || !has_colors)) { + // No vertex colors or texture coordinates, this can be treated as a regular + // paint op. + // TODO(jonahwilliams): optimization, texture coordinate + solid color + // contents should exit here too. + if (!has_texture_coordinates && + (blend_mode == BlendMode::kSource || !has_colors)) { entity.SetContents(paint.WithFilters( paint.CreateContentsForGeometry(std::move(vertices)))); GetCurrentPass().AddEntity(entity); diff --git a/impeller/display_list/display_list_vertices_geometry.cc b/impeller/display_list/display_list_vertices_geometry.cc index dd73180b9ce1f..a2c0d17206646 100644 --- a/impeller/display_list/display_list_vertices_geometry.cc +++ b/impeller/display_list/display_list_vertices_geometry.cc @@ -234,8 +234,8 @@ GeometryResult DLVerticesGeometry::GetPositionUVBuffer( auto sk_point = dl_vertices[i]; auto vertex = Point(sk_point.x(), sk_point.y()); - // TODO(jonahwilliams): Instead of the coverage rect, this should use the size - // of what is being sampled, such as the image size or gradient bounds. + // TODO(jonahwilliams): Instead of the coverage rect, this should use the + // size of what is being sampled, such as the image size or gradient bounds. auto coverage_coords = ToPoint(dl_tex_coords[i]) / coverage_rect.size; vertex_data[i] = { @@ -284,8 +284,8 @@ GeometryResult DLVerticesGeometry::GetPositionUVColorBuffer( auto sk_point = dl_vertices[i]; auto vertex = Point(sk_point.x(), sk_point.y()); - // TODO(jonahwilliams): Instead of the coverage rect, this should use the size - // of what is being sampled, such as the image size or gradient bounds. + // TODO(jonahwilliams): Instead of the coverage rect, this should use the + // size of what is being sampled, such as the image size or gradient bounds. auto coverage_coords = (vertex - coverage_rect.origin) / coverage_rect.size; if (dl_tex_coords != nullptr) { coverage_coords = ToPoint(dl_tex_coords[i]) / coverage_rect.size; diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index 79c5db4b62f49..2d68ceae00177 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -81,9 +81,10 @@ class VerticesGeometry : public Geometry { const Entity& entity, RenderPass& pass) = 0; - virtual GeometryResult GetPositionUVColorBuffer(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) = 0; + virtual GeometryResult GetPositionUVColorBuffer( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) = 0; virtual bool HasTextureCoordinates() const; From 3905cb17b3e77746cb697476bad795807d8daad5 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 12 Jan 2023 16:45:50 -0800 Subject: [PATCH 12/26] ++ --- impeller/entity/geometry.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index 2d68ceae00177..4e73f8985a766 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -86,9 +86,9 @@ class VerticesGeometry : public Geometry { const Entity& entity, RenderPass& pass) = 0; - virtual bool HasTextureCoordinates() const; + virtual bool HasTextureCoordinates() const = 0; - virtual bool HasVertexColors() const; + virtual bool HasVertexColors() const = 0; }; /// @brief A geometry that is created from a filled path object. From 426d6a19b0503baa6d0b9439f4806734f08ac2d3 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 12 Jan 2023 16:59:00 -0800 Subject: [PATCH 13/26] ++ --- impeller/entity/contents/vertices_contents.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 17d728aa75711..5b8294f6affdc 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -179,7 +179,7 @@ bool VerticesContents::Render(const ContentContext& renderer, OptionsFromPassAndEntity(pass, entity)); break; } - // TODO: skip this step if we're given an image shader. + // TODO(jonahwilliams): skip this step if we're given an image shader. auto src_texture = src_contents_->RenderToSnapshot(renderer, entity); if (!src_texture.has_value()) { return false; @@ -240,7 +240,7 @@ bool VerticesContents::RenderSource(const ContentContext& renderer, using VS = TextureFillVertexShader; using FS = TextureFillFragmentShader; - // TODO: skip this step if we're given an image shader. + // TODO(jonahwilliams): skip this step if we're given an image shader. auto src_texture = src_contents_->RenderToSnapshot(renderer, entity); if (!src_texture.has_value()) { return false; From 94e6c2429481b745540886e5735dacca4fca12f4 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 13 Jan 2023 13:37:33 -0800 Subject: [PATCH 14/26] Delete color blending --- impeller/entity/entity_unittests.cc | 232 ---------------------------- impeller/geometry/color.cc | 130 ---------------- impeller/geometry/color.h | 4 - 3 files changed, 366 deletions(-) diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 31bd009a123db..5deed280eba0e 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -1713,238 +1713,6 @@ TEST_P(EntityTest, SrgbToLinearFilter) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } -TEST_P(EntityTest, TTTBlendColor) { - { - Color src = {1, 0, 0, 0.5}; - Color dst = {1, 0, 1, 1}; - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), - Color(1, 0, 0, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), - Color(1, 0, 1, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), - Color(1.5, 0, 0.5, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), - Color(1, 0, 1, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), - Color(1, 0, 0, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), - Color(0.5, 0, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), - Color(0.5, 0, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), - Color(1.5, 0, 0.5, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), - Color(0.5, 0, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), - Color(0.5, 0, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), Color(1, 0, 1, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), - Color(1, 0, 0, 0.5)); - } - - { - Color src = {1, 1, 0, 1}; - Color dst = {1, 0, 1, 1}; - - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), - Color(1, 1, 0, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), - Color(1, 0, 1, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), - Color(1, 1, 0, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), - Color(1, 0, 1, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), - Color(1, 1, 0, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), - Color(1, 0, 1, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), - Color(1, 1, 0, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), - Color(1, 0, 1, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), Color(1, 1, 1, 1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), - Color(1, 0, 0, 1)); - } - - { - Color src = {1, 1, 0, 0.2}; - Color dst = {1, 1, 1, 0.5}; - - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), - Color(1, 1, 0, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), - Color(1, 1, 1, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), - Color(1.8, 1.8, 0.8, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), - Color(1.5, 1.5, 1, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), - Color(0.5, 0.5, 0, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), - Color(0.2, 0.2, 0.2, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), - Color(0.5, 0.5, 0, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), - Color(0.8, 0.8, 0.8, 0.4)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), - Color(1.3, 1.3, 0.8, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), - Color(0.7, 0.7, 0.2, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), - Color(1.3, 1.3, 0.8, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), - Color(1, 1, 1, 0.7)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), - Color(1, 1, 0, 0.1)); - } - - { - Color src = {1, 0.5, 0, 0.2}; - Color dst = {1, 1, 0.5, 0.5}; - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), - Color(1, 0.5, 0, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), - Color(1, 1, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), - Color(1.8, 1.3, 0.4, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), - Color(1.5, 1.25, 0.5, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), - Color(0.5, 0.25, 0, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), - Color(0.2, 0.2, 0.1, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), - Color(0.5, 0.25, 0, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), - Color(0.8, 0.8, 0.4, 0.4)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), - Color(1.3, 1.05, 0.4, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), - Color(0.7, 0.45, 0.1, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), - Color(1.3, 1.05, 0.4, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), - Color(1, 1, 0.5, 0.7)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), - Color(1, 0.5, 0, 0.1)); - } - - { - Color src = {0.5, 0.5, 0, 0.2}; - Color dst = {0, 1, 0.5, 0.5}; - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), - Color(0.5, 0.5, 0, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), - Color(0, 1, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), - Color(0.5, 1.3, 0.4, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), - Color(0.25, 1.25, 0.5, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), - Color(0.25, 0.25, 0, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), - Color(0, 0.2, 0.1, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), - Color(0.25, 0.25, 0, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), - Color(0, 0.8, 0.4, 0.4)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), - Color(0.25, 1.05, 0.4, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), - Color(0.25, 0.45, 0.1, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), - Color(0.25, 1.05, 0.4, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), - Color(0.5, 1, 0.5, 0.7)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), - Color(0, 0.5, 0, 0.1)); - } - - { - Color src = {0.5, 0.5, 0.2, 0.2}; - Color dst = {0.2, 1, 0.5, 0.5}; - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), - Color(0.5, 0.5, 0.2, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), - Color(0.2, 1, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), - Color(0.66, 1.3, 0.6, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), - Color(0.45, 1.25, 0.6, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), - Color(0.25, 0.25, 0.1, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), - Color(0.04, 0.2, 0.1, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), - Color(0.25, 0.25, 0.1, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), - Color(0.16, 0.8, 0.4, 0.4)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), - Color(0.41, 1.05, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), - Color(0.29, 0.45, 0.2, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), - Color(0.41, 1.05, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), - Color(0.7, 1, 0.7, 0.7)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), - Color(0.1, 0.5, 0.1, 0.1)); - } - - { - Color src = {0.5, 0.5, 0.2, 0.2}; - Color dst = {0.2, 0.2, 0.5, 0.5}; - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), - Color(0, 0, 0, 0)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), - Color(0.5, 0.5, 0.2, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), - Color(0.2, 0.2, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), - Color(0.66, 0.66, 0.6, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), - Color(0.45, 0.45, 0.6, 0.6)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), - Color(0.25, 0.25, 0.1, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), - Color(0.04, 0.04, 0.1, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), - Color(0.25, 0.25, 0.1, 0.1)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), - Color(0.16, 0.16, 0.4, 0.4)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), - Color(0.41, 0.41, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), - Color(0.29, 0.29, 0.2, 0.2)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), - Color(0.41, 0.41, 0.5, 0.5)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), - Color(0.7, 0.7, 0.7, 0.7)); - ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), - Color(0.1, 0.1, 0.1, 0.1)); - } -} - TEST_P(EntityTest, SdfText) { auto callback = [&](ContentContext& context, RenderPass& pass) -> bool { SkFont font; diff --git a/impeller/geometry/color.cc b/impeller/geometry/color.cc index 70946f66a8528..34da51c04144a 100644 --- a/impeller/geometry/color.cc +++ b/impeller/geometry/color.cc @@ -110,134 +110,4 @@ Color Min(Color c, float threshold) { std::min(c.blue, threshold), std::min(c.alpha, threshold)); } -Color Color::BlendColor(const Color& src, - const Color& dst, - BlendMode blend_mode) { - static auto apply_rgb_srcover_alpha = [&](auto f) -> Color { - return Color(f(src.red, dst.red), f(src.green, dst.green), - f(src.blue, dst.blue), - dst.alpha * (1 - src.alpha) + src.alpha // srcOver alpha - ); - }; - - switch (blend_mode) { - case BlendMode::kClear: - return Color::BlackTransparent(); - case BlendMode::kSource: - return src; - case BlendMode::kDestination: - return dst; - case BlendMode::kSourceOver: - // r = s + (1-sa)*d - return src + dst * (1 - src.alpha); - case BlendMode::kDestinationOver: - // r = d + (1-da)*s - return dst + src * (1 - dst.alpha); - case BlendMode::kSourceIn: - // r = s * da - return src * dst.alpha; - case BlendMode::kDestinationIn: - // r = d * sa - return dst * src.alpha; - case BlendMode::kSourceOut: - // r = s * ( 1- da) - return src * (1 - dst.alpha); - case BlendMode::kDestinationOut: - // r = d * (1-sa) - return dst * (1 - src.alpha); - case BlendMode::kSourceATop: - // r = s*da + d*(1-sa) - return src * dst.alpha + dst * (1 - src.alpha); - case BlendMode::kDestinationATop: - // r = d*sa + s*(1-da) - return dst * src.alpha + src * (1 - dst.alpha); - case BlendMode::kXor: - // r = s*(1-da) + d*(1-sa) - return src * (1 - dst.alpha) + dst * (1 - src.alpha); - case BlendMode::kPlus: - // r = min(s + d, 1) - return Min(src + dst, 1); - case BlendMode::kModulate: - // r = s*d - return src * dst; - case BlendMode::kScreen: { - // r = s + d - s*d - return src + dst - src * dst; - } - case BlendMode::kOverlay: - return apply_rgb_srcover_alpha([&](auto s, auto d) { - if (d * 2 < dst.alpha) { - return 2 * s * d; - } - return src.alpha * dst.alpha - 2 * (dst.alpha - s) * (src.alpha - d); - }); - case BlendMode::kDarken: { - return apply_rgb_srcover_alpha([&](auto s, auto d) { - return (1 - dst.alpha) * s + (1 - src.alpha) * d + std::min(s, d); - }); - } - case BlendMode::kLighten: - return apply_rgb_srcover_alpha([&](auto s, auto d) { - return (1 - dst.alpha) * s + (1 - src.alpha) * d + std::max(s, d); - }); - case BlendMode::kColorDodge: - return apply_rgb_srcover_alpha([&](auto s, auto d) { - if (d == 0) { - return s * (1 - src.alpha); - } - if (s == src.alpha) { - return s + dst.alpha * (1 - src.alpha); - } - return src.alpha * - std::min(dst.alpha, d * src.alpha / (src.alpha - s)) + - s * (1 - dst.alpha + dst.alpha * (1 - src.alpha)); - }); - case BlendMode::kColorBurn: - return apply_rgb_srcover_alpha([&](auto s, auto d) { - if (s == 0) { - return dst.alpha * (1 - src.alpha); - } - if (d == dst.alpha) { - return d + s * (1 - dst.alpha); - } - // s.a * (d.a - min(d.a, (d.a - s) * s.a/s)) + s * (1-d.a) + d.a * (1 - - // s.a) - return src.alpha * - (dst.alpha - - std::min(dst.alpha, (dst.alpha - d) * src.alpha / s)) + - s * (1 - dst.alpha) + dst.alpha * (1 - src.alpha); - }); - case BlendMode::kHardLight: - return apply_rgb_srcover_alpha([&](auto s, auto d) { - if (src.alpha >= s * (1 - dst.alpha) + d * (1 - src.alpha) + 2 * s) { - return 2 * s * d; - } - // s.a * d.a - 2 * (d.a - d) * (s.a - s) - return src.alpha * dst.alpha - 2 * (dst.alpha - d) * (src.alpha - s); - }); - case BlendMode::kDifference: - return apply_rgb_srcover_alpha([&](auto s, auto d) { - // s + d - 2 * min(s * d.a, d * s.a); - return s + d - 2 * std::min(s * dst.alpha, d * src.alpha); - }); - case BlendMode::kExclusion: - return apply_rgb_srcover_alpha([&](auto s, auto d) { - // s + d - 2 * s * d - return s + d - 2 * s * d; - }); - case BlendMode::kMultiply: - return apply_rgb_srcover_alpha([&](auto s, auto d) { - // s * (1 - d.a) + d * (1 - s.a) + (s * d) - return s * (1 - dst.alpha) + d * (1 - src.alpha) + (s * d); - }); - case BlendMode::kHue: - case BlendMode::kSaturation: - case BlendMode::kColor: - case BlendMode::kLuminosity: - case BlendMode::kSoftLight: - default: - return src + dst * (1 - src.alpha); - } -} - } // namespace impeller diff --git a/impeller/geometry/color.h b/impeller/geometry/color.h index 6966a3ccc0f6d..5a3a0b7d8091d 100644 --- a/impeller/geometry/color.h +++ b/impeller/geometry/color.h @@ -734,10 +734,6 @@ struct Color { }; } - static Color BlendColor(const Color& src, - const Color& dst, - BlendMode blend_mode); - Color operator*(const Color& c) const { return Color(red * c.red, green * c.green, blue * c.blue, alpha * c.alpha); } From 997bb3fa337ed826b142745d3a0607d511a72ee0 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 17 Jan 2023 17:06:23 -0800 Subject: [PATCH 15/26] back out vertices change --- ci/licenses_golden/licenses_flutter | 62 +--- impeller/aiks/canvas.cc | 59 ++-- .../display_list_vertices_geometry.cc | 207 +++++--------- .../display_list_vertices_geometry.h | 15 +- impeller/entity/BUILD.gn | 27 -- impeller/entity/contents/atlas_contents.cc | 251 +++++------------ impeller/entity/contents/atlas_contents.h | 9 +- impeller/entity/contents/content_context.cc | 56 ---- impeller/entity/contents/content_context.h | 256 ----------------- impeller/entity/contents/vertices_contents.cc | 266 +++--------------- impeller/entity/contents/vertices_contents.h | 15 +- impeller/entity/entity_unittests.cc | 232 +++++++++++++++ impeller/entity/geometry.h | 13 +- .../atlas_blending/atlas_advanced_blend.glsl | 34 --- .../atlas_advanced_blend_color.frag | 11 - .../atlas_advanced_blend_colorburn.frag | 11 - .../atlas_advanced_blend_colordodge.frag | 11 - .../atlas_advanced_blend_darken.frag | 11 - .../atlas_advanced_blend_difference.frag | 11 - .../atlas_advanced_blend_exclusion.frag | 11 - .../atlas_advanced_blend_hardlight.frag | 11 - .../atlas_advanced_blend_hue.frag | 11 - .../atlas_advanced_blend_lighten.frag | 11 - .../atlas_advanced_blend_luminosity.frag | 11 - .../atlas_advanced_blend_multiply.frag | 11 - .../atlas_advanced_blend_overlay.frag | 11 - .../atlas_advanced_blend_saturation.frag | 11 - .../atlas_advanced_blend_screen.frag | 11 - .../atlas_advanced_blend_softlight.frag | 11 - .../shaders/atlas_blending/atlas_blend.glsl | 33 --- .../shaders/atlas_blending/atlas_blend.vert | 23 -- .../atlas_blending/atlas_blend_dst_a_top.frag | 11 - .../atlas_blending/atlas_blend_dst_in.frag | 11 - .../atlas_blending/atlas_blend_dst_out.frag | 11 - .../atlas_blending/atlas_blend_dst_over.frag | 11 - .../atlas_blending/atlas_blend_modulate.frag | 11 - .../atlas_blending/atlas_blend_plus.frag | 11 - .../atlas_blending/atlas_blend_src_a_top.frag | 11 - .../atlas_blending/atlas_blend_src_in.frag | 11 - .../atlas_blending/atlas_blend_src_out.frag | 11 - .../atlas_blending/atlas_blend_src_over.frag | 11 - .../atlas_blending/atlas_blend_xor.frag | 11 - impeller/geometry/color.cc | 130 +++++++++ impeller/geometry/color.h | 4 + 44 files changed, 567 insertions(+), 1411 deletions(-) delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend.glsl delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend.vert delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag delete mode 100644 impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 6fe692c52b5e6..809ebb4c30865 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1313,35 +1313,8 @@ ORIGIN: ../../../flutter/impeller/entity/geometry.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/inline_pass_context.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/inline_pass_context.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend.glsl + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend.vert + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_fill.frag + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_fill.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_color.frag + ../../../flutter/LICENSE @@ -3821,35 +3794,8 @@ FILE: ../../../flutter/impeller/entity/geometry.cc FILE: ../../../flutter/impeller/entity/geometry.h FILE: ../../../flutter/impeller/entity/inline_pass_context.cc FILE: ../../../flutter/impeller/entity/inline_pass_context.h -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend.glsl -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend.vert -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_fill.frag +FILE: ../../../flutter/impeller/entity/shaders/atlas_fill.vert FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_color.frag diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 8bc7fc6e3fbc6..80344bcbfd879 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -380,55 +380,25 @@ void Canvas::DrawTextFrame(const TextFrame& text_frame, void Canvas::DrawVertices(std::unique_ptr vertices, BlendMode blend_mode, const Paint& paint) { - // drawVertices rendering: - // * If there are no per-vertex colors and no texture coordinates, use the - // color source and apply the vertex geometry to this. - // * If there are vertex colors or vertex colors and texture coordinates, - // then - // the blend_mode parameter applies: - // * The paint color, if any, is treated as fully opaque. The alpha is - // applied - // separately even to other paint sources. - // * If there are only texture coordinates and the paint source is not a - // solid - // color, then pretend this is per-vertex color with a source blend mode. - - auto has_colors = vertices->HasVertexColors(); - auto has_texture_coordinates = vertices->HasTextureCoordinates(); - auto rect = vertices->GetCoverage(GetCurrentTransformation()); - - // Clear blend mode can be ignored entirely. - if ((has_colors && blend_mode == BlendMode::kClear) || !rect.has_value()) { - return; - } - Entity entity; entity.SetTransformation(GetCurrentTransformation()); entity.SetStencilDepth(GetStencilDepth()); entity.SetBlendMode(paint.blend_mode); - // No vertex colors or texture coordinates, this can be treated as a regular - // paint op. - // TODO(jonahwilliams): optimization, texture coordinate + solid color - // contents should exit here too. - if (!has_texture_coordinates && - (blend_mode == BlendMode::kSource || !has_colors)) { - entity.SetContents(paint.WithFilters( - paint.CreateContentsForGeometry(std::move(vertices)))); - GetCurrentPass().AddEntity(entity); - return; + if (paint.color_source.has_value()) { + auto& source = paint.color_source.value(); + auto contents = source(); + contents->SetGeometry(std::move(vertices)); + contents->SetAlpha(paint.color.alpha); + entity.SetContents(paint.WithFilters(std::move(contents), true)); + } else { + std::shared_ptr contents = + std::make_shared(); + contents->SetColor(paint.color); + contents->SetBlendMode(blend_mode); + contents->SetGeometry(std::move(vertices)); + entity.SetContents(paint.WithFilters(std::move(contents), true)); } - // The paint color, if present, should be treated as fully opaque. - auto opaque_paint = paint; - opaque_paint.color = opaque_paint.color.WithAlpha(1.0); - - auto contents = std::make_shared(); - contents->SetSrcContents(opaque_paint.CreateContentsForGeometry( - Geometry::MakeRect(Rect::MakeSize(rect.value().size)))); - contents->SetAlpha(paint.color.alpha); - contents->SetBlendMode(blend_mode); - contents->SetGeometry(std::move(vertices)); - entity.SetContents(paint.WithFilters(contents)); GetCurrentPass().AddEntity(entity); } @@ -449,6 +419,7 @@ void Canvas::DrawAtlas(const std::shared_ptr& atlas, if (size.IsEmpty()) { return; } + SaveLayer(Paint()); std::shared_ptr contents = std::make_shared(); contents->SetColors(std::move(colors)); @@ -467,6 +438,8 @@ void Canvas::DrawAtlas(const std::shared_ptr& atlas, entity.SetContents(paint.WithFilters(contents, false)); GetCurrentPass().AddEntity(entity); + + Restore(); } } // namespace impeller diff --git a/impeller/display_list/display_list_vertices_geometry.cc b/impeller/display_list/display_list_vertices_geometry.cc index a2c0d17206646..1cab24c1fb861 100644 --- a/impeller/display_list/display_list_vertices_geometry.cc +++ b/impeller/display_list/display_list_vertices_geometry.cc @@ -21,10 +21,6 @@ static Rect ToRect(const SkRect& rect) { return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); } -static Point ToPoint(const SkPoint& point) { - return Point::MakeXY(point.fX, point.fY); -} - // Fan mode isn't natively supported. Unroll into triangle mode by // manipulating the index array. // @@ -104,21 +100,20 @@ static PrimitiveType GetPrimitiveType(const flutter::DlVertices* vertices) { } } -bool DLVerticesGeometry::HasTextureCoordinates() const { - return vertices_->texture_coordinates() != nullptr; -} - -bool DLVerticesGeometry::HasVertexColors() const { - return vertices_->colors() != nullptr; -} +GeometryResult DLVerticesGeometry::GetPositionBuffer( + const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) { + auto index_count = normalized_indices_.size() == 0 + ? vertices_->index_count() + : normalized_indices_.size(); + auto vertex_count = vertices_->vertex_count(); + auto* dl_indices = normalized_indices_.size() == 0 + ? vertices_->indices() + : normalized_indices_.data(); + auto* dl_vertices = vertices_->vertices(); -static VertexBuffer CreateVertexBuffer(const ContentContext& renderer, - size_t vertex_count, - size_t index_count, - size_t vertex_size, - const uint8_t* vertex_data, - const uint8_t* index_data) { - size_t total_vtx_bytes = vertex_count * vertex_size; + size_t total_vtx_bytes = vertex_count * sizeof(float) * 2; size_t total_idx_bytes = index_count * sizeof(uint16_t); DeviceBufferDescriptor buffer_desc; @@ -128,41 +123,28 @@ static VertexBuffer CreateVertexBuffer(const ContentContext& renderer, auto buffer = renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); - if (!buffer->CopyHostBuffer(vertex_data, Range{0, total_vtx_bytes}, 0)) { + if (!buffer->CopyHostBuffer(reinterpret_cast(dl_vertices), + Range{0, total_vtx_bytes}, 0)) { return {}; } - if (!buffer->CopyHostBuffer(index_data, Range{0, total_idx_bytes}, - total_vtx_bytes)) { + if (!buffer->CopyHostBuffer( + reinterpret_cast(const_cast(dl_indices)), + Range{0, total_idx_bytes}, total_vtx_bytes)) { return {}; } - return { - .vertex_buffer = {.buffer = buffer, .range = Range{0, total_vtx_bytes}}, - .index_buffer = {.buffer = buffer, - .range = Range{total_vtx_bytes, total_idx_bytes}}, - .index_count = index_count, - .index_type = IndexType::k16bit, - }; -} - -GeometryResult DLVerticesGeometry::GetPositionBuffer( - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) { - auto index_count = normalized_indices_.size() == 0 - ? vertices_->index_count() - : normalized_indices_.size(); - auto vertex_count = vertices_->vertex_count(); - auto* dl_indices = normalized_indices_.size() == 0 - ? vertices_->indices() - : normalized_indices_.data(); - auto* dl_vertices = vertices_->vertices(); return GeometryResult{ .type = GetPrimitiveType(vertices_), - .vertex_buffer = CreateVertexBuffer( - renderer, vertex_count, index_count, sizeof(float) * 2, - reinterpret_cast(dl_vertices), - reinterpret_cast(dl_indices)), + .vertex_buffer = + { + .vertex_buffer = {.buffer = buffer, + .range = Range{0, total_vtx_bytes}}, + .index_buffer = {.buffer = buffer, + .range = + Range{total_vtx_bytes, total_idx_bytes}}, + .index_count = index_count, + .index_type = IndexType::k16bit, + }, .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), .prevent_overdraw = false, @@ -172,7 +154,9 @@ GeometryResult DLVerticesGeometry::GetPositionBuffer( GeometryResult DLVerticesGeometry::GetPositionColorBuffer( const ContentContext& renderer, const Entity& entity, - RenderPass& pass) { + RenderPass& pass, + Color paint_color, + BlendMode blend_mode) { using VS = GeometryColorPipeline::VertexShader; auto index_count = normalized_indices_.size() == 0 @@ -189,125 +173,62 @@ GeometryResult DLVerticesGeometry::GetPositionColorBuffer( { for (auto i = 0; i < vertex_count; i++) { auto dl_color = dl_colors[i]; - auto color = Color(dl_color.getRedF(), dl_color.getGreenF(), - dl_color.getBlueF(), dl_color.getAlphaF()); + auto pre_color = Color(dl_color.getRedF(), dl_color.getGreenF(), + dl_color.getBlueF(), dl_color.getAlphaF()); + auto color = Color::BlendColor(paint_color, pre_color, blend_mode); auto sk_point = dl_vertices[i]; vertex_data[i] = { .position = Point(sk_point.x(), sk_point.y()), - .color = color.Premultiply(), + .color = color, }; } } - return GeometryResult{ - .type = GetPrimitiveType(vertices_), - .vertex_buffer = CreateVertexBuffer( - renderer, vertex_count, index_count, sizeof(VS::PerVertexData), - reinterpret_cast(vertex_data.data()), - reinterpret_cast(dl_indices)), - .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * - entity.GetTransformation(), - .prevent_overdraw = false, - }; -} - -GeometryResult DLVerticesGeometry::GetPositionUVBuffer( - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) { - using VS = TexturePipeline::VertexShader; - - auto index_count = normalized_indices_.size() == 0 - ? vertices_->index_count() - : normalized_indices_.size(); - auto vertex_count = vertices_->vertex_count(); - auto* dl_indices = normalized_indices_.size() == 0 - ? vertices_->indices() - : normalized_indices_.data(); - auto* dl_vertices = vertices_->vertices(); - auto* dl_tex_coords = vertices_->texture_coordinates(); - - auto coverage_rect = ToRect(vertices_->bounds()); + size_t total_vtx_bytes = vertex_data.size() * sizeof(VS::PerVertexData); + size_t total_idx_bytes = index_count * sizeof(uint16_t); - std::vector vertex_data(vertex_count); - for (auto i = 0; i < vertex_count; i++) { - auto sk_point = dl_vertices[i]; - auto vertex = Point(sk_point.x(), sk_point.y()); + DeviceBufferDescriptor buffer_desc; + buffer_desc.size = total_vtx_bytes + total_idx_bytes; + buffer_desc.storage_mode = StorageMode::kHostVisible; - // TODO(jonahwilliams): Instead of the coverage rect, this should use the - // size of what is being sampled, such as the image size or gradient bounds. - auto coverage_coords = ToPoint(dl_tex_coords[i]) / coverage_rect.size; + auto buffer = + renderer.GetContext()->GetResourceAllocator()->CreateBuffer(buffer_desc); - vertex_data[i] = { - .position = vertex, - .texture_coords = coverage_coords, - }; + if (!buffer->CopyHostBuffer(reinterpret_cast(vertex_data.data()), + Range{0, total_vtx_bytes}, 0)) { + return {}; + } + if (!buffer->CopyHostBuffer( + reinterpret_cast(const_cast(dl_indices)), + Range{0, total_idx_bytes}, total_vtx_bytes)) { + return {}; } return GeometryResult{ .type = GetPrimitiveType(vertices_), - .vertex_buffer = CreateVertexBuffer( - renderer, vertex_count, index_count, sizeof(VS::PerVertexData), - reinterpret_cast(vertex_data.data()), - reinterpret_cast(dl_indices)), + .vertex_buffer = + { + .vertex_buffer = {.buffer = buffer, + .range = Range{0, total_vtx_bytes}}, + .index_buffer = {.buffer = buffer, + .range = + Range{total_vtx_bytes, total_idx_bytes}}, + .index_count = index_count, + .index_type = IndexType::k16bit, + }, .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(), .prevent_overdraw = false, }; } -// This method is used even if there are no user-provided texture coordinates. -GeometryResult DLVerticesGeometry::GetPositionUVColorBuffer( +GeometryResult DLVerticesGeometry::GetPositionUVBuffer( const ContentContext& renderer, const Entity& entity, RenderPass& pass) { - using VS = AtlasBlendSrcOverPipeline::VertexShader; - - auto index_count = normalized_indices_.size() == 0 - ? vertices_->index_count() - : normalized_indices_.size(); - auto vertex_count = vertices_->vertex_count(); - auto* dl_indices = normalized_indices_.size() == 0 - ? vertices_->indices() - : normalized_indices_.data(); - auto* dl_vertices = vertices_->vertices(); - auto* dl_colors = vertices_->colors(); - auto* dl_tex_coords = vertices_->texture_coordinates(); - - auto coverage_rect = ToRect(vertices_->bounds()); - std::vector vertex_data(vertex_count); - - for (auto i = 0; i < vertex_count; i++) { - auto dl_color = dl_colors[i]; - auto color = Color(dl_color.getRedF(), dl_color.getGreenF(), - dl_color.getBlueF(), dl_color.getAlphaF()); - auto sk_point = dl_vertices[i]; - auto vertex = Point(sk_point.x(), sk_point.y()); - - // TODO(jonahwilliams): Instead of the coverage rect, this should use the - // size of what is being sampled, such as the image size or gradient bounds. - auto coverage_coords = (vertex - coverage_rect.origin) / coverage_rect.size; - if (dl_tex_coords != nullptr) { - coverage_coords = ToPoint(dl_tex_coords[i]) / coverage_rect.size; - } - - vertex_data[i] = { - .vertices = vertex, - .dst_color = color, - .src_texture_coords = coverage_coords, - }; - } - - return GeometryResult{ - .type = GetPrimitiveType(vertices_), - .vertex_buffer = CreateVertexBuffer( - renderer, vertex_count, index_count, sizeof(VS::PerVertexData), - reinterpret_cast(vertex_data.data()), - reinterpret_cast(dl_indices)), - .transform = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * - entity.GetTransformation(), - .prevent_overdraw = false, - }; + // TODO(jonahwilliams): support texture coordinates in vertices + // https://github.com/flutter/flutter/issues/109956 + return {}; } GeometryVertexType DLVerticesGeometry::GetVertexType() const { diff --git a/impeller/display_list/display_list_vertices_geometry.h b/impeller/display_list/display_list_vertices_geometry.h index 8a56e5faf28a8..510f496a30110 100644 --- a/impeller/display_list/display_list_vertices_geometry.h +++ b/impeller/display_list/display_list_vertices_geometry.h @@ -29,24 +29,15 @@ class DLVerticesGeometry : public VerticesGeometry { // |VerticesGeometry| GeometryResult GetPositionColorBuffer(const ContentContext& renderer, const Entity& entity, - RenderPass& pass) override; + RenderPass& pass, + Color paint_color, + BlendMode blend_mode) override; // |VerticesGeometry| GeometryResult GetPositionUVBuffer(const ContentContext& renderer, const Entity& entity, RenderPass& pass) override; - // |VerticesGeometry| - GeometryResult GetPositionUVColorBuffer(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) override; - - // |VerticesGeometry| - bool HasTextureCoordinates() const override; - - // |VerticesGeometry| - bool HasVertexColors() const override; - // |Geometry| GeometryResult GetPositionBuffer(const ContentContext& renderer, const Entity& entity, diff --git a/impeller/entity/BUILD.gn b/impeller/entity/BUILD.gn index 3b1baad05a4b4..261a89a0ac27c 100644 --- a/impeller/entity/BUILD.gn +++ b/impeller/entity/BUILD.gn @@ -54,33 +54,6 @@ impeller_shaders("entity_shaders") { "shaders/srgb_to_linear_filter.frag", "shaders/srgb_to_linear_filter.vert", "shaders/sweep_gradient_fill.frag", - "shaders/atlas_blending/atlas_blend.vert", - "shaders/atlas_blending/atlas_advanced_blend_color.frag", - "shaders/atlas_blending/atlas_advanced_blend_colorburn.frag", - "shaders/atlas_blending/atlas_advanced_blend_colordodge.frag", - "shaders/atlas_blending/atlas_advanced_blend_darken.frag", - "shaders/atlas_blending/atlas_advanced_blend_difference.frag", - "shaders/atlas_blending/atlas_advanced_blend_exclusion.frag", - "shaders/atlas_blending/atlas_advanced_blend_hardlight.frag", - "shaders/atlas_blending/atlas_advanced_blend_hue.frag", - "shaders/atlas_blending/atlas_advanced_blend_lighten.frag", - "shaders/atlas_blending/atlas_advanced_blend_luminosity.frag", - "shaders/atlas_blending/atlas_advanced_blend_multiply.frag", - "shaders/atlas_blending/atlas_advanced_blend_overlay.frag", - "shaders/atlas_blending/atlas_advanced_blend_saturation.frag", - "shaders/atlas_blending/atlas_advanced_blend_screen.frag", - "shaders/atlas_blending/atlas_advanced_blend_softlight.frag", - "shaders/atlas_blending/atlas_blend_dst_a_top.frag", - "shaders/atlas_blending/atlas_blend_dst_in.frag", - "shaders/atlas_blending/atlas_blend_dst_out.frag", - "shaders/atlas_blending/atlas_blend_dst_over.frag", - "shaders/atlas_blending/atlas_blend_modulate.frag", - "shaders/atlas_blending/atlas_blend_plus.frag", - "shaders/atlas_blending/atlas_blend_src_a_top.frag", - "shaders/atlas_blending/atlas_blend_src_in.frag", - "shaders/atlas_blending/atlas_blend_src_out.frag", - "shaders/atlas_blending/atlas_blend_src_over.frag", - "shaders/atlas_blending/atlas_blend_xor.frag", "shaders/texture_fill.frag", "shaders/texture_fill.vert", "shaders/tiled_texture_fill.frag", diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 6e2b97f070aa0..bdde94960f3c0 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include #include #include +#include "impeller/entity/contents/filters/color_filter_contents.h" +#include "impeller/entity/contents/filters/filter_contents.h" #include "impeller/renderer/formats.h" #include "impeller/renderer/sampler_library.h" #include "impeller/renderer/vertex_buffer_builder.h" @@ -58,7 +61,10 @@ std::optional AtlasContents::GetCoverage(const Entity& entity) const { if (cull_rect_.has_value()) { return cull_rect_.value().TransformBounds(entity.GetTransformation()); } + return ComputeBoundingBox().TransformBounds(entity.GetTransformation()); +} +Rect AtlasContents::ComputeBoundingBox() const { Rect bounding_box = {}; for (size_t i = 0; i < texture_coords_.size(); i++) { auto matrix = transforms_[i]; @@ -66,7 +72,7 @@ std::optional AtlasContents::GetCoverage(const Entity& entity) const { auto bounds = Rect::MakeSize(sample_rect.size).TransformBounds(matrix); bounding_box = bounds.Union(bounding_box); } - return bounding_box.TransformBounds(entity.GetTransformation()); + return bounding_box; } void AtlasContents::SetSamplerDescriptor(SamplerDescriptor desc) { @@ -85,192 +91,60 @@ bool AtlasContents::Render(const ContentContext& renderer, } if (blend_mode_ == BlendMode::kSource || colors_.size() == 0) { - return RenderNoColor(renderer, entity, pass); + return RenderTexture(renderer, entity, pass); } if (blend_mode_ == BlendMode::kDestination) { - return RenderOnlyColor(renderer, entity, pass); + return RenderColors(renderer, entity, pass); } - using VS = AtlasBlendSrcOverPipeline::VertexShader; - using FS = AtlasBlendSrcOverPipeline::FragmentShader; - - const auto texture_size = texture_->GetSize(); - if (texture_size.IsEmpty()) { - return true; - } - - VertexBufferBuilder vertex_builder; - vertex_builder.Reserve(texture_coords_.size() * 6); - constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3}; - constexpr Scalar width[6] = {0, 1, 0, 1, 0, 1}; - constexpr Scalar height[6] = {0, 0, 1, 0, 1, 1}; - for (size_t i = 0; i < texture_coords_.size(); i++) { - auto sample_rect = texture_coords_[i]; - auto matrix = transforms_[i]; - auto color = colors_[i]; - auto transformed_points = - Rect::MakeSize(sample_rect.size).GetTransformedPoints(matrix); - - for (size_t j = 0; j < 6; j++) { - VS::PerVertexData data; - data.vertices = transformed_points[indices[j]]; - data.src_texture_coords = - (sample_rect.origin + Point(sample_rect.size.width * width[j], - sample_rect.size.height * height[j])) / - texture_size; - data.dst_color = color; - vertex_builder.AppendVertex(data); + // Simple blends. + if (blend_mode_ < BlendMode::kScreen) { + if (!RenderColors(renderer, entity, pass)) { + return false; } + return RenderTexture(renderer, entity, pass, true); } - if (!vertex_builder.HasVertices()) { - return true; - } - - auto& host_buffer = pass.GetTransientsBuffer(); - - VS::FrameInfo frame_info; - frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * - entity.GetTransformation(); - - FS::FragInfo frag_info; - frag_info.src_y_coord_scale = texture_->GetYCoordScale(); - frag_info.alpha = alpha_; - - Command cmd; - cmd.label = "DrawAtlas"; - switch (blend_mode_) { - case BlendMode::kClear: - case BlendMode::kSource: - case BlendMode::kDestination: - // All handled above. - return true; - case BlendMode::kSourceOver: - cmd.pipeline = renderer.GetAtlasBlendSrcOverPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDestinationOver: - cmd.pipeline = renderer.GetAtlasBlendDstOverPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSourceIn: - cmd.pipeline = renderer.GetAtlasBlendSrcInPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDestinationIn: - cmd.pipeline = renderer.GetAtlasBlendDstInPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSourceOut: - cmd.pipeline = renderer.GetAtlasBlendSrcOutPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDestinationOut: - cmd.pipeline = renderer.GetAtlasBlendDstOutPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSourceATop: - cmd.pipeline = renderer.GetAtlasBlendSrcATopPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDestinationATop: - cmd.pipeline = renderer.GetAtlasBlendDstATopPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kXor: - cmd.pipeline = renderer.GetAtlasBlendXorPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kPlus: - cmd.pipeline = renderer.GetAtlasBlendPlusPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kModulate: - cmd.pipeline = renderer.GetAtlasBlendModulatePipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - // Advanced - case BlendMode::kScreen: - cmd.pipeline = renderer.GetAtlasBlendScreenPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kOverlay: - cmd.pipeline = renderer.GetAtlasBlendOverlayPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDarken: - cmd.pipeline = renderer.GetAtlasBlendDarkenPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kLighten: - cmd.pipeline = renderer.GetAtlasBlendLightenPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kColorDodge: - cmd.pipeline = renderer.GetAtlasBlendColorDodgePipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kColorBurn: - cmd.pipeline = renderer.GetAtlasBlendColorBurnPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kHardLight: - cmd.pipeline = renderer.GetAtlasBlendHardLightPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSoftLight: - cmd.pipeline = renderer.GetAtlasBlendSoftLightPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDifference: - cmd.pipeline = renderer.GetAtlasBlendDifferencePipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kExclusion: - cmd.pipeline = renderer.GetAtlasBlendExclusionPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kMultiply: - cmd.pipeline = renderer.GetAtlasBlendMultiplyPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kHue: - cmd.pipeline = renderer.GetAtlasBlendHuePipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSaturation: - cmd.pipeline = renderer.GetAtlasBlendSaturationPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kColor: - cmd.pipeline = renderer.GetAtlasBlendColorPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kLuminosity: - cmd.pipeline = renderer.GetAtlasBlendLuminosityPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; + // Ensure that we use the actual computed bounds and not a cull-rect + // approximation of them. + auto coverage = ComputeBoundingBox(); + auto size = coverage.size; + + auto dst_texture = renderer.MakeSubpass( + ISize::Ceil(size), + [&contents = *this, &coverage](const ContentContext& renderer, + RenderPass& pass) -> bool { + Entity sub_entity; + sub_entity.SetBlendMode(BlendMode::kSourceOver); + sub_entity.SetTransformation( + Matrix::MakeTranslation(Vector3(-coverage.origin))); + return contents.RenderColors(renderer, sub_entity, pass); + }); + auto src_texture = renderer.MakeSubpass( + ISize::Ceil(size), + [&contents = *this, &coverage](const ContentContext& renderer, + RenderPass& pass) -> bool { + Entity sub_entity; + sub_entity.SetBlendMode(BlendMode::kSourceOver); + sub_entity.SetTransformation( + Matrix::MakeTranslation(Vector3(-coverage.origin))); + return contents.RenderTexture(renderer, sub_entity, pass); + }); + + if (!src_texture || !dst_texture) { + return false; } - cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); - VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); - FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); - FS::BindTextureSamplerSrc( - cmd, texture_, - renderer.GetContext()->GetSamplerLibrary()->GetSampler( - sampler_descriptor_)); - return pass.AddCommand(std::move(cmd)); + auto contents = ColorFilterContents::MakeBlend( + blend_mode_, + {FilterInput::Make(src_texture), FilterInput::Make(dst_texture)}); + return contents->Render(renderer, entity, pass); } -bool AtlasContents::RenderOnlyColor(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) const { +bool AtlasContents::RenderColors(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { using VS = GeometryColorPipeline::VertexShader; - - const auto texture_size = texture_->GetSize(); - if (texture_size.IsEmpty()) { - return true; - } + using FS = GeometryColorPipeline::FragmentShader; VertexBufferBuilder vertex_builder; vertex_builder.Reserve(texture_coords_.size() * 6); @@ -302,25 +176,27 @@ bool AtlasContents::RenderOnlyColor(const ContentContext& renderer, vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(); - cmd.pipeline = - renderer.GetGeometryColorPipeline(OptionsFromPassAndEntity(pass, entity)); + FS::FragInfo frag_info; + frag_info.alpha = 1.0; + + auto opts = OptionsFromPassAndEntity(pass, entity); + opts.blend_mode = BlendMode::kSourceOver; + cmd.pipeline = renderer.GetGeometryColorPipeline(opts); cmd.stencil_reference = entity.GetStencilDepth(); cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); + FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); return pass.AddCommand(std::move(cmd)); } -bool AtlasContents::RenderNoColor(const ContentContext& renderer, +bool AtlasContents::RenderTexture(const ContentContext& renderer, const Entity& entity, - RenderPass& pass) const { + RenderPass& pass, + bool apply_blend) const { using VS = TextureFillVertexShader; using FS = TextureFillFragmentShader; const auto texture_size = texture_->GetSize(); - if (texture_size.IsEmpty()) { - return true; - } - VertexBufferBuilder vertex_builder; vertex_builder.Reserve(texture_coords_.size() * 6); constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3}; @@ -360,8 +236,11 @@ bool AtlasContents::RenderNoColor(const ContentContext& renderer, frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale(); frag_info.alpha = alpha_; - cmd.pipeline = - renderer.GetTexturePipeline(OptionsFromPassAndEntity(pass, entity)); + auto options = OptionsFromPassAndEntity(pass, entity); + if (apply_blend) { + options.blend_mode = blend_mode_; + } + cmd.pipeline = renderer.GetTexturePipeline(options); cmd.stencil_reference = entity.GetStencilDepth(); cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); diff --git a/impeller/entity/contents/atlas_contents.h b/impeller/entity/contents/atlas_contents.h index 0c4a40f97ea39..3a0340d9aaae6 100644 --- a/impeller/entity/contents/atlas_contents.h +++ b/impeller/entity/contents/atlas_contents.h @@ -50,14 +50,17 @@ class AtlasContents final : public Contents { RenderPass& pass) const override; private: - bool RenderNoColor(const ContentContext& renderer, + bool RenderTexture(const ContentContext& renderer, const Entity& entity, - RenderPass& pass) const; + RenderPass& pass, + bool apply_blend = false) const; - bool RenderOnlyColor(const ContentContext& renderer, + bool RenderColors(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const; + Rect ComputeBoundingBox() const; + std::shared_ptr texture_; std::vector texture_coords_; std::vector colors_; diff --git a/impeller/entity/contents/content_context.cc b/impeller/entity/contents/content_context.cc index d40caa826b5bb..1f0f8c4c37130 100644 --- a/impeller/entity/contents/content_context.cc +++ b/impeller/entity/contents/content_context.cc @@ -228,62 +228,6 @@ ContentContext::ContentContext(std::shared_ptr context) yuv_to_rgb_filter_pipelines_[{}] = CreateDefaultPipeline(*context_); - // Atlas/vertices advanced pipelines - atlas_blend_color_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_colorburn_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_colordodge_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_darken_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_difference_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_exclusion_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_hardlight_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_hue_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_lighten_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_luminosity_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_multiply_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_overlay_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_saturation_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_screen_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_softlight_pipelines_[{}] = - CreateDefaultPipeline(*context_); - - // Atlas/vertices normal pipelines - atlas_blend_dst_a_top_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_dst_in_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_dst_over_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_dst_out_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_modulate_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_plus_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_src_a_top_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_src_in_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_src_over_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_src_out_pipelines_[{}] = - CreateDefaultPipeline(*context_); - atlas_blend_xor_pipelines_[{}] = - CreateDefaultPipeline(*context_); - if (solid_fill_pipelines_[{}]->GetDescriptor().has_value()) { auto clip_pipeline_descriptor = solid_fill_pipelines_[{}]->GetDescriptor().value(); diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index 7110689d26d60..ccf8b3b49f77c 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -28,34 +28,6 @@ #include "impeller/entity/advanced_blend_screen.frag.h" #include "impeller/entity/advanced_blend_softlight.frag.h" -#include "impeller/entity/atlas_advanced_blend_color.frag.h" -#include "impeller/entity/atlas_advanced_blend_colorburn.frag.h" -#include "impeller/entity/atlas_advanced_blend_colordodge.frag.h" -#include "impeller/entity/atlas_advanced_blend_darken.frag.h" -#include "impeller/entity/atlas_advanced_blend_difference.frag.h" -#include "impeller/entity/atlas_advanced_blend_exclusion.frag.h" -#include "impeller/entity/atlas_advanced_blend_hardlight.frag.h" -#include "impeller/entity/atlas_advanced_blend_hue.frag.h" -#include "impeller/entity/atlas_advanced_blend_lighten.frag.h" -#include "impeller/entity/atlas_advanced_blend_luminosity.frag.h" -#include "impeller/entity/atlas_advanced_blend_multiply.frag.h" -#include "impeller/entity/atlas_advanced_blend_overlay.frag.h" -#include "impeller/entity/atlas_advanced_blend_saturation.frag.h" -#include "impeller/entity/atlas_advanced_blend_screen.frag.h" -#include "impeller/entity/atlas_advanced_blend_softlight.frag.h" -#include "impeller/entity/atlas_blend.vert.h" -#include "impeller/entity/atlas_blend_dst_a_top.frag.h" -#include "impeller/entity/atlas_blend_dst_in.frag.h" -#include "impeller/entity/atlas_blend_dst_out.frag.h" -#include "impeller/entity/atlas_blend_dst_over.frag.h" -#include "impeller/entity/atlas_blend_modulate.frag.h" -#include "impeller/entity/atlas_blend_plus.frag.h" -#include "impeller/entity/atlas_blend_src_a_top.frag.h" -#include "impeller/entity/atlas_blend_src_in.frag.h" -#include "impeller/entity/atlas_blend_src_out.frag.h" -#include "impeller/entity/atlas_blend_src_over.frag.h" -#include "impeller/entity/atlas_blend_xor.frag.h" - #include "impeller/entity/blend.frag.h" #include "impeller/entity/blend.vert.h" #include "impeller/entity/border_mask_blur.frag.h" @@ -205,75 +177,6 @@ using GeometryColorPipeline = using YUVToRGBFilterPipeline = RenderPipelineT; -// Atlas/vertices specific shaders -using AtlasBlendColorPipeline = - RenderPipelineT; -using AtlasBlendColorBurnPipeline = - RenderPipelineT; -using AtlasBlendColorDodgePipeline = - RenderPipelineT; -using AtlasBlendDarkenPipeline = - RenderPipelineT; -using AtlasBlendDifferencePipeline = - RenderPipelineT; -using AtlasBlendExclusionPipeline = - RenderPipelineT; -using AtlasBlendHardLightPipeline = - RenderPipelineT; -using AtlasBlendHuePipeline = - RenderPipelineT; -using AtlasBlendLightenPipeline = - RenderPipelineT; -using AtlasBlendLuminosityPipeline = - RenderPipelineT; -using AtlasBlendMultiplyPipeline = - RenderPipelineT; -using AtlasBlendOverlayPipeline = - RenderPipelineT; -using AtlasBlendSaturationPipeline = - RenderPipelineT; -using AtlasBlendScreenPipeline = - RenderPipelineT; -using AtlasBlendSoftLightPipeline = - RenderPipelineT; -using AtlasBlendDstATopPipeline = - RenderPipelineT; -using AtlasBlendDstInPipeline = - RenderPipelineT; -using AtlasBlendDstOutPipeline = - RenderPipelineT; -using AtlasBlendDstOverPipeline = - RenderPipelineT; -using AtlasBlendModulatePipeline = - RenderPipelineT; -using AtlasBlendPlusPipeline = - RenderPipelineT; -using AtlasBlendSrcATopPipeline = - RenderPipelineT; -using AtlasBlendSrcInPipeline = - RenderPipelineT; -using AtlasBlendSrcOutPipeline = - RenderPipelineT; -using AtlasBlendSrcOverPipeline = - RenderPipelineT; -using AtlasBlendXorPipeline = - RenderPipelineT; - struct ContentContextOptions { SampleCount sample_count = SampleCount::kCount1; BlendMode blend_mode = BlendMode::kSourceOver; @@ -511,129 +414,6 @@ class ContentContext { return GetPipeline(blend_softlight_pipelines_, opts); } - // Atlas/Vertices advanced blends. - - std::shared_ptr> GetAtlasBlendColorPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_color_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendColorBurnPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_colorburn_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendColorDodgePipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_colordodge_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendDarkenPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_darken_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendDifferencePipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_difference_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendExclusionPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_exclusion_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendHardLightPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_hardlight_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendHuePipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_hue_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendLightenPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_lighten_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendLuminosityPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_luminosity_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendMultiplyPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_multiply_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendOverlayPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_overlay_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendSaturationPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_saturation_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendScreenPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_screen_pipelines_, opts); - } - - std::shared_ptr> GetAtlasBlendSoftLightPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_softlight_pipelines_, opts); - } - - // Atlas/Vertices Normal blend - std::shared_ptr> GetAtlasBlendDstATopPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_dst_a_top_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendDstInPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_dst_in_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendDstOverPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_dst_over_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendDstOutPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_dst_out_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendModulatePipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_modulate_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendPlusPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_plus_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendSrcATopPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_src_a_top_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendSrcInPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_src_in_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendSrcOverPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_src_over_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendSrcOutPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_src_out_pipelines_, opts); - } - std::shared_ptr> GetAtlasBlendXorPipeline( - ContentContextOptions opts) const { - return GetPipeline(atlas_blend_xor_pipelines_, opts); - } - std::shared_ptr GetContext() const; std::shared_ptr GetGlyphAtlasContext() const; @@ -704,42 +484,6 @@ class ContentContext { mutable Variants blend_saturation_pipelines_; mutable Variants blend_screen_pipelines_; mutable Variants blend_softlight_pipelines_; - // Atlas/Vertices advanced blends. - mutable Variants atlas_blend_color_pipelines_; - mutable Variants - atlas_blend_colorburn_pipelines_; - mutable Variants - atlas_blend_colordodge_pipelines_; - mutable Variants atlas_blend_darken_pipelines_; - mutable Variants - atlas_blend_difference_pipelines_; - mutable Variants - atlas_blend_exclusion_pipelines_; - mutable Variants - atlas_blend_hardlight_pipelines_; - mutable Variants atlas_blend_hue_pipelines_; - mutable Variants atlas_blend_lighten_pipelines_; - mutable Variants - atlas_blend_luminosity_pipelines_; - mutable Variants atlas_blend_multiply_pipelines_; - mutable Variants atlas_blend_overlay_pipelines_; - mutable Variants - atlas_blend_saturation_pipelines_; - mutable Variants atlas_blend_screen_pipelines_; - mutable Variants - atlas_blend_softlight_pipelines_; - // Atlas/Vertices normal blends. - mutable Variants atlas_blend_dst_a_top_pipelines_; - mutable Variants atlas_blend_dst_in_pipelines_; - mutable Variants atlas_blend_dst_over_pipelines_; - mutable Variants atlas_blend_dst_out_pipelines_; - mutable Variants atlas_blend_modulate_pipelines_; - mutable Variants atlas_blend_plus_pipelines_; - mutable Variants atlas_blend_src_a_top_pipelines_; - mutable Variants atlas_blend_src_in_pipelines_; - mutable Variants atlas_blend_src_over_pipelines_; - mutable Variants atlas_blend_src_out_pipelines_; - mutable Variants atlas_blend_xor_pipelines_; template std::shared_ptr> GetPipeline( diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 5b8294f6affdc..3d0357ed9ae12 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -29,253 +29,63 @@ void VerticesContents::SetGeometry(std::unique_ptr geometry) { geometry_ = std::move(geometry); } -void VerticesContents::SetAlpha(Scalar alpha) { - alpha_ = alpha; +void VerticesContents::SetColor(Color color) { + color_ = color.Premultiply(); } void VerticesContents::SetBlendMode(BlendMode blend_mode) { blend_mode_ = blend_mode; } -void VerticesContents::SetSrcContents(std::shared_ptr src_contents) { - src_contents_ = std::move(src_contents); -} - bool VerticesContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - if (blend_mode_ == BlendMode::kDestination) { - return RenderDestination(renderer, entity, pass); - } - if (blend_mode_ == BlendMode::kSource || - (geometry_->HasTextureCoordinates() && !geometry_->HasVertexColors())) { - return RenderSource(renderer, entity, pass); - } - - using VS = AtlasBlendSrcOverPipeline::VertexShader; - using FS = AtlasBlendSrcOverPipeline::FragmentShader; - auto& host_buffer = pass.GetTransientsBuffer(); + auto vertex_type = geometry_->GetVertexType(); Command cmd; cmd.label = "Vertices"; cmd.stencil_reference = entity.GetStencilDepth(); auto opts = OptionsFromPassAndEntity(pass, entity); - auto geometry_result = - geometry_->GetPositionUVColorBuffer(renderer, entity, pass); - cmd.BindVertices(geometry_result.vertex_buffer); - opts.primitive_type = geometry_result.type; - switch (blend_mode_) { - case BlendMode::kClear: - case BlendMode::kSource: - case BlendMode::kDestination: - // All handled above. - return true; - case BlendMode::kSourceOver: - cmd.pipeline = renderer.GetAtlasBlendSrcOverPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDestinationOver: - cmd.pipeline = renderer.GetAtlasBlendDstOverPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSourceIn: - cmd.pipeline = renderer.GetAtlasBlendSrcInPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDestinationIn: - cmd.pipeline = renderer.GetAtlasBlendDstInPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSourceOut: - cmd.pipeline = renderer.GetAtlasBlendSrcOutPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDestinationOut: - cmd.pipeline = renderer.GetAtlasBlendDstOutPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSourceATop: - cmd.pipeline = renderer.GetAtlasBlendSrcATopPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDestinationATop: - cmd.pipeline = renderer.GetAtlasBlendDstATopPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kXor: - cmd.pipeline = renderer.GetAtlasBlendXorPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kPlus: - cmd.pipeline = renderer.GetAtlasBlendPlusPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kModulate: - cmd.pipeline = renderer.GetAtlasBlendModulatePipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - // Advanced - case BlendMode::kScreen: - cmd.pipeline = renderer.GetAtlasBlendScreenPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kOverlay: - cmd.pipeline = renderer.GetAtlasBlendOverlayPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDarken: - cmd.pipeline = renderer.GetAtlasBlendDarkenPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kLighten: - cmd.pipeline = renderer.GetAtlasBlendLightenPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kColorDodge: - cmd.pipeline = renderer.GetAtlasBlendColorDodgePipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kColorBurn: - cmd.pipeline = renderer.GetAtlasBlendColorBurnPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kHardLight: - cmd.pipeline = renderer.GetAtlasBlendHardLightPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSoftLight: - cmd.pipeline = renderer.GetAtlasBlendSoftLightPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kDifference: - cmd.pipeline = renderer.GetAtlasBlendDifferencePipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kExclusion: - cmd.pipeline = renderer.GetAtlasBlendExclusionPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kMultiply: - cmd.pipeline = renderer.GetAtlasBlendMultiplyPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kHue: - cmd.pipeline = renderer.GetAtlasBlendHuePipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kSaturation: - cmd.pipeline = renderer.GetAtlasBlendSaturationPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kColor: - cmd.pipeline = renderer.GetAtlasBlendColorPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - case BlendMode::kLuminosity: - cmd.pipeline = renderer.GetAtlasBlendLuminosityPipeline( - OptionsFromPassAndEntity(pass, entity)); - break; - } - // TODO(jonahwilliams): skip this step if we're given an image shader. - auto src_texture = src_contents_->RenderToSnapshot(renderer, entity); - if (!src_texture.has_value()) { - return false; + switch (vertex_type) { + case GeometryVertexType::kColor: { + using VS = GeometryColorPipeline::VertexShader; + + auto geometry_result = geometry_->GetPositionColorBuffer( + renderer, entity, pass, color_, blend_mode_); + opts.primitive_type = geometry_result.type; + cmd.pipeline = renderer.GetGeometryColorPipeline(opts); + cmd.BindVertices(geometry_result.vertex_buffer); + + VS::VertInfo vert_info; + vert_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * + entity.GetTransformation(); + VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); + break; + } + case GeometryVertexType::kUV: + case GeometryVertexType::kPosition: { + using VS = GeometryPositionPipeline::VertexShader; + + auto geometry_result = + geometry_->GetPositionBuffer(renderer, entity, pass); + opts.primitive_type = geometry_result.type; + cmd.pipeline = renderer.GetGeometryPositionPipeline(opts); + cmd.BindVertices(geometry_result.vertex_buffer); + + VS::VertInfo vert_info; + vert_info.mvp = geometry_result.transform; + vert_info.color = color_.Premultiply(); + VS::BindVertInfo(cmd, + pass.GetTransientsBuffer().EmplaceUniform(vert_info)); + break; + } } + pass.AddCommand(std::move(cmd)); - VS::FrameInfo frame_info; - frame_info.mvp = geometry_result.transform; - - FS::FragInfo frag_info; - frag_info.src_y_coord_scale = src_texture->texture->GetYCoordScale(); - frag_info.alpha = alpha_; - - cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(geometry_result.vertex_buffer); - VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); - FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); - FS::BindTextureSamplerSrc( - cmd, src_texture.value().texture, - renderer.GetContext()->GetSamplerLibrary()->GetSampler({})); - - return pass.AddCommand(std::move(cmd)); -} - -bool VerticesContents::RenderDestination(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) const { - using VS = GeometryColorPipeline::VertexShader; - using FS = GeometryColorPipeline::FragmentShader; - - auto& host_buffer = pass.GetTransientsBuffer(); - - Command cmd; - cmd.label = "Vertices"; - cmd.stencil_reference = entity.GetStencilDepth(); - - auto opts = OptionsFromPassAndEntity(pass, entity); - - auto geometry_result = - geometry_->GetPositionColorBuffer(renderer, entity, pass); - opts.primitive_type = geometry_result.type; - cmd.pipeline = renderer.GetGeometryColorPipeline(opts); - cmd.BindVertices(geometry_result.vertex_buffer); - - VS::VertInfo vert_info; - vert_info.mvp = geometry_result.transform; - VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); - - FS::FragInfo frag_info; - frag_info.alpha = alpha_; - FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); - - return pass.AddCommand(std::move(cmd)); -} - -bool VerticesContents::RenderSource(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) const { - using VS = TextureFillVertexShader; - using FS = TextureFillFragmentShader; - - // TODO(jonahwilliams): skip this step if we're given an image shader. - auto src_texture = src_contents_->RenderToSnapshot(renderer, entity); - if (!src_texture.has_value()) { - return false; - } - - auto& host_buffer = pass.GetTransientsBuffer(); - - Command cmd; - cmd.label = "Vertices"; - cmd.stencil_reference = entity.GetStencilDepth(); - - auto opts = OptionsFromPassAndEntity(pass, entity); - - auto geometry_result = geometry_->GetPositionUVBuffer(renderer, entity, pass); - opts.primitive_type = geometry_result.type; - cmd.pipeline = renderer.GetTexturePipeline(opts); - cmd.BindVertices(geometry_result.vertex_buffer); - - VS::VertInfo vert_info; - vert_info.mvp = geometry_result.transform; - - FS::FragInfo frag_info; - frag_info.texture_sampler_y_coord_scale = - src_texture->texture->GetYCoordScale(); - frag_info.alpha = alpha_; - - cmd.stencil_reference = entity.GetStencilDepth(); - cmd.BindVertices(geometry_result.vertex_buffer); - VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); - FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); - FS::BindTextureSampler( - cmd, src_texture.value().texture, - renderer.GetContext()->GetSamplerLibrary()->GetSampler({})); - - return pass.AddCommand(std::move(cmd)); + return true; } } // namespace impeller diff --git a/impeller/entity/contents/vertices_contents.h b/impeller/entity/contents/vertices_contents.h index b10c7c0b7c250..0f754c4c8ea25 100644 --- a/impeller/entity/contents/vertices_contents.h +++ b/impeller/entity/contents/vertices_contents.h @@ -27,12 +27,10 @@ class VerticesContents final : public Contents { void SetGeometry(std::unique_ptr geometry); - void SetAlpha(Scalar alpha); + void SetColor(Color color); void SetBlendMode(BlendMode blend_mode); - void SetSrcContents(std::shared_ptr src_contents); - // |Contents| std::optional GetCoverage(const Entity& entity) const override; @@ -42,16 +40,7 @@ class VerticesContents final : public Contents { RenderPass& pass) const override; public: - bool RenderDestination(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) const; - - bool RenderSource(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) const; - - Scalar alpha_; - std::shared_ptr src_contents_; + Color color_; std::unique_ptr geometry_; BlendMode blend_mode_ = BlendMode::kSource; diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 5deed280eba0e..31bd009a123db 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -1713,6 +1713,238 @@ TEST_P(EntityTest, SrgbToLinearFilter) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } +TEST_P(EntityTest, TTTBlendColor) { + { + Color src = {1, 0, 0, 0.5}; + Color dst = {1, 0, 1, 1}; + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), + Color(1, 0, 0, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), + Color(1, 0, 1, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), + Color(1.5, 0, 0.5, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), + Color(1, 0, 1, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), + Color(1, 0, 0, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), + Color(0.5, 0, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), + Color(0.5, 0, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), + Color(1.5, 0, 0.5, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), + Color(0.5, 0, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), + Color(0.5, 0, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), Color(1, 0, 1, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), + Color(1, 0, 0, 0.5)); + } + + { + Color src = {1, 1, 0, 1}; + Color dst = {1, 0, 1, 1}; + + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), + Color(1, 1, 0, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), + Color(1, 0, 1, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), + Color(1, 1, 0, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), + Color(1, 0, 1, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), + Color(1, 1, 0, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), + Color(1, 0, 1, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), + Color(1, 1, 0, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), + Color(1, 0, 1, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), Color(1, 1, 1, 1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), + Color(1, 0, 0, 1)); + } + + { + Color src = {1, 1, 0, 0.2}; + Color dst = {1, 1, 1, 0.5}; + + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), + Color(1, 1, 0, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), + Color(1, 1, 1, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), + Color(1.8, 1.8, 0.8, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), + Color(1.5, 1.5, 1, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), + Color(0.5, 0.5, 0, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), + Color(0.2, 0.2, 0.2, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), + Color(0.5, 0.5, 0, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), + Color(0.8, 0.8, 0.8, 0.4)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), + Color(1.3, 1.3, 0.8, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), + Color(0.7, 0.7, 0.2, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), + Color(1.3, 1.3, 0.8, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), + Color(1, 1, 1, 0.7)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), + Color(1, 1, 0, 0.1)); + } + + { + Color src = {1, 0.5, 0, 0.2}; + Color dst = {1, 1, 0.5, 0.5}; + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), + Color(1, 0.5, 0, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), + Color(1, 1, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), + Color(1.8, 1.3, 0.4, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), + Color(1.5, 1.25, 0.5, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), + Color(0.5, 0.25, 0, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), + Color(0.2, 0.2, 0.1, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), + Color(0.5, 0.25, 0, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), + Color(0.8, 0.8, 0.4, 0.4)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), + Color(1.3, 1.05, 0.4, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), + Color(0.7, 0.45, 0.1, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), + Color(1.3, 1.05, 0.4, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), + Color(1, 1, 0.5, 0.7)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), + Color(1, 0.5, 0, 0.1)); + } + + { + Color src = {0.5, 0.5, 0, 0.2}; + Color dst = {0, 1, 0.5, 0.5}; + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), + Color(0.5, 0.5, 0, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), + Color(0, 1, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), + Color(0.5, 1.3, 0.4, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), + Color(0.25, 1.25, 0.5, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), + Color(0.25, 0.25, 0, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), + Color(0, 0.2, 0.1, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), + Color(0.25, 0.25, 0, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), + Color(0, 0.8, 0.4, 0.4)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), + Color(0.25, 1.05, 0.4, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), + Color(0.25, 0.45, 0.1, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), + Color(0.25, 1.05, 0.4, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), + Color(0.5, 1, 0.5, 0.7)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), + Color(0, 0.5, 0, 0.1)); + } + + { + Color src = {0.5, 0.5, 0.2, 0.2}; + Color dst = {0.2, 1, 0.5, 0.5}; + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), + Color(0.5, 0.5, 0.2, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), + Color(0.2, 1, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), + Color(0.66, 1.3, 0.6, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), + Color(0.45, 1.25, 0.6, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), + Color(0.25, 0.25, 0.1, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), + Color(0.04, 0.2, 0.1, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), + Color(0.25, 0.25, 0.1, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), + Color(0.16, 0.8, 0.4, 0.4)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), + Color(0.41, 1.05, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), + Color(0.29, 0.45, 0.2, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), + Color(0.41, 1.05, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), + Color(0.7, 1, 0.7, 0.7)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), + Color(0.1, 0.5, 0.1, 0.1)); + } + + { + Color src = {0.5, 0.5, 0.2, 0.2}; + Color dst = {0.2, 0.2, 0.5, 0.5}; + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kClear), + Color(0, 0, 0, 0)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSource), + Color(0.5, 0.5, 0.2, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestination), + Color(0.2, 0.2, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOver), + Color(0.66, 0.66, 0.6, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOver), + Color(0.45, 0.45, 0.6, 0.6)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceIn), + Color(0.25, 0.25, 0.1, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationIn), + Color(0.04, 0.04, 0.1, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceOut), + Color(0.25, 0.25, 0.1, 0.1)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationOut), + Color(0.16, 0.16, 0.4, 0.4)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kSourceATop), + Color(0.41, 0.41, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kDestinationATop), + Color(0.29, 0.29, 0.2, 0.2)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kXor), + Color(0.41, 0.41, 0.5, 0.5)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kPlus), + Color(0.7, 0.7, 0.7, 0.7)); + ASSERT_EQ(Color::BlendColor(src, dst, BlendMode::kModulate), + Color(0.1, 0.1, 0.1, 0.1)); + } +} + TEST_P(EntityTest, SdfText) { auto callback = [&](ContentContext& context, RenderPass& pass) -> bool { SkFont font; diff --git a/impeller/entity/geometry.h b/impeller/entity/geometry.h index 4e73f8985a766..dabab1d1dc42a 100644 --- a/impeller/entity/geometry.h +++ b/impeller/entity/geometry.h @@ -75,20 +75,13 @@ class VerticesGeometry : public Geometry { public: virtual GeometryResult GetPositionColorBuffer(const ContentContext& renderer, const Entity& entity, - RenderPass& pass) = 0; + RenderPass& pass, + Color paint_color, + BlendMode blend_mode) = 0; virtual GeometryResult GetPositionUVBuffer(const ContentContext& renderer, const Entity& entity, RenderPass& pass) = 0; - - virtual GeometryResult GetPositionUVColorBuffer( - const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) = 0; - - virtual bool HasTextureCoordinates() const = 0; - - virtual bool HasVertexColors() const = 0; }; /// @brief A geometry that is created from a filled path object. diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl deleted file mode 100644 index 6d71fdfc9ad8b..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend.glsl +++ /dev/null @@ -1,34 +0,0 @@ -// 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 -#include -#include - -uniform FragInfo { - float src_y_coord_scale; - float alpha; -} -blend_info; - -uniform sampler2D texture_sampler_src; - -in vec2 v_src_texture_coords; -in vec4 v_dst_color; // This color input is expected to be unpremultiplied. - -out vec4 frag_color; - -void main() { - vec4 dst = v_dst_color; - vec4 src = IPUnpremultiply(IPSampleWithTileMode( - texture_sampler_src, // sampler - v_src_texture_coords, // texture coordinates - blend_info.src_y_coord_scale, // y coordinate scale - kTileModeDecal // tile mode - )); - - vec4 blended = vec4(Blend(dst.rgb, src.rgb), 1) * dst.a; - frag_color = mix(dst, blended, src.a) * blend_info.alpha; -} diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag deleted file mode 100644 index 849ee76c172b4..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_color.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendColor(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag deleted file mode 100644 index 78e34c22addb2..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colorburn.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendColorBurn(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag deleted file mode 100644 index 57e2b03b61baa..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_colordodge.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendColorDodge(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag deleted file mode 100644 index a0a2fa4e82f54..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_darken.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendDarken(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag deleted file mode 100644 index d0489cb9a6e5f..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_difference.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendDifference(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag deleted file mode 100644 index 8879eac4fe47a..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_exclusion.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendExclusion(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag deleted file mode 100644 index 776d03a0dddeb..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hardlight.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendHardLight(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag deleted file mode 100644 index 5153f4890b14b..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_hue.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendHue(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag deleted file mode 100644 index e1f134d783b57..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_lighten.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendLighten(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag deleted file mode 100644 index e6990eb0ddc9d..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_luminosity.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendLuminosity(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag deleted file mode 100644 index ef9eec81fea1c..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_multiply.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendMultiply(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag deleted file mode 100644 index b31ce6c1f4abb..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_overlay.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendOverlay(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag deleted file mode 100644 index f00daeab4dc32..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_saturation.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendSaturation(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag deleted file mode 100644 index 9beeedd345538..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_screen.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendScreen(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag b/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag deleted file mode 100644 index 70b6ad4300092..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_advanced_blend_softlight.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec3 Blend(vec3 dst, vec3 src) { - return IPBlendSoftLight(dst, src); -} - -#include "atlas_advanced_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend.glsl b/impeller/entity/shaders/atlas_blending/atlas_blend.glsl deleted file mode 100644 index b869cb79b7660..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend.glsl +++ /dev/null @@ -1,33 +0,0 @@ -// 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 -#include -#include - -uniform FragInfo { - float src_y_coord_scale; - float alpha; -} -blend_info; - -uniform sampler2D texture_sampler_src; - -in vec2 v_src_texture_coords; -in vec4 v_dst_color; // This color input is expected to be unpremultiplied. - -out vec4 frag_color; - -void main() { - vec4 dst = IPPremultiply(v_dst_color); - vec4 src = - IPSampleWithTileMode(texture_sampler_src, // sampler - v_src_texture_coords, // texture coordinates - blend_info.src_y_coord_scale, // y coordinate scale - kTileModeDecal // tile mode - ); - - frag_color = Blend(dst, src) * blend_info.alpha; -} diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend.vert b/impeller/entity/shaders/atlas_blending/atlas_blend.vert deleted file mode 100644 index 53bb320bb05bb..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend.vert +++ /dev/null @@ -1,23 +0,0 @@ -// 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 FrameInfo { - mat4 mvp; -} -frame_info; - -in vec2 vertices; -in vec4 dst_color; -in vec2 src_texture_coords; - -out vec2 v_src_texture_coords; -out vec4 v_dst_color; - -void main() { - gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0); - v_src_texture_coords = src_texture_coords; - v_dst_color = dst_color; -} diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag deleted file mode 100644 index 165a5aa9627f9..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_a_top.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendDstATop(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag deleted file mode 100644 index 837e01cf61787..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_in.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendDstIn(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag deleted file mode 100644 index b1edb35c402b3..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_out.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendDstOut(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag deleted file mode 100644 index c5d1be410d5c8..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_dst_over.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendDstOver(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag deleted file mode 100644 index 0893836ea40c1..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_modulate.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendModulate(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag deleted file mode 100644 index 9857adc512638..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_plus.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendPlus(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag deleted file mode 100644 index c4e06d8f0fa10..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_src_a_top.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendSrcATop(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag deleted file mode 100644 index fa5eccc6f6ca0..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_src_in.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendSrcIn(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag deleted file mode 100644 index 6e4a63570bc97..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_src_out.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendSrcOut(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag deleted file mode 100644 index dbf179304f929..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_src_over.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendSrcOver(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag b/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag deleted file mode 100644 index a88653def3cba..0000000000000 --- a/impeller/entity/shaders/atlas_blending/atlas_blend_xor.frag +++ /dev/null @@ -1,11 +0,0 @@ -// 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 - -vec4 Blend(vec4 dst, vec4 src) { - return IPBlendXor(dst, src); -} - -#include "atlas_blend.glsl" diff --git a/impeller/geometry/color.cc b/impeller/geometry/color.cc index 34da51c04144a..70946f66a8528 100644 --- a/impeller/geometry/color.cc +++ b/impeller/geometry/color.cc @@ -110,4 +110,134 @@ Color Min(Color c, float threshold) { std::min(c.blue, threshold), std::min(c.alpha, threshold)); } +Color Color::BlendColor(const Color& src, + const Color& dst, + BlendMode blend_mode) { + static auto apply_rgb_srcover_alpha = [&](auto f) -> Color { + return Color(f(src.red, dst.red), f(src.green, dst.green), + f(src.blue, dst.blue), + dst.alpha * (1 - src.alpha) + src.alpha // srcOver alpha + ); + }; + + switch (blend_mode) { + case BlendMode::kClear: + return Color::BlackTransparent(); + case BlendMode::kSource: + return src; + case BlendMode::kDestination: + return dst; + case BlendMode::kSourceOver: + // r = s + (1-sa)*d + return src + dst * (1 - src.alpha); + case BlendMode::kDestinationOver: + // r = d + (1-da)*s + return dst + src * (1 - dst.alpha); + case BlendMode::kSourceIn: + // r = s * da + return src * dst.alpha; + case BlendMode::kDestinationIn: + // r = d * sa + return dst * src.alpha; + case BlendMode::kSourceOut: + // r = s * ( 1- da) + return src * (1 - dst.alpha); + case BlendMode::kDestinationOut: + // r = d * (1-sa) + return dst * (1 - src.alpha); + case BlendMode::kSourceATop: + // r = s*da + d*(1-sa) + return src * dst.alpha + dst * (1 - src.alpha); + case BlendMode::kDestinationATop: + // r = d*sa + s*(1-da) + return dst * src.alpha + src * (1 - dst.alpha); + case BlendMode::kXor: + // r = s*(1-da) + d*(1-sa) + return src * (1 - dst.alpha) + dst * (1 - src.alpha); + case BlendMode::kPlus: + // r = min(s + d, 1) + return Min(src + dst, 1); + case BlendMode::kModulate: + // r = s*d + return src * dst; + case BlendMode::kScreen: { + // r = s + d - s*d + return src + dst - src * dst; + } + case BlendMode::kOverlay: + return apply_rgb_srcover_alpha([&](auto s, auto d) { + if (d * 2 < dst.alpha) { + return 2 * s * d; + } + return src.alpha * dst.alpha - 2 * (dst.alpha - s) * (src.alpha - d); + }); + case BlendMode::kDarken: { + return apply_rgb_srcover_alpha([&](auto s, auto d) { + return (1 - dst.alpha) * s + (1 - src.alpha) * d + std::min(s, d); + }); + } + case BlendMode::kLighten: + return apply_rgb_srcover_alpha([&](auto s, auto d) { + return (1 - dst.alpha) * s + (1 - src.alpha) * d + std::max(s, d); + }); + case BlendMode::kColorDodge: + return apply_rgb_srcover_alpha([&](auto s, auto d) { + if (d == 0) { + return s * (1 - src.alpha); + } + if (s == src.alpha) { + return s + dst.alpha * (1 - src.alpha); + } + return src.alpha * + std::min(dst.alpha, d * src.alpha / (src.alpha - s)) + + s * (1 - dst.alpha + dst.alpha * (1 - src.alpha)); + }); + case BlendMode::kColorBurn: + return apply_rgb_srcover_alpha([&](auto s, auto d) { + if (s == 0) { + return dst.alpha * (1 - src.alpha); + } + if (d == dst.alpha) { + return d + s * (1 - dst.alpha); + } + // s.a * (d.a - min(d.a, (d.a - s) * s.a/s)) + s * (1-d.a) + d.a * (1 - + // s.a) + return src.alpha * + (dst.alpha - + std::min(dst.alpha, (dst.alpha - d) * src.alpha / s)) + + s * (1 - dst.alpha) + dst.alpha * (1 - src.alpha); + }); + case BlendMode::kHardLight: + return apply_rgb_srcover_alpha([&](auto s, auto d) { + if (src.alpha >= s * (1 - dst.alpha) + d * (1 - src.alpha) + 2 * s) { + return 2 * s * d; + } + // s.a * d.a - 2 * (d.a - d) * (s.a - s) + return src.alpha * dst.alpha - 2 * (dst.alpha - d) * (src.alpha - s); + }); + case BlendMode::kDifference: + return apply_rgb_srcover_alpha([&](auto s, auto d) { + // s + d - 2 * min(s * d.a, d * s.a); + return s + d - 2 * std::min(s * dst.alpha, d * src.alpha); + }); + case BlendMode::kExclusion: + return apply_rgb_srcover_alpha([&](auto s, auto d) { + // s + d - 2 * s * d + return s + d - 2 * s * d; + }); + case BlendMode::kMultiply: + return apply_rgb_srcover_alpha([&](auto s, auto d) { + // s * (1 - d.a) + d * (1 - s.a) + (s * d) + return s * (1 - dst.alpha) + d * (1 - src.alpha) + (s * d); + }); + case BlendMode::kHue: + case BlendMode::kSaturation: + case BlendMode::kColor: + case BlendMode::kLuminosity: + case BlendMode::kSoftLight: + default: + return src + dst * (1 - src.alpha); + } +} + } // namespace impeller diff --git a/impeller/geometry/color.h b/impeller/geometry/color.h index 5a3a0b7d8091d..6966a3ccc0f6d 100644 --- a/impeller/geometry/color.h +++ b/impeller/geometry/color.h @@ -734,6 +734,10 @@ struct Color { }; } + static Color BlendColor(const Color& src, + const Color& dst, + BlendMode blend_mode); + Color operator*(const Color& c) const { return Color(red * c.red, green * c.green, blue * c.blue, alpha * c.alpha); } From d8b3023899af301394273d57183c860d8f70006b Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 17 Jan 2023 17:06:53 -0800 Subject: [PATCH 16/26] ++ --- impeller/entity/contents/atlas_contents.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/entity/contents/atlas_contents.h b/impeller/entity/contents/atlas_contents.h index 3a0340d9aaae6..661c34a79307e 100644 --- a/impeller/entity/contents/atlas_contents.h +++ b/impeller/entity/contents/atlas_contents.h @@ -56,8 +56,8 @@ class AtlasContents final : public Contents { bool apply_blend = false) const; bool RenderColors(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass) const; + const Entity& entity, + RenderPass& pass) const; Rect ComputeBoundingBox() const; From a4f25cd5cd2ff07890363935d9011475ee8631e0 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 17 Jan 2023 17:11:14 -0800 Subject: [PATCH 17/26] ++ --- .../shader_lib/impeller/blending.glsl | 51 ------- .../display_list/display_list_unittests.cc | 132 ------------------ impeller/entity/contents/atlas_contents.cc | 1 - impeller/entity/shaders/vertices.frag | 7 +- 4 files changed, 1 insertion(+), 190 deletions(-) diff --git a/impeller/compiler/shader_lib/impeller/blending.glsl b/impeller/compiler/shader_lib/impeller/blending.glsl index 77ac61a5c4049..f92e6bc4ab9a0 100644 --- a/impeller/compiler/shader_lib/impeller/blending.glsl +++ b/impeller/compiler/shader_lib/impeller/blending.glsl @@ -190,55 +190,4 @@ vec3 IPBlendLuminosity(vec3 dst, vec3 src) { return IPSetLuminosity(dst, IPLuminosity(src)); } -vec4 IPBlendSrcOver(vec4 dst, vec4 src) { - return src + dst * (1 - src.a); -} - -vec4 IPBlendSrcIn(vec4 dst, vec4 src) { - // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcin - return src * dst.a; -} - -vec4 IPBlendDstOver(vec4 dst, vec4 src) { - // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstout - return dst + src * (1 - dst.a); -} - -vec4 IPBlendDstIn(vec4 dst, vec4 src) { - // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstin - return dst * src.a; -} - -vec4 IPBlendDstOut(vec4 dst, vec4 src) { - return dst * (1 - src.a); -} - -vec4 IPBlendSrcOut(vec4 dst, vec4 src) { - // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcout - return src * (1 - dst.a); -} - -vec4 IPBlendSrcATop(vec4 dst, vec4 src) { - // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcatop - return src * dst.a + dst * (1 - src.a); -} - -vec4 IPBlendDstATop(vec4 dst, vec4 src) { - // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstatop - return dst * src.a + src * (1 - dst.a); -} - -vec4 IPBlendXor(vec4 dst, vec4 src) { - // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_xor - return src * (1 - dst.a) + dst * (1 - src.a); -} - -vec4 IPBlendPlus(vec4 dst, vec4 src) { - return min(src + dst, vec4(1)); -} - -vec4 IPBlendModulate(vec4 dst, vec4 src) { - return src * dst; -} - #endif diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc index 08371f4019536..3ce405483022a 100644 --- a/impeller/display_list/display_list_unittests.cc +++ b/impeller/display_list/display_list_unittests.cc @@ -34,15 +34,6 @@ namespace impeller { namespace testing { -flutter::DlColor toColor(const float* components) { - auto value = (((std::lround(components[3] * 255) & 0xff) << 24) | - ((std::lround(components[0] * 255) & 0xff) << 16) | - ((std::lround(components[1] * 255) & 0xff) << 8) | - ((std::lround(components[2] * 255) & 0xff) << 0)) & - 0xFFFFFFFF; - return flutter::DlColor(value); -} - using DisplayListTest = DisplayListPlayground; INSTANTIATE_PLAYGROUND_SUITE(DisplayListTest); @@ -1111,38 +1102,6 @@ TEST_P(DisplayListTest, DrawVerticesLinearGradientWithoutIndices) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } -TEST_P(DisplayListTest, DrawVerticesLinearGradientWithTextureCoordinates) { - std::vector positions = {SkPoint::Make(100, 300), - SkPoint::Make(200, 100), - SkPoint::Make(300, 300)}; - std::vector texture_coordinates = {SkPoint::Make(1.0, 1.0), - SkPoint::Make(0.0, 1.0), - SkPoint::Make(0.0, 0.0)}; - std::vector colors = {flutter::DlColor::kRed(), - flutter::DlColor::kGreen(), - flutter::DlColor::kBlue()}; - - auto vertices = flutter::DlVertices::Make( - flutter::DlVertexMode::kTriangles, 3, positions.data(), - texture_coordinates.data(), colors.data()); - - std::vector gradient_colors = {flutter::DlColor::kBlue(), - flutter::DlColor::kRed()}; - const float stops[2] = {0.0, 1.0}; - - auto linear = flutter::DlColorSource::MakeLinear( - {100.0, 100.0}, {300.0, 300.0}, 2, gradient_colors.data(), stops, - flutter::DlTileMode::kRepeat); - - flutter::DisplayListBuilder builder; - flutter::DlPaint paint; - - paint.setColorSource(linear); - builder.drawVertices(vertices, flutter::DlBlendMode::kSrcOver, paint); - - ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); -} - TEST_P(DisplayListTest, DrawVerticesSolidColorTrianglesWithIndices) { std::vector positions = { SkPoint::Make(100, 300), SkPoint::Make(200, 100), SkPoint::Make(300, 300), @@ -1200,97 +1159,6 @@ TEST_P(DisplayListTest, DrawShapes) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } -TEST_P(DisplayListTest, DrawVerticesBlendModes) { - std::vector blend_mode_names; - std::vector blend_mode_values; - { - const std::vector> blends = { - // Pipeline blends (Porter-Duff alpha compositing) - {"Clear", flutter::DlBlendMode::kClear}, - {"Source", flutter::DlBlendMode::kSrc}, - {"Destination", flutter::DlBlendMode::kDst}, - {"SourceOver", flutter::DlBlendMode::kSrcOver}, - {"DestinationOver", flutter::DlBlendMode::kDstOver}, - {"SourceIn", flutter::DlBlendMode::kSrcIn}, - {"DestinationIn", flutter::DlBlendMode::kDstIn}, - {"SourceOut", flutter::DlBlendMode::kSrcOut}, - {"DestinationOut", flutter::DlBlendMode::kDstOut}, - {"SourceATop", flutter::DlBlendMode::kSrcATop}, - {"DestinationATop", flutter::DlBlendMode::kDstATop}, - {"Xor", flutter::DlBlendMode::kXor}, - {"Plus", flutter::DlBlendMode::kPlus}, - {"Modulate", flutter::DlBlendMode::kModulate}, - // Advanced blends (color component blends) - {"Screen", flutter::DlBlendMode::kScreen}, - {"Overlay", flutter::DlBlendMode::kOverlay}, - {"Darken", flutter::DlBlendMode::kDarken}, - {"Lighten", flutter::DlBlendMode::kLighten}, - {"ColorDodge", flutter::DlBlendMode::kColorDodge}, - {"ColorBurn", flutter::DlBlendMode::kColorBurn}, - {"HardLight", flutter::DlBlendMode::kHardLight}, - {"SoftLight", flutter::DlBlendMode::kSoftLight}, - {"Difference", flutter::DlBlendMode::kDifference}, - {"Exclusion", flutter::DlBlendMode::kExclusion}, - {"Multiply", flutter::DlBlendMode::kMultiply}, - {"Hue", flutter::DlBlendMode::kHue}, - {"Saturation", flutter::DlBlendMode::kSaturation}, - {"Color", flutter::DlBlendMode::kColor}, - {"Luminosity", flutter::DlBlendMode::kLuminosity}, - }; - assert(blends.size() == - static_cast(flutter::DlBlendMode::kLastMode) + 1); - for (const auto& [name, mode] : blends) { - blend_mode_names.push_back(name); - blend_mode_values.push_back(mode); - } - } - - auto callback = [&]() { - static int current_blend_index = 3; - static float dst_alpha = 1; - static float src_alpha = 1; - static float color0[4] = {1.0f, 0.0f, 0.0f, 1.0f}; - static float color1[4] = {0.0f, 1.0f, 0.0f, 1.0f}; - static float color2[4] = {0.0f, 0.0f, 1.0f, 1.0f}; - static float src_color[4] = {1.0f, 1.0f, 1.0f, 1.0f}; - - ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize); - { - ImGui::ListBox("Blending mode", ¤t_blend_index, - blend_mode_names.data(), blend_mode_names.size()); - ImGui::SliderFloat("Source alpha", &src_alpha, 0, 1); - ImGui::ColorEdit4("Color A", color0); - ImGui::ColorEdit4("Color B", color1); - ImGui::ColorEdit4("Color C", color2); - ImGui::ColorEdit4("Source Color", src_color); - ImGui::SliderFloat("Destination alpha", &dst_alpha, 0, 1); - } - ImGui::End(); - - std::vector positions = {SkPoint::Make(100, 300), - SkPoint::Make(200, 100), - SkPoint::Make(300, 300)}; - std::vector colors = { - toColor(color0).modulateOpacity(dst_alpha), - toColor(color1).modulateOpacity(dst_alpha), - toColor(color2).modulateOpacity(dst_alpha)}; - - auto vertices = flutter::DlVertices::Make( - flutter::DlVertexMode::kTriangles, 3, positions.data(), - /*texture_coorindates=*/nullptr, colors.data()); - - flutter::DisplayListBuilder builder; - flutter::DlPaint paint; - - paint.setColor(toColor(src_color).modulateOpacity(src_alpha)); - builder.drawVertices(vertices, blend_mode_values[current_blend_index], - paint); - return builder.Build(); - }; - - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - #ifdef IMPELLER_ENABLE_3D TEST_P(DisplayListTest, SceneColorSource) { // Load up the scene. diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index bdde94960f3c0..52c99142bf0b7 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.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 #include #include diff --git a/impeller/entity/shaders/vertices.frag b/impeller/entity/shaders/vertices.frag index 029d33da06ba9..c42e809ecc14d 100644 --- a/impeller/entity/shaders/vertices.frag +++ b/impeller/entity/shaders/vertices.frag @@ -4,15 +4,10 @@ #include -uniform FragInfo { - float alpha; -} -frag_info; - in vec4 v_color; out vec4 frag_color; void main() { - frag_color = v_color * frag_info.alpha; + frag_color = v_color; } From 7d9e751ad49959fd76568350f38c98815e1808a7 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 17 Jan 2023 17:16:37 -0800 Subject: [PATCH 18/26] ++ --- impeller/entity/contents/vertices_contents.cc | 5 +++++ impeller/entity/shaders/vertices.frag | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/impeller/entity/contents/vertices_contents.cc b/impeller/entity/contents/vertices_contents.cc index 3d0357ed9ae12..65b8c88762b48 100644 --- a/impeller/entity/contents/vertices_contents.cc +++ b/impeller/entity/contents/vertices_contents.cc @@ -83,6 +83,11 @@ bool VerticesContents::Render(const ContentContext& renderer, break; } } + using FS = GeometryColorPipeline::FragmentShader; + FS::FragInfo frag_info; + frag_info.alpha = 1.0; + FS::BindFragInfo(cmd, pass.GetTransientsBuffer().EmplaceUniform(frag_info)); + pass.AddCommand(std::move(cmd)); return true; diff --git a/impeller/entity/shaders/vertices.frag b/impeller/entity/shaders/vertices.frag index c42e809ecc14d..029d33da06ba9 100644 --- a/impeller/entity/shaders/vertices.frag +++ b/impeller/entity/shaders/vertices.frag @@ -4,10 +4,15 @@ #include +uniform FragInfo { + float alpha; +} +frag_info; + in vec4 v_color; out vec4 frag_color; void main() { - frag_color = v_color; + frag_color = v_color * frag_info.alpha; } From 040a83f7e3cbac0c7c90f806a231a397d39d2d4c Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 17 Jan 2023 18:22:47 -0800 Subject: [PATCH 19/26] remove atlas_fill from licenses --- ci/licenses_golden/licenses_flutter | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 809ebb4c30865..f31e391326953 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1313,8 +1313,6 @@ ORIGIN: ../../../flutter/impeller/entity/geometry.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/geometry.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/inline_pass_context.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/inline_pass_context.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_fill.frag + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/impeller/entity/shaders/atlas_fill.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_color.frag + ../../../flutter/LICENSE @@ -3794,8 +3792,6 @@ FILE: ../../../flutter/impeller/entity/geometry.cc FILE: ../../../flutter/impeller/entity/geometry.h FILE: ../../../flutter/impeller/entity/inline_pass_context.cc FILE: ../../../flutter/impeller/entity/inline_pass_context.h -FILE: ../../../flutter/impeller/entity/shaders/atlas_fill.frag -FILE: ../../../flutter/impeller/entity/shaders/atlas_fill.vert FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.glsl FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend.vert FILE: ../../../flutter/impeller/entity/shaders/blending/advanced_blend_color.frag From e83fb612bc9ee9b7f03ad44ac13b11ec6f03d118 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 18 Jan 2023 12:05:53 -0800 Subject: [PATCH 20/26] blending cleanup --- impeller/aiks/canvas.cc | 8 ---- impeller/entity/contents/atlas_contents.cc | 46 +++++++++++++------ impeller/entity/contents/atlas_contents.h | 4 +- .../contents/filters/blend_filter_contents.cc | 42 +++++++++-------- .../contents/filters/blend_filter_contents.h | 3 +- .../contents/filters/color_filter_contents.cc | 8 ++++ .../contents/filters/color_filter_contents.h | 7 +++ impeller/entity/entity_unittests.cc | 40 +++++++++++++++- 8 files changed, 113 insertions(+), 45 deletions(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 80344bcbfd879..671528394c8cc 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -414,12 +414,6 @@ void Canvas::DrawAtlas(const std::shared_ptr& atlas, if (!atlas) { return; } - auto size = atlas->GetSize(); - - if (size.IsEmpty()) { - return; - } - SaveLayer(Paint()); std::shared_ptr contents = std::make_shared(); contents->SetColors(std::move(colors)); @@ -438,8 +432,6 @@ void Canvas::DrawAtlas(const std::shared_ptr& atlas, entity.SetContents(paint.WithFilters(contents, false)); GetCurrentPass().AddEntity(entity); - - Restore(); } } // namespace impeller diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 52c99142bf0b7..0477b8016f133 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -90,18 +90,10 @@ bool AtlasContents::Render(const ContentContext& renderer, } if (blend_mode_ == BlendMode::kSource || colors_.size() == 0) { - return RenderTexture(renderer, entity, pass); + return RenderTexture(renderer, entity, pass, alpha_); } if (blend_mode_ == BlendMode::kDestination) { - return RenderColors(renderer, entity, pass); - } - - // Simple blends. - if (blend_mode_ < BlendMode::kScreen) { - if (!RenderColors(renderer, entity, pass)) { - return false; - } - return RenderTexture(renderer, entity, pass, true); + return RenderColors(renderer, entity, pass, alpha_); } // Ensure that we use the actual computed bounds and not a cull-rect @@ -109,6 +101,27 @@ bool AtlasContents::Render(const ContentContext& renderer, auto coverage = ComputeBoundingBox(); auto size = coverage.size; + // Simple blends. + if (blend_mode_ < BlendMode::kScreen) { + auto subpass_texture = renderer.MakeSubpass( + ISize::Ceil(size), + [&contents = *this, &coverage](const ContentContext& renderer, + RenderPass& pass) -> bool { + Entity sub_entity; + sub_entity.SetBlendMode(BlendMode::kSourceOver); + sub_entity.SetTransformation( + Matrix::MakeTranslation(Vector3(-coverage.origin))); + if (!contents.RenderColors(renderer, sub_entity, pass, 1.0)) { + return false; + } + return contents.RenderTexture(renderer, sub_entity, pass, 1.0, true); + }); + auto contents = ColorFilterContents::MakeBlend( + blend_mode_, {FilterInput::Make(subpass_texture)}); + contents->SetAlpha(alpha_); + return contents->Render(renderer, entity, pass); + } + auto dst_texture = renderer.MakeSubpass( ISize::Ceil(size), [&contents = *this, &coverage](const ContentContext& renderer, @@ -117,7 +130,7 @@ bool AtlasContents::Render(const ContentContext& renderer, sub_entity.SetBlendMode(BlendMode::kSourceOver); sub_entity.SetTransformation( Matrix::MakeTranslation(Vector3(-coverage.origin))); - return contents.RenderColors(renderer, sub_entity, pass); + return contents.RenderColors(renderer, sub_entity, pass, 1.0); }); auto src_texture = renderer.MakeSubpass( ISize::Ceil(size), @@ -127,7 +140,7 @@ bool AtlasContents::Render(const ContentContext& renderer, sub_entity.SetBlendMode(BlendMode::kSourceOver); sub_entity.SetTransformation( Matrix::MakeTranslation(Vector3(-coverage.origin))); - return contents.RenderTexture(renderer, sub_entity, pass); + return contents.RenderTexture(renderer, sub_entity, pass, 1.0); }); if (!src_texture || !dst_texture) { @@ -136,12 +149,14 @@ bool AtlasContents::Render(const ContentContext& renderer, auto contents = ColorFilterContents::MakeBlend( blend_mode_, {FilterInput::Make(src_texture), FilterInput::Make(dst_texture)}); + contents->SetAlpha(alpha_); return contents->Render(renderer, entity, pass); } bool AtlasContents::RenderColors(const ContentContext& renderer, const Entity& entity, - RenderPass& pass) const { + RenderPass& pass, + Scalar alpha) const { using VS = GeometryColorPipeline::VertexShader; using FS = GeometryColorPipeline::FragmentShader; @@ -176,7 +191,7 @@ bool AtlasContents::RenderColors(const ContentContext& renderer, entity.GetTransformation(); FS::FragInfo frag_info; - frag_info.alpha = 1.0; + frag_info.alpha = alpha; auto opts = OptionsFromPassAndEntity(pass, entity); opts.blend_mode = BlendMode::kSourceOver; @@ -191,6 +206,7 @@ bool AtlasContents::RenderColors(const ContentContext& renderer, bool AtlasContents::RenderTexture(const ContentContext& renderer, const Entity& entity, RenderPass& pass, + Scalar alpha, bool apply_blend) const { using VS = TextureFillVertexShader; using FS = TextureFillFragmentShader; @@ -233,7 +249,7 @@ bool AtlasContents::RenderTexture(const ContentContext& renderer, FS::FragInfo frag_info; frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale(); - frag_info.alpha = alpha_; + frag_info.alpha = alpha; auto options = OptionsFromPassAndEntity(pass, entity); if (apply_blend) { diff --git a/impeller/entity/contents/atlas_contents.h b/impeller/entity/contents/atlas_contents.h index 661c34a79307e..ab8c862e63787 100644 --- a/impeller/entity/contents/atlas_contents.h +++ b/impeller/entity/contents/atlas_contents.h @@ -53,11 +53,13 @@ class AtlasContents final : public Contents { bool RenderTexture(const ContentContext& renderer, const Entity& entity, RenderPass& pass, + Scalar alpha, bool apply_blend = false) const; bool RenderColors(const ContentContext& renderer, const Entity& entity, - RenderPass& pass) const; + RenderPass& pass, + Scalar alpha) const; Rect ComputeBoundingBox() const; diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index 687d19f4012b5..ad353f309b93f 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -36,7 +36,8 @@ static std::optional AdvancedBlend( const Rect& coverage, std::optional foreground_color, bool absorb_opacity, - PipelineProc pipeline_proc) { + PipelineProc pipeline_proc, + std::optional alpha) { using VS = typename TPipeline::VertexShader; using FS = typename TPipeline::FragmentShader; @@ -109,7 +110,8 @@ static std::optional AdvancedBlend( auto sampler = renderer.GetContext()->GetSamplerLibrary()->GetSampler({}); FS::BindTextureSamplerDst(cmd, dst_snapshot->texture, sampler); blend_info.dst_y_coord_scale = dst_snapshot->texture->GetYCoordScale(); - blend_info.dst_input_alpha = absorb_opacity ? dst_snapshot->opacity : 1.0f; + blend_info.dst_input_alpha = + absorb_opacity ? dst_snapshot->opacity : alpha.value_or(1.0f); if (foreground_color.has_value()) { blend_info.color_factor = 1; @@ -155,7 +157,8 @@ static std::optional PipelineBlend( const Rect& coverage, BlendMode pipeline_blend, std::optional foreground_color, - bool absorb_opacity) { + bool absorb_opacity, + std::optional alpha) { using VS = BlendPipeline::VertexShader; using FS = BlendPipeline::FragmentShader; @@ -202,7 +205,8 @@ static std::optional PipelineBlend( FS::FragInfo frag_info; frag_info.texture_sampler_y_coord_scale = input->texture->GetYCoordScale(); - frag_info.input_alpha = absorb_opacity ? input->opacity : 1.0f; + frag_info.input_alpha = + absorb_opacity ? input->opacity : alpha.value_or(1.0f); FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); @@ -267,17 +271,18 @@ static std::optional PipelineBlend( .opacity = absorb_opacity ? 1.0f : input_snapshot->opacity}; } -#define BLEND_CASE(mode) \ - case BlendMode::k##mode: \ - advanced_blend_proc_ = [](const FilterInput::Vector& inputs, \ - const ContentContext& renderer, \ - const Entity& entity, const Rect& coverage, \ - std::optional fg_color, \ - bool absorb_opacity) { \ - PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \ - return AdvancedBlend( \ - inputs, renderer, entity, coverage, fg_color, absorb_opacity, p); \ - }; \ +#define BLEND_CASE(mode) \ + case BlendMode::k##mode: \ + advanced_blend_proc_ = \ + [](const FilterInput::Vector& inputs, const ContentContext& renderer, \ + const Entity& entity, const Rect& coverage, \ + std::optional fg_color, bool absorb_opacity, \ + std::optional alpha) { \ + PipelineProc p = &ContentContext::GetBlend##mode##Pipeline; \ + return AdvancedBlend(inputs, renderer, entity, \ + coverage, fg_color, \ + absorb_opacity, p, alpha); \ + }; \ break; void BlendFilterContents::SetBlendMode(BlendMode blend_mode) { @@ -328,17 +333,18 @@ std::optional BlendFilterContents::RenderFilter( if (inputs.size() == 1 && !foreground_color_.has_value()) { // Nothing to blend. return PipelineBlend(inputs, renderer, entity, coverage, BlendMode::kSource, - std::nullopt, GetAbsorbOpacity()); + std::nullopt, GetAbsorbOpacity(), GetAlpha()); } if (blend_mode_ <= Entity::kLastPipelineBlendMode) { return PipelineBlend(inputs, renderer, entity, coverage, blend_mode_, - foreground_color_, GetAbsorbOpacity()); + foreground_color_, GetAbsorbOpacity(), GetAlpha()); } if (blend_mode_ <= Entity::kLastAdvancedBlendMode) { return advanced_blend_proc_(inputs, renderer, entity, coverage, - foreground_color_, GetAbsorbOpacity()); + foreground_color_, GetAbsorbOpacity(), + GetAlpha()); } FML_UNREACHABLE(); } diff --git a/impeller/entity/contents/filters/blend_filter_contents.h b/impeller/entity/contents/filters/blend_filter_contents.h index 5276eb81f05f1..47734ffa7b554 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.h +++ b/impeller/entity/contents/filters/blend_filter_contents.h @@ -17,7 +17,8 @@ class BlendFilterContents : public ColorFilterContents { const Entity& entity, const Rect& coverage, std::optional foreground_color, - bool absorb_opacity)>; + bool absorb_opacity, + std::optional alpha)>; BlendFilterContents(); diff --git a/impeller/entity/contents/filters/color_filter_contents.cc b/impeller/entity/contents/filters/color_filter_contents.cc index a4b8db8fc6cce..2fd233ae1813d 100644 --- a/impeller/entity/contents/filters/color_filter_contents.cc +++ b/impeller/entity/contents/filters/color_filter_contents.cc @@ -90,4 +90,12 @@ bool ColorFilterContents::GetAbsorbOpacity() const { return absorb_opacity_; } +void ColorFilterContents::SetAlpha(Scalar alpha) { + alpha_ = alpha; +} + +std::optional ColorFilterContents::GetAlpha() const { + return alpha_; +} + } // namespace impeller diff --git a/impeller/entity/contents/filters/color_filter_contents.h b/impeller/entity/contents/filters/color_filter_contents.h index 17e54b56039f0..76b205eb924bf 100644 --- a/impeller/entity/contents/filters/color_filter_contents.h +++ b/impeller/entity/contents/filters/color_filter_contents.h @@ -33,8 +33,15 @@ class ColorFilterContents : public FilterContents { bool GetAbsorbOpacity() const; + /// @brief Sets an alpha that is applied to the blended result, overriding any + /// inherited opacity. + void SetAlpha(Scalar alpha); + + std::optional GetAlpha() const; + private: bool absorb_opacity_ = false; + std::optional alpha_; FML_DISALLOW_COPY_AND_ASSIGN(ColorFilterContents); }; diff --git a/impeller/entity/entity_unittests.cc b/impeller/entity/entity_unittests.cc index 31bd009a123db..d9f0a9ca9c15f 100644 --- a/impeller/entity/entity_unittests.cc +++ b/impeller/entity/entity_unittests.cc @@ -1244,7 +1244,7 @@ TEST_P(EntityTest, DrawAtlasNoColor) { ASSERT_TRUE(OpenPlaygroundHere(e)); } -TEST_P(EntityTest, DrawAtlasWithColor) { +TEST_P(EntityTest, DrawAtlasWithColorAdvanced) { // Draws the image as four squares stiched together. Because blend modes // aren't implented this ends up as four solid color blocks. auto atlas = CreateTextureForFixture("bay_bridge.jpg"); @@ -1271,7 +1271,43 @@ TEST_P(EntityTest, DrawAtlasWithColor) { contents->SetTextureCoordinates(std::move(texture_coordinates)); contents->SetTexture(atlas); contents->SetColors(colors); - contents->SetBlendMode(BlendMode::kSource); + contents->SetBlendMode(BlendMode::kModulate); + + Entity e; + e.SetTransformation(Matrix::MakeScale(GetContentScale())); + e.SetContents(contents); + + ASSERT_TRUE(OpenPlaygroundHere(e)); +} + +TEST_P(EntityTest, DrawAtlasWithColorSimple) { + // Draws the image as four squares stiched together. Because blend modes + // aren't implented this ends up as four solid color blocks. + auto atlas = CreateTextureForFixture("bay_bridge.jpg"); + auto size = atlas->GetSize(); + // Divide image into four quadrants. + Scalar half_width = size.width / 2; + Scalar half_height = size.height / 2; + std::vector texture_coordinates = { + Rect::MakeLTRB(0, 0, half_width, half_height), + Rect::MakeLTRB(half_width, 0, size.width, half_height), + Rect::MakeLTRB(0, half_height, half_width, size.height), + Rect::MakeLTRB(half_width, half_height, size.width, size.height)}; + // Position quadrants adjacent to eachother. + std::vector transforms = { + Matrix::MakeTranslation({0, 0, 0}), + Matrix::MakeTranslation({half_width, 0, 0}), + Matrix::MakeTranslation({0, half_height, 0}), + Matrix::MakeTranslation({half_width, half_height, 0})}; + std::vector colors = {Color::Red(), Color::Green(), Color::Blue(), + Color::Yellow()}; + std::shared_ptr contents = std::make_shared(); + + contents->SetTransforms(std::move(transforms)); + contents->SetTextureCoordinates(std::move(texture_coordinates)); + contents->SetTexture(atlas); + contents->SetColors(colors); + contents->SetBlendMode(BlendMode::kSourceATop); Entity e; e.SetTransformation(Matrix::MakeScale(GetContentScale())); From 53a21899c12c2323060f0503897756aeb073dfb2 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 18 Jan 2023 15:32:16 -0800 Subject: [PATCH 21/26] Use sub-contents --- impeller/entity/contents/atlas_contents.cc | 216 ++++++++++-------- impeller/entity/contents/atlas_contents.h | 69 +++++- .../contents/filters/blend_filter_contents.cc | 4 +- 3 files changed, 179 insertions(+), 110 deletions(-) diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 0477b8016f133..899a02ffa774f 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -82,6 +82,18 @@ const SamplerDescriptor& AtlasContents::GetSamplerDescriptor() const { return sampler_descriptor_; } +const std::vector& AtlasContents::GetTransforms() const { + return transforms_; +} + +const std::vector& AtlasContents::GetTextureCoordinates() const { + return texture_coords_; +} + +const std::vector& AtlasContents::GetColors() const { + return colors_; +} + bool AtlasContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { @@ -89,90 +101,86 @@ bool AtlasContents::Render(const ContentContext& renderer, return true; } + // Ensure that we use the actual computed bounds and not a cull-rect + // approximation of them. + auto coverage = ComputeBoundingBox(); + if (blend_mode_ == BlendMode::kSource || colors_.size() == 0) { - return RenderTexture(renderer, entity, pass, alpha_); + auto child_contents = AtlasTextureContents(*this); + child_contents.SetAlpha(alpha_); + child_contents.SetCoverage(coverage); + return child_contents.Render(renderer, entity, pass); } if (blend_mode_ == BlendMode::kDestination) { - return RenderColors(renderer, entity, pass, alpha_); + auto child_contents = AtlasColorContents(*this); + child_contents.SetAlpha(alpha_); + child_contents.SetCoverage(coverage); + return child_contents.Render(renderer, entity, pass); } - // Ensure that we use the actual computed bounds and not a cull-rect - // approximation of them. - auto coverage = ComputeBoundingBox(); - auto size = coverage.size; - - // Simple blends. - if (blend_mode_ < BlendMode::kScreen) { - auto subpass_texture = renderer.MakeSubpass( - ISize::Ceil(size), - [&contents = *this, &coverage](const ContentContext& renderer, - RenderPass& pass) -> bool { - Entity sub_entity; - sub_entity.SetBlendMode(BlendMode::kSourceOver); - sub_entity.SetTransformation( - Matrix::MakeTranslation(Vector3(-coverage.origin))); - if (!contents.RenderColors(renderer, sub_entity, pass, 1.0)) { - return false; - } - return contents.RenderTexture(renderer, sub_entity, pass, 1.0, true); - }); - auto contents = ColorFilterContents::MakeBlend( - blend_mode_, {FilterInput::Make(subpass_texture)}); - contents->SetAlpha(alpha_); - return contents->Render(renderer, entity, pass); - } + auto src_contents = std::make_shared(*this); + src_contents->SetCoverage(coverage); + + auto dst_contents = std::make_shared(*this); + dst_contents->SetCoverage(coverage); - auto dst_texture = renderer.MakeSubpass( - ISize::Ceil(size), - [&contents = *this, &coverage](const ContentContext& renderer, - RenderPass& pass) -> bool { - Entity sub_entity; - sub_entity.SetBlendMode(BlendMode::kSourceOver); - sub_entity.SetTransformation( - Matrix::MakeTranslation(Vector3(-coverage.origin))); - return contents.RenderColors(renderer, sub_entity, pass, 1.0); - }); - auto src_texture = renderer.MakeSubpass( - ISize::Ceil(size), - [&contents = *this, &coverage](const ContentContext& renderer, - RenderPass& pass) -> bool { - Entity sub_entity; - sub_entity.SetBlendMode(BlendMode::kSourceOver); - sub_entity.SetTransformation( - Matrix::MakeTranslation(Vector3(-coverage.origin))); - return contents.RenderTexture(renderer, sub_entity, pass, 1.0); - }); - - if (!src_texture || !dst_texture) { - return false; - } auto contents = ColorFilterContents::MakeBlend( blend_mode_, - {FilterInput::Make(src_texture), FilterInput::Make(dst_texture)}); + {FilterInput::Make(dst_contents), FilterInput::Make(src_contents)}); contents->SetAlpha(alpha_); return contents->Render(renderer, entity, pass); } -bool AtlasContents::RenderColors(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass, - Scalar alpha) const { - using VS = GeometryColorPipeline::VertexShader; - using FS = GeometryColorPipeline::FragmentShader; +// AtlasTextureContents +// --------------------------------------------------------- + +AtlasTextureContents::AtlasTextureContents(const AtlasContents& parent) + : parent_(parent) {} + +AtlasTextureContents::~AtlasTextureContents() {} +std::optional AtlasTextureContents::GetCoverage( + const Entity& entity) const { + return coverage_.TransformBounds(entity.GetTransformation()); +} + +void AtlasTextureContents::SetAlpha(Scalar alpha) { + alpha_ = alpha; +} + +void AtlasTextureContents::SetCoverage(Rect coverage) { + coverage_ = coverage; +} + +bool AtlasTextureContents::Render(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + using VS = TextureFillVertexShader; + using FS = TextureFillFragmentShader; + + auto texture = parent_.GetTexture(); + auto texture_coords = parent_.GetTextureCoordinates(); + auto transforms = parent_.GetTransforms(); + + const auto texture_size = texture->GetSize(); VertexBufferBuilder vertex_builder; - vertex_builder.Reserve(texture_coords_.size() * 6); + vertex_builder.Reserve(texture_coords.size() * 6); constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3}; - for (size_t i = 0; i < texture_coords_.size(); i++) { - auto sample_rect = texture_coords_[i]; - auto matrix = transforms_[i]; + constexpr Scalar width[6] = {0, 1, 0, 1, 0, 1}; + constexpr Scalar height[6] = {0, 0, 1, 0, 1, 1}; + for (size_t i = 0; i < texture_coords.size(); i++) { + auto sample_rect = texture_coords[i]; + auto matrix = transforms[i]; auto transformed_points = Rect::MakeSize(sample_rect.size).GetTransformedPoints(matrix); for (size_t j = 0; j < 6; j++) { VS::PerVertexData data; data.position = transformed_points[indices[j]]; - data.color = colors_[i].Premultiply(); + data.texture_coords = + (sample_rect.origin + Point(sample_rect.size.width * width[j], + sample_rect.size.height * height[j])) / + texture_size; vertex_builder.AppendVertex(data); } } @@ -182,7 +190,7 @@ bool AtlasContents::RenderColors(const ContentContext& renderer, } Command cmd; - cmd.label = "DrawAtlas"; + cmd.label = "AtlasTexture"; auto& host_buffer = pass.GetTransientsBuffer(); @@ -191,45 +199,65 @@ bool AtlasContents::RenderColors(const ContentContext& renderer, entity.GetTransformation(); FS::FragInfo frag_info; - frag_info.alpha = alpha; + frag_info.texture_sampler_y_coord_scale = texture->GetYCoordScale(); + frag_info.alpha = alpha_; - auto opts = OptionsFromPassAndEntity(pass, entity); - opts.blend_mode = BlendMode::kSourceOver; - cmd.pipeline = renderer.GetGeometryColorPipeline(opts); + auto options = OptionsFromPassAndEntity(pass, entity); + cmd.pipeline = renderer.GetTexturePipeline(options); cmd.stencil_reference = entity.GetStencilDepth(); cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); + FS::BindTextureSampler(cmd, texture, + renderer.GetContext()->GetSamplerLibrary()->GetSampler( + parent_.GetSamplerDescriptor())); return pass.AddCommand(std::move(cmd)); } -bool AtlasContents::RenderTexture(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass, - Scalar alpha, - bool apply_blend) const { - using VS = TextureFillVertexShader; - using FS = TextureFillFragmentShader; +// AtlasColorContents +// --------------------------------------------------------- + +AtlasColorContents::AtlasColorContents(const AtlasContents& parent) + : parent_(parent) {} + +AtlasColorContents::~AtlasColorContents() {} + +std::optional AtlasColorContents::GetCoverage( + const Entity& entity) const { + return coverage_.TransformBounds(entity.GetTransformation()); +} + +void AtlasColorContents::SetAlpha(Scalar alpha) { + alpha_ = alpha; +} + +void AtlasColorContents::SetCoverage(Rect coverage) { + coverage_ = coverage; +} + +bool AtlasColorContents::Render(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const { + using VS = GeometryColorPipeline::VertexShader; + using FS = GeometryColorPipeline::FragmentShader; + + auto texture_coords = parent_.GetTextureCoordinates(); + auto transforms = parent_.GetTransforms(); + auto colors = parent_.GetColors(); - const auto texture_size = texture_->GetSize(); VertexBufferBuilder vertex_builder; - vertex_builder.Reserve(texture_coords_.size() * 6); + vertex_builder.Reserve(texture_coords.size() * 6); constexpr size_t indices[6] = {0, 1, 2, 1, 2, 3}; - constexpr Scalar width[6] = {0, 1, 0, 1, 0, 1}; - constexpr Scalar height[6] = {0, 0, 1, 0, 1, 1}; - for (size_t i = 0; i < texture_coords_.size(); i++) { - auto sample_rect = texture_coords_[i]; - auto matrix = transforms_[i]; + for (size_t i = 0; i < texture_coords.size(); i++) { + auto sample_rect = texture_coords[i]; + auto matrix = transforms[i]; auto transformed_points = Rect::MakeSize(sample_rect.size).GetTransformedPoints(matrix); for (size_t j = 0; j < 6; j++) { VS::PerVertexData data; data.position = transformed_points[indices[j]]; - data.texture_coords = - (sample_rect.origin + Point(sample_rect.size.width * width[j], - sample_rect.size.height * height[j])) / - texture_size; + data.color = colors[i].Premultiply(); vertex_builder.AppendVertex(data); } } @@ -239,7 +267,7 @@ bool AtlasContents::RenderTexture(const ContentContext& renderer, } Command cmd; - cmd.label = "DrawAtlas"; + cmd.label = "AtlasColors"; auto& host_buffer = pass.GetTransientsBuffer(); @@ -248,21 +276,15 @@ bool AtlasContents::RenderTexture(const ContentContext& renderer, entity.GetTransformation(); FS::FragInfo frag_info; - frag_info.texture_sampler_y_coord_scale = texture_->GetYCoordScale(); - frag_info.alpha = alpha; + frag_info.alpha = alpha_; - auto options = OptionsFromPassAndEntity(pass, entity); - if (apply_blend) { - options.blend_mode = blend_mode_; - } - cmd.pipeline = renderer.GetTexturePipeline(options); + auto opts = OptionsFromPassAndEntity(pass, entity); + opts.blend_mode = BlendMode::kSourceOver; + cmd.pipeline = renderer.GetGeometryColorPipeline(opts); cmd.stencil_reference = entity.GetStencilDepth(); cmd.BindVertices(vertex_builder.CreateVertexBuffer(host_buffer)); VS::BindVertInfo(cmd, host_buffer.EmplaceUniform(vert_info)); FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); - FS::BindTextureSampler(cmd, texture_, - renderer.GetContext()->GetSamplerLibrary()->GetSampler( - sampler_descriptor_)); return pass.AddCommand(std::move(cmd)); } diff --git a/impeller/entity/contents/atlas_contents.h b/impeller/entity/contents/atlas_contents.h index ab8c862e63787..2313f3402f995 100644 --- a/impeller/entity/contents/atlas_contents.h +++ b/impeller/entity/contents/atlas_contents.h @@ -41,6 +41,12 @@ class AtlasContents final : public Contents { const SamplerDescriptor& GetSamplerDescriptor() const; + const std::vector& GetTransforms() const; + + const std::vector& GetTextureCoordinates() const; + + const std::vector& GetColors() const; + // |Contents| std::optional GetCoverage(const Entity& entity) const override; @@ -50,17 +56,6 @@ class AtlasContents final : public Contents { RenderPass& pass) const override; private: - bool RenderTexture(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass, - Scalar alpha, - bool apply_blend = false) const; - - bool RenderColors(const ContentContext& renderer, - const Entity& entity, - RenderPass& pass, - Scalar alpha) const; - Rect ComputeBoundingBox() const; std::shared_ptr texture_; @@ -75,4 +70,56 @@ class AtlasContents final : public Contents { FML_DISALLOW_COPY_AND_ASSIGN(AtlasContents); }; +class AtlasTextureContents final : public Contents { + public: + explicit AtlasTextureContents(const AtlasContents& parent); + + ~AtlasTextureContents() override; + + // |Contents| + std::optional GetCoverage(const Entity& entity) const override; + + // |Contents| + bool Render(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const override; + + void SetAlpha(Scalar alpha); + + void SetCoverage(Rect coverage); + + private: + const AtlasContents& parent_; + Scalar alpha_ = 1.0; + Rect coverage_; + + FML_DISALLOW_COPY_AND_ASSIGN(AtlasTextureContents); +}; + +class AtlasColorContents final : public Contents { + public: + explicit AtlasColorContents(const AtlasContents& parent); + + ~AtlasColorContents() override; + + // |Contents| + std::optional GetCoverage(const Entity& entity) const override; + + // |Contents| + bool Render(const ContentContext& renderer, + const Entity& entity, + RenderPass& pass) const override; + + void SetAlpha(Scalar alpha); + + void SetCoverage(Rect coverage); + + private: + const AtlasContents& parent_; + Scalar alpha_ = 1.0; + Rect coverage_; + + FML_DISALLOW_COPY_AND_ASSIGN(AtlasColorContents); +}; + } // namespace impeller diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index ad353f309b93f..18a4f2973e0b1 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -111,7 +111,7 @@ static std::optional AdvancedBlend( FS::BindTextureSamplerDst(cmd, dst_snapshot->texture, sampler); blend_info.dst_y_coord_scale = dst_snapshot->texture->GetYCoordScale(); blend_info.dst_input_alpha = - absorb_opacity ? dst_snapshot->opacity : alpha.value_or(1.0f); + (absorb_opacity ? dst_snapshot->opacity : 1.0) * alpha.value_or(1.0); if (foreground_color.has_value()) { blend_info.color_factor = 1; @@ -206,7 +206,7 @@ static std::optional PipelineBlend( frag_info.texture_sampler_y_coord_scale = input->texture->GetYCoordScale(); frag_info.input_alpha = - absorb_opacity ? input->opacity : alpha.value_or(1.0f); + (absorb_opacity ? input->opacity : 1.0) * alpha.value_or(1.0); FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); From fd230d22123c0a0c06850e8460637b0ca09b7c72 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Wed, 18 Jan 2023 19:07:33 -0800 Subject: [PATCH 22/26] fix opacity for pipeline blends --- impeller/entity/contents/atlas_contents.cc | 43 ++++++++++++++++--- .../contents/filters/blend_filter_contents.cc | 10 ++--- .../contents/filters/color_filter_contents.h | 2 + 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 899a02ffa774f..33d1d6dec5e52 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -5,18 +5,19 @@ #include #include -#include "impeller/entity/contents/filters/color_filter_contents.h" -#include "impeller/entity/contents/filters/filter_contents.h" -#include "impeller/renderer/formats.h" -#include "impeller/renderer/sampler_library.h" -#include "impeller/renderer/vertex_buffer_builder.h" - #include "impeller/entity/contents/atlas_contents.h" #include "impeller/entity/contents/content_context.h" +#include "impeller/entity/contents/filters/color_filter_contents.h" +#include "impeller/entity/contents/filters/filter_contents.h" +#include "impeller/entity/contents/texture_contents.h" #include "impeller/entity/entity.h" +#include "impeller/entity/geometry.h" #include "impeller/entity/texture_fill.frag.h" #include "impeller/entity/texture_fill.vert.h" +#include "impeller/renderer/formats.h" #include "impeller/renderer/render_pass.h" +#include "impeller/renderer/sampler_library.h" +#include "impeller/renderer/vertex_buffer_builder.h" namespace impeller { @@ -124,9 +125,37 @@ bool AtlasContents::Render(const ContentContext& renderer, auto dst_contents = std::make_shared(*this); dst_contents->SetCoverage(coverage); + if (blend_mode_ < BlendMode::kScreen) { + auto subpass_texture = renderer.MakeSubpass( + ISize::Ceil(coverage.size), + [&contents = *this, &coverage, &dst_contents, &src_contents]( + const ContentContext& renderer, RenderPass& pass) -> bool { + Entity sub_entity; + sub_entity.SetBlendMode(BlendMode::kSourceOver); + sub_entity.SetTransformation( + Matrix::MakeTranslation(Vector3(-coverage.origin))); + + auto filter_contents = ColorFilterContents::MakeBlend( + contents.blend_mode_, {FilterInput::Make(dst_contents), + FilterInput::Make(src_contents)}); + + return filter_contents->Render(renderer, sub_entity, pass); + }); + if (!subpass_texture) { + return false; + } + auto texture_contents = TextureContents::MakeRect(coverage); + texture_contents->SetTexture(subpass_texture); + texture_contents->SetOpacity(alpha_); + texture_contents->SetSourceRect(Rect::MakeSize(subpass_texture->GetSize())); + return texture_contents->Render(renderer, entity, pass); + } + + // For some reason this looks backwards compared to Skia unless + // we reverse the src/dst. auto contents = ColorFilterContents::MakeBlend( blend_mode_, - {FilterInput::Make(dst_contents), FilterInput::Make(src_contents)}); + {FilterInput::Make(src_contents), FilterInput::Make(dst_contents)}); contents->SetAlpha(alpha_); return contents->Render(renderer, entity, pass); } diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index 18a4f2973e0b1..d976daf08d7ef 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -157,8 +157,7 @@ static std::optional PipelineBlend( const Rect& coverage, BlendMode pipeline_blend, std::optional foreground_color, - bool absorb_opacity, - std::optional alpha) { + bool absorb_opacity) { using VS = BlendPipeline::VertexShader; using FS = BlendPipeline::FragmentShader; @@ -205,8 +204,7 @@ static std::optional PipelineBlend( FS::FragInfo frag_info; frag_info.texture_sampler_y_coord_scale = input->texture->GetYCoordScale(); - frag_info.input_alpha = - (absorb_opacity ? input->opacity : 1.0) * alpha.value_or(1.0); + frag_info.input_alpha = absorb_opacity ? input->opacity : 1.0; FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); @@ -333,12 +331,12 @@ std::optional BlendFilterContents::RenderFilter( if (inputs.size() == 1 && !foreground_color_.has_value()) { // Nothing to blend. return PipelineBlend(inputs, renderer, entity, coverage, BlendMode::kSource, - std::nullopt, GetAbsorbOpacity(), GetAlpha()); + std::nullopt, GetAbsorbOpacity()); } if (blend_mode_ <= Entity::kLastPipelineBlendMode) { return PipelineBlend(inputs, renderer, entity, coverage, blend_mode_, - foreground_color_, GetAbsorbOpacity(), GetAlpha()); + foreground_color_, GetAbsorbOpacity()); } if (blend_mode_ <= Entity::kLastAdvancedBlendMode) { diff --git a/impeller/entity/contents/filters/color_filter_contents.h b/impeller/entity/contents/filters/color_filter_contents.h index 76b205eb924bf..6f691b3d0ce04 100644 --- a/impeller/entity/contents/filters/color_filter_contents.h +++ b/impeller/entity/contents/filters/color_filter_contents.h @@ -35,6 +35,8 @@ class ColorFilterContents : public FilterContents { /// @brief Sets an alpha that is applied to the blended result, overriding any /// inherited opacity. + /// + /// This is only used for advanced blends. void SetAlpha(Scalar alpha); std::optional GetAlpha() const; From b3b51b232928035d5f33715140a587b56e59df03 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 19 Jan 2023 18:52:56 -0800 Subject: [PATCH 23/26] use alpha in snapshot to avoid extra pass --- impeller/entity/contents/atlas_contents.cc | 31 +++++-------------- .../contents/filters/blend_filter_contents.cc | 18 ++++++----- .../contents/filters/color_filter_contents.h | 5 +-- 3 files changed, 18 insertions(+), 36 deletions(-) diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 33d1d6dec5e52..7c12932d96342 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -98,7 +98,8 @@ const std::vector& AtlasContents::GetColors() const { bool AtlasContents::Render(const ContentContext& renderer, const Entity& entity, RenderPass& pass) const { - if (texture_ == nullptr || blend_mode_ == BlendMode::kClear) { + if (texture_ == nullptr || blend_mode_ == BlendMode::kClear || + alpha_ <= 0.0) { return true; } @@ -126,29 +127,11 @@ bool AtlasContents::Render(const ContentContext& renderer, dst_contents->SetCoverage(coverage); if (blend_mode_ < BlendMode::kScreen) { - auto subpass_texture = renderer.MakeSubpass( - ISize::Ceil(coverage.size), - [&contents = *this, &coverage, &dst_contents, &src_contents]( - const ContentContext& renderer, RenderPass& pass) -> bool { - Entity sub_entity; - sub_entity.SetBlendMode(BlendMode::kSourceOver); - sub_entity.SetTransformation( - Matrix::MakeTranslation(Vector3(-coverage.origin))); - - auto filter_contents = ColorFilterContents::MakeBlend( - contents.blend_mode_, {FilterInput::Make(dst_contents), - FilterInput::Make(src_contents)}); - - return filter_contents->Render(renderer, sub_entity, pass); - }); - if (!subpass_texture) { - return false; - } - auto texture_contents = TextureContents::MakeRect(coverage); - texture_contents->SetTexture(subpass_texture); - texture_contents->SetOpacity(alpha_); - texture_contents->SetSourceRect(Rect::MakeSize(subpass_texture->GetSize())); - return texture_contents->Render(renderer, entity, pass); + auto contents = ColorFilterContents::MakeBlend( + blend_mode_, + {FilterInput::Make(dst_contents), FilterInput::Make(src_contents)}); + contents->SetAlpha(alpha_); + return contents->Render(renderer, entity, pass); } // For some reason this looks backwards compared to Skia unless diff --git a/impeller/entity/contents/filters/blend_filter_contents.cc b/impeller/entity/contents/filters/blend_filter_contents.cc index d976daf08d7ef..901bb05a0cb86 100644 --- a/impeller/entity/contents/filters/blend_filter_contents.cc +++ b/impeller/entity/contents/filters/blend_filter_contents.cc @@ -110,8 +110,7 @@ static std::optional AdvancedBlend( auto sampler = renderer.GetContext()->GetSamplerLibrary()->GetSampler({}); FS::BindTextureSamplerDst(cmd, dst_snapshot->texture, sampler); blend_info.dst_y_coord_scale = dst_snapshot->texture->GetYCoordScale(); - blend_info.dst_input_alpha = - (absorb_opacity ? dst_snapshot->opacity : 1.0) * alpha.value_or(1.0); + blend_info.dst_input_alpha = absorb_opacity ? dst_snapshot->opacity : 1.0; if (foreground_color.has_value()) { blend_info.color_factor = 1; @@ -147,7 +146,8 @@ static std::optional AdvancedBlend( return Snapshot{.texture = out_texture, .transform = Matrix::MakeTranslation(coverage.origin), .sampler_descriptor = dst_snapshot->sampler_descriptor, - .opacity = absorb_opacity ? 1.0f : dst_snapshot->opacity}; + .opacity = (absorb_opacity ? 1.0f : dst_snapshot->opacity) * + alpha.value_or(1.0)}; } static std::optional PipelineBlend( @@ -157,7 +157,8 @@ static std::optional PipelineBlend( const Rect& coverage, BlendMode pipeline_blend, std::optional foreground_color, - bool absorb_opacity) { + bool absorb_opacity, + std::optional alpha) { using VS = BlendPipeline::VertexShader; using FS = BlendPipeline::FragmentShader; @@ -204,7 +205,7 @@ static std::optional PipelineBlend( FS::FragInfo frag_info; frag_info.texture_sampler_y_coord_scale = input->texture->GetYCoordScale(); - frag_info.input_alpha = absorb_opacity ? input->opacity : 1.0; + frag_info.input_alpha = absorb_opacity ? input->opacity : 1.0f; FS::BindFragInfo(cmd, host_buffer.EmplaceUniform(frag_info)); VS::BindFrameInfo(cmd, host_buffer.EmplaceUniform(frame_info)); @@ -266,7 +267,8 @@ static std::optional PipelineBlend( .transform = Matrix::MakeTranslation(coverage.origin), .sampler_descriptor = inputs[0]->GetSnapshot(renderer, entity)->sampler_descriptor, - .opacity = absorb_opacity ? 1.0f : input_snapshot->opacity}; + .opacity = (absorb_opacity ? 1.0f : input_snapshot->opacity) * + alpha.value_or(1.0)}; } #define BLEND_CASE(mode) \ @@ -331,12 +333,12 @@ std::optional BlendFilterContents::RenderFilter( if (inputs.size() == 1 && !foreground_color_.has_value()) { // Nothing to blend. return PipelineBlend(inputs, renderer, entity, coverage, BlendMode::kSource, - std::nullopt, GetAbsorbOpacity()); + std::nullopt, GetAbsorbOpacity(), GetAlpha()); } if (blend_mode_ <= Entity::kLastPipelineBlendMode) { return PipelineBlend(inputs, renderer, entity, coverage, blend_mode_, - foreground_color_, GetAbsorbOpacity()); + foreground_color_, GetAbsorbOpacity(), GetAlpha()); } if (blend_mode_ <= Entity::kLastAdvancedBlendMode) { diff --git a/impeller/entity/contents/filters/color_filter_contents.h b/impeller/entity/contents/filters/color_filter_contents.h index 6f691b3d0ce04..c273dceb59003 100644 --- a/impeller/entity/contents/filters/color_filter_contents.h +++ b/impeller/entity/contents/filters/color_filter_contents.h @@ -33,10 +33,7 @@ class ColorFilterContents : public FilterContents { bool GetAbsorbOpacity() const; - /// @brief Sets an alpha that is applied to the blended result, overriding any - /// inherited opacity. - /// - /// This is only used for advanced blends. + /// @brief Sets an alpha that is applied to the final blended result. void SetAlpha(Scalar alpha); std::optional GetAlpha() const; From b422933093adfd66cb15951c25f4bab771714fa2 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 19 Jan 2023 18:55:10 -0800 Subject: [PATCH 24/26] ++ --- impeller/entity/contents/content_context.h | 1 - 1 file changed, 1 deletion(-) diff --git a/impeller/entity/contents/content_context.h b/impeller/entity/contents/content_context.h index ccf8b3b49f77c..e8cabf188c246 100644 --- a/impeller/entity/contents/content_context.h +++ b/impeller/entity/contents/content_context.h @@ -27,7 +27,6 @@ #include "impeller/entity/advanced_blend_saturation.frag.h" #include "impeller/entity/advanced_blend_screen.frag.h" #include "impeller/entity/advanced_blend_softlight.frag.h" - #include "impeller/entity/blend.frag.h" #include "impeller/entity/blend.vert.h" #include "impeller/entity/border_mask_blur.frag.h" From c3aa8cef8993df97f9f5edcb02817db32f2adbe3 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 19 Jan 2023 18:56:27 -0800 Subject: [PATCH 25/26] ++ --- impeller/aiks/canvas.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 671528394c8cc..536fb378df21a 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -414,6 +414,11 @@ void Canvas::DrawAtlas(const std::shared_ptr& atlas, if (!atlas) { return; } + auto size = atlas->GetSize(); + + if (size.IsEmpty()) { + return; + } std::shared_ptr contents = std::make_shared(); contents->SetColors(std::move(colors)); From 4837acc2113165475d566d73dc6f176ddc08317f Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 20 Jan 2023 14:26:49 -0800 Subject: [PATCH 26/26] fix order --- impeller/entity/contents/atlas_contents.cc | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/impeller/entity/contents/atlas_contents.cc b/impeller/entity/contents/atlas_contents.cc index 7c12932d96342..69a4f07679c94 100644 --- a/impeller/entity/contents/atlas_contents.cc +++ b/impeller/entity/contents/atlas_contents.cc @@ -126,19 +126,11 @@ bool AtlasContents::Render(const ContentContext& renderer, auto dst_contents = std::make_shared(*this); dst_contents->SetCoverage(coverage); - if (blend_mode_ < BlendMode::kScreen) { - auto contents = ColorFilterContents::MakeBlend( - blend_mode_, - {FilterInput::Make(dst_contents), FilterInput::Make(src_contents)}); - contents->SetAlpha(alpha_); - return contents->Render(renderer, entity, pass); - } - // For some reason this looks backwards compared to Skia unless // we reverse the src/dst. auto contents = ColorFilterContents::MakeBlend( blend_mode_, - {FilterInput::Make(src_contents), FilterInput::Make(dst_contents)}); + {FilterInput::Make(dst_contents), FilterInput::Make(src_contents)}); contents->SetAlpha(alpha_); return contents->Render(renderer, entity, pass); }