Skip to content

Commit

Permalink
Turn on RasterCache based on view hierarchy (#13360)
Browse files Browse the repository at this point in the history
Previously the cache was disabled on whether or not PlatformViews were
globally enabled. Instead track their existence in the view hierarchy
and only disable RasterCache if a PlatformView is actually present.
  • Loading branch information
Michael Klimushyn committed Oct 30, 2019
1 parent acff7b5 commit 3ad3bc7
Show file tree
Hide file tree
Showing 14 changed files with 281 additions and 29 deletions.
14 changes: 14 additions & 0 deletions flow/layers/container_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,28 @@ void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
void ContainerLayer::PrerollChildren(PrerollContext* context,
const SkMatrix& child_matrix,
SkRect* child_paint_bounds) {
// Platform views have no children, so context->has_platform_view should
// always be false.
FML_DCHECK(!context->has_platform_view);
bool child_has_platform_view = false;
for (auto& layer : layers_) {
// Reset context->has_platform_view to false so that layers aren't treated
// as if they have a platform view based on one being previously found in a
// sibling tree.
context->has_platform_view = false;

layer->Preroll(context, child_matrix);

if (layer->needs_system_composite()) {
set_needs_system_composite(true);
}
child_paint_bounds->join(layer->paint_bounds());

child_has_platform_view =
child_has_platform_view || context->has_platform_view;
}

context->has_platform_view = child_has_platform_view;
}

void ContainerLayer::PaintChildren(PaintContext& context) const {
Expand Down
1 change: 1 addition & 0 deletions flow/layers/layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct PrerollContext {
TextureRegistry& texture_registry;
const bool checkerboard_offscreen_layers;
float total_elevation = 0.0f;
bool has_platform_view = false;
};

// Represents a single composited layer. Created on the UI thread but then
Expand Down
8 changes: 2 additions & 6 deletions flow/layers/opacity_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void OpacityLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
set_paint_bounds(paint_bounds().makeOffset(offset_.fX, offset_.fY));
// See |EnsureSingleChild|.
FML_DCHECK(layers().size() == 1);
if (context->view_embedder == nullptr && context->raster_cache &&
if (!context->has_platform_view && context->raster_cache &&
SkRect::Intersects(context->cull_rect, paint_bounds())) {
Layer* child = layers()[0].get();
SkMatrix ctm = child_matrix;
Expand Down Expand Up @@ -75,11 +75,7 @@ void OpacityLayer::Paint(PaintContext& context) const {
// See |EnsureSingleChild|.
FML_DCHECK(layers().size() == 1);

// Embedded platform views are changing the canvas in the middle of the paint
// traversal. To make sure we paint on the right canvas, when the embedded
// platform views preview is enabled (context.view_embedded is not null) we
// don't use the cache.
if (context.view_embedder == nullptr && context.raster_cache) {
if (context.raster_cache) {
const SkMatrix& ctm = context.leaf_nodes_canvas->getTotalMatrix();
RasterCacheResult child_cache =
context.raster_cache->Get(layers()[0].get(), ctm);
Expand Down
1 change: 1 addition & 0 deletions flow/layers/platform_view_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ void PlatformViewLayer::Preroll(PrerollContext* context,
"does not support embedding";
return;
}
context->has_platform_view = true;
std::unique_ptr<EmbeddedViewParams> params =
std::make_unique<EmbeddedViewParams>();
params->offsetPixels =
Expand Down
47 changes: 26 additions & 21 deletions flow/raster_cache.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,27 +158,28 @@ void RasterCache::Prepare(PrerollContext* context,
entry.access_count = ClampSize(entry.access_count + 1, 0, access_threshold_);
entry.used_this_frame = true;
if (!entry.image.is_valid()) {
entry.image = Rasterize(context->gr_context, ctm, context->dst_color_space,
checkerboard_images_, layer->paint_bounds(),
[layer, context](SkCanvas* canvas) {
SkISize canvas_size = canvas->getBaseLayerSize();
SkNWayCanvas internal_nodes_canvas(
canvas_size.width(), canvas_size.height());
internal_nodes_canvas.addCanvas(canvas);
Layer::PaintContext paintContext = {
(SkCanvas*)&internal_nodes_canvas,
canvas,
context->gr_context,
nullptr,
context->raster_time,
context->ui_time,
context->texture_registry,
context->raster_cache,
context->checkerboard_offscreen_layers};
if (layer->needs_painting()) {
layer->Paint(paintContext);
}
});
entry.image = Rasterize(
context->gr_context, ctm, context->dst_color_space,
checkerboard_images_, layer->paint_bounds(),
[layer, context](SkCanvas* canvas) {
SkISize canvas_size = canvas->getBaseLayerSize();
SkNWayCanvas internal_nodes_canvas(canvas_size.width(),
canvas_size.height());
internal_nodes_canvas.addCanvas(canvas);
Layer::PaintContext paintContext = {
(SkCanvas*)&internal_nodes_canvas,
canvas,
context->gr_context,
nullptr,
context->raster_time,
context->ui_time,
context->texture_registry,
context->has_platform_view ? nullptr : context->raster_cache,
context->checkerboard_offscreen_layers};
if (layer->needs_painting()) {
layer->Paint(paintContext);
}
});
}
}

Expand Down Expand Up @@ -251,6 +252,10 @@ void RasterCache::Clear() {
layer_cache_.clear();
}

size_t RasterCache::GetCachedEntriesCount() const {
return layer_cache_.size() + picture_cache_.size();
}

void RasterCache::SetCheckboardCacheImages(bool checkerboard) {
if (checkerboard_images_ == checkerboard) {
return;
Expand Down
2 changes: 2 additions & 0 deletions flow/raster_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ class RasterCache {

void SetCheckboardCacheImages(bool checkerboard);

size_t GetCachedEntriesCount() const;

private:
struct Entry {
bool used_this_frame = false;
Expand Down
2 changes: 1 addition & 1 deletion shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ const TaskRunners& Shell::GetTaskRunners() const {
return task_runners_;
}

fml::WeakPtr<Rasterizer> Shell::GetRasterizer() {
fml::WeakPtr<Rasterizer> Shell::GetRasterizer() const {
FML_DCHECK(is_setup_);
return weak_rasterizer_;
}
Expand Down
2 changes: 1 addition & 1 deletion shell/common/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ class Shell final : public PlatformView::Delegate,
///
/// @return A weak pointer to the rasterizer.
///
fml::WeakPtr<Rasterizer> GetRasterizer();
fml::WeakPtr<Rasterizer> GetRasterizer() const;

//------------------------------------------------------------------------------
/// @brief Engines may only be accessed on the UI thread. This method is
Expand Down
1 change: 1 addition & 0 deletions shell/platform/embedder/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ if (current_toolchain == host_toolchain) {
":fixtures",
"$flutter_root/lib/ui",
"$flutter_root/runtime",
"$flutter_root/flow",
"$flutter_root/testing:dart",
"$flutter_root/testing:opengl",
"$flutter_root/testing:skia",
Expand Down
5 changes: 5 additions & 0 deletions shell/platform/embedder/embedder_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,9 @@ bool EmbedderEngine::RunTask(const FlutterTask* task) {
task->task);
}

const Shell& EmbedderEngine::GetShell() const {
FML_DCHECK(shell_);
return *shell_.get();
}

} // namespace flutter
2 changes: 2 additions & 0 deletions shell/platform/embedder/embedder_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ class EmbedderEngine {

bool RunTask(const FlutterTask* task);

const Shell& GetShell() const;

private:
const std::unique_ptr<EmbedderThreadHost> thread_host_;
TaskRunners task_runners_;
Expand Down
44 changes: 44 additions & 0 deletions shell/platform/embedder/fixtures/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,50 @@ void can_composite_platform_views() {
window.scheduleFrame();
}

@pragma('vm:entry-point')
void can_composite_platform_views_with_opacity() {
window.onBeginFrame = (Duration duration) {
SceneBuilder builder = SceneBuilder();

// Root node
builder.pushOffset(1.0, 2.0);

// First sibling layer (no platform view, should be cached)
builder.pushOpacity(127);
builder.addPicture(Offset(1.0, 1.0), CreateSimplePicture());
builder.pop();

// Second sibling layer (platform view, should not be cached)
builder.pushOpacity(127);
builder.addPlatformView(42, width: 123.0, height: 456.0);
builder.pop();

// Third sibling layer (no platform view, should be cached)
builder.pushOpacity(127);
builder.addPicture(Offset(2.0, 1.0), CreateSimplePicture());
builder.pop();

signalNativeTest(); // Signal 2
window.render(builder.build());
};
signalNativeTest(); // Signal 1
window.scheduleFrame();
}

@pragma('vm:entry-point')
void can_composite_with_opacity() {
window.onBeginFrame = (Duration duration) {
SceneBuilder builder = SceneBuilder();
builder.pushOpacity(127);
builder.addPicture(Offset(1.0, 1.0), CreateSimplePicture());
builder.pop(); // offset
signalNativeTest(); // Signal 2
window.render(builder.build());
};
signalNativeTest(); // Signal 1
window.scheduleFrame();
}

Picture CreateColoredBox(Color color, Size size) {
Paint paint = Paint();
paint.color = color;
Expand Down
5 changes: 5 additions & 0 deletions shell/platform/embedder/tests/embedder_assertions.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "flutter/fml/logging.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/embedder_engine.h"
#include "flutter/testing/assertions.h"
#include "gtest/gtest.h"
#include "third_party/skia/include/core/SkPoint.h"
Expand Down Expand Up @@ -261,4 +262,8 @@ inline FlutterTransformation FlutterTransformationMake(const SkMatrix& matrix) {
return transformation;
}

inline flutter::EmbedderEngine* ToEmbedderEngine(const FlutterEngine& engine) {
return reinterpret_cast<flutter::EmbedderEngine*>(engine);
}

#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_ASSERTIONS_H_
Loading

0 comments on commit 3ad3bc7

Please sign in to comment.