From 49760a8b0b5cef31b9f05eb8d20c4116386eb7d9 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 1 Nov 2021 10:03:28 -0700 Subject: [PATCH] Trace calls to Canvas::saveLayer --- flow/compositor_context.cc | 2 +- flow/layers/clip_path_layer.cc | 1 + flow/layers/clip_rect_layer.cc | 1 + flow/layers/clip_rrect_layer.cc | 1 + flow/layers/physical_shape_layer.cc | 5 +- lib/ui/painting/canvas.cc | 2 + testing/dart/observatory/BUILD.gn | 5 +- testing/dart/observatory/tracing_test.dart | 59 ++++++++++++++++++++++ 8 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 testing/dart/observatory/tracing_test.dart diff --git a/flow/compositor_context.cc b/flow/compositor_context.cc index 4cb523a5958da..2557512650a46 100644 --- a/flow/compositor_context.cc +++ b/flow/compositor_context.cc @@ -88,7 +88,7 @@ RasterStatus CompositorContext::ScopedFrame::Raster( // paints some raster cache. if (canvas()) { if (needs_save_layer) { - FML_LOG(INFO) << "Using SaveLayer to protect non-readback surface"; + TRACE_EVENT0("flutter", "Canvas::saveLayer"); SkRect bounds = SkRect::Make(layer_tree.frame_size()); SkPaint paint; paint.setBlendMode(SkBlendMode::kSrc); diff --git a/flow/layers/clip_path_layer.cc b/flow/layers/clip_path_layer.cc index c895f6611be1e..fc90c3b422a26 100644 --- a/flow/layers/clip_path_layer.cc +++ b/flow/layers/clip_path_layer.cc @@ -63,6 +63,7 @@ void ClipPathLayer::Paint(PaintContext& context) const { clip_behavior_ != Clip::hardEdge); if (UsesSaveLayer()) { + TRACE_EVENT0("flutter", "Canvas::saveLayer"); context.internal_nodes_canvas->saveLayer(paint_bounds(), nullptr); } PaintChildren(context); diff --git a/flow/layers/clip_rect_layer.cc b/flow/layers/clip_rect_layer.cc index 3c885a472ce97..e85b0bf303b57 100644 --- a/flow/layers/clip_rect_layer.cc +++ b/flow/layers/clip_rect_layer.cc @@ -62,6 +62,7 @@ void ClipRectLayer::Paint(PaintContext& context) const { clip_behavior_ != Clip::hardEdge); if (UsesSaveLayer()) { + TRACE_EVENT0("flutter", "Canvas::saveLayer"); context.internal_nodes_canvas->saveLayer(clip_rect_, nullptr); } PaintChildren(context); diff --git a/flow/layers/clip_rrect_layer.cc b/flow/layers/clip_rrect_layer.cc index 225c110abda04..41f2f44302548 100644 --- a/flow/layers/clip_rrect_layer.cc +++ b/flow/layers/clip_rrect_layer.cc @@ -63,6 +63,7 @@ void ClipRRectLayer::Paint(PaintContext& context) const { clip_behavior_ != Clip::hardEdge); if (UsesSaveLayer()) { + TRACE_EVENT0("flutter", "Canvas::saveLayer"); context.internal_nodes_canvas->saveLayer(paint_bounds(), nullptr); } PaintChildren(context); diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc index a9b76e1ea18eb..b7316af72eb48 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_shape_layer.cc @@ -101,10 +101,11 @@ void PhysicalShapeLayer::Paint(PaintContext& context) const { case Clip::antiAlias: context.internal_nodes_canvas->clipPath(path_, true); break; - case Clip::antiAliasWithSaveLayer: + case Clip::antiAliasWithSaveLayer: { + TRACE_EVENT0("flutter", "Canvas::saveLayer"); context.internal_nodes_canvas->clipPath(path_, true); context.internal_nodes_canvas->saveLayer(paint_bounds(), nullptr); - break; + } break; case Clip::none: break; } diff --git a/lib/ui/painting/canvas.cc b/lib/ui/painting/canvas.cc index 66c1bcdd2ba1b..14270e994137f 100644 --- a/lib/ui/painting/canvas.cc +++ b/lib/ui/painting/canvas.cc @@ -105,6 +105,7 @@ void Canvas::saveLayerWithoutBounds(const Paint& paint, if (!canvas_) { return; } + TRACE_EVENT0("flutter", "Canvas::saveLayer"); canvas_->saveLayer(nullptr, paint.paint()); } @@ -117,6 +118,7 @@ void Canvas::saveLayer(double left, if (!canvas_) { return; } + TRACE_EVENT0("flutter", "Canvas::saveLayer"); SkRect bounds = SkRect::MakeLTRB(left, top, right, bottom); canvas_->saveLayer(&bounds, paint.paint()); } diff --git a/testing/dart/observatory/BUILD.gn b/testing/dart/observatory/BUILD.gn index ea5d285e0fd2c..e2acc5af47800 100644 --- a/testing/dart/observatory/BUILD.gn +++ b/testing/dart/observatory/BUILD.gn @@ -4,7 +4,10 @@ import("//flutter/testing/dart/compile_test.gni") -tests = [ "skp_test.dart" ] +tests = [ + "skp_test.dart", + "tracing_test.dart", +] foreach(test, tests) { compile_flutter_dart_test("compile_$test") { diff --git a/testing/dart/observatory/tracing_test.dart b/testing/dart/observatory/tracing_test.dart new file mode 100644 index 0000000000000..50274db5bcfa8 --- /dev/null +++ b/testing/dart/observatory/tracing_test.dart @@ -0,0 +1,59 @@ +// 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. + +import 'dart:async'; +import 'dart:developer' as developer; +import 'dart:ui'; + +import 'package:litetest/litetest.dart'; +import 'package:vm_service/vm_service.dart' as vms; +import 'package:vm_service/vm_service_io.dart'; + +void main() { + test('Canvas.saveLayer emits tracing', () async { + final developer.ServiceProtocolInfo info = await developer.Service.getInfo(); + + if (info.serverUri == null) { + fail('This test must not be run with --disable-observatory.'); + } + + final vms.VmService vmService = await vmServiceConnectUri( + 'ws://localhost:${info.serverUri!.port}${info.serverUri!.path}ws', + ); + + final Completer completer = Completer(); + window.onBeginFrame = (Duration timeStamp) { + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.saveLayer(null, Paint()); + canvas.saveLayer(const Rect.fromLTWH(0, 0, 100, 100), Paint()); + canvas.drawRect(const Rect.fromLTRB(10, 10, 20, 20), Paint()); + canvas.restore(); + canvas.restore(); + final Picture picture = recorder.endRecording(); + + final SceneBuilder builder = SceneBuilder(); + builder.addPicture(Offset.zero, picture); + final Scene scene = builder.build(); + + window.render(scene); + scene.dispose(); + completer.complete(); + }; + window.scheduleFrame(); + await completer.future; + + final vms.Timeline timeline = await vmService.getVMTimeline(); + await vmService.dispose(); + + int saveLayerCount = 0; + for (final vms.TimelineEvent event in timeline.traceEvents!) { + final Map json = event.json!; + if (json['name'] == 'Canvas::saveLayer' && json['ph'] == 'B') { + saveLayerCount += 1; + } + } + expect(saveLayerCount, 2); + }); +}