mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
The overlay surfaces are going to be the same IOSSurface implementation
with the platform views controller set to null (so these are surfaces
that don't support embedding platform views to them).
* Adds a FlutterOverlayView which is a UIView that's showing an
overlay surface.
* Creates an overlay surface for each embedded UIView (done in
FlutterPlatformViewsController).
* Changes CompositeEmbeddedView to return a new canvas.
* Makes the PlatformViewLayer replace the PaintContext's canvas with
the canvas for the overlay view.
* Changed canvas in PaintContext to be a pointer so it can be changed.
TBD in following PRs:
* Copy the current canvas state when replacing a canvas in PaintContext.
* Make FlutterOverlayView work with a GL backend (currently it only
works with software rendering)
133 lines
4.6 KiB
C++
133 lines
4.6 KiB
C++
// Copyright 2015 The Chromium 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/layers/layer_tree.h"
|
|
|
|
#include "flutter/flow/layers/layer.h"
|
|
#include "flutter/fml/trace_event.h"
|
|
#include "third_party/skia/include/core/SkPictureRecorder.h"
|
|
|
|
namespace flow {
|
|
|
|
LayerTree::LayerTree()
|
|
: frame_size_{},
|
|
rasterizer_tracing_threshold_(0),
|
|
checkerboard_raster_cache_images_(false),
|
|
checkerboard_offscreen_layers_(false) {}
|
|
|
|
LayerTree::~LayerTree() = default;
|
|
|
|
void LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
|
|
bool ignore_raster_cache) {
|
|
TRACE_EVENT0("flutter", "LayerTree::Preroll");
|
|
SkColorSpace* color_space =
|
|
frame.canvas() ? frame.canvas()->imageInfo().colorSpace() : nullptr;
|
|
frame.context().raster_cache().SetCheckboardCacheImages(
|
|
checkerboard_raster_cache_images_);
|
|
PrerollContext context = {
|
|
ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
|
|
frame.gr_context(),
|
|
color_space,
|
|
SkRect::MakeEmpty(),
|
|
frame.context().frame_time(),
|
|
frame.context().engine_time(),
|
|
frame.context().texture_registry(),
|
|
checkerboard_offscreen_layers_};
|
|
|
|
root_layer_->Preroll(&context, frame.root_surface_transformation());
|
|
}
|
|
|
|
#if defined(OS_FUCHSIA)
|
|
void LayerTree::UpdateScene(SceneUpdateContext& context,
|
|
scenic::ContainerNode& container) {
|
|
TRACE_EVENT0("flutter", "LayerTree::UpdateScene");
|
|
const auto& metrics = context.metrics();
|
|
SceneUpdateContext::Transform transform(context, // context
|
|
1.0f / metrics->scale_x, // X
|
|
1.0f / metrics->scale_y, // Y
|
|
1.0f / metrics->scale_z // Z
|
|
);
|
|
SceneUpdateContext::Frame frame(
|
|
context,
|
|
SkRRect::MakeRect(
|
|
SkRect::MakeWH(frame_size_.width(), frame_size_.height())),
|
|
SK_ColorTRANSPARENT, 0.f);
|
|
if (root_layer_->needs_system_composite()) {
|
|
root_layer_->UpdateScene(context);
|
|
}
|
|
if (root_layer_->needs_painting()) {
|
|
frame.AddPaintedLayer(root_layer_.get());
|
|
}
|
|
container.AddChild(transform.entity_node());
|
|
}
|
|
#endif
|
|
|
|
void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
|
|
bool ignore_raster_cache) const {
|
|
TRACE_EVENT0("flutter", "LayerTree::Paint");
|
|
Layer::PaintContext context = {
|
|
frame.canvas(),
|
|
frame.view_embedder(),
|
|
frame.context().frame_time(),
|
|
frame.context().engine_time(),
|
|
frame.context().texture_registry(),
|
|
ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
|
|
checkerboard_offscreen_layers_};
|
|
|
|
if (root_layer_->needs_painting())
|
|
root_layer_->Paint(context);
|
|
}
|
|
|
|
sk_sp<SkPicture> LayerTree::Flatten(const SkRect& bounds) {
|
|
TRACE_EVENT0("flutter", "LayerTree::Flatten");
|
|
|
|
SkPictureRecorder recorder;
|
|
auto canvas = recorder.beginRecording(bounds);
|
|
|
|
if (!canvas) {
|
|
return nullptr;
|
|
}
|
|
|
|
const Stopwatch unused_stopwatch;
|
|
TextureRegistry unused_texture_registry;
|
|
SkMatrix root_surface_transformation;
|
|
// No root surface transformation. So assume identity.
|
|
root_surface_transformation.reset();
|
|
|
|
PrerollContext preroll_context{
|
|
nullptr, // raster_cache (don't consult the cache)
|
|
nullptr, // gr_context (used for the raster cache)
|
|
nullptr, // SkColorSpace* dst_color_space
|
|
SkRect::MakeEmpty(), // SkRect child_paint_bounds
|
|
unused_stopwatch, // frame time (dont care)
|
|
unused_stopwatch, // engine time (dont care)
|
|
unused_texture_registry, // texture registry (not supported)
|
|
false, // checkerboard_offscreen_layers
|
|
};
|
|
|
|
Layer::PaintContext paint_context = {
|
|
canvas, // canvas
|
|
nullptr,
|
|
unused_stopwatch, // frame time (dont care)
|
|
unused_stopwatch, // engine time (dont care)
|
|
unused_texture_registry, // texture registry (not supported)
|
|
nullptr, // raster cache
|
|
false // checkerboard offscreen layers
|
|
};
|
|
|
|
// Even if we don't have a root layer, we still need to create an empty
|
|
// picture.
|
|
if (root_layer_) {
|
|
root_layer_->Preroll(&preroll_context, root_surface_transformation);
|
|
// The needs painting flag may be set after the preroll. So check it after.
|
|
if (root_layer_->needs_painting()) {
|
|
root_layer_->Paint(paint_context);
|
|
}
|
|
}
|
|
|
|
return recorder.finishRecordingAsPicture();
|
|
}
|
|
|
|
} // namespace flow
|