[canvaskit] Disable createImageBitmap support on Chrome 110 or older on Windows. (flutter/engine#48475)
On Chrome 110 or older, there is a bug where an ImageBitmap will be read back upside down if it is stored upside down on the GPU. This only happens on Windows. So if we are on Windows and running on Chrome 110 or older, then fall back to `drawImage` based rendering. Fixes https://github.com/flutter/flutter/issues/138827 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
@@ -81,7 +81,8 @@ BrowserEngine detectBrowserEngineByVendorAgent(String vendor, String agent) {
|
||||
}
|
||||
|
||||
// Assume Blink otherwise, but issue a warning.
|
||||
print('WARNING: failed to detect current browser engine. Assuming this is a Chromium-compatible browser.');
|
||||
print(
|
||||
'WARNING: failed to detect current browser engine. Assuming this is a Chromium-compatible browser.');
|
||||
return BrowserEngine.blink;
|
||||
}
|
||||
|
||||
@@ -141,8 +142,9 @@ OperatingSystem detectOperatingSystem({
|
||||
if (platform.startsWith('Mac')) {
|
||||
// iDevices requesting a "desktop site" spoof their UA so it looks like a Mac.
|
||||
// This checks if we're in a touch device, or on a real mac.
|
||||
final int maxTouchPoints =
|
||||
overrideMaxTouchPoints ?? domWindow.navigator.maxTouchPoints?.toInt() ?? 0;
|
||||
final int maxTouchPoints = overrideMaxTouchPoints ??
|
||||
domWindow.navigator.maxTouchPoints?.toInt() ??
|
||||
0;
|
||||
if (maxTouchPoints > 2) {
|
||||
return OperatingSystem.iOs;
|
||||
}
|
||||
@@ -204,6 +206,36 @@ bool get isIOS15 {
|
||||
domWindow.navigator.userAgent.contains('OS 15_');
|
||||
}
|
||||
|
||||
/// Detect if running on Chrome version 110 or older on Windows.
|
||||
///
|
||||
/// These versions of Chrome have a bug on Windows which causes
|
||||
/// rendering to be flipped upside down.
|
||||
// TODO(harryterkelsen): Remove this check once we stop supporting Chrome 110
|
||||
// and earlier, https://github.com/flutter/flutter/issues/139186.
|
||||
bool get isChrome110OrOlderOnWindows {
|
||||
if (debugIsChrome110OrOlderOnWindows != null) {
|
||||
return debugIsChrome110OrOlderOnWindows!;
|
||||
}
|
||||
if (_cachedIsChrome110OrOlderOnWindows != null) {
|
||||
return _cachedIsChrome110OrOlderOnWindows!;
|
||||
}
|
||||
if (operatingSystem != OperatingSystem.windows) {
|
||||
return _cachedIsChrome110OrOlderOnWindows = false;
|
||||
}
|
||||
final RegExp chromeRegexp = RegExp(r'Chrom(e|ium)\/([0-9]+)\.');
|
||||
final RegExpMatch? match =
|
||||
chromeRegexp.firstMatch(domWindow.navigator.userAgent);
|
||||
if (match != null) {
|
||||
final int chromeVersion = int.parse(match.group(2)!);
|
||||
return _cachedIsChrome110OrOlderOnWindows = chromeVersion <= 110;
|
||||
}
|
||||
return _cachedIsChrome110OrOlderOnWindows = false;
|
||||
}
|
||||
|
||||
// Cache the result of checking if the app is running on Chrome 110 on Windows
|
||||
// since we check this on every frame.
|
||||
bool? _cachedIsChrome110OrOlderOnWindows;
|
||||
|
||||
/// If set to true pretends that the current browser is iOS Safari.
|
||||
///
|
||||
/// Useful for tests. Do not use in production code.
|
||||
@@ -234,6 +266,9 @@ bool get isWasm => const bool.fromEnvironment('dart.library.ffi');
|
||||
/// Use in tests to simulate the detection of iOS 15.
|
||||
bool? debugIsIOS15;
|
||||
|
||||
/// Use in tests to simulated the detection of Chrome 110 or older on Windows.
|
||||
bool? debugIsChrome110OrOlderOnWindows;
|
||||
|
||||
int? _cachedWebGLVersion;
|
||||
|
||||
/// The highest WebGL version supported by the current browser, or -1 if WebGL
|
||||
|
||||
@@ -3672,8 +3672,10 @@ external JSAny? get _createImageBitmapFunction;
|
||||
/// Set to `true` to disable `createImageBitmap` support. Used in tests.
|
||||
bool debugDisableCreateImageBitmapSupport = false;
|
||||
|
||||
bool browserSupportsCreateImageBitmap =
|
||||
!debugDisableCreateImageBitmapSupport || _createImageBitmapFunction != null;
|
||||
bool get browserSupportsCreateImageBitmap =>
|
||||
_createImageBitmapFunction != null &&
|
||||
!isChrome110OrOlderOnWindows &&
|
||||
!debugDisableCreateImageBitmapSupport;
|
||||
|
||||
@JS()
|
||||
@staticInterop
|
||||
|
||||
@@ -20,14 +20,18 @@ void testMain() {
|
||||
setUpCanvasKitTest();
|
||||
setUp(() async {
|
||||
EngineFlutterDisplay.instance.debugOverrideDevicePixelRatio(1.0);
|
||||
debugDisableCreateImageBitmapSupport = true;
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
debugDisableCreateImageBitmapSupport = false;
|
||||
debugIsChrome110OrOlderOnWindows = null;
|
||||
});
|
||||
|
||||
test('can render without createImageBitmap', () async {
|
||||
debugDisableCreateImageBitmapSupport = true;
|
||||
|
||||
expect(browserSupportsCreateImageBitmap, isFalse);
|
||||
|
||||
final CkPictureRecorder recorder = CkPictureRecorder();
|
||||
final CkCanvas canvas = recorder.beginRecording(region);
|
||||
|
||||
@@ -61,5 +65,14 @@ void testMain() {
|
||||
region: region,
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'createImageBitmap support is disabled on '
|
||||
'Windows on Chrome version 110 or older', () async {
|
||||
debugIsChrome110OrOlderOnWindows = true;
|
||||
debugDisableCreateImageBitmapSupport = false;
|
||||
|
||||
expect(browserSupportsCreateImageBitmap, isFalse);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user