flutter_flutter/engine/src/flutter/flow/embedded_views.cc
Tong Mu 7553282a55 Multiview backing store (flutter/engine#51722)
With this PR, backing stores are labeled with view IDs. When the engine requests the embedder to create a backing store, the engine will promise that it will only be used for a specific view.

This follows the design doc http://flutter.dev/go/backing-stores-for-multi-view-partial-repaint, so that backing stores can be used as a front surface that retains its content last frame.

The engine will create a render target cache for each view to cache backing stores separately.

### Alternative design

The separate render target cache for each view is not needed to implement the design doc, since all usages described in the design doc avoids the engine cache. Instead, we can make the engine still only manage one render target cache for all views, and backing stores in it are interchangeable across views. We might describe the behavior in this way:
* In general, the view ID is just provided to the creating callback as information. (This is how it is seen when the engine cache is avoided.)
* If the engine cache is used, then the created backing store might not be immediately collected, and might be reused for different views.

But it's really hard to explain the mechanism and the result is really confusing (as can be seen from my attempt). Why is there a view ID but it's not used, and if you enable the engine cache it's not even followed?

That's why I chose the current approach. Feel free to suggest otherwise for this.

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
2024-04-04 20:47:30 +00:00

125 lines
3.3 KiB
C++

// 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 "flutter/flow/embedded_views.h"
namespace flutter {
DisplayListEmbedderViewSlice::DisplayListEmbedderViewSlice(SkRect view_bounds) {
builder_ = std::make_unique<DisplayListBuilder>(
/*bounds=*/view_bounds,
/*prepare_rtree=*/true);
}
DlCanvas* DisplayListEmbedderViewSlice::canvas() {
return builder_ ? builder_.get() : nullptr;
}
void DisplayListEmbedderViewSlice::end_recording() {
display_list_ = builder_->Build();
FML_DCHECK(display_list_->has_rtree());
builder_ = nullptr;
}
const DlRegion& DisplayListEmbedderViewSlice::getRegion() const {
return display_list_->rtree()->region();
}
void DisplayListEmbedderViewSlice::render_into(DlCanvas* canvas) {
canvas->DrawDisplayList(display_list_);
}
void DisplayListEmbedderViewSlice::dispatch(DlOpReceiver& receiver) {
display_list_->Dispatch(receiver);
}
bool DisplayListEmbedderViewSlice::is_empty() {
return display_list_->bounds().isEmpty();
}
bool DisplayListEmbedderViewSlice::recording_ended() {
return builder_ == nullptr;
}
void ExternalViewEmbedder::CollectView(int64_t view_id) {}
void ExternalViewEmbedder::SubmitFlutterView(
int64_t flutter_view_id,
GrDirectContext* context,
const std::shared_ptr<impeller::AiksContext>& aiks_context,
std::unique_ptr<SurfaceFrame> frame) {
frame->Submit();
}
bool ExternalViewEmbedder::SupportsDynamicThreadMerging() {
return false;
}
void ExternalViewEmbedder::Teardown() {}
void MutatorsStack::PushClipRect(const SkRect& rect) {
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(rect);
vector_.push_back(element);
}
void MutatorsStack::PushClipRRect(const SkRRect& rrect) {
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(rrect);
vector_.push_back(element);
}
void MutatorsStack::PushClipPath(const SkPath& path) {
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(path);
vector_.push_back(element);
}
void MutatorsStack::PushTransform(const SkMatrix& matrix) {
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(matrix);
vector_.push_back(element);
}
void MutatorsStack::PushOpacity(const int& alpha) {
std::shared_ptr<Mutator> element = std::make_shared<Mutator>(alpha);
vector_.push_back(element);
}
void MutatorsStack::PushBackdropFilter(
const std::shared_ptr<const DlImageFilter>& filter,
const SkRect& filter_rect) {
std::shared_ptr<Mutator> element =
std::make_shared<Mutator>(filter, filter_rect);
vector_.push_back(element);
}
void MutatorsStack::Pop() {
vector_.pop_back();
}
void MutatorsStack::PopTo(size_t stack_count) {
while (vector_.size() > stack_count) {
Pop();
}
}
const std::vector<std::shared_ptr<Mutator>>::const_reverse_iterator
MutatorsStack::Top() const {
return vector_.rend();
}
const std::vector<std::shared_ptr<Mutator>>::const_reverse_iterator
MutatorsStack::Bottom() const {
return vector_.rbegin();
}
const std::vector<std::shared_ptr<Mutator>>::const_iterator
MutatorsStack::Begin() const {
return vector_.begin();
}
const std::vector<std::shared_ptr<Mutator>>::const_iterator MutatorsStack::End()
const {
return vector_.end();
}
} // namespace flutter