Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ task:
mv $CIRRUS_WORKING_DIR flutter
gclient sync
matrix:
# The following test depends on Flutter framework repo. It may fail if the
# The following test depends on Flutter framework repo. It will fail if the
# framework repo is currently broken.
- name: build_and_test_linux_unopt_debug
compile_host_script: |
Expand Down
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ vars = {
# Dart is: https://github.com/dart-lang/sdk/blob/master/DEPS.
# You can use //tools/dart/create_updated_flutter_deps.py to produce
# updated revision list of existing dependencies.
'dart_revision': '2607b01bec99f324e45b00fde76591f244f65a4e',
'dart_revision': '7c8c6b3053d0ba91fcf15f81c45650184dc27e88',

# WARNING: DO NOT EDIT MANUALLY
# The lines between blank lines above and below are generated by a script. See create_updated_flutter_deps.py
Expand Down
4 changes: 3 additions & 1 deletion ci/licenses_golden/licenses_third_party
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Signature: 8d4521c3fe82b7be926a7af5f8b15557
Signature: 5c79cd2b2923476fb5c2db8b6fa7b779

UNUSED LICENSES:

Expand Down Expand Up @@ -9750,9 +9750,11 @@ FILE: ../../../third_party/dart/samples_2/ffi/sqlite/lib/src/ffi/arena.dart
FILE: ../../../third_party/dart/samples_2/ffi/sqlite/lib/src/ffi/dylib_utils.dart
FILE: ../../../third_party/dart/sdk/lib/_internal/js_runtime/lib/rti.dart
FILE: ../../../third_party/dart/sdk/lib/_internal/js_runtime/lib/shared/recipe_syntax.dart
FILE: ../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart
FILE: ../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart
FILE: ../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
FILE: ../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart
FILE: ../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart
FILE: ../../../third_party/dart/sdk/lib/ffi/annotations.dart
FILE: ../../../third_party/dart/sdk/lib/ffi/dynamic_library.dart
FILE: ../../../third_party/dart/sdk/lib/ffi/ffi.dart
Expand Down
8 changes: 6 additions & 2 deletions flow/compositor_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ enum class RasterStatus {
kEnqueuePipeline,
// Failed to rasterize the frame.
kFailed,
// Layer tree was discarded due to LayerTreeDiscardCallback
kDiscarded
// Layer tree was discarded due to LayerTreeDiscardCallback or inability to
// access the GPU.
kDiscarded,
// Drawing was yielded to allow the correct thread to draw as a result of the
// RasterThreadMerger.
kYielded,
};

class CompositorContext {
Expand Down
6 changes: 2 additions & 4 deletions flow/embedded_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@

namespace flutter {

void ExternalViewEmbedder::SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch) {
void ExternalViewEmbedder::SubmitFrame(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame) {
frame->Submit();
};

Expand Down
7 changes: 2 additions & 5 deletions flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "flutter/flow/surface_frame.h"
#include "flutter/fml/memory/ref_counted.h"
#include "flutter/fml/raster_thread_merger.h"
#include "flutter/fml/synchronization/sync_switch.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPoint.h"
Expand Down Expand Up @@ -310,10 +309,8 @@ class ExternalViewEmbedder {
// This method can mutate the root Skia canvas before submitting the frame.
//
// It can also allocate frames for overlay surfaces to compose hybrid views.
virtual void SubmitFrame(
GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame,
const std::shared_ptr<fml::SyncSwitch>& gpu_disable_sync_switch);
virtual void SubmitFrame(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame);

// This method provides the embedder a way to do additional tasks after
// |SubmitFrame|. For example, merge task runners if `should_resubmit_frame`
Expand Down
4 changes: 4 additions & 0 deletions flow/surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ bool Surface::ClearRenderContext() {
return false;
}

bool Surface::AllowsDrawingWhenGpuDisabled() const {
return true;
}

} // namespace flutter
2 changes: 2 additions & 0 deletions flow/surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class Surface {

virtual bool ClearRenderContext();

virtual bool AllowsDrawingWhenGpuDisabled() const;

private:
FML_DISALLOW_COPY_AND_ASSIGN(Surface);
};
Expand Down
4 changes: 3 additions & 1 deletion lib/snapshot/libraries.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@
"ffi": {
"uri": "../../../third_party/dart/sdk/lib/ffi/ffi.dart",
"patches": [
"../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart",
"../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart",
"../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart",
"../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart",
"../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
"../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart"
]
},
"wasm": {
Expand Down
4 changes: 3 additions & 1 deletion lib/snapshot/libraries.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ flutter:
ffi:
uri: "../../../third_party/dart/sdk/lib/ffi/ffi.dart"
patches:
- "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
- "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_allocation_patch.dart"
- "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_dynamic_library_patch.dart"
- "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart"
- "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_patch.dart"
- "../../../third_party/dart/sdk/lib/_internal/vm/lib/ffi_struct_patch.dart"

wasm:
uri: "../../../third_party/dart/sdk/lib/wasm/wasm.dart"
Expand Down
11 changes: 6 additions & 5 deletions lib/ui/painting.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1939,12 +1939,13 @@ class Codec extends NativeFieldWrapperClass2 {
final Completer<FrameInfo> completer = Completer<FrameInfo>.sync();
final String? error = _getNextFrame((_Image? image, int durationMilliseconds) {
if (image == null) {
throw Exception('Codec failed to produce an image, possibly due to invalid image data.');
completer.completeError(Exception('Codec failed to produce an image, possibly due to invalid image data.'));
} else {
completer.complete(FrameInfo._(
image: Image._(image),
duration: Duration(milliseconds: durationMilliseconds),
));
}
completer.complete(FrameInfo._(
image: Image._(image),
duration: Duration(milliseconds: durationMilliseconds),
));
});
if (error != null) {
throw Exception(error);
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/dev/goldens_lock.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
repository: https://github.com/flutter/goldens.git
revision: b85f9093e6bc6d4e7cbb7f97491667c143c4a360
revision: 4b4c256d6124a135b70c1a9a7ff10cf2827df31c
81 changes: 49 additions & 32 deletions lib/web_ui/dev/test_runner.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ class TestCommand extends Command<bool> with ArgUtils {
'.dart_tool/goldens. Use this option to bulk-update all screenshots, '
'for example, when a new browser version affects pixels.',
)
..addFlag(
'fetch-goldens-repo',
defaultsTo: true,
negatable: true,
help:
'Whether to fetch the goldens repo. Set this to false to iterate '
'on golden tests without fearing that the fetcher will overwrite '
'your local changes.',
)
..addOption(
'browser',
defaultsTo: 'chrome',
Expand Down Expand Up @@ -165,39 +174,41 @@ class TestCommand extends Command<bool> with ArgUtils {
final FilePath dir = FilePath.fromWebUi('');
print('');
print('Initial test run is done!');
print('Watching ${dir.relativeToCwd}/lib and ${dir.relativeToCwd}/test to re-run tests');
print(
'Watching ${dir.relativeToCwd}/lib and ${dir.relativeToCwd}/test to re-run tests');
print('');
PipelineWatcher(
dir: dir.absolute,
pipeline: testPipeline,
ignore: (event) {
// Ignore font files that are copied whenever tests run.
if (event.path.endsWith('.ttf')) {
return true;
}
dir: dir.absolute,
pipeline: testPipeline,
ignore: (event) {
// Ignore font files that are copied whenever tests run.
if (event.path.endsWith('.ttf')) {
return true;
}

// Ignore auto-generated JS files.
// The reason we are using `.contains()` instead of `.endsWith()` is
// because the auto-generated files could end with any of the
// following:
//
// - browser_test.dart.js
// - browser_test.dart.js.map
// - browser_test.dart.js.deps
if (event.path.contains('browser_test.dart.js')) {
return true;
}
// Ignore auto-generated JS files.
// The reason we are using `.contains()` instead of `.endsWith()` is
// because the auto-generated files could end with any of the
// following:
//
// - browser_test.dart.js
// - browser_test.dart.js.map
// - browser_test.dart.js.deps
if (event.path.contains('browser_test.dart.js')) {
return true;
}

// React to changes in lib/ and test/ folders.
final String relativePath = path.relative(event.path, from: dir.absolute);
if (relativePath.startsWith('lib/') || relativePath.startsWith('test/')) {
return false;
}
// React to changes in lib/ and test/ folders.
final String relativePath =
path.relative(event.path, from: dir.absolute);
if (relativePath.startsWith('lib/') ||
relativePath.startsWith('test/')) {
return false;
}

// Ignore anything else.
return true;
}
).start();
// Ignore anything else.
return true;
}).start();
// Return a never-ending future.
return Completer<bool>().future;
} else {
Expand All @@ -217,15 +228,17 @@ class TestCommand extends Command<bool> with ArgUtils {
bool unitTestResult = await runUnitTests();
bool integrationTestResult = await runIntegrationTests();
if (integrationTestResult != unitTestResult) {
print('Tests run. Integration tests passed: $integrationTestResult '
print(
'Tests run. Integration tests passed: $integrationTestResult '
'unit tests passed: $unitTestResult');
}
return integrationTestResult && unitTestResult;
} else {
return await runUnitTests();
}
}
throw UnimplementedError('Unknown test type requested: $testTypesRequested');
throw UnimplementedError(
'Unknown test type requested: $testTypesRequested');
} on TestFailureException {
return true;
}
Expand Down Expand Up @@ -272,9 +285,9 @@ class TestCommand extends Command<bool> with ArgUtils {
environment.webUiTestResultsDirectory.createSync(recursive: true);

// If screenshot tests are available, fetch the screenshot goldens.
if (isScreenshotTestsAvailable) {
if (isScreenshotTestsAvailable && doFetchGoldensRepo) {
if (isVerboseLoggingEnabled) {
print('INFO: Screenshot tests available');
print('INFO: Fetching goldens repo');
}
final GoldensRepoFetcher goldensRepoFetcher = GoldensRepoFetcher(
environment.webUiGoldensRepositoryDirectory,
Expand Down Expand Up @@ -483,6 +496,9 @@ class TestCommand extends Command<bool> with ArgUtils {
/// ".dart_tool/goldens".
bool get doUpdateScreenshotGoldens => boolArg('update-screenshot-goldens');

/// Whether to fetch the goldens repo prior to running tests.
bool get doFetchGoldensRepo => boolArg('fetch-goldens-repo');

/// Runs all tests specified in [targets].
///
/// Unlike [_runAllTestsForCurrentPlatform], this does not filter targets
Expand Down Expand Up @@ -774,6 +790,7 @@ const List<String> _kTestFonts = <String>[
'ahem.ttf',
'Roboto-Regular.ttf',
'NotoNaskhArabic-Regular.ttf',
'NotoColorEmoji.ttf',
];

void _copyTestFontsIntoWebUi() {
Expand Down
11 changes: 10 additions & 1 deletion lib/web_ui/lib/src/engine/assets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,16 @@ class AssetManagerException implements Exception {
class WebOnlyMockAssetManager implements AssetManager {
String defaultAssetsDir = '';
String defaultAssetManifest = '{}';
String defaultFontManifest = '[]';
String defaultFontManifest = '''[
{
"family":"$_robotoFontFamily",
"fonts":[{"asset":"$_robotoTestFontUrl"}]
},
{
"family":"$_ahemFontFamily",
"fonts":[{"asset":"$_ahemFontUrl"}]
}
]''';

@override
String get assetsDir => defaultAssetsDir;
Expand Down
4 changes: 3 additions & 1 deletion lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ class SkImage {
Float32List? matrix, // 3x3 matrix
);
external Uint8List readPixels(int srcX, int srcY, SkImageInfo imageInfo);
external SkData encodeToData();
external Uint8List? encodeToBytes();
external bool isAliasOf(SkImage other);
external bool isDeleted();
}
Expand Down Expand Up @@ -1643,6 +1643,8 @@ class SkTypeface {}
class SkFont {
external SkFont(SkTypeface typeface);
external Uint8List getGlyphIDs(String text);
external void getGlyphBounds(
List<int> glyphs, SkPaint? paint, Uint8List? output);
}

@JS()
Expand Down
24 changes: 19 additions & 5 deletions lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart
Original file line number Diff line number Diff line change
Expand Up @@ -359,14 +359,17 @@ class HtmlViewEmbedder {
final Set<int> unusedViews = Set<int>.from(_activeCompositionOrder);
_activeCompositionOrder.clear();

List<int>? debugInvalidViewIds;
for (int i = 0; i < _compositionOrder.length; i++) {
int viewId = _compositionOrder[i];

assert(
_views.containsKey(viewId),
'Cannot render platform view $viewId. '
'It has not been created, or it has been deleted.',
);
if (assertionsEnabled) {
if (!_views.containsKey(viewId)) {
debugInvalidViewIds ??= <int>[];
debugInvalidViewIds.add(viewId);
continue;
}
}

unusedViews.remove(viewId);
html.Element platformViewRoot = _rootViews[viewId]!;
Expand All @@ -381,6 +384,16 @@ class HtmlViewEmbedder {

for (final int unusedViewId in unusedViews) {
_releaseOverlay(unusedViewId);
_rootViews[unusedViewId]?.remove();
}

if (assertionsEnabled) {
if (debugInvalidViewIds != null && debugInvalidViewIds.isNotEmpty) {
throw AssertionError(
'Cannot render platform views: ${debugInvalidViewIds.join(', ')}. '
'These views have not been created, or they have been deleted.',
);
}
}
}

Expand Down Expand Up @@ -476,6 +489,7 @@ class OverlayCache {
for (final Surface overlay in _cache) {
overlay.dispose();
}
_cache.clear();
}
}

Expand Down
Loading