cacheWidth cacheHeight support for canvaskit on web (#117423)
* cacheWidth cacheHeight support for web canvaskit * comments * clarifying comment for loadTestImageProvider class Co-authored-by: alanwutang11 <alpwu@google.com>
This commit is contained in:
parent
2a502363e1
commit
1970bc919b
@ -1182,6 +1182,11 @@ Future<void> _runWebLongRunningTests() async {
|
|||||||
() => _runWebE2eTest('capabilities_integration_canvaskit', buildMode: 'profile', renderer: 'canvaskit'),
|
() => _runWebE2eTest('capabilities_integration_canvaskit', buildMode: 'profile', renderer: 'canvaskit'),
|
||||||
() => _runWebE2eTest('capabilities_integration_html', buildMode: 'release', renderer: 'html'),
|
() => _runWebE2eTest('capabilities_integration_html', buildMode: 'release', renderer: 'html'),
|
||||||
|
|
||||||
|
// This test doesn't do anything interesting w.r.t. rendering, so we don't run the full build mode x renderer matrix.
|
||||||
|
// CacheWidth and CacheHeight are only currently supported in CanvasKit mode, so we don't run the test in HTML mode.
|
||||||
|
() => _runWebE2eTest('cache_width_cache_height_integration', buildMode: 'debug', renderer: 'auto'),
|
||||||
|
() => _runWebE2eTest('cache_width_cache_height_integration', buildMode: 'profile', renderer: 'canvaskit'),
|
||||||
|
|
||||||
() => _runWebTreeshakeTest(),
|
() => _runWebTreeshakeTest(),
|
||||||
|
|
||||||
() => _runFlutterDriverWebTest(
|
() => _runFlutterDriverWebTest(
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2014 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:ui' as ui;
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
import 'package:integration_test/integration_test.dart';
|
||||||
|
|
||||||
|
// This class allows loadBuffer, a protected method, to be called with a custom
|
||||||
|
// DecoderBufferCallback function.
|
||||||
|
class LoadTestImageProvider extends ImageProvider<Object> {
|
||||||
|
LoadTestImageProvider(this.provider);
|
||||||
|
|
||||||
|
final ImageProvider provider;
|
||||||
|
|
||||||
|
ImageStreamCompleter testLoad(Object key, DecoderBufferCallback decode) {
|
||||||
|
return provider.loadBuffer(key, decode);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<Object> obtainKey(ImageConfiguration configuration) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
ImageStreamCompleter loadBuffer(Object key, DecoderBufferCallback decode) {
|
||||||
|
throw UnimplementedError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
testWidgets('Image.network uses cacheWidth and cacheHeight', (WidgetTester tester) async {
|
||||||
|
const int expectedCacheHeight = 9;
|
||||||
|
const int expectedCacheWidth = 11;
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final Image image = Image.network(
|
||||||
|
'assets/packages/flutter_gallery_assets/assets/icons/material/material.png',
|
||||||
|
cacheHeight: 9,
|
||||||
|
cacheWidth: 11,
|
||||||
|
);
|
||||||
|
|
||||||
|
bool called = false;
|
||||||
|
|
||||||
|
Future<ui.Codec> decode(ui.ImmutableBuffer buffer, {int? cacheWidth, int? cacheHeight, bool allowUpscaling = false}) {
|
||||||
|
expect(cacheHeight, expectedCacheHeight);
|
||||||
|
expect(cacheWidth, expectedCacheWidth);
|
||||||
|
expect(allowUpscaling, false);
|
||||||
|
called = true;
|
||||||
|
return PaintingBinding.instance.instantiateImageCodecFromBuffer(buffer, cacheWidth: cacheWidth, cacheHeight: cacheHeight, allowUpscaling: allowUpscaling);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ImageProvider resizeImage = image.image;
|
||||||
|
expect(image.image, isA<ResizeImage>());
|
||||||
|
|
||||||
|
final LoadTestImageProvider testProvider = LoadTestImageProvider(image.image);
|
||||||
|
final ImageStreamCompleter streamCompleter = testProvider.testLoad(await resizeImage.obtainKey(ImageConfiguration.empty), decode);
|
||||||
|
|
||||||
|
final Completer<void> completer = Completer<void>();
|
||||||
|
int? imageInfoCachedWidth;
|
||||||
|
int? imageInfoCachedHeight;
|
||||||
|
streamCompleter.addListener(ImageStreamListener((ImageInfo imageInfo, bool syncCall) {
|
||||||
|
imageInfoCachedWidth = imageInfo.image.width;
|
||||||
|
imageInfoCachedHeight = imageInfo.image.height;
|
||||||
|
completer.complete();
|
||||||
|
}));
|
||||||
|
await completer.future;
|
||||||
|
|
||||||
|
expect(imageInfoCachedHeight, isNotNull);
|
||||||
|
expect(imageInfoCachedHeight, expectedCacheHeight);
|
||||||
|
expect(imageInfoCachedWidth, isNotNull);
|
||||||
|
expect(imageInfoCachedWidth, expectedCacheWidth);
|
||||||
|
expect(called, true);
|
||||||
|
});
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2014 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 'package:integration_test/integration_test_driver.dart' as test;
|
||||||
|
|
||||||
|
Future<void> main() async => test.integrationDriver();
|
@ -103,10 +103,7 @@ class NetworkImage
|
|||||||
return collector;
|
return collector;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(garyq): We should eventually support custom decoding of network images on Web as
|
// Html renderer does not support decoding network images to a specified size. The decode parameter
|
||||||
// well, see https://github.com/flutter/flutter/issues/42789.
|
|
||||||
//
|
|
||||||
// Web does not support decoding network images to a specified size. The decode parameter
|
|
||||||
// here is ignored and the web-only `ui.webOnlyInstantiateImageCodecFromUrl` will be used
|
// here is ignored and the web-only `ui.webOnlyInstantiateImageCodecFromUrl` will be used
|
||||||
// directly in place of the typical `instantiateImageCodec` method.
|
// directly in place of the typical `instantiateImageCodec` method.
|
||||||
Future<ui.Codec> _loadAsync(
|
Future<ui.Codec> _loadAsync(
|
||||||
@ -119,18 +116,22 @@ class NetworkImage
|
|||||||
|
|
||||||
final Uri resolved = Uri.base.resolve(key.url);
|
final Uri resolved = Uri.base.resolve(key.url);
|
||||||
|
|
||||||
|
final bool containsNetworkImageHeaders = key.headers?.isNotEmpty ?? false;
|
||||||
|
|
||||||
// We use a different method when headers are set because the
|
// We use a different method when headers are set because the
|
||||||
// `ui.webOnlyInstantiateImageCodecFromUrl` method is not capable of handling headers.
|
// `ui.webOnlyInstantiateImageCodecFromUrl` method is not capable of handling headers.
|
||||||
if (key.headers?.isNotEmpty ?? false) {
|
if (isCanvasKit || containsNetworkImageHeaders) {
|
||||||
final Completer<DomXMLHttpRequest> completer =
|
final Completer<DomXMLHttpRequest> completer =
|
||||||
Completer<DomXMLHttpRequest>();
|
Completer<DomXMLHttpRequest>();
|
||||||
final DomXMLHttpRequest request = httpRequestFactory();
|
final DomXMLHttpRequest request = httpRequestFactory();
|
||||||
|
|
||||||
request.open('GET', key.url, true);
|
request.open('GET', key.url, true);
|
||||||
request.responseType = 'arraybuffer';
|
request.responseType = 'arraybuffer';
|
||||||
key.headers!.forEach((String header, String value) {
|
if (containsNetworkImageHeaders) {
|
||||||
request.setRequestHeader(header, value);
|
key.headers!.forEach((String header, String value) {
|
||||||
});
|
request.setRequestHeader(header, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
request.addEventListener('load', allowInterop((DomEvent e) {
|
request.addEventListener('load', allowInterop((DomEvent e) {
|
||||||
final int? status = request.status;
|
final int? status = request.status;
|
||||||
|
@ -901,9 +901,10 @@ class ResizeImage extends ImageProvider<ResizeImageKey> {
|
|||||||
/// The image will be cached regardless of cache headers from the server.
|
/// The image will be cached regardless of cache headers from the server.
|
||||||
///
|
///
|
||||||
/// When a network image is used on the Web platform, the `cacheWidth` and
|
/// When a network image is used on the Web platform, the `cacheWidth` and
|
||||||
/// `cacheHeight` parameters of the [DecoderCallback] are ignored as the Web
|
/// `cacheHeight` parameters of the [DecoderCallback] are only supported when the
|
||||||
/// engine delegates image decoding of network images to the Web, which does
|
/// application is running with the CanvasKit renderer. When the application is using
|
||||||
/// not support custom decode sizes.
|
/// the HTML renderer, the web engine delegates image decoding of network images to the Web,
|
||||||
|
/// which does not support custom decode sizes.
|
||||||
///
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
|
@ -288,8 +288,9 @@ typedef ImageErrorWidgetBuilder = Widget Function(
|
|||||||
/// memory usage of [ImageCache].
|
/// memory usage of [ImageCache].
|
||||||
///
|
///
|
||||||
/// In the case where a network image is used on the Web platform, the
|
/// In the case where a network image is used on the Web platform, the
|
||||||
/// `cacheWidth` and `cacheHeight` parameters are ignored as the Web engine
|
/// `cacheWidth` and `cacheHeight` parameters are only supported when the application is
|
||||||
/// delegates image decoding of network images to the Web, which does not support
|
/// running with the CanvasKit renderer. When the application is using the HTML renderer,
|
||||||
|
/// the web engine delegates image decoding of network images to the Web, which does not support
|
||||||
/// custom decode sizes.
|
/// custom decode sizes.
|
||||||
///
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user