From ead8058c967f6b788e2e53b27f8452edc030cb45 Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Sun, 28 Nov 2021 14:28:44 -0800 Subject: [PATCH] Setup a paint pass delgate. --- impeller/aiks/BUILD.gn | 2 ++ impeller/aiks/aiks_unittests.cc | 2 +- impeller/aiks/canvas.cc | 5 +++- impeller/aiks/canvas.h | 2 +- impeller/aiks/paint.h | 2 +- impeller/aiks/paint_pass_delegate.cc | 35 +++++++++++++++++++++++ impeller/aiks/paint_pass_delegate.h | 33 +++++++++++++++++++++ impeller/entity/contents.cc | 5 ++++ impeller/entity/contents.h | 3 ++ impeller/entity/entity_pass.cc | 16 ++++++----- impeller/entity/entity_pass.h | 7 +++-- impeller/entity/entity_pass_delegate.cc | 2 +- impeller/entity/entity_pass_delegate.h | 2 +- impeller/entity/shaders/texture_fill.frag | 2 ++ impeller/entity/shaders/texture_fill.vert | 3 ++ impeller/geometry/color.h | 2 ++ 16 files changed, 108 insertions(+), 15 deletions(-) create mode 100644 impeller/aiks/paint_pass_delegate.cc create mode 100644 impeller/aiks/paint_pass_delegate.h diff --git a/impeller/aiks/BUILD.gn b/impeller/aiks/BUILD.gn index a061204f7806d..a3398f394b54a 100644 --- a/impeller/aiks/BUILD.gn +++ b/impeller/aiks/BUILD.gn @@ -14,6 +14,8 @@ impeller_component("aiks") { "image.h", "paint.cc", "paint.h", + "paint_pass_delegate.cc", + "paint_pass_delegate.h", "picture.cc", "picture.h", "picture_recorder.cc", diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index c64d894003159..ecc3b4fa0ec39 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -112,7 +112,7 @@ TEST_F(AiksTest, CanRenderGroupOpacity) { Paint red; red.color = Color::Red(); Paint green; - green.color = Color::Green(); + green.color = Color::Green().WithAlpha(0.5); Paint blue; blue.color = Color::Blue(); diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index f41aa125451f5..1c11d886ba172 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -7,6 +7,7 @@ #include #include "flutter/fml/logging.h" +#include "impeller/aiks/paint_pass_delegate.h" #include "impeller/geometry/path_builder.h" namespace impeller { @@ -90,7 +91,9 @@ void Canvas::DrawPath(Path path, Paint paint) { GetCurrentPass().AddEntity(std::move(entity)); } -void Canvas::SaveLayer(const Paint& paint, std::optional bounds) { +void Canvas::SaveLayer(Paint paint, std::optional bounds) { + GetCurrentPass().SetDelegate( + std::make_unique(std::move(paint))); Save(true); } diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index 470c9b1b6ad6a..c7b16fcdaf6b8 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -31,7 +31,7 @@ class Canvas { void Save(); - void SaveLayer(const Paint& paint, std::optional bounds = std::nullopt); + void SaveLayer(Paint paint, std::optional bounds = std::nullopt); bool Restore(); diff --git a/impeller/aiks/paint.h b/impeller/aiks/paint.h index 98cb1ce1cac49..6334e42471375 100644 --- a/impeller/aiks/paint.h +++ b/impeller/aiks/paint.h @@ -18,7 +18,7 @@ struct Paint { kStroke, }; - Color color; + Color color = Color::Black(); Scalar stroke_width = 0.0; Style style = Style::kFill; diff --git a/impeller/aiks/paint_pass_delegate.cc b/impeller/aiks/paint_pass_delegate.cc new file mode 100644 index 0000000000000..5a683cfe6655d --- /dev/null +++ b/impeller/aiks/paint_pass_delegate.cc @@ -0,0 +1,35 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "impeller/aiks/paint_pass_delegate.h" + +#include "impeller/entity/contents.h" + +namespace impeller { + +PaintPassDelegate::PaintPassDelegate(Paint paint) : paint_(std::move(paint)) {} + +// |EntityPassDelgate| +PaintPassDelegate::~PaintPassDelegate() = default; + +// |EntityPassDelgate| +bool PaintPassDelegate::CanCollapseIntoParentPass() { + if (paint_.color.IsOpaque()) { + return true; + } + + return false; +} + +// |EntityPassDelgate| +std::shared_ptr PaintPassDelegate::CreateContentsForSubpassTarget( + std::shared_ptr target) { + auto contents = std::make_shared(); + contents->SetTexture(target); + contents->SetSourceRect(IRect::MakeSize(target->GetSize())); + contents->SetOpacity(paint_.color.alpha); + return contents; +} + +} // namespace impeller diff --git a/impeller/aiks/paint_pass_delegate.h b/impeller/aiks/paint_pass_delegate.h new file mode 100644 index 0000000000000..b731503971d7a --- /dev/null +++ b/impeller/aiks/paint_pass_delegate.h @@ -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. + +#pragma once + +#include "flutter/fml/macros.h" +#include "impeller/aiks/paint.h" +#include "impeller/entity/entity_pass_delegate.h" + +namespace impeller { + +class PaintPassDelegate final : public EntityPassDelegate { + public: + PaintPassDelegate(Paint paint); + + // |EntityPassDelgate| + ~PaintPassDelegate() override; + + // |EntityPassDelgate| + bool CanCollapseIntoParentPass() override; + + // |EntityPassDelgate| + std::shared_ptr CreateContentsForSubpassTarget( + std::shared_ptr target) override; + + private: + const Paint paint_; + + FML_DISALLOW_COPY_AND_ASSIGN(PaintPassDelegate); +}; + +} // namespace impeller diff --git a/impeller/entity/contents.cc b/impeller/entity/contents.cc index 3bf1c0daba8a9..48be6459c92bc 100644 --- a/impeller/entity/contents.cc +++ b/impeller/entity/contents.cc @@ -184,6 +184,10 @@ std::shared_ptr TextureContents::GetTexture() const { return texture_; } +void TextureContents::SetOpacity(Scalar opacity) { + opacity_ = opacity; +} + bool TextureContents::Render(const ContentRenderer& renderer, const Entity& entity, RenderPass& pass) const { @@ -233,6 +237,7 @@ bool TextureContents::Render(const ContentRenderer& renderer, VS::FrameInfo frame_info; frame_info.mvp = Matrix::MakeOrthographic(pass.GetRenderTargetSize()) * entity.GetTransformation(); + frame_info.alpha = opacity_; Command cmd; cmd.label = "TextureFill"; diff --git a/impeller/entity/contents.h b/impeller/entity/contents.h index 381a11f5f011f..ffda5f7d432a8 100644 --- a/impeller/entity/contents.h +++ b/impeller/entity/contents.h @@ -94,6 +94,8 @@ class TextureContents final : public Contents { void SetSourceRect(const IRect& source_rect); + void SetOpacity(Scalar opacity); + const IRect& GetSourceRect() const; // |Contents| @@ -104,6 +106,7 @@ class TextureContents final : public Contents { public: std::shared_ptr texture_; IRect source_rect_; + Scalar opacity_ = 1.0f; FML_DISALLOW_COPY_AND_ASSIGN(TextureContents); }; diff --git a/impeller/entity/entity_pass.cc b/impeller/entity/entity_pass.cc index 22128553b0e10..40866649e38bb 100644 --- a/impeller/entity/entity_pass.cc +++ b/impeller/entity/entity_pass.cc @@ -11,15 +11,17 @@ namespace impeller { -EntityPass::EntityPass(std::unique_ptr delegate) - : delegate_(std::move(delegate)) { - if (!delegate_) { - delegate_ = EntityPassDelegate::MakeDefault(); - } -} +EntityPass::EntityPass() = default; EntityPass::~EntityPass() = default; +void EntityPass::SetDelegate(std::unique_ptr delegate) { + if (!delegate) { + return; + } + delegate_ = std::move(delegate); +} + void EntityPass::AddEntity(Entity entity) { entities_.emplace_back(std::move(entity)); } @@ -117,7 +119,7 @@ bool EntityPass::Render(ContentRenderer& renderer, } auto offscreen_texture_contents = - delegate_->CreateContentsForSubpassTarget(*subpass_texture); + delegate_->CreateContentsForSubpassTarget(subpass_texture); if (!offscreen_texture_contents) { // This is an error because the subpass delegate said the pass couldn't be diff --git a/impeller/entity/entity_pass.h b/impeller/entity/entity_pass.h index 5c1b1315e5e79..47cf3b2a0f427 100644 --- a/impeller/entity/entity_pass.h +++ b/impeller/entity/entity_pass.h @@ -23,10 +23,12 @@ class EntityPass { using Entities = std::vector; using Subpasses = std::vector>; - EntityPass(std::unique_ptr delegate = nullptr); + EntityPass(); ~EntityPass(); + void SetDelegate(std::unique_ptr delgate); + size_t GetSubpassesDepth() const; std::unique_ptr Clone() const; @@ -61,7 +63,8 @@ class EntityPass { EntityPass* superpass_ = nullptr; Matrix xformation_; size_t stencil_depth_ = 0u; - std::unique_ptr delegate_; + std::unique_ptr delegate_ = + EntityPassDelegate::MakeDefault(); FML_DISALLOW_COPY_AND_ASSIGN(EntityPass); }; diff --git a/impeller/entity/entity_pass_delegate.cc b/impeller/entity/entity_pass_delegate.cc index a1567f451d1de..daf328328522b 100644 --- a/impeller/entity/entity_pass_delegate.cc +++ b/impeller/entity/entity_pass_delegate.cc @@ -19,7 +19,7 @@ class DefaultEntityPassDelegate final : public EntityPassDelegate { bool CanCollapseIntoParentPass() override { return true; } std::shared_ptr CreateContentsForSubpassTarget( - const Texture& target) override { + std::shared_ptr target) override { // Not possible since this pass always collapses into its parent. FML_UNREACHABLE(); } diff --git a/impeller/entity/entity_pass_delegate.h b/impeller/entity/entity_pass_delegate.h index 03a8d05853eba..456b79dc4ec01 100644 --- a/impeller/entity/entity_pass_delegate.h +++ b/impeller/entity/entity_pass_delegate.h @@ -23,7 +23,7 @@ class EntityPassDelegate { virtual bool CanCollapseIntoParentPass() = 0; virtual std::shared_ptr CreateContentsForSubpassTarget( - const Texture& target) = 0; + std::shared_ptr target) = 0; private: FML_DISALLOW_COPY_AND_ASSIGN(EntityPassDelegate); diff --git a/impeller/entity/shaders/texture_fill.frag b/impeller/entity/shaders/texture_fill.frag index 9c4dd1ec58b30..4c7810480d3ce 100644 --- a/impeller/entity/shaders/texture_fill.frag +++ b/impeller/entity/shaders/texture_fill.frag @@ -5,10 +5,12 @@ uniform sampler2D texture_sampler; in vec2 v_texture_coords; +in float v_alpha; out vec4 frag_color; void main() { vec4 sampled = texture(texture_sampler, v_texture_coords); + sampled.w *= v_alpha; frag_color = sampled; } diff --git a/impeller/entity/shaders/texture_fill.vert b/impeller/entity/shaders/texture_fill.vert index daa30f5650a3f..303936eec685e 100644 --- a/impeller/entity/shaders/texture_fill.vert +++ b/impeller/entity/shaders/texture_fill.vert @@ -4,14 +4,17 @@ uniform FrameInfo { mat4 mvp; + float alpha; } frame_info; in vec2 vertices; in vec2 texture_coords; out vec2 v_texture_coords; +out float v_alpha; void main() { gl_Position = frame_info.mvp * vec4(vertices, 0.0, 1.0); v_texture_coords = texture_coords; + v_alpha = frame_info.alpha; } diff --git a/impeller/geometry/color.h b/impeller/geometry/color.h index 30706da4c678a..86d40f6abb61d 100644 --- a/impeller/geometry/color.h +++ b/impeller/geometry/color.h @@ -644,6 +644,8 @@ struct Color { } constexpr bool IsTransparent() const { return alpha == 0.0; } + + constexpr bool IsOpaque() const { return alpha == 1.0; } }; /**