未验证 提交 13d8565c 编写于 作者: D Dan Field 提交者: GitHub

Support SKP captures in flutter_tester (#25566)

上级 971a851f
......@@ -454,7 +454,6 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) {
// Deleting a surface also clears the GL context. Therefore, acquire the
// frame after calling `BeginFrame` as this operation resets the GL context.
auto frame = surface_->AcquireFrame(layer_tree.frame_size());
if (frame == nullptr) {
return RasterStatus::kFailed;
}
......
......@@ -21,7 +21,7 @@ namespace flutter {
/// rasterizer needs to allocate and present the software backing
/// store.
///
/// @see |IOSurfaceSoftware|, |AndroidSurfaceSoftware|,
/// @see |IOSSurfaceSoftware|, |AndroidSurfaceSoftware|,
/// |EmbedderSurfaceSoftware|.
///
class GPUSurfaceSoftwareDelegate {
......
......@@ -28,6 +28,7 @@ executable("testing") {
"//flutter/fml",
"//flutter/lib/snapshot",
"//flutter/shell/common",
"//flutter/shell/gpu:gpu_surface_software",
"//flutter/third_party/tonic",
"//third_party/dart/runtime:libdart_jit",
"//third_party/dart/runtime/bin:dart_io_api",
......
......@@ -22,6 +22,7 @@
#include "flutter/shell/common/shell.h"
#include "flutter/shell/common/switches.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/shell/gpu/gpu_surface_software.h"
#include "third_party/dart/runtime/include/bin/dart_io_api.h"
#include "third_party/dart/runtime/include/dart_api.h"
......@@ -31,6 +32,51 @@
namespace flutter {
class TesterPlatformView : public PlatformView,
public GPUSurfaceSoftwareDelegate {
public:
TesterPlatformView(Delegate& delegate, TaskRunners task_runners)
: PlatformView(delegate, std::move(task_runners)) {}
// |PlatformView|
std::unique_ptr<Surface> CreateRenderingSurface() override {
auto surface = std::make_unique<GPUSurfaceSoftware>(
this, true /* render to surface */);
FML_DCHECK(surface->IsValid());
return surface;
}
// |GPUSurfaceSoftwareDelegate|
sk_sp<SkSurface> AcquireBackingStore(const SkISize& size) override {
if (sk_surface_ != nullptr &&
SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
// The old and new surface sizes are the same. Nothing to do here.
return sk_surface_;
}
SkImageInfo info =
SkImageInfo::MakeN32(size.fWidth, size.fHeight, kPremul_SkAlphaType,
SkColorSpace::MakeSRGB());
sk_surface_ = SkSurface::MakeRaster(info, nullptr);
if (sk_surface_ == nullptr) {
FML_LOG(ERROR)
<< "Could not create backing store for software rendering.";
return nullptr;
}
return sk_surface_;
}
// |GPUSurfaceSoftwareDelegate|
bool PresentBackingStore(sk_sp<SkSurface> backing_store) override {
return true;
}
private:
sk_sp<SkSurface> sk_surface_ = nullptr;
};
// Checks whether the engine's main Dart isolate has no pending work. If so,
// then exit the given message loop.
class ScriptCompletionTaskObserver {
......@@ -138,7 +184,8 @@ int RunTester(const flutter::Settings& settings,
Shell::CreateCallback<PlatformView> on_create_platform_view =
[](Shell& shell) {
return std::make_unique<PlatformView>(shell, shell.GetTaskRunners());
return std::make_unique<TesterPlatformView>(shell,
shell.GetTaskRunners());
};
Shell::CreateCallback<Rasterizer> on_create_rasterizer = [](Shell& shell) {
......@@ -162,6 +209,8 @@ int RunTester(const flutter::Settings& settings,
return EXIT_FAILURE;
}
shell->GetPlatformView()->NotifyCreated();
// Initialize default testing locales. There is no platform to
// pass locales on the tester, so to retain expected locale behavior,
// we emulate it in here by passing in 'en_US' and 'zh_CN' as test locales.
......
Tests in this folder need to be run with the observatory enabled, e.g. to make
VM service method calls.
The `run_tests.py` script disables the observatory for other tests in the
parent directory.
\ No newline at end of file
// 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.
// @dart=2.12
import 'dart:async';
import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:typed_data';
import 'dart:ui';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart' as vms;
import 'package:vm_service/vm_service_io.dart';
void main() {
late vms.VmService vmService;
setUpAll(() async {
final developer.ServiceProtocolInfo info =
await developer.Service.getInfo();
if (info.serverUri == null) {
fail('This test must not be run with --disable-observatory.');
}
vmService = await vmServiceConnectUri(
'ws://localhost:${info.serverUri!.port}${info.serverUri!.path}ws',
);
});
tearDownAll(() async {
await vmService.dispose();
});
test('Capture an SKP ', () async {
final Completer<void> completer = Completer<void>();
window.onBeginFrame = (Duration timeStamp) {
final PictureRecorder recorder = PictureRecorder();
final Canvas canvas = Canvas(recorder);
canvas.drawRect(const Rect.fromLTRB(10, 10, 20, 20), Paint());
final Picture picture = recorder.endRecording();
final SceneBuilder builder = SceneBuilder();
builder.addPicture(Offset.zero, picture);
final Scene scene = builder.build();
window.render(scene);
scene.dispose();
// window.onBeginFrame = (Duration timeStamp) {
completer.complete();
// };
// window.scheduleFrame();
};
window.scheduleFrame();
await completer.future;
final vms.Response response = await vmService.callServiceExtension('_flutter.screenshotSkp');
final String base64data = response.json!['skp'] as String;
expect(base64data, isNotNull);
expect(base64data, isNotEmpty);
final Uint8List decoded = base64Decode(base64data);
expect(decoded.sublist(0, 8), 'skiapict'.codeUnits);
});
}
......@@ -4,9 +4,10 @@ environment:
sdk: '>=2.8.0 <3.0.0'
dependencies:
test: 1.3.0
path: 1.6.2
image: ^2.1.4
test: 1.16.8
path: 1.8.0
image: 3.0.2
vm_service: 6.2.0
dependency_overrides:
sky_engine:
......
......@@ -225,14 +225,17 @@ def SnapshotTest(build_dir, dart_file, kernel_file_output, verbose_dart_snapshot
assert os.path.exists(kernel_file_output)
def RunDartTest(build_dir, dart_file, verbose_dart_snapshot, multithreaded):
def RunDartTest(build_dir, dart_file, verbose_dart_snapshot, multithreaded, enable_observatory=False):
kernel_file_name = os.path.basename(dart_file) + '.kernel.dill'
kernel_file_output = os.path.join(out_dir, kernel_file_name)
SnapshotTest(build_dir, dart_file, kernel_file_output, verbose_dart_snapshot)
command_args = [
'--disable-observatory',
command_args = []
if not enable_observatory:
command_args.append('--disable-observatory')
command_args += [
'--use-test-fonts',
kernel_file_output
]
......@@ -415,8 +418,18 @@ def RunDartTests(build_dir, filter, verbose_dart_snapshot):
# Now that we have the Sky packages at the hardcoded location, run `pub get`.
RunEngineExecutable(build_dir, os.path.join('dart-sdk', 'bin', 'pub'), None, flags=['get'], cwd=dart_tests_dir)
dart_observatory_tests = glob.glob('%s/observatory/*_test.dart' % dart_tests_dir)
dart_tests = glob.glob('%s/*_test.dart' % dart_tests_dir)
if 'release' not in build_dir:
for dart_test_file in dart_observatory_tests:
if filter is not None and os.path.basename(dart_test_file) not in filter:
print("Skipping %s due to filter." % dart_test_file)
else:
print("Testing dart file %s with observatory enabled" % dart_test_file)
RunDartTest(build_dir, dart_test_file, verbose_dart_snapshot, True, True)
RunDartTest(build_dir, dart_test_file, verbose_dart_snapshot, False, True)
for dart_test_file in dart_tests:
if filter is not None and os.path.basename(dart_test_file) not in filter:
print("Skipping %s due to filter." % dart_test_file)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册