未验证 提交 3930ac1b 编写于 作者: D Dan Field 提交者: GitHub

Hint freed (#19842)

* Hint the VM when a layer or picture goes out of scope
上级 93a17907
......@@ -9,8 +9,10 @@
namespace flutter {
CompositorContext::CompositorContext(fml::Milliseconds frame_budget)
: raster_time_(frame_budget), ui_time_(frame_budget) {}
CompositorContext::CompositorContext(Delegate& delegate)
: delegate_(delegate),
raster_time_(delegate.GetFrameBudget()),
ui_time_(delegate.GetFrameBudget()) {}
CompositorContext::~CompositorContext() = default;
......@@ -23,8 +25,11 @@ void CompositorContext::BeginFrame(ScopedFrame& frame,
}
void CompositorContext::EndFrame(ScopedFrame& frame,
bool enable_instrumentation) {
raster_cache_.SweepAfterFrame();
bool enable_instrumentation,
size_t freed_hint) {
freed_hint += raster_cache_.SweepAfterFrame();
delegate_.OnCompositorEndFrame(freed_hint);
if (enable_instrumentation) {
raster_time_.Stop();
}
......@@ -64,7 +69,7 @@ CompositorContext::ScopedFrame::ScopedFrame(
}
CompositorContext::ScopedFrame::~ScopedFrame() {
context_.EndFrame(*this, instrumentation_enabled_);
context_.EndFrame(*this, instrumentation_enabled_, uncached_external_size_);
}
RasterStatus CompositorContext::ScopedFrame::Raster(
......
......@@ -37,6 +37,18 @@ enum class RasterStatus {
class CompositorContext {
public:
class Delegate {
public:
/// Called at the end of a frame with approximately how many bytes mightbe
/// freed if a GC ran now.
///
/// This method is called from the raster task runner.
virtual void OnCompositorEndFrame(size_t freed_hint) = 0;
/// Time limit for a smooth frame. See `Engine::GetDisplayRefreshRate`.
virtual fml::Milliseconds GetFrameBudget() = 0;
};
class ScopedFrame {
public:
ScopedFrame(CompositorContext& context,
......@@ -67,6 +79,8 @@ class CompositorContext {
virtual RasterStatus Raster(LayerTree& layer_tree,
bool ignore_raster_cache);
void add_external_size(size_t size) { uncached_external_size_ += size; }
private:
CompositorContext& context_;
GrDirectContext* gr_context_;
......@@ -76,11 +90,12 @@ class CompositorContext {
const bool instrumentation_enabled_;
const bool surface_supports_readback_;
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger_;
size_t uncached_external_size_ = 0;
FML_DISALLOW_COPY_AND_ASSIGN(ScopedFrame);
};
CompositorContext(fml::Milliseconds frame_budget = fml::kDefaultFrameBudget);
explicit CompositorContext(Delegate& delegate);
virtual ~CompositorContext();
......@@ -108,6 +123,7 @@ class CompositorContext {
Stopwatch& ui_time() { return ui_time_; }
private:
Delegate& delegate_;
RasterCache raster_cache_;
TextureRegistry texture_registry_;
Counter frame_count_;
......@@ -116,7 +132,9 @@ class CompositorContext {
void BeginFrame(ScopedFrame& frame, bool enable_instrumentation);
void EndFrame(ScopedFrame& frame, bool enable_instrumentation);
void EndFrame(ScopedFrame& frame,
bool enable_instrumentation,
size_t freed_hint);
FML_DISALLOW_COPY_AND_ASSIGN(CompositorContext);
};
......
......@@ -9,10 +9,11 @@
namespace flutter {
Layer::Layer()
Layer::Layer(size_t external_size)
: paint_bounds_(SkRect::MakeEmpty()),
unique_id_(NextUniqueID()),
needs_system_composite_(false) {}
needs_system_composite_(false),
external_size_(external_size) {}
Layer::~Layer() = default;
......
......@@ -67,13 +67,14 @@ struct PrerollContext {
// Informs whether a layer needs to be system composited.
bool child_scene_layer_exists_below = false;
#endif
size_t uncached_external_size = 0;
};
// Represents a single composited layer. Created on the UI thread but then
// subquently used on the Rasterizer thread.
class Layer {
public:
Layer();
Layer(size_t external_size = 0);
virtual ~Layer();
virtual void Preroll(PrerollContext* context, const SkMatrix& matrix);
......@@ -178,6 +179,8 @@ class Layer {
uint64_t unique_id() const { return unique_id_; }
size_t external_size() const { return external_size_; }
protected:
#if defined(LEGACY_FUCHSIA_EMBEDDER)
bool child_layer_exists_below_ = false;
......@@ -187,6 +190,7 @@ class Layer {
SkRect paint_bounds_;
uint64_t unique_id_;
bool needs_system_composite_;
size_t external_size_ = 0;
static uint64_t NextUniqueID();
......
......@@ -58,6 +58,7 @@ bool LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
device_pixel_ratio_};
root_layer_->Preroll(&context, frame.root_surface_transformation());
frame.add_external_size(context.uncached_external_size);
return context.surface_needs_readback;
}
......
......@@ -15,11 +15,11 @@
namespace flutter {
namespace testing {
class LayerTreeTest : public CanvasTest {
class LayerTreeTest : public CanvasTest, public CompositorContext::Delegate {
public:
LayerTreeTest()
: layer_tree_(SkISize::Make(64, 64), 1.0f),
compositor_context_(fml::kDefaultFrameBudget),
compositor_context_(*this),
root_transform_(SkMatrix::Translate(1.0f, 1.0f)),
scoped_frame_(compositor_context_.AcquireFrame(nullptr,
&mock_canvas(),
......@@ -33,11 +33,24 @@ class LayerTreeTest : public CanvasTest {
CompositorContext::ScopedFrame& frame() { return *scoped_frame_.get(); }
const SkMatrix& root_transform() { return root_transform_; }
// |CompositorContext::Delegate|
void OnCompositorEndFrame(size_t freed_hint) override {
last_freed_hint_ = freed_hint;
}
// |CompositorContext::Delegate|
fml::Milliseconds GetFrameBudget() override {
return fml::kDefaultFrameBudget;
}
size_t last_freed_hint() { return last_freed_hint_; }
private:
LayerTree layer_tree_;
CompositorContext compositor_context_;
SkMatrix root_transform_;
std::unique_ptr<CompositorContext::ScopedFrame> scoped_frame_;
size_t last_freed_hint_ = 0;
};
TEST_F(LayerTreeTest, PaintingEmptyLayerDies) {
......
......@@ -11,8 +11,10 @@ namespace flutter {
PictureLayer::PictureLayer(const SkPoint& offset,
SkiaGPUObject<SkPicture> picture,
bool is_complex,
bool will_change)
: offset_(offset),
bool will_change,
size_t external_size)
: Layer(external_size),
offset_(offset),
picture_(std::move(picture)),
is_complex_(is_complex),
will_change_(will_change) {}
......@@ -26,6 +28,7 @@ void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
SkPicture* sk_picture = picture();
bool cached = false;
if (auto* cache = context->raster_cache) {
TRACE_EVENT0("flutter", "PictureLayer::RasterCache (Preroll)");
......@@ -34,8 +37,13 @@ void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
#ifndef SUPPORT_FRACTIONAL_TRANSLATION
ctm = RasterCache::GetIntegralTransCTM(ctm);
#endif
cache->Prepare(context->gr_context, sk_picture, ctm,
context->dst_color_space, is_complex_, will_change_);
cached = cache->Prepare(context->gr_context, sk_picture, ctm,
context->dst_color_space, is_complex_, will_change_,
external_size());
}
if (!cached) {
context->uncached_external_size += external_size();
}
SkRect bounds = sk_picture->cullRect().makeOffset(offset_.x(), offset_.y());
......
......@@ -18,7 +18,8 @@ class PictureLayer : public Layer {
PictureLayer(const SkPoint& offset,
SkiaGPUObject<SkPicture> picture,
bool is_complex,
bool will_change);
bool will_change,
size_t external_size);
SkPicture* picture() const { return picture_.get().get(); }
......
......@@ -24,7 +24,7 @@ using PictureLayerTest = SkiaGPUObjectLayerTest;
TEST_F(PictureLayerTest, PaintBeforePrerollInvalidPictureDies) {
const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
auto layer = std::make_shared<PictureLayer>(
layer_offset, SkiaGPUObject<SkPicture>(), false, false);
layer_offset, SkiaGPUObject<SkPicture>(), false, false, 0);
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
"picture_\\.get\\(\\)");
......@@ -35,7 +35,8 @@ TEST_F(PictureLayerTest, PaintBeforePreollDies) {
const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
auto mock_picture = SkPicture::MakePlaceholder(picture_bounds);
auto layer = std::make_shared<PictureLayer>(
layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false);
layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false,
0);
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
EXPECT_DEATH_IF_SUPPORTED(layer->Paint(paint_context()),
......@@ -47,7 +48,8 @@ TEST_F(PictureLayerTest, PaintingEmptyLayerDies) {
const SkRect picture_bounds = SkRect::MakeEmpty();
auto mock_picture = SkPicture::MakePlaceholder(picture_bounds);
auto layer = std::make_shared<PictureLayer>(
layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false);
layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false,
0);
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty());
......@@ -62,7 +64,7 @@ TEST_F(PictureLayerTest, PaintingEmptyLayerDies) {
TEST_F(PictureLayerTest, InvalidPictureDies) {
const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
auto layer = std::make_shared<PictureLayer>(
layer_offset, SkiaGPUObject<SkPicture>(), false, false);
layer_offset, SkiaGPUObject<SkPicture>(), false, false, 0);
// Crashes reading a nullptr.
EXPECT_DEATH_IF_SUPPORTED(layer->Preroll(preroll_context(), SkMatrix()), "");
......@@ -75,7 +77,10 @@ TEST_F(PictureLayerTest, SimplePicture) {
const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
auto mock_picture = SkPicture::MakePlaceholder(picture_bounds);
auto layer = std::make_shared<PictureLayer>(
layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false);
layer_offset, SkiaGPUObject(mock_picture, unref_queue()), false, false,
1000);
EXPECT_EQ(layer->external_size(), 1000ul);
layer->Preroll(preroll_context(), SkMatrix());
EXPECT_EQ(layer->paint_bounds(),
......
......@@ -141,6 +141,7 @@ void RasterCache::Prepare(PrerollContext* context,
Entry& entry = layer_cache_[cache_key];
entry.access_count++;
entry.used_this_frame = true;
entry.external_size = layer->external_size();
if (!entry.image) {
entry.image = RasterizeLayer(context, layer, ctm, checkerboard_images_);
}
......@@ -181,7 +182,8 @@ bool RasterCache::Prepare(GrDirectContext* context,
const SkMatrix& transformation_matrix,
SkColorSpace* dst_color_space,
bool is_complex,
bool will_change) {
bool will_change,
size_t external_size) {
// Disabling caching when access_threshold is zero is historic behavior.
if (access_threshold_ == 0) {
return false;
......@@ -207,6 +209,7 @@ bool RasterCache::Prepare(GrDirectContext* context,
// Creates an entry, if not present prior.
Entry& entry = picture_cache_[cache_key];
entry.external_size = external_size;
if (entry.access_count < access_threshold_) {
// Frame threshold has not yet been reached.
return false;
......@@ -260,11 +263,12 @@ bool RasterCache::Draw(const Layer* layer,
return false;
}
void RasterCache::SweepAfterFrame() {
SweepOneCacheAfterFrame(picture_cache_);
SweepOneCacheAfterFrame(layer_cache_);
size_t RasterCache::SweepAfterFrame() {
size_t removed_size = SweepOneCacheAfterFrame(picture_cache_);
removed_size += SweepOneCacheAfterFrame(layer_cache_);
picture_cached_this_frame_ = 0;
TraceStatsToTimeline();
return removed_size;
}
void RasterCache::Clear() {
......
......@@ -137,7 +137,8 @@ class RasterCache {
const SkMatrix& transformation_matrix,
SkColorSpace* dst_color_space,
bool is_complex,
bool will_change);
bool will_change,
size_t external_size = 0);
void Prepare(PrerollContext* context, Layer* layer, const SkMatrix& ctm);
......@@ -156,7 +157,8 @@ class RasterCache {
SkCanvas& canvas,
SkPaint* paint = nullptr) const;
void SweepAfterFrame();
/// Returns the amount of external bytes freed by the sweep.
size_t SweepAfterFrame();
void Clear();
......@@ -192,17 +194,20 @@ class RasterCache {
struct Entry {
bool used_this_frame = false;
size_t access_count = 0;
size_t external_size = 0;
std::unique_ptr<RasterCacheResult> image;
};
template <class Cache>
static void SweepOneCacheAfterFrame(Cache& cache) {
static size_t SweepOneCacheAfterFrame(Cache& cache) {
std::vector<typename Cache::iterator> dead;
size_t removed_size = 0;
for (auto it = cache.begin(); it != cache.end(); ++it) {
Entry& entry = it->second;
if (!entry.used_this_frame) {
dead.push_back(it);
removed_size += entry.external_size;
}
entry.used_this_frame = false;
}
......@@ -210,6 +215,7 @@ class RasterCache {
for (auto it : dead) {
cache.erase(it);
}
return removed_size;
}
const size_t access_threshold_;
......
......@@ -220,7 +220,7 @@ void SceneBuilder::addPicture(double dx,
pictureRect.offset(offset.x(), offset.y());
auto layer = std::make_unique<flutter::PictureLayer>(
offset, UIDartState::CreateGPUObject(picture->picture()), !!(hints & 1),
!!(hints & 2));
!!(hints & 2), picture->GetAllocationSize());
AddLayer(std::move(layer));
}
......
......@@ -3,6 +3,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'dart:typed_data';
import 'dart:ui';
......@@ -73,3 +74,59 @@ Future<void> encodeImageProducesExternalUint8List() async {
void _encodeImage(Image i, int format, void Function(Uint8List result))
native 'EncodeImage';
void _validateExternal(Uint8List result) native 'ValidateExternal';
@pragma('vm:entry-point')
Future<void> pumpImage() async {
final FrameCallback renderBlank = (Duration duration) {
final PictureRecorder recorder = PictureRecorder();
final Canvas canvas = Canvas(recorder);
canvas.drawRect(Rect.largest, Paint());
final Picture picture = recorder.endRecording();
final SceneBuilder builder = SceneBuilder();
builder.addPicture(Offset.zero, picture);
final Scene scene = builder.build();
window.render(scene);
scene.dispose();
window.onBeginFrame = (Duration duration) {
window.onDrawFrame = _onBeginFrameDone;
};
window.scheduleFrame();
};
final FrameCallback renderImage = (Duration duration) {
const int width = 8000;
const int height = 8000;
final Completer<Image> completer = Completer<Image>();
decodeImageFromPixels(
Uint8List.fromList(List<int>.filled(width * height * 4, 0xFF)),
width,
height,
PixelFormat.rgba8888,
(Image image) => completer.complete(image),
);
completer.future.then((Image image) {
final PictureRecorder recorder = PictureRecorder();
final Canvas canvas = Canvas(recorder);
canvas.drawImage(image, Offset.zero, Paint());
final Picture picture = recorder.endRecording();
final SceneBuilder builder = SceneBuilder();
builder.addPicture(Offset.zero, picture);
_captureImageAndPicture(image, picture);
final Scene scene = builder.build();
window.render(scene);
scene.dispose();
window.onBeginFrame = renderBlank;
window.scheduleFrame();
});
};
window.onBeginFrame = renderImage;
window.scheduleFrame();
}
void _captureImageAndPicture(Image image, Picture picture) native 'CaptureImageAndPicture';
Future<void> _onBeginFrameDone() native 'OnBeginFrameDone';
......@@ -233,7 +233,7 @@ bool RuntimeController::ReportTimings(std::vector<int64_t> timings) {
return false;
}
bool RuntimeController::NotifyIdle(int64_t deadline) {
bool RuntimeController::NotifyIdle(int64_t deadline, size_t freed_hint) {
std::shared_ptr<DartIsolate> root_isolate = root_isolate_.lock();
if (!root_isolate) {
return false;
......@@ -241,6 +241,9 @@ bool RuntimeController::NotifyIdle(int64_t deadline) {
tonic::DartState::Scope scope(root_isolate);
// Dart will use the freed hint at the next idle notification. Make sure to
// Update it with our latest value before calling NotifyIdle.
Dart_HintFreed(freed_hint);
Dart_NotifyIdle(deadline);
// Idle notifications being in isolate scope are part of the contract.
......
......@@ -329,9 +329,12 @@ class RuntimeController : public PlatformConfigurationClient {
/// system's monotonic time. The clock can be accessed via
/// `Dart_TimelineGetMicros`.
///
/// @param[in] freed_hint A hint of the number of bytes potentially freed
/// since the last call to NotifyIdle if a GC were run.
///
/// @return If the idle notification was forwarded to the running isolate.
///
bool NotifyIdle(int64_t deadline);
bool NotifyIdle(int64_t deadline, size_t freed_hint);
//----------------------------------------------------------------------------
/// @brief Returns if the root isolate is running. The isolate must be
......
......@@ -248,11 +248,16 @@ void Engine::ReportTimings(std::vector<int64_t> timings) {
runtime_controller_->ReportTimings(std::move(timings));
}
void Engine::HintFreed(size_t size) {
hint_freed_bytes_since_last_idle_ += size;
}
void Engine::NotifyIdle(int64_t deadline) {
auto trace_event = std::to_string(deadline - Dart_TimelineGetMicros());
TRACE_EVENT1("flutter", "Engine::NotifyIdle", "deadline_now_delta",
trace_event.c_str());
runtime_controller_->NotifyIdle(deadline);
runtime_controller_->NotifyIdle(deadline, hint_freed_bytes_since_last_idle_);
hint_freed_bytes_since_last_idle_ = 0;
}
std::pair<bool, uint32_t> Engine::GetUIIsolateReturnCode() {
......
......@@ -465,6 +465,14 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
///
void BeginFrame(fml::TimePoint frame_time);
//----------------------------------------------------------------------------
/// @brief Notifies the engine that native bytes might be freed if a
/// garbage collection ran now.
///
/// @param[in] size The number of bytes freed.
///
void HintFreed(size_t size);
//----------------------------------------------------------------------------
/// @brief Notifies the engine that the UI task runner is not expected to
/// undertake a new frame workload till a specified timepoint. The
......@@ -797,6 +805,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate {
FontCollection font_collection_;
ImageDecoder image_decoder_;
TaskRunners task_runners_;
size_t hint_freed_bytes_since_last_idle_ = 0;
fml::WeakPtrFactory<Engine> weak_factory_;
// |RuntimeDelegate|
......
......@@ -27,8 +27,7 @@ static constexpr std::chrono::milliseconds kSkiaCleanupExpiration(15000);
Rasterizer::Rasterizer(Delegate& delegate)
: Rasterizer(delegate,
std::make_unique<flutter::CompositorContext>(
delegate.GetFrameBudget())) {}
std::make_unique<flutter::CompositorContext>(delegate)) {}
Rasterizer::Rasterizer(
Delegate& delegate,
......
......@@ -50,7 +50,7 @@ class Rasterizer final : public SnapshotDelegate {
/// are made on the GPU task runner. Any delegate must ensure that
/// they can handle the threading implications.
///
class Delegate {
class Delegate : public CompositorContext::Delegate {
public:
//--------------------------------------------------------------------------
/// @brief Notifies the delegate that a frame has been rendered. The
......
......@@ -1179,6 +1179,16 @@ void Shell::OnFrameRasterized(const FrameTiming& timing) {
}
}
void Shell::OnCompositorEndFrame(size_t freed_hint) {
FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread());
task_runners_.GetUITaskRunner()->PostTask(
[engine = weak_engine_, freed_hint = freed_hint]() {
if (engine) {
engine->HintFreed(freed_hint);
}
});
}
fml::Milliseconds Shell::GetFrameBudget() {
if (display_refresh_rate_ > 0) {
return fml::RefreshRateToFrameBudget(display_refresh_rate_.load());
......
......@@ -12,6 +12,7 @@
#include "flutter/common/settings.h"
#include "flutter/common/task_runners.h"
#include "flutter/flow/compositor_context.h"
#include "flutter/flow/surface.h"
#include "flutter/flow/texture.h"
#include "flutter/fml/closure.h"
......@@ -528,10 +529,14 @@ class Shell final : public PlatformView::Delegate,
void OnFrameRasterized(const FrameTiming&) override;
// |Rasterizer::Delegate|
fml::Milliseconds GetFrameBudget() override;
fml::TimePoint GetLatestFrameTargetTime() const override;
// |Rasterizer::Delegate|
fml::TimePoint GetLatestFrameTargetTime() const override;
// |CompositorContext::Delegate|
fml::Milliseconds GetFrameBudget() override;
// |CompositorContext::Delegate|
void OnCompositorEndFrame(size_t freed_hint) override;
// |ServiceProtocol::Handler|
fml::RefPtr<fml::TaskRunner> GetServiceProtocolHandlerTaskRunner(
......
......@@ -106,6 +106,40 @@ void ShellTest::VSyncFlush(Shell* shell, bool& will_draw_new_frame) {
latch.Wait();
}
void ShellTest::SetViewportMetrics(Shell* shell, double width, double height) {
flutter::ViewportMetrics viewport_metrics = {
1, // device pixel ratio
width, // physical width
height, // physical height
0, // padding top
0, // padding right
0, // padding bottom
0, // padding left
0, // view inset top
0, // view inset right
0, // view inset bottom
0, // view inset left
0, // gesture inset top
0, // gesture inset right
0, // gesture inset bottom
0 // gesture inset left
};
// Set viewport to nonempty, and call Animator::BeginFrame to make the layer
// tree pipeline nonempty. Without either of this, the layer tree below
// won't be rasterized.
fml::AutoResetWaitableEvent latch;
shell->GetTaskRunners().GetUITaskRunner()->PostTask(
[&latch, engine = shell->weak_engine_, viewport_metrics]() {
engine->SetViewportMetrics(std::move(viewport_metrics));
const auto frame_begin_time = fml::TimePoint::Now();
const auto frame_end_time =
frame_begin_time + fml::TimeDelta::FromSecondsF(1.0 / 60.0);
engine->animator_->BeginFrame(frame_begin_time, frame_end_time);
latch.Signal();
});
latch.Wait();
}
void ShellTest::PumpOneFrame(Shell* shell,
double width,
double height,
......
......@@ -59,6 +59,7 @@ class ShellTest : public FixtureTest {
/// the `will_draw_new_frame` to true.
static void VSyncFlush(Shell* shell, bool& will_draw_new_frame);
static void SetViewportMetrics(Shell* shell, double width, double height);
/// Given the root layer, this callback builds the layer tree to be rasterized
/// in PumpOneFrame.
using LayerTreeBuilder =
......
......@@ -536,7 +536,8 @@ TEST_F(ShellTest, ExternalEmbedderNoThreadMerger) {
this->GetCurrentTaskRunner(), fml::TimeDelta::FromSeconds(0));
auto picture_layer = std::make_shared<PictureLayer>(
SkPoint::Make(10, 10),
flutter::SkiaGPUObject<SkPicture>({sk_picture, queue}), false, false);
flutter::SkiaGPUObject<SkPicture>({sk_picture, queue}), false, false,
0);
root->Add(picture_layer);
};
......@@ -585,7 +586,8 @@ TEST_F(ShellTest,
this->GetCurrentTaskRunner(), fml::TimeDelta::FromSeconds(0));
auto picture_layer = std::make_shared<PictureLayer>(
SkPoint::Make(10, 10),
flutter::SkiaGPUObject<SkPicture>({sk_picture, queue}), false, false);
flutter::SkiaGPUObject<SkPicture>({sk_picture, queue}), false, false,
0);
root->Add(picture_layer);
};
......@@ -1460,7 +1462,8 @@ TEST_F(ShellTest, Screenshot) {
this->GetCurrentTaskRunner(), fml::TimeDelta::FromSeconds(0));
auto picture_layer = std::make_shared<PictureLayer>(
SkPoint::Make(10, 10),
flutter::SkiaGPUObject<SkPicture>({sk_picture, queue}), false, false);
flutter::SkiaGPUObject<SkPicture>({sk_picture, queue}), false, false,
0);
root->Add(picture_layer);
};
......@@ -1746,7 +1749,7 @@ TEST_F(ShellTest, OnServiceProtocolEstimateRasterCacheMemoryWorks) {
auto picture_layer = std::make_shared<PictureLayer>(
SkPoint::Make(0, 0),
flutter::SkiaGPUObject<SkPicture>({MakeSizedPicture(100, 100), queue}),
false, false);
false, false, 0);
picture_layer->set_paint_bounds(SkRect::MakeWH(100, 100));
// 2. Rasterize the picture and the picture layer in the raster cache.
......
......@@ -153,7 +153,8 @@ class SkpWarmupTest : public ShellTest {
auto picture_layer = std::make_shared<PictureLayer>(
SkPoint::Make(0, 0), SkiaGPUObject<SkPicture>(picture, queue),
/* is_complex */ false,
/* will_change */ false);
/* will_change */ false,
/* external_size */ 0);
root->Add(picture_layer);
};
PumpOneFrame(shell.get(), picture->cullRect().width(),
......@@ -235,7 +236,8 @@ TEST_F(SkpWarmupTest, Image) {
auto picture_layer = std::make_shared<PictureLayer>(
SkPoint::Make(0, 0), SkiaGPUObject<SkPicture>(picture, queue),
/* is_complex */ false,
/* will_change */ false);
/* will_change */ false,
/* external_size */ 0);
root->Add(picture_layer);
};
......
......@@ -140,10 +140,12 @@ class ScopedFrame final : public flutter::CompositorContext::ScopedFrame {
};
CompositorContext::CompositorContext(
flutter::CompositorContext::Delegate& delegate,
SessionConnection& session_connection,
VulkanSurfaceProducer& surface_producer,
flutter::SceneUpdateContext& scene_update_context)
: session_connection_(session_connection),
: flutter::CompositorContext(delegate),
session_connection_(session_connection),
surface_producer_(surface_producer),
scene_update_context_(scene_update_context) {}
......
......@@ -21,7 +21,8 @@ namespace flutter_runner {
// Fuchsia.
class CompositorContext final : public flutter::CompositorContext {
public:
CompositorContext(SessionConnection& session_connection,
CompositorContext(CompositorContext::Delegate& delegate,
SessionConnection& session_connection,
VulkanSurfaceProducer& surface_producer,
flutter::SceneUpdateContext& scene_update_context);
......
......@@ -216,7 +216,7 @@ Engine::Engine(Delegate& delegate,
std::unique_ptr<flutter_runner::CompositorContext> compositor_context =
std::make_unique<flutter_runner::CompositorContext>(
session_connection_.value(), surface_producer_.value(),
shell, session_connection_.value(), surface_producer_.value(),
scene_update_context_.value());
return std::make_unique<flutter::Rasterizer>(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册