Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 31 additions & 12 deletions shell/common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("$flutter_root/testing/testing.gni")

# Template to generate a dart embedder resource.cc file.
# Required invoker inputs:
# String output (name of output file)
Expand Down Expand Up @@ -61,18 +63,18 @@ source_set("common") {
"animator.h",
"engine.cc",
"engine.h",
"null_platform_view.cc",
"null_platform_view.h",
"null_rasterizer.cc",
"null_rasterizer.h",
"io_manager.cc",
"io_manager.h",
"isolate_configuration.cc",
"isolate_configuration.h",
"picture_serializer.cc",
"picture_serializer.h",
"platform_view.cc",
"platform_view.h",
"platform_view_service_protocol.cc",
"platform_view_service_protocol.h",
"rasterizer.cc",
"rasterizer.h",
"run_configuration.cc",
"run_configuration.h",
"shell.cc",
"shell.h",
"skia_event_tracer_impl.cc",
Expand All @@ -81,28 +83,29 @@ source_set("common") {
"surface.h",
"switches.cc",
"switches.h",
"tracing_controller.cc",
"tracing_controller.h",
"thread_host.cc",
"thread_host.h",
"vsync_waiter.cc",
"vsync_waiter.h",
"vsync_waiter_fallback.cc",
"vsync_waiter_fallback.h",
]

deps = [
"//third_party/dart/runtime:dart_api",
"//third_party/dart/runtime/platform:libdart_platform",
"$flutter_root/assets",
"$flutter_root/common",
"$flutter_root/flow",
"$flutter_root/fml",
"$flutter_root/glue",
"$flutter_root/lib/ui",
"$flutter_root/runtime",
"$flutter_root/sky/engine/platform",
"$flutter_root/sky/engine/wtf",
"$flutter_root/synchronization",
"$flutter_root/third_party/txt",
"//garnet/public/lib/fxl",
"//third_party/dart/runtime:dart_api",
"//third_party/dart/runtime/platform:libdart_platform",
"//third_party/rapidjson",
"//third_party/skia",
"//third_party/skia:gpu",
Expand All @@ -112,7 +115,23 @@ source_set("common") {
"//topaz/lib/tonic",
]

public_configs = [
"$flutter_root:config",
public_configs = [ "$flutter_root:config" ]
}

executable("shell_unittests") {
testonly = true

sources = [
"shell_unittests.cc",
]
deps = [
":common",
"$flutter_root/fml",
"$flutter_root/lib/snapshot",
"$flutter_root/testing",
"//garnet/public/lib/fxl",
"//third_party/dart/runtime:libdart_jit",
"//third_party/skia",
"//topaz/lib/tonic",
]
}
81 changes: 36 additions & 45 deletions shell/common/animator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@

#include "flutter/shell/common/animator.h"

#include "flutter/common/threads.h"
#include "flutter/fml/trace_event.h"
#include "flutter/glue/trace_event.h"
#include "lib/fxl/time/stopwatch.h"
#include "third_party/dart/runtime/include/dart_tools_api.h"

namespace shell {

Animator::Animator(fml::WeakPtr<Rasterizer> rasterizer,
VsyncWaiter* waiter,
Engine* engine)
: rasterizer_(rasterizer),
waiter_(waiter),
engine_(engine),
Animator::Animator(Delegate& delegate,
blink::TaskRunners task_runners,
std::unique_ptr<VsyncWaiter> waiter)
: delegate_(delegate),
task_runners_(std::move(task_runners)),
waiter_(std::move(waiter)),
last_begin_frame_time_(),
dart_frame_deadline_(0),
layer_tree_pipeline_(fxl::MakeRefCounted<LayerTreePipeline>(2)),
Expand All @@ -28,7 +27,11 @@ Animator::Animator(fml::WeakPtr<Rasterizer> rasterizer,
dimension_change_pending_(false),
weak_factory_(this) {}

Animator::~Animator() = default;
Animator::~Animator() {
// TODO(chinmaygarde): Remove after
// https://github.com/flutter/flutter/issues/13692 is fixed.
pending_frame_semaphore_.Signal();
}

void Animator::Stop() {
paused_ = true;
Expand Down Expand Up @@ -79,7 +82,6 @@ void Animator::BeginFrame(fxl::TimePoint frame_start_time,
// If we still don't have valid continuation, the pipeline is currently
// full because the consumer is being too slow. Try again at the next
// frame interval.
TRACE_EVENT_INSTANT0("flutter", "ConsumerSlowDefer");
RequestFrame();
return;
}
Expand All @@ -94,13 +96,13 @@ void Animator::BeginFrame(fxl::TimePoint frame_start_time,
{
TRACE_EVENT2("flutter", "Framework Workload", "mode", "basic", "frame",
FrameParity());
engine_->BeginFrame(last_begin_frame_time_);
delegate_.OnAnimatorBeginFrame(*this, last_begin_frame_time_);
}

if (!frame_scheduled_) {
// We don't have another frame pending, so we're waiting on user input
// or I/O. Allow the Dart VM 100 ms.
engine_->NotifyIdle(dart_frame_deadline_ + 100000);
delegate_.OnAnimatorNotifyIdle(*this, dart_frame_deadline_ + 100000);
}
}

Expand All @@ -120,15 +122,7 @@ void Animator::Render(std::unique_ptr<flow::LayerTree> layer_tree) {
// Commit the pending continuation.
producer_continuation_.Complete(std::move(layer_tree));

blink::Threads::Gpu()->PostTask([
rasterizer = rasterizer_, pipeline = layer_tree_pipeline_,
frame_id = FrameParity()
]() {
if (!rasterizer.get())
return;
TRACE_EVENT2("flutter", "GPU Workload", "mode", "basic", "frame", frame_id);
rasterizer->Draw(pipeline);
});
delegate_.OnAnimatorDraw(*this, layer_tree_pipeline_);
}

bool Animator::CanReuseLastLayerTree() {
Expand All @@ -137,10 +131,7 @@ bool Animator::CanReuseLastLayerTree() {

void Animator::DrawLastLayerTree() {
pending_frame_semaphore_.Signal();
blink::Threads::Gpu()->PostTask([rasterizer = rasterizer_]() {
if (rasterizer.get())
rasterizer->DrawLastLayerTree();
});
delegate_.OnAnimatorDrawLastLayerTree(*this);
}

void Animator::RequestFrame(bool regenerate_layer_tree) {
Expand All @@ -164,31 +155,31 @@ void Animator::RequestFrame(bool regenerate_layer_tree) {
// started an expensive operation right after posting this message however.
// To support that, we need edge triggered wakes on VSync.

blink::Threads::UI()->PostTask(
[ self = weak_factory_.GetWeakPtr(), frame_number = frame_number_ ]() {
if (!self.get()) {
return;
}
TRACE_EVENT_ASYNC_BEGIN0("flutter", "Frame Request Pending",
frame_number);
self->AwaitVSync();
});
task_runners_.GetUITaskRunner()->PostTask([self = weak_factory_.GetWeakPtr(),
frame_number = frame_number_]() {
if (!self.get()) {
return;
}
TRACE_EVENT_ASYNC_BEGIN0("flutter", "Frame Request Pending", frame_number);
self->AwaitVSync();
});
frame_scheduled_ = true;
}

void Animator::AwaitVSync() {
waiter_->AsyncWaitForVsync([self = weak_factory_.GetWeakPtr()](
fxl::TimePoint frame_start_time, fxl::TimePoint frame_target_time) {
if (self) {
if (self->CanReuseLastLayerTree()) {
self->DrawLastLayerTree();
} else {
self->BeginFrame(frame_start_time, frame_target_time);
}
}
});
waiter_->AsyncWaitForVsync(
[self = weak_factory_.GetWeakPtr()](fxl::TimePoint frame_start_time,
fxl::TimePoint frame_target_time) {
if (self) {
if (self->CanReuseLastLayerTree()) {
self->DrawLastLayerTree();
} else {
self->BeginFrame(frame_start_time, frame_target_time);
}
}
});

engine_->NotifyIdle(dart_frame_deadline_);
delegate_.OnAnimatorNotifyIdle(*this, dart_frame_deadline_);
}

} // namespace shell
37 changes: 24 additions & 13 deletions shell/common/animator.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#ifndef FLUTTER_SHELL_COMMON_ANIMATOR_H_
#define FLUTTER_SHELL_COMMON_ANIMATOR_H_

#include "flutter/shell/common/engine.h"
#include "flutter/common/task_runners.h"
#include "flutter/shell/common/rasterizer.h"
#include "flutter/shell/common/vsync_waiter.h"
#include "flutter/synchronization/pipeline.h"
Expand All @@ -16,17 +16,28 @@

namespace shell {

class Animator {
class Animator final {
public:
Animator(fml::WeakPtr<Rasterizer> rasterizer,
VsyncWaiter* waiter,
Engine* engine);
class Delegate {
public:
virtual void OnAnimatorBeginFrame(const Animator& animator,
fxl::TimePoint frame_time) = 0;

~Animator();
virtual void OnAnimatorNotifyIdle(const Animator& animator,
int64_t deadline) = 0;

virtual void OnAnimatorDraw(
const Animator& animator,
fxl::RefPtr<flutter::Pipeline<flow::LayerTree>> pipeline) = 0;

virtual void OnAnimatorDrawLastLayerTree(const Animator& animator) = 0;
};

void set_rasterizer(fml::WeakPtr<Rasterizer> rasterizer) {
rasterizer_ = rasterizer;
}
Animator(Delegate& delegate,
blink::TaskRunners task_runners,
std::unique_ptr<VsyncWaiter> waiter);

~Animator();

void RequestFrame(bool regenerate_layer_tree = true);

Expand All @@ -51,9 +62,9 @@ class Animator {

const char* FrameParity();

fml::WeakPtr<Rasterizer> rasterizer_;
VsyncWaiter* waiter_;
Engine* engine_;
Delegate& delegate_;
blink::TaskRunners task_runners_;
std::unique_ptr<VsyncWaiter> waiter_;

fxl::TimePoint last_begin_frame_time_;
int64_t dart_frame_deadline_;
Expand All @@ -67,7 +78,7 @@ class Animator {
bool dimension_change_pending_;
SkISize last_layer_tree_size_;

fml::WeakPtrFactory<Animator> weak_factory_;
fxl::WeakPtrFactory<Animator> weak_factory_;

FXL_DISALLOW_COPY_AND_ASSIGN(Animator);
};
Expand Down
Loading