mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This moves the Metal `GrContext` creation utilities from `GPUSurfaceMetal` into a separate `IOSContext` object subclass. An analogue of this object was used in the GL regime for the management of onscreen and offscreen contexts that were not tied to the lifecycle of the `GPUSurface`. This pattern has now been generalized for use with all backends that need a resource context (`IOSContextGL` and `IOContextMetal`). The platform views controller management in the `ExternalViewEmbedder` interface implementation was repeated three times for [Metal][metal], [OpenGL](opengl) and [Software](software) rendering. This repetition has been removed and a single implementation present in the base `IOSSurface` and used on all platforms. Addition of new client rendering APIs should not affect how the engine renders into the platform view interleaving levels. All rendering API selection logic has been moved into a single set of utilities in `rendering_api_selection.h`. This enables the removal of a lot of code blocks guarded by `FLUTTER_SHELL_ENABLE_METAL`. The remaining uses of this will be removed when unified builds are enabled. The Metal backend now also adds traces similar to the GL backend. The `IOGLContext` has been renamed to `IOContextGL` to be more in line with the convention used in this library. Fixes https://github.com/flutter/flutter/issues/41827 Adds https://github.com/flutter/flutter/issues/52150 [metal]:1194ba2b21/shell/platform/darwin/ios/ios_surface_metal.mm (L55)[opengl]:1194ba2b21/shell/platform/darwin/ios/ios_surface_gl.mm (L95)[software]:1194ba2b21/shell/platform/darwin/ios/ios_surface_software.mm (L146)
114 lines
3.8 KiB
C++
114 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(
|
|
GrContext* gr_context,
|
|
SkCanvas* canvas,
|
|
ExternalViewEmbedder* view_embedder,
|
|
const SkMatrix& root_surface_transformation,
|
|
bool instrumentation_enabled,
|
|
bool surface_supports_readback,
|
|
fml::RefPtr<fml::GpuThreadMerger> gpu_thread_merger) {
|
|
return std::make_unique<ScopedFrame>(
|
|
*this, gr_context, canvas, view_embedder, root_surface_transformation,
|
|
instrumentation_enabled, surface_supports_readback, gpu_thread_merger);
|
|
}
|
|
|
|
CompositorContext::ScopedFrame::ScopedFrame(
|
|
CompositorContext& context,
|
|
GrContext* gr_context,
|
|
SkCanvas* canvas,
|
|
ExternalViewEmbedder* view_embedder,
|
|
const SkMatrix& root_surface_transformation,
|
|
bool instrumentation_enabled,
|
|
bool surface_supports_readback,
|
|
fml::RefPtr<fml::GpuThreadMerger> gpu_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),
|
|
gpu_thread_merger_(gpu_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_ && gpu_thread_merger_) {
|
|
post_preroll_result = view_embedder_->PostPrerollAction(gpu_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
|