flutter_flutter/flow/compositor_context.cc
Adlai Holler c57aff1800
Use the GrDirectContext factories instead of deprecated GrContext ones (#19962)
This is part of a larger effort to expose the difference between GrDirectContext,
which runs on the GPU thread and can directly perform operations like uploading
textures, and GrRecordingContext, which can only queue up work to be delivered
to the GrDirectContext later.
2020-07-28 13:32:09 -07:00

115 lines
3.8 KiB
C++

// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/flow/compositor_context.h"
#include "flutter/flow/layers/layer_tree.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace flutter {
CompositorContext::CompositorContext(fml::Milliseconds frame_budget)
: raster_time_(frame_budget), ui_time_(frame_budget) {}
CompositorContext::~CompositorContext() = default;
void CompositorContext::BeginFrame(ScopedFrame& frame,
bool enable_instrumentation) {
if (enable_instrumentation) {
frame_count_.Increment();
raster_time_.Start();
}
}
void CompositorContext::EndFrame(ScopedFrame& frame,
bool enable_instrumentation) {
raster_cache_.SweepAfterFrame();
if (enable_instrumentation) {
raster_time_.Stop();
}
}
std::unique_ptr<CompositorContext::ScopedFrame> CompositorContext::AcquireFrame(
GrDirectContext* gr_context,
SkCanvas* canvas,
ExternalViewEmbedder* view_embedder,
const SkMatrix& root_surface_transformation,
bool instrumentation_enabled,
bool surface_supports_readback,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
return std::make_unique<ScopedFrame>(
*this, gr_context, canvas, view_embedder, root_surface_transformation,
instrumentation_enabled, surface_supports_readback, raster_thread_merger);
}
CompositorContext::ScopedFrame::ScopedFrame(
CompositorContext& context,
GrDirectContext* gr_context,
SkCanvas* canvas,
ExternalViewEmbedder* view_embedder,
const SkMatrix& root_surface_transformation,
bool instrumentation_enabled,
bool surface_supports_readback,
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger)
: context_(context),
gr_context_(gr_context),
canvas_(canvas),
view_embedder_(view_embedder),
root_surface_transformation_(root_surface_transformation),
instrumentation_enabled_(instrumentation_enabled),
surface_supports_readback_(surface_supports_readback),
raster_thread_merger_(raster_thread_merger) {
context_.BeginFrame(*this, instrumentation_enabled_);
}
CompositorContext::ScopedFrame::~ScopedFrame() {
context_.EndFrame(*this, instrumentation_enabled_);
}
RasterStatus CompositorContext::ScopedFrame::Raster(
flutter::LayerTree& layer_tree,
bool ignore_raster_cache) {
TRACE_EVENT0("flutter", "CompositorContext::ScopedFrame::Raster");
bool root_needs_readback = layer_tree.Preroll(*this, ignore_raster_cache);
bool needs_save_layer = root_needs_readback && !surface_supports_readback();
PostPrerollResult post_preroll_result = PostPrerollResult::kSuccess;
if (view_embedder_ && raster_thread_merger_) {
post_preroll_result =
view_embedder_->PostPrerollAction(raster_thread_merger_);
}
if (post_preroll_result == PostPrerollResult::kResubmitFrame) {
return RasterStatus::kResubmit;
}
// Clearing canvas after preroll reduces one render target switch when preroll
// paints some raster cache.
if (canvas()) {
if (needs_save_layer) {
FML_LOG(INFO) << "Using SaveLayer to protect non-readback surface";
SkRect bounds = SkRect::Make(layer_tree.frame_size());
SkPaint paint;
paint.setBlendMode(SkBlendMode::kSrc);
canvas()->saveLayer(&bounds, &paint);
}
canvas()->clear(SK_ColorTRANSPARENT);
}
layer_tree.Paint(*this, ignore_raster_cache);
if (canvas() && needs_save_layer) {
canvas()->restore();
}
return RasterStatus::kSuccess;
}
void CompositorContext::OnGrContextCreated() {
texture_registry_.OnGrContextCreated();
raster_cache_.Clear();
}
void CompositorContext::OnGrContextDestroyed() {
texture_registry_.OnGrContextDestroyed();
raster_cache_.Clear();
}
} // namespace flutter