diff --git a/engine/src/flutter/flow/compositor_context.cc b/engine/src/flutter/flow/compositor_context.cc index b2872b9aaaa..5dbc25f7958 100644 --- a/engine/src/flutter/flow/compositor_context.cc +++ b/engine/src/flutter/flow/compositor_context.cc @@ -5,10 +5,7 @@ #include "flow/compositor_context.h" #include "base/logging.h" -#include "base/trace_event/trace_event.h" -#include "flow/layers/layer_tree.h" #include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkPictureRecorder.h" namespace flow { @@ -18,39 +15,40 @@ CompositorContext::CompositorContext() { CompositorContext::~CompositorContext() { } -void CompositorContext::Preroll(GrContext* gr_context, LayerTree* layer_tree) { - TRACE_EVENT0("flutter", "CompositorContext::Preroll"); - engine_time_.SetLapTime(layer_tree->construction_time()); - Layer::PrerollContext context = { - raster_cache_, - gr_context, - SkRect::MakeEmpty(), - }; - layer_tree->root_layer()->Preroll(&context, SkMatrix()); +void CompositorContext::BeginFrame(ScopedFrame& frame, + bool enable_instrumentation) { + if (enable_instrumentation) { + frame_count_.Increment(); + frame_time_.Start(); + } } -sk_sp CompositorContext::Record(const SkRect& bounds, Layer* layer) { - TRACE_EVENT0("flutter", "CompositorContext::Record"); - SkRTreeFactory rtree_factory; - uint32_t flags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; - SkPictureRecorder recorder; - Layer::PaintContext paint_context{ - *recorder.beginRecording(bounds, &rtree_factory, flags), - frame_time_, - engine_time_, - }; - layer->Paint(paint_context); - return recorder.finishRecordingAsPicture(); +void CompositorContext::EndFrame(ScopedFrame& frame, + bool enable_instrumentation) { + raster_cache_.SweepAfterFrame(); + if (enable_instrumentation) { + frame_time_.Stop(); + } } -CompositorContext::Scope::Scope(CompositorContext& context) - : context_(context) { - context_.frame_time_.Start(); +CompositorContext::ScopedFrame CompositorContext::AcquireFrame( + GrContext* gr_context, SkCanvas& canvas, bool instrumentation_enabled) { + return ScopedFrame(*this, gr_context, canvas, instrumentation_enabled); } -CompositorContext::Scope::~Scope() { - context_.raster_cache_.SweepAfterFrame(); - context_.frame_time_.Stop(); +CompositorContext::ScopedFrame::ScopedFrame(CompositorContext& context, + GrContext* gr_context, + SkCanvas& canvas, + bool instrumentation_enabled) + : context_(context), gr_context_(gr_context), canvas_(&canvas), + instrumentation_enabled_(instrumentation_enabled) { + context_.BeginFrame(*this, instrumentation_enabled_); +} + +CompositorContext::ScopedFrame::ScopedFrame(ScopedFrame&& frame) = default; + +CompositorContext::ScopedFrame::~ScopedFrame() { + context_.EndFrame(*this, instrumentation_enabled_); } void CompositorContext::OnGrContextDestroyed() { diff --git a/engine/src/flutter/flow/compositor_context.h b/engine/src/flutter/flow/compositor_context.h index 3df3617b9aa..4ac7d517455 100644 --- a/engine/src/flutter/flow/compositor_context.h +++ b/engine/src/flutter/flow/compositor_context.h @@ -8,46 +8,66 @@ #include #include -#include "base/logging.h" #include "base/macros.h" +#include "base/logging.h" #include "flow/instrumentation.h" #include "flow/raster_cache.h" -#include "third_party/skia/include/core/SkPicture.h" -#include "third_party/skia/include/core/SkRect.h" -#include "third_party/skia/include/gpu/GrContext.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkPictureRecorder.h" namespace flow { -class Layer; -class LayerTree; class CompositorContext { public: - class Scope { + class ScopedFrame { public: - explicit Scope(CompositorContext& context); - ~Scope(); + SkCanvas& canvas() { return *canvas_; } + CompositorContext& context() const { return context_; } + GrContext* gr_context() const { return gr_context_; } + + ScopedFrame(ScopedFrame&& frame); + ~ScopedFrame(); private: CompositorContext& context_; + GrContext* gr_context_; + SkCanvas* canvas_; + const bool instrumentation_enabled_; - DISALLOW_COPY_AND_ASSIGN(Scope); + ScopedFrame(CompositorContext& context, + GrContext* gr_context, + SkCanvas& canvas, + bool instrumentation_enabled); + + friend class CompositorContext; + + DISALLOW_COPY_AND_ASSIGN(ScopedFrame); }; CompositorContext(); ~CompositorContext(); - void Preroll(GrContext* gr_context, LayerTree* layer_tree); - sk_sp Record(const SkRect& bounds, Layer* layer); + ScopedFrame AcquireFrame(GrContext* gr_context, + SkCanvas& canvas, + bool instrumentation_enabled = true); void OnGrContextDestroyed(); - const Stopwatch& frame_time() { return frame_time_; } + RasterCache& raster_cache() { return raster_cache_; } + const Counter& frame_count() const { return frame_count_; } + const Stopwatch& frame_time() const { return frame_time_; } + Stopwatch& engine_time() { return engine_time_; }; private: RasterCache raster_cache_; + + Counter frame_count_; Stopwatch frame_time_; Stopwatch engine_time_; + void BeginFrame(ScopedFrame& frame, bool enable_instrumentation); + void EndFrame(ScopedFrame& frame, bool enable_instrumentation); + DISALLOW_COPY_AND_ASSIGN(CompositorContext); }; diff --git a/engine/src/flutter/flow/layers/layer_tree.cc b/engine/src/flutter/flow/layers/layer_tree.cc index c3cac5179c5..0d4e58b9710 100644 --- a/engine/src/flutter/flow/layers/layer_tree.cc +++ b/engine/src/flutter/flow/layers/layer_tree.cc @@ -15,8 +15,26 @@ LayerTree::LayerTree() : scene_version_(0), rasterizer_tracing_threshold_(0) { LayerTree::~LayerTree() { } -SkRect LayerTree::GetBounds() const { - return SkRect::MakeWH(frame_size_.width(), frame_size_.height()); +void LayerTree::Raster(CompositorContext::ScopedFrame& frame) { + { + TRACE_EVENT0("flutter", "LayerTree::Preroll"); + Layer::PrerollContext context = { + frame.context().raster_cache(), + frame.gr_context(), + SkRect::MakeEmpty(), + }; + root_layer_->Preroll(&context, SkMatrix()); + } + + { + Layer::PaintContext context = { + frame.canvas(), + frame.context().frame_time(), + frame.context().engine_time(), + }; + TRACE_EVENT0("flutter", "LayerTree::Paint"); + root_layer_->Paint(context); + } } void LayerTree::UpdateScene(mojo::gfx::composition::SceneUpdate* update, diff --git a/engine/src/flutter/flow/layers/layer_tree.h b/engine/src/flutter/flow/layers/layer_tree.h index 349ed5649f3..ef83ce6abb5 100644 --- a/engine/src/flutter/flow/layers/layer_tree.h +++ b/engine/src/flutter/flow/layers/layer_tree.h @@ -21,6 +21,8 @@ class LayerTree { LayerTree(); ~LayerTree(); + void Raster(CompositorContext::ScopedFrame& frame); + // TODO(abarth): Integrate scene updates with the rasterization pass so that // we can draw on top of child scenes (and so that we can apply clips and // blending operations to child scene). @@ -33,7 +35,6 @@ class LayerTree { root_layer_ = std::move(root_layer); } - SkRect GetBounds() const; const SkISize& frame_size() const { return frame_size_; } void set_frame_size(const SkISize& frame_size) { frame_size_ = frame_size; }