Record layer tree to an SkPicture before rasterization (flutter/engine#2628)
This lets Skia run an optimization pass over the SkPicture before actually issuing GL commands.
This commit is contained in:
@@ -5,7 +5,10 @@
|
||||
#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 {
|
||||
|
||||
@@ -15,40 +18,39 @@ CompositorContext::CompositorContext() {
|
||||
CompositorContext::~CompositorContext() {
|
||||
}
|
||||
|
||||
void CompositorContext::BeginFrame(ScopedFrame& frame,
|
||||
bool enable_instrumentation) {
|
||||
if (enable_instrumentation) {
|
||||
frame_count_.Increment();
|
||||
frame_time_.Start();
|
||||
}
|
||||
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::EndFrame(ScopedFrame& frame,
|
||||
bool enable_instrumentation) {
|
||||
raster_cache_.SweepAfterFrame();
|
||||
if (enable_instrumentation) {
|
||||
frame_time_.Stop();
|
||||
}
|
||||
sk_sp<SkPicture> 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();
|
||||
}
|
||||
|
||||
CompositorContext::ScopedFrame CompositorContext::AcquireFrame(
|
||||
GrContext* gr_context, SkCanvas& canvas, bool instrumentation_enabled) {
|
||||
return ScopedFrame(*this, gr_context, canvas, instrumentation_enabled);
|
||||
CompositorContext::Scope::Scope(CompositorContext& context)
|
||||
: context_(context) {
|
||||
context_.frame_time_.Start();
|
||||
}
|
||||
|
||||
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_);
|
||||
CompositorContext::Scope::~Scope() {
|
||||
context_.raster_cache_.SweepAfterFrame();
|
||||
context_.frame_time_.Stop();
|
||||
}
|
||||
|
||||
void CompositorContext::OnGrContextDestroyed() {
|
||||
|
||||
@@ -8,66 +8,46 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/macros.h"
|
||||
#include "flow/instrumentation.h"
|
||||
#include "flow/raster_cache.h"
|
||||
#include "third_party/skia/include/core/SkCanvas.h"
|
||||
#include "third_party/skia/include/core/SkPictureRecorder.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"
|
||||
|
||||
namespace flow {
|
||||
class Layer;
|
||||
class LayerTree;
|
||||
|
||||
class CompositorContext {
|
||||
public:
|
||||
class ScopedFrame {
|
||||
class Scope {
|
||||
public:
|
||||
SkCanvas& canvas() { return *canvas_; }
|
||||
CompositorContext& context() const { return context_; }
|
||||
GrContext* gr_context() const { return gr_context_; }
|
||||
|
||||
ScopedFrame(ScopedFrame&& frame);
|
||||
~ScopedFrame();
|
||||
explicit Scope(CompositorContext& context);
|
||||
~Scope();
|
||||
|
||||
private:
|
||||
CompositorContext& context_;
|
||||
GrContext* gr_context_;
|
||||
SkCanvas* canvas_;
|
||||
const bool instrumentation_enabled_;
|
||||
|
||||
ScopedFrame(CompositorContext& context,
|
||||
GrContext* gr_context,
|
||||
SkCanvas& canvas,
|
||||
bool instrumentation_enabled);
|
||||
|
||||
friend class CompositorContext;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ScopedFrame);
|
||||
DISALLOW_COPY_AND_ASSIGN(Scope);
|
||||
};
|
||||
|
||||
CompositorContext();
|
||||
~CompositorContext();
|
||||
|
||||
ScopedFrame AcquireFrame(GrContext* gr_context,
|
||||
SkCanvas& canvas,
|
||||
bool instrumentation_enabled = true);
|
||||
void Preroll(GrContext* gr_context, LayerTree* layer_tree);
|
||||
sk_sp<SkPicture> Record(const SkRect& bounds, Layer* layer);
|
||||
|
||||
void OnGrContextDestroyed();
|
||||
|
||||
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_; };
|
||||
const Stopwatch& frame_time() { return frame_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);
|
||||
};
|
||||
|
||||
|
||||
@@ -15,26 +15,8 @@ LayerTree::LayerTree() : scene_version_(0), rasterizer_tracing_threshold_(0) {
|
||||
LayerTree::~LayerTree() {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
SkRect LayerTree::GetBounds() const {
|
||||
return SkRect::MakeWH(frame_size_.width(), frame_size_.height());
|
||||
}
|
||||
|
||||
void LayerTree::UpdateScene(mojo::gfx::composition::SceneUpdate* update,
|
||||
|
||||
@@ -21,8 +21,6 @@ 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).
|
||||
@@ -35,6 +33,7 @@ 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; }
|
||||
|
||||
Reference in New Issue
Block a user