mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Setup a framework to collapse passes.
This commit is contained in:
parent
5c0de80dd1
commit
30b243cdf7
@ -12,6 +12,8 @@ impeller_component("aiks") {
|
||||
"canvas.h",
|
||||
"canvas_pass.cc",
|
||||
"canvas_pass.h",
|
||||
"canvas_pass_delegate.cc",
|
||||
"canvas_pass_delegate.h",
|
||||
"image.cc",
|
||||
"image.h",
|
||||
"paint.cc",
|
||||
|
||||
@ -110,16 +110,16 @@ TEST_F(AiksTest, CanRenderGroupOpacity) {
|
||||
Canvas canvas;
|
||||
|
||||
Paint red;
|
||||
red.color = Color::Red(); //.WithAlpha(0.5);
|
||||
red.color = Color::Red();
|
||||
Paint green;
|
||||
green.color = Color::Green(); //.WithAlpha(0.5);
|
||||
green.color = Color::Green();
|
||||
Paint blue;
|
||||
blue.color = Color::Blue(); //.WithAlpha(0.5);
|
||||
blue.color = Color::Blue();
|
||||
|
||||
Paint alpha;
|
||||
alpha.color = Color::Red().WithAlpha(0.5);
|
||||
|
||||
// canvas.SaveLayer(alpha);
|
||||
canvas.SaveLayer(alpha);
|
||||
|
||||
canvas.DrawRect({000, 000, 100, 100}, red);
|
||||
canvas.DrawRect({020, 020, 100, 100}, green);
|
||||
|
||||
@ -8,11 +8,15 @@
|
||||
#include "impeller/geometry/path_builder.h"
|
||||
#include "impeller/renderer/command_buffer.h"
|
||||
#include "impeller/renderer/render_pass.h"
|
||||
#include "impeller/renderer/render_target.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
CanvasPass::CanvasPass() = default;
|
||||
CanvasPass::CanvasPass(std::unique_ptr<CanvasPassDelegate> delegate)
|
||||
: delegate_(std::move(delegate)) {
|
||||
if (!delegate_) {
|
||||
delegate_ = CanvasPassDelegate::MakeDefault();
|
||||
}
|
||||
}
|
||||
|
||||
CanvasPass::~CanvasPass() = default;
|
||||
|
||||
@ -85,8 +89,12 @@ bool CanvasPass::Render(ContentRenderer& renderer,
|
||||
}
|
||||
}
|
||||
for (const auto& subpass : subpasses_) {
|
||||
if (!subpass) {
|
||||
return false;
|
||||
if (delegate_->CanCollapseIntoParentPass()) {
|
||||
// Directly render into the parent pass and move on.
|
||||
if (!subpass->Render(renderer, parent_pass)) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto subpass_coverage = subpass->GetCoverageRect();
|
||||
@ -102,6 +110,27 @@ bool CanvasPass::Render(ContentRenderer& renderer,
|
||||
auto subpass_target = RenderTarget::CreateOffscreen(
|
||||
*context, ISize::Ceil(subpass_coverage.size));
|
||||
|
||||
auto subpass_texture = subpass_target.GetRenderTargetTexture();
|
||||
|
||||
if (!subpass_texture) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto offscreen_texture_contents =
|
||||
delegate_->CreateContentsForSubpassTarget(*subpass_texture);
|
||||
|
||||
if (!offscreen_texture_contents) {
|
||||
// This is an error because the subpass delegate said the pass couldn't be
|
||||
// collapsed into its parent. Yet, when asked how it want's to postprocess
|
||||
// the offscreen texture, it couldn't give us an answer.
|
||||
//
|
||||
// Theoretically, we could collapse the pass now. But that would be
|
||||
// wasteful as we already have the offscreen texture and we don't want to
|
||||
// discard it without ever using it. Just make the delegate do the right
|
||||
// thing.
|
||||
return false;
|
||||
}
|
||||
|
||||
auto sub_command_buffer = context->CreateRenderCommandBuffer();
|
||||
|
||||
sub_command_buffer->SetLabel("Offscreen Command Buffer");
|
||||
@ -130,12 +159,6 @@ bool CanvasPass::Render(ContentRenderer& renderer,
|
||||
return false;
|
||||
}
|
||||
|
||||
auto offscreen_texture_contents = std::make_shared<TextureContents>();
|
||||
offscreen_texture_contents->SetTexture(
|
||||
subpass_target.GetRenderTargetTexture());
|
||||
offscreen_texture_contents->SetSourceRect(
|
||||
IRect::MakeSize(subpass_target.GetRenderTargetTexture()->GetSize()));
|
||||
|
||||
Entity entity;
|
||||
entity.SetPath(PathBuilder{}.AddRect(subpass_coverage).CreatePath());
|
||||
entity.SetContents(std::move(offscreen_texture_contents));
|
||||
|
||||
@ -9,8 +9,10 @@
|
||||
#include <vector>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/aiks/canvas_pass_delegate.h"
|
||||
#include "impeller/entity/contents.h"
|
||||
#include "impeller/entity/entity.h"
|
||||
#include "impeller/renderer/render_target.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
@ -21,7 +23,7 @@ class CanvasPass {
|
||||
using Entities = std::vector<Entity>;
|
||||
using Subpasses = std::vector<std::unique_ptr<CanvasPass>>;
|
||||
|
||||
CanvasPass();
|
||||
CanvasPass(std::unique_ptr<CanvasPassDelegate> delegate = nullptr);
|
||||
|
||||
~CanvasPass();
|
||||
|
||||
@ -57,6 +59,7 @@ class CanvasPass {
|
||||
CanvasPass* superpass_ = nullptr;
|
||||
Matrix xformation_;
|
||||
size_t stencil_depth_ = 0u;
|
||||
std::unique_ptr<CanvasPassDelegate> delegate_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(CanvasPass);
|
||||
};
|
||||
|
||||
35
engine/src/flutter/impeller/aiks/canvas_pass_delegate.cc
Normal file
35
engine/src/flutter/impeller/aiks/canvas_pass_delegate.cc
Normal file
@ -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/canvas_pass_delegate.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
CanvasPassDelegate::CanvasPassDelegate() = default;
|
||||
|
||||
CanvasPassDelegate::~CanvasPassDelegate() = default;
|
||||
|
||||
class DefaultCanvasPassDelegate final : public CanvasPassDelegate {
|
||||
public:
|
||||
DefaultCanvasPassDelegate() = default;
|
||||
|
||||
~DefaultCanvasPassDelegate() override = default;
|
||||
|
||||
bool CanCollapseIntoParentPass() override { return true; }
|
||||
|
||||
std::shared_ptr<Contents> CreateContentsForSubpassTarget(
|
||||
const Texture& target) override {
|
||||
// Not possible since this pass always collapses into its parent.
|
||||
FML_UNREACHABLE();
|
||||
}
|
||||
|
||||
private:
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(DefaultCanvasPassDelegate);
|
||||
};
|
||||
|
||||
std::unique_ptr<CanvasPassDelegate> CanvasPassDelegate::MakeDefault() {
|
||||
return std::make_unique<DefaultCanvasPassDelegate>();
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
32
engine/src/flutter/impeller/aiks/canvas_pass_delegate.h
Normal file
32
engine/src/flutter/impeller/aiks/canvas_pass_delegate.h
Normal file
@ -0,0 +1,32 @@
|
||||
// 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 <memory>
|
||||
|
||||
#include "flutter/fml/macros.h"
|
||||
#include "impeller/entity/contents.h"
|
||||
#include "impeller/renderer/texture.h"
|
||||
|
||||
namespace impeller {
|
||||
|
||||
class CanvasPassDelegate {
|
||||
public:
|
||||
static std::unique_ptr<CanvasPassDelegate> MakeDefault();
|
||||
|
||||
CanvasPassDelegate();
|
||||
|
||||
virtual ~CanvasPassDelegate();
|
||||
|
||||
virtual bool CanCollapseIntoParentPass() = 0;
|
||||
|
||||
virtual std::shared_ptr<Contents> CreateContentsForSubpassTarget(
|
||||
const Texture& target) = 0;
|
||||
|
||||
private:
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(CanvasPassDelegate);
|
||||
};
|
||||
|
||||
} // namespace impeller
|
||||
Loading…
x
Reference in New Issue
Block a user