Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit ae1cc18

Browse files
authored
remove single-view assumption from paintImage (#118721)
* remove single-view assumption from paintImage * dpr * fix test for web
1 parent 374f09e commit ae1cc18

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

packages/flutter/lib/src/painting/decoration_image.dart

+16-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
// found in the LICENSE file.
44

55
import 'dart:developer' as developer;
6-
import 'dart:ui' as ui show Image;
6+
import 'dart:math' as math;
7+
import 'dart:ui' as ui show FlutterView, Image;
78

89
import 'package:flutter/foundation.dart';
910
import 'package:flutter/scheduler.dart';
@@ -558,13 +559,22 @@ void paintImage({
558559
bool invertedCanvas = false;
559560
// Output size and destination rect are fully calculated.
560561
if (!kReleaseMode) {
562+
// We can use the devicePixelRatio of the views directly here (instead of
563+
// going through a MediaQuery) because if it changes, whatever is aware of
564+
// the MediaQuery will be repainting the image anyways.
565+
// Furthermore, for the memory check below we just assume that all images
566+
// are decoded for the view with the highest device pixel ratio and use that
567+
// as an upper bound for the display size of the image.
568+
final double maxDevicePixelRatio = PaintingBinding.instance.platformDispatcher.views.fold(
569+
0.0,
570+
(double previousValue, ui.FlutterView view) => math.max(previousValue, view.devicePixelRatio),
571+
);
572+
561573
final ImageSizeInfo sizeInfo = ImageSizeInfo(
562574
// Some ImageProvider implementations may not have given this.
563575
source: debugImageLabel ?? '<Unknown Image(${image.width}×${image.height})>',
564576
imageSize: Size(image.width.toDouble(), image.height.toDouble()),
565-
// It's ok to use this instead of a MediaQuery because if this changes,
566-
// whatever is aware of the MediaQuery will be repainting the image anyway.
567-
displaySize: outputSize * PaintingBinding.instance.window.devicePixelRatio,
577+
displaySize: outputSize * maxDevicePixelRatio,
568578
);
569579
assert(() {
570580
if (debugInvertOversizedImages &&
@@ -576,7 +586,8 @@ void paintImage({
576586
exception: 'Image $debugImageLabel has a display size of '
577587
'$outputWidth×$outputHeight but a decode size of '
578588
'${image.width}×${image.height}, which uses an additional '
579-
'${overheadInKilobytes}KB.\n\n'
589+
'${overheadInKilobytes}KB (assuming a device pixel ratio of '
590+
'$maxDevicePixelRatio).\n\n'
580591
'Consider resizing the asset ahead of time, supplying a cacheWidth '
581592
'parameter of $outputWidth, a cacheHeight parameter of '
582593
'$outputHeight, or using a ResizeImage.',

packages/flutter/test/painting/paint_image_test.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void main() {
102102

103103
expect(
104104
messages.single,
105-
'Image TestImage has a display size of 300×150 but a decode size of 300×300, which uses an additional 234KB.\n\n'
105+
'Image TestImage has a display size of 300×150 but a decode size of 300×300, which uses an additional 234KB (assuming a device pixel ratio of ${3.0}).\n\n'
106106
'Consider resizing the asset ahead of time, supplying a cacheWidth parameter of 300, a cacheHeight parameter of 150, or using a ResizeImage.',
107107
);
108108

0 commit comments

Comments
 (0)