Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
4c7fae93
Unverified
Commit
4c7fae93
authored
Aug 04, 2020
by
Michael Goderbauer
Committed by
GitHub
Aug 04, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Revert "migrate part of painting to nullsafety (#62696)" (#62868)
This reverts commit
4518a72f
.
parent
0e558042
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
174 additions
and
157 deletions
+174
-157
alignment.dart
packages/flutter/lib/src/painting/alignment.dart
+23
-20
basic_types.dart
packages/flutter/lib/src/painting/basic_types.dart
+6
-0
binding.dart
packages/flutter/lib/src/painting/binding.dart
+14
-11
colors.dart
packages/flutter/lib/src/painting/colors.dart
+23
-22
debug.dart
packages/flutter/lib/src/painting/debug.dart
+14
-14
image_cache.dart
packages/flutter/lib/src/painting/image_cache.dart
+36
-35
image_stream.dart
packages/flutter/lib/src/painting/image_stream.dart
+57
-55
shader_warm_up.dart
packages/flutter/lib/src/painting/shader_warm_up.dart
+1
-0
No files found.
packages/flutter/lib/src/painting/alignment.dart
View file @
4c7fae93
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
// @dart = 2.8
import
'dart:ui'
as
ui
show
lerpDouble
;
import
'dart:ui'
as
ui
show
lerpDouble
;
...
@@ -87,12 +88,12 @@ abstract class AlignmentGeometry {
...
@@ -87,12 +88,12 @@ abstract class AlignmentGeometry {
/// into a concrete [Alignment] using [resolve].
/// into a concrete [Alignment] using [resolve].
///
///
/// {@macro dart.ui.shadow.lerp}
/// {@macro dart.ui.shadow.lerp}
static
AlignmentGeometry
?
lerp
(
AlignmentGeometry
?
a
,
AlignmentGeometry
?
b
,
double
t
)
{
static
AlignmentGeometry
lerp
(
AlignmentGeometry
a
,
AlignmentGeometry
b
,
double
t
)
{
assert
(
t
!=
null
);
assert
(
t
!=
null
);
if
(
a
==
null
&&
b
==
null
)
if
(
a
==
null
&&
b
==
null
)
return
null
;
return
null
;
if
(
a
==
null
)
if
(
a
==
null
)
return
b
!
*
t
;
return
b
*
t
;
if
(
b
==
null
)
if
(
b
==
null
)
return
a
*
(
1.0
-
t
);
return
a
*
(
1.0
-
t
);
if
(
a
is
Alignment
&&
b
is
Alignment
)
if
(
a
is
Alignment
&&
b
is
Alignment
)
...
@@ -100,9 +101,9 @@ abstract class AlignmentGeometry {
...
@@ -100,9 +101,9 @@ abstract class AlignmentGeometry {
if
(
a
is
AlignmentDirectional
&&
b
is
AlignmentDirectional
)
if
(
a
is
AlignmentDirectional
&&
b
is
AlignmentDirectional
)
return
AlignmentDirectional
.
lerp
(
a
,
b
,
t
);
return
AlignmentDirectional
.
lerp
(
a
,
b
,
t
);
return
_MixedAlignment
(
return
_MixedAlignment
(
ui
.
lerpDouble
(
a
.
_x
,
b
.
_x
,
t
)
!
,
ui
.
lerpDouble
(
a
.
_x
,
b
.
_x
,
t
),
ui
.
lerpDouble
(
a
.
_start
,
b
.
_start
,
t
)
!
,
ui
.
lerpDouble
(
a
.
_start
,
b
.
_start
,
t
),
ui
.
lerpDouble
(
a
.
_y
,
b
.
_y
,
t
)
!
,
ui
.
lerpDouble
(
a
.
_y
,
b
.
_y
,
t
),
);
);
}
}
...
@@ -115,7 +116,7 @@ abstract class AlignmentGeometry {
...
@@ -115,7 +116,7 @@ abstract class AlignmentGeometry {
/// * [Alignment], for which this is a no-op (returns itself).
/// * [Alignment], for which this is a no-op (returns itself).
/// * [AlignmentDirectional], which flips the horizontal direction
/// * [AlignmentDirectional], which flips the horizontal direction
/// based on the `direction` argument.
/// based on the `direction` argument.
Alignment
resolve
(
TextDirection
?
direction
);
Alignment
resolve
(
TextDirection
direction
);
@override
@override
String
toString
()
{
String
toString
()
{
...
@@ -332,19 +333,19 @@ class Alignment extends AlignmentGeometry {
...
@@ -332,19 +333,19 @@ class Alignment extends AlignmentGeometry {
/// If either is null, this function interpolates from [Alignment.center].
/// If either is null, this function interpolates from [Alignment.center].
///
///
/// {@macro dart.ui.shadow.lerp}
/// {@macro dart.ui.shadow.lerp}
static
Alignment
?
lerp
(
Alignment
?
a
,
Alignment
?
b
,
double
t
)
{
static
Alignment
lerp
(
Alignment
a
,
Alignment
b
,
double
t
)
{
assert
(
t
!=
null
);
assert
(
t
!=
null
);
if
(
a
==
null
&&
b
==
null
)
if
(
a
==
null
&&
b
==
null
)
return
null
;
return
null
;
if
(
a
==
null
)
if
(
a
==
null
)
return
Alignment
(
ui
.
lerpDouble
(
0.0
,
b
!.
x
,
t
)!,
ui
.
lerpDouble
(
0.0
,
b
.
y
,
t
)!
);
return
Alignment
(
ui
.
lerpDouble
(
0.0
,
b
.
x
,
t
),
ui
.
lerpDouble
(
0.0
,
b
.
y
,
t
)
);
if
(
b
==
null
)
if
(
b
==
null
)
return
Alignment
(
ui
.
lerpDouble
(
a
.
x
,
0.0
,
t
)
!,
ui
.
lerpDouble
(
a
.
y
,
0.0
,
t
)!
);
return
Alignment
(
ui
.
lerpDouble
(
a
.
x
,
0.0
,
t
)
,
ui
.
lerpDouble
(
a
.
y
,
0.0
,
t
)
);
return
Alignment
(
ui
.
lerpDouble
(
a
.
x
,
b
.
x
,
t
)
!,
ui
.
lerpDouble
(
a
.
y
,
b
.
y
,
t
)!
);
return
Alignment
(
ui
.
lerpDouble
(
a
.
x
,
b
.
x
,
t
)
,
ui
.
lerpDouble
(
a
.
y
,
b
.
y
,
t
)
);
}
}
@override
@override
Alignment
resolve
(
TextDirection
?
direction
)
=>
this
;
Alignment
resolve
(
TextDirection
direction
)
=>
this
;
static
String
_stringify
(
double
x
,
double
y
)
{
static
String
_stringify
(
double
x
,
double
y
)
{
if
(
x
==
-
1.0
&&
y
==
-
1.0
)
if
(
x
==
-
1.0
&&
y
==
-
1.0
)
...
@@ -513,26 +514,27 @@ class AlignmentDirectional extends AlignmentGeometry {
...
@@ -513,26 +514,27 @@ class AlignmentDirectional extends AlignmentGeometry {
/// If either is null, this function interpolates from [AlignmentDirectional.center].
/// If either is null, this function interpolates from [AlignmentDirectional.center].
///
///
/// {@macro dart.ui.shadow.lerp}
/// {@macro dart.ui.shadow.lerp}
static
AlignmentDirectional
?
lerp
(
AlignmentDirectional
?
a
,
AlignmentDirectional
?
b
,
double
t
)
{
static
AlignmentDirectional
lerp
(
AlignmentDirectional
a
,
AlignmentDirectional
b
,
double
t
)
{
assert
(
t
!=
null
);
assert
(
t
!=
null
);
if
(
a
==
null
&&
b
==
null
)
if
(
a
==
null
&&
b
==
null
)
return
null
;
return
null
;
if
(
a
==
null
)
if
(
a
==
null
)
return
AlignmentDirectional
(
ui
.
lerpDouble
(
0.0
,
b
!.
start
,
t
)!,
ui
.
lerpDouble
(
0.0
,
b
.
y
,
t
)!
);
return
AlignmentDirectional
(
ui
.
lerpDouble
(
0.0
,
b
.
start
,
t
),
ui
.
lerpDouble
(
0.0
,
b
.
y
,
t
)
);
if
(
b
==
null
)
if
(
b
==
null
)
return
AlignmentDirectional
(
ui
.
lerpDouble
(
a
.
start
,
0.0
,
t
)
!,
ui
.
lerpDouble
(
a
.
y
,
0.0
,
t
)!
);
return
AlignmentDirectional
(
ui
.
lerpDouble
(
a
.
start
,
0.0
,
t
)
,
ui
.
lerpDouble
(
a
.
y
,
0.0
,
t
)
);
return
AlignmentDirectional
(
ui
.
lerpDouble
(
a
.
start
,
b
.
start
,
t
)
!,
ui
.
lerpDouble
(
a
.
y
,
b
.
y
,
t
)!
);
return
AlignmentDirectional
(
ui
.
lerpDouble
(
a
.
start
,
b
.
start
,
t
)
,
ui
.
lerpDouble
(
a
.
y
,
b
.
y
,
t
)
);
}
}
@override
@override
Alignment
resolve
(
TextDirection
?
direction
)
{
Alignment
resolve
(
TextDirection
direction
)
{
assert
(
direction
!=
null
,
'Cannot resolve
$runtimeType
without a TextDirection.'
);
assert
(
direction
!=
null
,
'Cannot resolve
$runtimeType
without a TextDirection.'
);
switch
(
direction
!
)
{
switch
(
direction
)
{
case
TextDirection
.
rtl
:
case
TextDirection
.
rtl
:
return
Alignment
(-
start
,
y
);
return
Alignment
(-
start
,
y
);
case
TextDirection
.
ltr
:
case
TextDirection
.
ltr
:
return
Alignment
(
start
,
y
);
return
Alignment
(
start
,
y
);
}
}
return
null
;
}
}
static
String
_stringify
(
double
start
,
double
y
)
{
static
String
_stringify
(
double
start
,
double
y
)
{
...
@@ -620,14 +622,15 @@ class _MixedAlignment extends AlignmentGeometry {
...
@@ -620,14 +622,15 @@ class _MixedAlignment extends AlignmentGeometry {
}
}
@override
@override
Alignment
resolve
(
TextDirection
?
direction
)
{
Alignment
resolve
(
TextDirection
direction
)
{
assert
(
direction
!=
null
,
'Cannot resolve
$runtimeType
without a TextDirection.'
);
assert
(
direction
!=
null
,
'Cannot resolve
$runtimeType
without a TextDirection.'
);
switch
(
direction
!
)
{
switch
(
direction
)
{
case
TextDirection
.
rtl
:
case
TextDirection
.
rtl
:
return
Alignment
(
_x
-
_start
,
_y
);
return
Alignment
(
_x
-
_start
,
_y
);
case
TextDirection
.
ltr
:
case
TextDirection
.
ltr
:
return
Alignment
(
_x
+
_start
,
_y
);
return
Alignment
(
_x
+
_start
,
_y
);
}
}
return
null
;
}
}
}
}
...
@@ -649,7 +652,7 @@ class _MixedAlignment extends AlignmentGeometry {
...
@@ -649,7 +652,7 @@ class _MixedAlignment extends AlignmentGeometry {
class
TextAlignVertical
{
class
TextAlignVertical
{
/// Creates a TextAlignVertical from any y value between -1.0 and 1.0.
/// Creates a TextAlignVertical from any y value between -1.0 and 1.0.
const
TextAlignVertical
({
const
TextAlignVertical
({
required
this
.
y
,
@
required
this
.
y
,
})
:
assert
(
y
!=
null
),
})
:
assert
(
y
!=
null
),
assert
(
y
>=
-
1.0
&&
y
<=
1.0
);
assert
(
y
>=
-
1.0
&&
y
<=
1.0
);
...
...
packages/flutter/lib/src/painting/basic_types.dart
View file @
4c7fae93
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
// @dart = 2.8
import
'dart:ui'
show
TextDirection
;
import
'dart:ui'
show
TextDirection
;
...
@@ -142,6 +143,7 @@ Axis flipAxis(Axis direction) {
...
@@ -142,6 +143,7 @@ Axis flipAxis(Axis direction) {
case
Axis
.
vertical
:
case
Axis
.
vertical
:
return
Axis
.
horizontal
;
return
Axis
.
horizontal
;
}
}
return
null
;
}
}
/// A direction in which boxes flow vertically.
/// A direction in which boxes flow vertically.
...
@@ -212,6 +214,7 @@ Axis axisDirectionToAxis(AxisDirection axisDirection) {
...
@@ -212,6 +214,7 @@ Axis axisDirectionToAxis(AxisDirection axisDirection) {
case
AxisDirection
.
right
:
case
AxisDirection
.
right
:
return
Axis
.
horizontal
;
return
Axis
.
horizontal
;
}
}
return
null
;
}
}
/// Returns the [AxisDirection] in which reading occurs in the given [TextDirection].
/// Returns the [AxisDirection] in which reading occurs in the given [TextDirection].
...
@@ -226,6 +229,7 @@ AxisDirection textDirectionToAxisDirection(TextDirection textDirection) {
...
@@ -226,6 +229,7 @@ AxisDirection textDirectionToAxisDirection(TextDirection textDirection) {
case
TextDirection
.
ltr
:
case
TextDirection
.
ltr
:
return
AxisDirection
.
right
;
return
AxisDirection
.
right
;
}
}
return
null
;
}
}
/// Returns the opposite of the given [AxisDirection].
/// Returns the opposite of the given [AxisDirection].
...
@@ -249,6 +253,7 @@ AxisDirection flipAxisDirection(AxisDirection axisDirection) {
...
@@ -249,6 +253,7 @@ AxisDirection flipAxisDirection(AxisDirection axisDirection) {
case
AxisDirection
.
left
:
case
AxisDirection
.
left
:
return
AxisDirection
.
right
;
return
AxisDirection
.
right
;
}
}
return
null
;
}
}
/// Returns whether traveling along the given axis direction visits coordinates
/// Returns whether traveling along the given axis direction visits coordinates
...
@@ -266,4 +271,5 @@ bool axisDirectionIsReversed(AxisDirection axisDirection) {
...
@@ -266,4 +271,5 @@ bool axisDirectionIsReversed(AxisDirection axisDirection) {
case
AxisDirection
.
right
:
case
AxisDirection
.
right
:
return
false
;
return
false
;
}
}
return
null
;
}
}
packages/flutter/lib/src/painting/binding.dart
View file @
4c7fae93
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
// @dart = 2.8
import
'dart:typed_data'
show
Uint8List
;
import
'dart:typed_data'
show
Uint8List
;
import
'dart:ui'
as
ui
show
instantiateImageCodec
,
Codec
;
import
'dart:ui'
as
ui
show
instantiateImageCodec
,
Codec
;
...
@@ -22,12 +23,14 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
...
@@ -22,12 +23,14 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
super
.
initInstances
();
super
.
initInstances
();
_instance
=
this
;
_instance
=
this
;
_imageCache
=
createImageCache
();
_imageCache
=
createImageCache
();
shaderWarmUp
?.
execute
();
if
(
shaderWarmUp
!=
null
)
{
shaderWarmUp
.
execute
();
}
}
}
/// The current [PaintingBinding], if one has been created.
/// The current [PaintingBinding], if one has been created.
static
PaintingBinding
?
get
instance
=>
_instance
;
static
PaintingBinding
get
instance
=>
_instance
;
static
PaintingBinding
?
_instance
;
static
PaintingBinding
_instance
;
/// [ShaderWarmUp] to be executed during [initInstances].
/// [ShaderWarmUp] to be executed during [initInstances].
///
///
...
@@ -50,7 +53,7 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
...
@@ -50,7 +53,7 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
/// See also:
/// See also:
///
///
/// * [ShaderWarmUp], the interface of how this warm up works.
/// * [ShaderWarmUp], the interface of how this warm up works.
static
ShaderWarmUp
?
shaderWarmUp
=
const
DefaultShaderWarmUp
();
static
ShaderWarmUp
shaderWarmUp
=
const
DefaultShaderWarmUp
();
/// The singleton that implements the Flutter framework's image cache.
/// The singleton that implements the Flutter framework's image cache.
///
///
...
@@ -59,8 +62,8 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
...
@@ -59,8 +62,8 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
///
///
/// The image cache is created during startup by the [createImageCache]
/// The image cache is created during startup by the [createImageCache]
/// method.
/// method.
ImageCache
?
get
imageCache
=>
_imageCache
;
ImageCache
get
imageCache
=>
_imageCache
;
ImageCache
?
_imageCache
;
ImageCache
_imageCache
;
/// Creates the [ImageCache] singleton (accessible via [imageCache]).
/// Creates the [ImageCache] singleton (accessible via [imageCache]).
///
///
...
@@ -87,8 +90,8 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
...
@@ -87,8 +90,8 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
/// above its native resolution should prefer scaling the canvas the image is
/// above its native resolution should prefer scaling the canvas the image is
/// drawn into.
/// drawn into.
Future
<
ui
.
Codec
>
instantiateImageCodec
(
Uint8List
bytes
,
{
Future
<
ui
.
Codec
>
instantiateImageCodec
(
Uint8List
bytes
,
{
int
?
cacheWidth
,
int
cacheWidth
,
int
?
cacheHeight
,
int
cacheHeight
,
bool
allowUpscaling
=
false
,
bool
allowUpscaling
=
false
,
})
{
})
{
assert
(
cacheWidth
==
null
||
cacheWidth
>
0
);
assert
(
cacheWidth
==
null
||
cacheWidth
>
0
);
...
@@ -105,8 +108,8 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
...
@@ -105,8 +108,8 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
@override
@override
void
evict
(
String
asset
)
{
void
evict
(
String
asset
)
{
super
.
evict
(
asset
);
super
.
evict
(
asset
);
imageCache
!
.
clear
();
imageCache
.
clear
();
imageCache
!
.
clearLiveImages
();
imageCache
.
clearLiveImages
();
}
}
@override
@override
...
@@ -167,4 +170,4 @@ class _SystemFontsNotifier extends Listenable {
...
@@ -167,4 +170,4 @@ class _SystemFontsNotifier extends Listenable {
///
///
/// The image cache is created during startup by the [PaintingBinding]'s
/// The image cache is created during startup by the [PaintingBinding]'s
/// [PaintingBinding.createImageCache] method.
/// [PaintingBinding.createImageCache] method.
ImageCache
?
get
imageCache
=>
PaintingBinding
.
instance
!
.
imageCache
;
ImageCache
get
imageCache
=>
PaintingBinding
.
instance
.
imageCache
;
packages/flutter/lib/src/painting/colors.dart
View file @
4c7fae93
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
// @dart = 2.8
import
'dart:math'
as
math
;
import
'dart:math'
as
math
;
import
'dart:ui'
show
Color
,
lerpDouble
,
hashValues
;
import
'dart:ui'
show
Color
,
lerpDouble
,
hashValues
;
...
@@ -9,7 +10,7 @@ import 'dart:ui' show Color, lerpDouble, hashValues;
...
@@ -9,7 +10,7 @@ import 'dart:ui' show Color, lerpDouble, hashValues;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/foundation.dart'
;
double
_getHue
(
double
red
,
double
green
,
double
blue
,
double
max
,
double
delta
)
{
double
_getHue
(
double
red
,
double
green
,
double
blue
,
double
max
,
double
delta
)
{
late
double
hue
;
double
hue
;
if
(
max
==
0.0
)
{
if
(
max
==
0.0
)
{
hue
=
0.0
;
hue
=
0.0
;
}
else
if
(
max
==
red
)
{
}
else
if
(
max
==
red
)
{
...
@@ -198,19 +199,19 @@ class HSVColor {
...
@@ -198,19 +199,19 @@ class HSVColor {
/// {@macro dart.ui.shadow.lerp}
/// {@macro dart.ui.shadow.lerp}
///
///
/// Values outside of the valid range for each channel will be clamped.
/// Values outside of the valid range for each channel will be clamped.
static
HSVColor
?
lerp
(
HSVColor
?
a
,
HSVColor
?
b
,
double
t
)
{
static
HSVColor
lerp
(
HSVColor
a
,
HSVColor
b
,
double
t
)
{
assert
(
t
!=
null
);
assert
(
t
!=
null
);
if
(
a
==
null
&&
b
==
null
)
if
(
a
==
null
&&
b
==
null
)
return
null
;
return
null
;
if
(
a
==
null
)
if
(
a
==
null
)
return
b
!
.
_scaleAlpha
(
t
);
return
b
.
_scaleAlpha
(
t
);
if
(
b
==
null
)
if
(
b
==
null
)
return
a
.
_scaleAlpha
(
1.0
-
t
);
return
a
.
_scaleAlpha
(
1.0
-
t
);
return
HSVColor
.
fromAHSV
(
return
HSVColor
.
fromAHSV
(
lerpDouble
(
a
.
alpha
,
b
.
alpha
,
t
)
!
.
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
alpha
,
b
.
alpha
,
t
).
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
hue
,
b
.
hue
,
t
)
!
%
360.0
,
lerpDouble
(
a
.
hue
,
b
.
hue
,
t
)
%
360.0
,
lerpDouble
(
a
.
saturation
,
b
.
saturation
,
t
)
!
.
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
saturation
,
b
.
saturation
,
t
).
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
value
,
b
.
value
,
t
)
!
.
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
value
,
b
.
value
,
t
).
clamp
(
0.0
,
1.0
)
as
double
,
);
);
}
}
...
@@ -382,19 +383,19 @@ class HSLColor {
...
@@ -382,19 +383,19 @@ class HSLColor {
///
///
/// Values for `t` are usually obtained from an [Animation<double>], such as
/// Values for `t` are usually obtained from an [Animation<double>], such as
/// an [AnimationController].
/// an [AnimationController].
static
HSLColor
?
lerp
(
HSLColor
?
a
,
HSLColor
?
b
,
double
t
)
{
static
HSLColor
lerp
(
HSLColor
a
,
HSLColor
b
,
double
t
)
{
assert
(
t
!=
null
);
assert
(
t
!=
null
);
if
(
a
==
null
&&
b
==
null
)
if
(
a
==
null
&&
b
==
null
)
return
null
;
return
null
;
if
(
a
==
null
)
if
(
a
==
null
)
return
b
!
.
_scaleAlpha
(
t
);
return
b
.
_scaleAlpha
(
t
);
if
(
b
==
null
)
if
(
b
==
null
)
return
a
.
_scaleAlpha
(
1.0
-
t
);
return
a
.
_scaleAlpha
(
1.0
-
t
);
return
HSLColor
.
fromAHSL
(
return
HSLColor
.
fromAHSL
(
lerpDouble
(
a
.
alpha
,
b
.
alpha
,
t
)
!
.
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
alpha
,
b
.
alpha
,
t
).
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
hue
,
b
.
hue
,
t
)
!
%
360.0
,
lerpDouble
(
a
.
hue
,
b
.
hue
,
t
)
%
360.0
,
lerpDouble
(
a
.
saturation
,
b
.
saturation
,
t
)
!
.
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
saturation
,
b
.
saturation
,
t
).
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
lightness
,
b
.
lightness
,
t
)
!
.
clamp
(
0.0
,
1.0
)
as
double
,
lerpDouble
(
a
.
lightness
,
b
.
lightness
,
t
).
clamp
(
0.0
,
1.0
)
as
double
,
);
);
}
}
...
@@ -440,7 +441,7 @@ class ColorSwatch<T> extends Color {
...
@@ -440,7 +441,7 @@ class ColorSwatch<T> extends Color {
final
Map
<
T
,
Color
>
_swatch
;
final
Map
<
T
,
Color
>
_swatch
;
/// Returns an element of the swatch table.
/// Returns an element of the swatch table.
Color
?
operator
[](
T
index
)
=>
_swatch
[
index
];
Color
operator
[](
T
index
)
=>
_swatch
[
index
];
@override
@override
bool
operator
==(
Object
other
)
{
bool
operator
==(
Object
other
)
{
...
@@ -467,9 +468,9 @@ class ColorProperty extends DiagnosticsProperty<Color> {
...
@@ -467,9 +468,9 @@ class ColorProperty extends DiagnosticsProperty<Color> {
/// The [showName], [style], and [level] arguments must not be null.
/// The [showName], [style], and [level] arguments must not be null.
ColorProperty
(
ColorProperty
(
String
name
,
String
name
,
Color
?
value
,
{
Color
value
,
{
bool
showName
=
true
,
bool
showName
=
true
,
Object
?
defaultValue
=
kNoDefaultValue
,
Object
defaultValue
=
kNoDefaultValue
,
DiagnosticsTreeStyle
style
=
DiagnosticsTreeStyle
.
singleLine
,
DiagnosticsTreeStyle
style
=
DiagnosticsTreeStyle
.
singleLine
,
DiagnosticLevel
level
=
DiagnosticLevel
.
info
,
DiagnosticLevel
level
=
DiagnosticLevel
.
info
,
})
:
assert
(
showName
!=
null
),
})
:
assert
(
showName
!=
null
),
...
@@ -483,14 +484,14 @@ class ColorProperty extends DiagnosticsProperty<Color> {
...
@@ -483,14 +484,14 @@ class ColorProperty extends DiagnosticsProperty<Color> {
);
);
@override
@override
Map
<
String
,
Object
?
>
toJsonMap
(
DiagnosticsSerializationDelegate
delegate
)
{
Map
<
String
,
Object
>
toJsonMap
(
DiagnosticsSerializationDelegate
delegate
)
{
final
Map
<
String
,
Object
?
>
json
=
super
.
toJsonMap
(
delegate
);
final
Map
<
String
,
Object
>
json
=
super
.
toJsonMap
(
delegate
);
if
(
value
!=
null
)
{
if
(
value
!=
null
)
{
json
[
'valueProperties'
]
=
<
String
,
Object
>{
json
[
'valueProperties'
]
=
<
String
,
Object
>{
'red'
:
value
!
.
red
,
'red'
:
value
.
red
,
'green'
:
value
!
.
green
,
'green'
:
value
.
green
,
'blue'
:
value
!
.
blue
,
'blue'
:
value
.
blue
,
'alpha'
:
value
!
.
alpha
,
'alpha'
:
value
.
alpha
,
};
};
}
}
return
json
;
return
json
;
...
...
packages/flutter/lib/src/painting/debug.dart
View file @
4c7fae93
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
// @dart = 2.8
import
'dart:io'
;
import
'dart:io'
;
import
'dart:ui'
show
Size
,
hashValues
;
import
'dart:ui'
show
Size
,
hashValues
;
...
@@ -29,7 +30,7 @@ typedef HttpClientProvider = HttpClient Function();
...
@@ -29,7 +30,7 @@ typedef HttpClientProvider = HttpClient Function();
/// a mock client that hasn't been affected by other tests.
/// a mock client that hasn't been affected by other tests.
///
///
/// This value is ignored in non-debug builds.
/// This value is ignored in non-debug builds.
HttpClientProvider
?
debugNetworkImageHttpClientProvider
;
HttpClientProvider
debugNetworkImageHttpClientProvider
;
typedef
PaintImageCallback
=
void
Function
(
ImageSizeInfo
);
typedef
PaintImageCallback
=
void
Function
(
ImageSizeInfo
);
...
@@ -43,20 +44,20 @@ class ImageSizeInfo {
...
@@ -43,20 +44,20 @@ class ImageSizeInfo {
/// This class is used by the framework when it paints an image to a canvas
/// This class is used by the framework when it paints an image to a canvas
/// to report to `dart:developer`'s [postEvent], as well as to the
/// to report to `dart:developer`'s [postEvent], as well as to the
/// [debugOnPaintImage] callback if it is set.
/// [debugOnPaintImage] callback if it is set.
const
ImageSizeInfo
({
this
.
source
,
this
.
displaySize
,
required
this
.
imageSize
});
const
ImageSizeInfo
({
this
.
source
,
this
.
displaySize
,
this
.
imageSize
});
/// A unique identifier for this image, for example its asset path or network
/// A unique identifier for this image, for example its asset path or network
/// URL.
/// URL.
final
String
?
source
;
final
String
source
;
/// The size of the area the image will be rendered in.
/// The size of the area the image will be rendered in.
final
Size
?
displaySize
;
final
Size
displaySize
;
/// The size the image has been decoded to.
/// The size the image has been decoded to.
final
Size
imageSize
;
final
Size
imageSize
;
/// The number of bytes needed to render the image without scaling it.
/// The number of bytes needed to render the image without scaling it.
int
get
displaySizeInBytes
=>
_sizeToBytes
(
displaySize
!
);
int
get
displaySizeInBytes
=>
_sizeToBytes
(
displaySize
);
/// The number of bytes used by the image in memory.
/// The number of bytes used by the image in memory.
int
get
decodedSizeInBytes
=>
_sizeToBytes
(
imageSize
);
int
get
decodedSizeInBytes
=>
_sizeToBytes
(
imageSize
);
...
@@ -68,15 +69,14 @@ class ImageSizeInfo {
...
@@ -68,15 +69,14 @@ class ImageSizeInfo {
}
}
/// Returns a JSON encodable representation of this object.
/// Returns a JSON encodable representation of this object.
Map
<
String
,
Object
?
>
toJson
()
{
Map
<
String
,
Object
>
toJson
()
{
return
<
String
,
Object
?
>{
return
<
String
,
Object
>{
'source'
:
source
,
'source'
:
source
,
if
(
displaySize
!=
null
)
'displaySize'
:
<
String
,
double
>{
'displaySize'
:
<
String
,
Object
?>{
'width'
:
displaySize
.
width
,
'width'
:
displaySize
!.
width
,
'height'
:
displaySize
.
height
,
'height'
:
displaySize
!.
height
,
},
},
'imageSize'
:
<
String
,
Object
?
>{
'imageSize'
:
<
String
,
double
>{
'width'
:
imageSize
.
width
,
'width'
:
imageSize
.
width
,
'height'
:
imageSize
.
height
,
'height'
:
imageSize
.
height
,
},
},
...
@@ -125,7 +125,7 @@ class ImageSizeInfo {
...
@@ -125,7 +125,7 @@ class ImageSizeInfo {
/// a higher resolution while animating, but it would be problematic to have
/// a higher resolution while animating, but it would be problematic to have
/// a grid or list of such thumbnails all be at the full resolution at the same
/// a grid or list of such thumbnails all be at the full resolution at the same
/// time.
/// time.
PaintImageCallback
?
debugOnPaintImage
;
PaintImageCallback
debugOnPaintImage
;
/// If true, the framework will color invert and horizontally flip images that
/// If true, the framework will color invert and horizontally flip images that
/// have been decoded to a size taking at least [debugImageOverheadAllowance]
/// have been decoded to a size taking at least [debugImageOverheadAllowance]
...
...
packages/flutter/lib/src/painting/image_cache.dart
View file @
4c7fae93
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
// @dart = 2.8
import
'dart:developer'
;
import
'dart:developer'
;
import
'dart:ui'
show
hashValues
;
import
'dart:ui'
show
hashValues
;
...
@@ -102,7 +103,7 @@ class ImageCache {
...
@@ -102,7 +103,7 @@ class ImageCache {
assert
(
value
>=
0
);
assert
(
value
>=
0
);
if
(
value
==
maximumSize
)
if
(
value
==
maximumSize
)
return
;
return
;
TimelineTask
?
timelineTask
;
TimelineTask
timelineTask
;
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
timelineTask
=
TimelineTask
()..
start
(
timelineTask
=
TimelineTask
()..
start
(
'ImageCache.setMaximumSize'
,
'ImageCache.setMaximumSize'
,
...
@@ -116,7 +117,7 @@ class ImageCache {
...
@@ -116,7 +117,7 @@ class ImageCache {
_checkCacheSize
(
timelineTask
);
_checkCacheSize
(
timelineTask
);
}
}
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
timelineTask
!
.
finish
();
timelineTask
.
finish
();
}
}
}
}
...
@@ -141,7 +142,7 @@ class ImageCache {
...
@@ -141,7 +142,7 @@ class ImageCache {
assert
(
value
>=
0
);
assert
(
value
>=
0
);
if
(
value
==
_maximumSizeBytes
)
if
(
value
==
_maximumSizeBytes
)
return
;
return
;
TimelineTask
?
timelineTask
;
TimelineTask
timelineTask
;
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
timelineTask
=
TimelineTask
()..
start
(
timelineTask
=
TimelineTask
()..
start
(
'ImageCache.setMaximumSizeBytes'
,
'ImageCache.setMaximumSizeBytes'
,
...
@@ -155,7 +156,7 @@ class ImageCache {
...
@@ -155,7 +156,7 @@ class ImageCache {
_checkCacheSize
(
timelineTask
);
_checkCacheSize
(
timelineTask
);
}
}
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
timelineTask
!
.
finish
();
timelineTask
.
finish
();
}
}
}
}
...
@@ -238,10 +239,10 @@ class ImageCache {
...
@@ -238,10 +239,10 @@ class ImageCache {
// will never complete, e.g. it was loaded in a FakeAsync zone.
// will never complete, e.g. it was loaded in a FakeAsync zone.
// In such a case, we need to make sure subsequent calls to
// In such a case, we need to make sure subsequent calls to
// putIfAbsent don't return this image that may never complete.
// putIfAbsent don't return this image that may never complete.
final
_LiveImage
?
image
=
_liveImages
.
remove
(
key
);
final
_LiveImage
image
=
_liveImages
.
remove
(
key
);
image
?.
removeListener
();
image
?.
removeListener
();
}
}
final
_PendingImage
?
pendingImage
=
_pendingImages
.
remove
(
key
);
final
_PendingImage
pendingImage
=
_pendingImages
.
remove
(
key
);
if
(
pendingImage
!=
null
)
{
if
(
pendingImage
!=
null
)
{
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
Timeline
.
instantSync
(
'ImageCache.evict'
,
arguments:
<
String
,
dynamic
>{
Timeline
.
instantSync
(
'ImageCache.evict'
,
arguments:
<
String
,
dynamic
>{
...
@@ -251,7 +252,7 @@ class ImageCache {
...
@@ -251,7 +252,7 @@ class ImageCache {
pendingImage
.
removeListener
();
pendingImage
.
removeListener
();
return
true
;
return
true
;
}
}
final
_CachedImage
?
image
=
_cache
.
remove
(
key
);
final
_CachedImage
image
=
_cache
.
remove
(
key
);
if
(
image
!=
null
)
{
if
(
image
!=
null
)
{
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
Timeline
.
instantSync
(
'ImageCache.evict'
,
arguments:
<
String
,
dynamic
>{
Timeline
.
instantSync
(
'ImageCache.evict'
,
arguments:
<
String
,
dynamic
>{
...
@@ -259,7 +260,7 @@ class ImageCache {
...
@@ -259,7 +260,7 @@ class ImageCache {
'sizeInBytes'
:
image
.
sizeBytes
,
'sizeInBytes'
:
image
.
sizeBytes
,
});
});
}
}
_currentSizeBytes
-=
image
.
sizeBytes
!
;
_currentSizeBytes
-=
image
.
sizeBytes
;
return
true
;
return
true
;
}
}
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
...
@@ -275,13 +276,13 @@ class ImageCache {
...
@@ -275,13 +276,13 @@ class ImageCache {
///
///
/// Resizes the cache as appropriate to maintain the constraints of
/// Resizes the cache as appropriate to maintain the constraints of
/// [maximumSize] and [maximumSizeBytes].
/// [maximumSize] and [maximumSizeBytes].
void
_touch
(
Object
key
,
_CachedImage
image
,
TimelineTask
?
timelineTask
)
{
void
_touch
(
Object
key
,
_CachedImage
image
,
TimelineTask
timelineTask
)
{
// TODO(dnfield): Some customers test in release mode with asserts enabled.
// TODO(dnfield): Some customers test in release mode with asserts enabled.
// This is bound to cause problems, b/150295238 is tracking that. For now,
// This is bound to cause problems, b/150295238 is tracking that. For now,
// avoid this being a point of failure.
// avoid this being a point of failure.
assert
(
kReleaseMode
||
timelineTask
!=
null
);
assert
(
kReleaseMode
||
timelineTask
!=
null
);
if
(
image
.
sizeBytes
!=
null
&&
image
.
sizeBytes
!
<=
maximumSizeBytes
)
{
if
(
image
.
sizeBytes
!=
null
&&
image
.
sizeBytes
<=
maximumSizeBytes
)
{
_currentSizeBytes
+=
image
.
sizeBytes
!
;
_currentSizeBytes
+=
image
.
sizeBytes
;
_cache
[
key
]
=
image
;
_cache
[
key
]
=
image
;
_checkCacheSize
(
timelineTask
);
_checkCacheSize
(
timelineTask
);
}
}
...
@@ -309,11 +310,11 @@ class ImageCache {
...
@@ -309,11 +310,11 @@ class ImageCache {
/// `onError` is also provided. When an exception is caught resolving an image,
/// `onError` is also provided. When an exception is caught resolving an image,
/// no completers are cached and `null` is returned instead of a new
/// no completers are cached and `null` is returned instead of a new
/// completer.
/// completer.
ImageStreamCompleter
?
putIfAbsent
(
Object
key
,
ImageStreamCompleter
loader
(),
{
ImageErrorListener
?
onError
})
{
ImageStreamCompleter
putIfAbsent
(
Object
key
,
ImageStreamCompleter
loader
(),
{
ImageErrorListener
onError
})
{
assert
(
key
!=
null
);
assert
(
key
!=
null
);
assert
(
loader
!=
null
);
assert
(
loader
!=
null
);
TimelineTask
?
timelineTask
;
TimelineTask
timelineTask
;
TimelineTask
?
listenerTask
;
TimelineTask
listenerTask
;
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
timelineTask
=
TimelineTask
()..
start
(
timelineTask
=
TimelineTask
()..
start
(
'ImageCache.putIfAbsent'
,
'ImageCache.putIfAbsent'
,
...
@@ -322,11 +323,11 @@ class ImageCache {
...
@@ -322,11 +323,11 @@ class ImageCache {
},
},
);
);
}
}
ImageStreamCompleter
?
result
=
_pendingImages
[
key
]?.
completer
;
ImageStreamCompleter
result
=
_pendingImages
[
key
]?.
completer
;
// Nothing needs to be done because the image hasn't loaded yet.
// Nothing needs to be done because the image hasn't loaded yet.
if
(
result
!=
null
)
{
if
(
result
!=
null
)
{
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
timelineTask
!
.
finish
(
arguments:
<
String
,
dynamic
>{
'result'
:
'pending'
});
timelineTask
.
finish
(
arguments:
<
String
,
dynamic
>{
'result'
:
'pending'
});
}
}
return
result
;
return
result
;
}
}
...
@@ -334,10 +335,10 @@ class ImageCache {
...
@@ -334,10 +335,10 @@ class ImageCache {
// recently used position below.
// recently used position below.
// Don't use _touch here, which would trigger a check on cache size that is
// Don't use _touch here, which would trigger a check on cache size that is
// not needed since this is just moving an existing cache entry to the head.
// not needed since this is just moving an existing cache entry to the head.
final
_CachedImage
?
image
=
_cache
.
remove
(
key
);
final
_CachedImage
image
=
_cache
.
remove
(
key
);
if
(
image
!=
null
)
{
if
(
image
!=
null
)
{
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
timelineTask
!
.
finish
(
arguments:
<
String
,
dynamic
>{
'result'
:
'keepAlive'
});
timelineTask
.
finish
(
arguments:
<
String
,
dynamic
>{
'result'
:
'keepAlive'
});
}
}
// The image might have been keptAlive but had no listeners (so not live).
// The image might have been keptAlive but had no listeners (so not live).
// Make sure the cache starts tracking it as live again.
// Make sure the cache starts tracking it as live again.
...
@@ -346,11 +347,11 @@ class ImageCache {
...
@@ -346,11 +347,11 @@ class ImageCache {
return
image
.
completer
;
return
image
.
completer
;
}
}
final
_CachedImage
?
liveImage
=
_liveImages
[
key
];
final
_CachedImage
liveImage
=
_liveImages
[
key
];
if
(
liveImage
!=
null
)
{
if
(
liveImage
!=
null
)
{
_touch
(
key
,
liveImage
,
timelineTask
);
_touch
(
key
,
liveImage
,
timelineTask
);
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
timelineTask
!
.
finish
(
arguments:
<
String
,
dynamic
>{
'result'
:
'keepAlive'
});
timelineTask
.
finish
(
arguments:
<
String
,
dynamic
>{
'result'
:
'keepAlive'
});
}
}
return
liveImage
.
completer
;
return
liveImage
.
completer
;
}
}
...
@@ -360,7 +361,7 @@ class ImageCache {
...
@@ -360,7 +361,7 @@ class ImageCache {
_trackLiveImage
(
key
,
_LiveImage
(
result
,
null
,
()
=>
_liveImages
.
remove
(
key
)));
_trackLiveImage
(
key
,
_LiveImage
(
result
,
null
,
()
=>
_liveImages
.
remove
(
key
)));
}
catch
(
error
,
stackTrace
)
{
}
catch
(
error
,
stackTrace
)
{
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
timelineTask
!
.
finish
(
arguments:
<
String
,
dynamic
>{
timelineTask
.
finish
(
arguments:
<
String
,
dynamic
>{
'result'
:
'error'
,
'result'
:
'error'
,
'error'
:
error
.
toString
(),
'error'
:
error
.
toString
(),
'stackTrace'
:
stackTrace
.
toString
(),
'stackTrace'
:
stackTrace
.
toString
(),
...
@@ -386,12 +387,12 @@ class ImageCache {
...
@@ -386,12 +387,12 @@ class ImageCache {
// will have to listen to the image at least once so we don't leak it in
// will have to listen to the image at least once so we don't leak it in
// the live image tracking.
// the live image tracking.
// If the cache is disabled, this variable will be set.
// If the cache is disabled, this variable will be set.
_PendingImage
?
untrackedPendingImage
;
_PendingImage
untrackedPendingImage
;
void
listener
(
ImageInfo
?
info
,
bool
syncCall
)
{
void
listener
(
ImageInfo
info
,
bool
syncCall
)
{
// Images that fail to load don't contribute to cache size.
// Images that fail to load don't contribute to cache size.
final
int
imageSize
=
info
==
null
||
info
.
image
==
null
?
0
:
info
.
image
.
height
*
info
.
image
.
width
*
4
;
final
int
imageSize
=
info
?
.
image
==
null
?
0
:
info
.
image
.
height
*
info
.
image
.
width
*
4
;
final
_CachedImage
image
=
_CachedImage
(
result
!
,
imageSize
);
final
_CachedImage
image
=
_CachedImage
(
result
,
imageSize
);
_trackLiveImage
(
_trackLiveImage
(
key
,
key
,
...
@@ -402,7 +403,7 @@ class ImageCache {
...
@@ -402,7 +403,7 @@ class ImageCache {
),
),
);
);
final
_PendingImage
?
pendingImage
=
untrackedPendingImage
??
_pendingImages
.
remove
(
key
);
final
_PendingImage
pendingImage
=
untrackedPendingImage
??
_pendingImages
.
remove
(
key
);
if
(
pendingImage
!=
null
)
{
if
(
pendingImage
!=
null
)
{
pendingImage
.
removeListener
();
pendingImage
.
removeListener
();
}
}
...
@@ -412,11 +413,11 @@ class ImageCache {
...
@@ -412,11 +413,11 @@ class ImageCache {
}
}
if
(!
kReleaseMode
&&
!
listenedOnce
)
{
if
(!
kReleaseMode
&&
!
listenedOnce
)
{
listenerTask
!
.
finish
(
arguments:
<
String
,
dynamic
>{
listenerTask
.
finish
(
arguments:
<
String
,
dynamic
>{
'syncCall'
:
syncCall
,
'syncCall'
:
syncCall
,
'sizeInBytes'
:
imageSize
,
'sizeInBytes'
:
imageSize
,
});
});
timelineTask
!
.
finish
(
arguments:
<
String
,
dynamic
>{
timelineTask
.
finish
(
arguments:
<
String
,
dynamic
>{
'currentSizeBytes'
:
currentSizeBytes
,
'currentSizeBytes'
:
currentSizeBytes
,
'currentSize'
:
currentSize
,
'currentSize'
:
currentSize
,
});
});
...
@@ -480,9 +481,9 @@ class ImageCache {
...
@@ -480,9 +481,9 @@ class ImageCache {
// Remove images from the cache until both the length and bytes are below
// Remove images from the cache until both the length and bytes are below
// maximum, or the cache is empty.
// maximum, or the cache is empty.
void
_checkCacheSize
(
TimelineTask
?
timelineTask
)
{
void
_checkCacheSize
(
TimelineTask
timelineTask
)
{
final
Map
<
String
,
dynamic
>
finishArgs
=
<
String
,
dynamic
>{};
final
Map
<
String
,
dynamic
>
finishArgs
=
<
String
,
dynamic
>{};
TimelineTask
?
checkCacheTask
;
TimelineTask
checkCacheTask
;
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
checkCacheTask
=
TimelineTask
(
parent:
timelineTask
)..
start
(
'checkCacheSize'
);
checkCacheTask
=
TimelineTask
(
parent:
timelineTask
)..
start
(
'checkCacheSize'
);
finishArgs
[
'evictedKeys'
]
=
<
String
>[];
finishArgs
[
'evictedKeys'
]
=
<
String
>[];
...
@@ -491,8 +492,8 @@ class ImageCache {
...
@@ -491,8 +492,8 @@ class ImageCache {
}
}
while
(
_currentSizeBytes
>
_maximumSizeBytes
||
_cache
.
length
>
_maximumSize
)
{
while
(
_currentSizeBytes
>
_maximumSizeBytes
||
_cache
.
length
>
_maximumSize
)
{
final
Object
key
=
_cache
.
keys
.
first
;
final
Object
key
=
_cache
.
keys
.
first
;
final
_CachedImage
image
=
_cache
[
key
]
!
;
final
_CachedImage
image
=
_cache
[
key
];
_currentSizeBytes
-=
image
.
sizeBytes
!
;
_currentSizeBytes
-=
image
.
sizeBytes
;
_cache
.
remove
(
key
);
_cache
.
remove
(
key
);
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
finishArgs
[
'evictedKeys'
].
add
(
key
.
toString
());
finishArgs
[
'evictedKeys'
].
add
(
key
.
toString
());
...
@@ -501,7 +502,7 @@ class ImageCache {
...
@@ -501,7 +502,7 @@ class ImageCache {
if
(!
kReleaseMode
)
{
if
(!
kReleaseMode
)
{
finishArgs
[
'endSize'
]
=
currentSize
;
finishArgs
[
'endSize'
]
=
currentSize
;
finishArgs
[
'endSizeBytes'
]
=
currentSizeBytes
;
finishArgs
[
'endSizeBytes'
]
=
currentSizeBytes
;
checkCacheTask
!
.
finish
(
arguments:
finishArgs
);
checkCacheTask
.
finish
(
arguments:
finishArgs
);
}
}
assert
(
_currentSizeBytes
>=
0
);
assert
(
_currentSizeBytes
>=
0
);
assert
(
_cache
.
length
<=
maximumSize
);
assert
(
_cache
.
length
<=
maximumSize
);
...
@@ -584,11 +585,11 @@ class _CachedImage {
...
@@ -584,11 +585,11 @@ class _CachedImage {
_CachedImage
(
this
.
completer
,
this
.
sizeBytes
);
_CachedImage
(
this
.
completer
,
this
.
sizeBytes
);
final
ImageStreamCompleter
completer
;
final
ImageStreamCompleter
completer
;
int
?
sizeBytes
;
int
sizeBytes
;
}
}
class
_LiveImage
extends
_CachedImage
{
class
_LiveImage
extends
_CachedImage
{
_LiveImage
(
ImageStreamCompleter
completer
,
int
?
sizeBytes
,
this
.
handleRemove
)
_LiveImage
(
ImageStreamCompleter
completer
,
int
sizeBytes
,
this
.
handleRemove
)
:
super
(
completer
,
sizeBytes
);
:
super
(
completer
,
sizeBytes
);
final
VoidCallback
handleRemove
;
final
VoidCallback
handleRemove
;
...
...
packages/flutter/lib/src/painting/image_stream.dart
View file @
4c7fae93
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
// @dart = 2.8
import
'dart:async'
;
import
'dart:async'
;
import
'dart:ui'
as
ui
show
Image
,
Codec
,
FrameInfo
;
import
'dart:ui'
as
ui
show
Image
,
Codec
,
FrameInfo
;
...
@@ -21,7 +22,7 @@ class ImageInfo {
...
@@ -21,7 +22,7 @@ class ImageInfo {
/// Both the image and the scale must not be null.
/// Both the image and the scale must not be null.
///
///
/// The tag may be used to identify the source of this image.
/// The tag may be used to identify the source of this image.
const
ImageInfo
({
required
this
.
image
,
this
.
scale
=
1.0
,
this
.
debugLabel
})
const
ImageInfo
({
@
required
this
.
image
,
this
.
scale
=
1.0
,
this
.
debugLabel
})
:
assert
(
image
!=
null
),
:
assert
(
image
!=
null
),
assert
(
scale
!=
null
);
assert
(
scale
!=
null
);
...
@@ -44,7 +45,7 @@ class ImageInfo {
...
@@ -44,7 +45,7 @@ class ImageInfo {
final
double
scale
;
final
double
scale
;
/// A string used for debugging purpopses to identify the source of this image.
/// A string used for debugging purpopses to identify the source of this image.
final
String
?
debugLabel
;
final
String
debugLabel
;
@override
@override
String
toString
()
=>
'
${debugLabel != null ? '$debugLabel ' : ''}$image
@
${debugFormatDouble(scale)}
x'
;
String
toString
()
=>
'
${debugLabel != null ? '$debugLabel ' : ''}$image
@
${debugFormatDouble(scale)}
x'
;
...
@@ -111,13 +112,13 @@ class ImageStreamListener {
...
@@ -111,13 +112,13 @@ class ImageStreamListener {
/// This callback may also continue to fire after the [onImage] callback has
/// This callback may also continue to fire after the [onImage] callback has
/// fired (e.g. for multi-frame images that continue to load after the first
/// fired (e.g. for multi-frame images that continue to load after the first
/// frame is available).
/// frame is available).
final
ImageChunkListener
?
onChunk
;
final
ImageChunkListener
onChunk
;
/// Callback for getting notified when an error occurs while loading an image.
/// Callback for getting notified when an error occurs while loading an image.
///
///
/// If an error occurs during loading, [onError] will be called instead of
/// If an error occurs during loading, [onError] will be called instead of
/// [onImage].
/// [onImage].
final
ImageErrorListener
?
onError
;
final
ImageErrorListener
onError
;
@override
@override
int
get
hashCode
=>
hashValues
(
onImage
,
onChunk
,
onError
);
int
get
hashCode
=>
hashValues
(
onImage
,
onChunk
,
onError
);
...
@@ -154,7 +155,7 @@ typedef ImageChunkListener = void Function(ImageChunkEvent event);
...
@@ -154,7 +155,7 @@ typedef ImageChunkListener = void Function(ImageChunkEvent event);
///
///
/// Used in [ImageStreamListener], as well as by [ImageCache.putIfAbsent] and
/// Used in [ImageStreamListener], as well as by [ImageCache.putIfAbsent] and
/// [precacheImage], to report errors.
/// [precacheImage], to report errors.
typedef
ImageErrorListener
=
void
Function
(
dynamic
exception
,
StackTrace
?
stackTrace
);
typedef
ImageErrorListener
=
void
Function
(
dynamic
exception
,
StackTrace
stackTrace
);
/// An immutable notification of image bytes that have been incrementally loaded.
/// An immutable notification of image bytes that have been incrementally loaded.
///
///
...
@@ -169,8 +170,8 @@ typedef ImageErrorListener = void Function(dynamic exception, StackTrace? stackT
...
@@ -169,8 +170,8 @@ typedef ImageErrorListener = void Function(dynamic exception, StackTrace? stackT
class
ImageChunkEvent
with
Diagnosticable
{
class
ImageChunkEvent
with
Diagnosticable
{
/// Creates a new chunk event.
/// Creates a new chunk event.
const
ImageChunkEvent
({
const
ImageChunkEvent
({
required
this
.
cumulativeBytesLoaded
,
@
required
this
.
cumulativeBytesLoaded
,
required
this
.
expectedTotalBytes
,
@
required
this
.
expectedTotalBytes
,
})
:
assert
(
cumulativeBytesLoaded
>=
0
),
})
:
assert
(
cumulativeBytesLoaded
>=
0
),
assert
(
expectedTotalBytes
==
null
||
expectedTotalBytes
>=
0
);
assert
(
expectedTotalBytes
==
null
||
expectedTotalBytes
>=
0
);
...
@@ -188,7 +189,7 @@ class ImageChunkEvent with Diagnosticable {
...
@@ -188,7 +189,7 @@ class ImageChunkEvent with Diagnosticable {
/// When this value is null, the chunk event may still be useful as an
/// When this value is null, the chunk event may still be useful as an
/// indication that data is loading (and how much), but it cannot represent a
/// indication that data is loading (and how much), but it cannot represent a
/// loading completion percentage.
/// loading completion percentage.
final
int
?
expectedTotalBytes
;
final
int
expectedTotalBytes
;
@override
@override
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
...
@@ -228,10 +229,10 @@ class ImageStream with Diagnosticable {
...
@@ -228,10 +229,10 @@ class ImageStream with Diagnosticable {
/// The completer that has been assigned to this image stream.
/// The completer that has been assigned to this image stream.
///
///
/// Generally there is no need to deal with the completer directly.
/// Generally there is no need to deal with the completer directly.
ImageStreamCompleter
?
get
completer
=>
_completer
;
ImageStreamCompleter
get
completer
=>
_completer
;
ImageStreamCompleter
?
_completer
;
ImageStreamCompleter
_completer
;
List
<
ImageStreamListener
>
?
_listeners
;
List
<
ImageStreamListener
>
_listeners
;
/// Assigns a particular [ImageStreamCompleter] to this [ImageStream].
/// Assigns a particular [ImageStreamCompleter] to this [ImageStream].
///
///
...
@@ -245,9 +246,9 @@ class ImageStream with Diagnosticable {
...
@@ -245,9 +246,9 @@ class ImageStream with Diagnosticable {
assert
(
_completer
==
null
);
assert
(
_completer
==
null
);
_completer
=
value
;
_completer
=
value
;
if
(
_listeners
!=
null
)
{
if
(
_listeners
!=
null
)
{
final
List
<
ImageStreamListener
>
initialListeners
=
_listeners
!
;
final
List
<
ImageStreamListener
>
initialListeners
=
_listeners
;
_listeners
=
null
;
_listeners
=
null
;
initialListeners
.
forEach
(
_completer
!
.
addListener
);
initialListeners
.
forEach
(
_completer
.
addListener
);
}
}
}
}
...
@@ -271,9 +272,9 @@ class ImageStream with Diagnosticable {
...
@@ -271,9 +272,9 @@ class ImageStream with Diagnosticable {
/// {@endtemplate}
/// {@endtemplate}
void
addListener
(
ImageStreamListener
listener
)
{
void
addListener
(
ImageStreamListener
listener
)
{
if
(
_completer
!=
null
)
if
(
_completer
!=
null
)
return
_completer
!
.
addListener
(
listener
);
return
_completer
.
addListener
(
listener
);
_listeners
??=
<
ImageStreamListener
>[];
_listeners
??=
<
ImageStreamListener
>[];
_listeners
!
.
add
(
listener
);
_listeners
.
add
(
listener
);
}
}
/// Stops listening for events from this stream's [ImageStreamCompleter].
/// Stops listening for events from this stream's [ImageStreamCompleter].
...
@@ -282,11 +283,11 @@ class ImageStream with Diagnosticable {
...
@@ -282,11 +283,11 @@ class ImageStream with Diagnosticable {
/// instance of the listener.
/// instance of the listener.
void
removeListener
(
ImageStreamListener
listener
)
{
void
removeListener
(
ImageStreamListener
listener
)
{
if
(
_completer
!=
null
)
if
(
_completer
!=
null
)
return
_completer
!
.
removeListener
(
listener
);
return
_completer
.
removeListener
(
listener
);
assert
(
_listeners
!=
null
);
assert
(
_listeners
!=
null
);
for
(
int
i
=
0
;
i
<
_listeners
!
.
length
;
i
+=
1
)
{
for
(
int
i
=
0
;
i
<
_listeners
.
length
;
i
+=
1
)
{
if
(
_listeners
!
[
i
]
==
listener
)
{
if
(
_listeners
[
i
]
==
listener
)
{
_listeners
!
.
removeAt
(
i
);
_listeners
.
removeAt
(
i
);
break
;
break
;
}
}
}
}
...
@@ -333,11 +334,11 @@ class ImageStream with Diagnosticable {
...
@@ -333,11 +334,11 @@ class ImageStream with Diagnosticable {
/// configure it with the right [ImageStreamCompleter] when possible.
/// configure it with the right [ImageStreamCompleter] when possible.
abstract
class
ImageStreamCompleter
with
Diagnosticable
{
abstract
class
ImageStreamCompleter
with
Diagnosticable
{
final
List
<
ImageStreamListener
>
_listeners
=
<
ImageStreamListener
>[];
final
List
<
ImageStreamListener
>
_listeners
=
<
ImageStreamListener
>[];
ImageInfo
?
_currentImage
;
ImageInfo
_currentImage
;
FlutterErrorDetails
?
_currentError
;
FlutterErrorDetails
_currentError
;
/// A string identifying the source of the underlying image.
/// A string identifying the source of the underlying image.
String
?
debugLabel
;
String
debugLabel
;
/// Whether any listeners are currently registered.
/// Whether any listeners are currently registered.
///
///
...
@@ -371,7 +372,7 @@ abstract class ImageStreamCompleter with Diagnosticable {
...
@@ -371,7 +372,7 @@ abstract class ImageStreamCompleter with Diagnosticable {
_listeners
.
add
(
listener
);
_listeners
.
add
(
listener
);
if
(
_currentImage
!=
null
)
{
if
(
_currentImage
!=
null
)
{
try
{
try
{
listener
.
onImage
(
_currentImage
!
,
true
);
listener
.
onImage
(
_currentImage
,
true
);
}
catch
(
exception
,
stack
)
{
}
catch
(
exception
,
stack
)
{
reportError
(
reportError
(
context:
ErrorDescription
(
'by a synchronously-called image listener'
),
context:
ErrorDescription
(
'by a synchronously-called image listener'
),
...
@@ -382,7 +383,7 @@ abstract class ImageStreamCompleter with Diagnosticable {
...
@@ -382,7 +383,7 @@ abstract class ImageStreamCompleter with Diagnosticable {
}
}
if
(
_currentError
!=
null
&&
listener
.
onError
!=
null
)
{
if
(
_currentError
!=
null
&&
listener
.
onError
!=
null
)
{
try
{
try
{
listener
.
onError
!(
_currentError
!.
exception
,
_currentError
!
.
stack
);
listener
.
onError
(
_currentError
.
exception
,
_currentError
.
stack
);
}
catch
(
exception
,
stack
)
{
}
catch
(
exception
,
stack
)
{
FlutterError
.
reportError
(
FlutterError
.
reportError
(
FlutterErrorDetails
(
FlutterErrorDetails
(
...
@@ -485,10 +486,10 @@ abstract class ImageStreamCompleter with Diagnosticable {
...
@@ -485,10 +486,10 @@ abstract class ImageStreamCompleter with Diagnosticable {
/// See [FlutterErrorDetails] for further details on these values.
/// See [FlutterErrorDetails] for further details on these values.
@protected
@protected
void
reportError
({
void
reportError
({
DiagnosticsNode
?
context
,
DiagnosticsNode
context
,
dynamic
exception
,
dynamic
exception
,
StackTrace
?
stack
,
StackTrace
stack
,
InformationCollector
?
informationCollector
,
InformationCollector
informationCollector
,
bool
silent
=
false
,
bool
silent
=
false
,
})
{
})
{
_currentError
=
FlutterErrorDetails
(
_currentError
=
FlutterErrorDetails
(
...
@@ -502,12 +503,12 @@ abstract class ImageStreamCompleter with Diagnosticable {
...
@@ -502,12 +503,12 @@ abstract class ImageStreamCompleter with Diagnosticable {
// Make a copy to allow for concurrent modification.
// Make a copy to allow for concurrent modification.
final
List
<
ImageErrorListener
>
localErrorListeners
=
_listeners
final
List
<
ImageErrorListener
>
localErrorListeners
=
_listeners
.
map
<
ImageErrorListener
?
>((
ImageStreamListener
listener
)
=>
listener
.
onError
)
.
map
<
ImageErrorListener
>((
ImageStreamListener
listener
)
=>
listener
.
onError
)
.
where
Type
<
ImageErrorListener
>(
)
.
where
((
ImageErrorListener
errorListener
)
=>
errorListener
!=
null
)
.
toList
();
.
toList
();
if
(
localErrorListeners
.
isEmpty
)
{
if
(
localErrorListeners
.
isEmpty
)
{
FlutterError
.
reportError
(
_currentError
!
);
FlutterError
.
reportError
(
_currentError
);
}
else
{
}
else
{
for
(
final
ImageErrorListener
errorListener
in
localErrorListeners
)
{
for
(
final
ImageErrorListener
errorListener
in
localErrorListeners
)
{
try
{
try
{
...
@@ -534,8 +535,8 @@ abstract class ImageStreamCompleter with Diagnosticable {
...
@@ -534,8 +535,8 @@ abstract class ImageStreamCompleter with Diagnosticable {
if
(
hasListeners
)
{
if
(
hasListeners
)
{
// Make a copy to allow for concurrent modification.
// Make a copy to allow for concurrent modification.
final
List
<
ImageChunkListener
>
localListeners
=
_listeners
final
List
<
ImageChunkListener
>
localListeners
=
_listeners
.
map
<
ImageChunkListener
?
>((
ImageStreamListener
listener
)
=>
listener
.
onChunk
)
.
map
<
ImageChunkListener
>((
ImageStreamListener
listener
)
=>
listener
.
onChunk
)
.
where
Type
<
ImageChunkListener
>(
)
.
where
((
ImageChunkListener
chunkListener
)
=>
chunkListener
!=
null
)
.
toList
();
.
toList
();
for
(
final
ImageChunkListener
listener
in
localListeners
)
{
for
(
final
ImageChunkListener
listener
in
localListeners
)
{
listener
(
event
);
listener
(
event
);
...
@@ -552,7 +553,7 @@ abstract class ImageStreamCompleter with Diagnosticable {
...
@@ -552,7 +553,7 @@ abstract class ImageStreamCompleter with Diagnosticable {
description
.
add
(
ObjectFlagProperty
<
List
<
ImageStreamListener
>>(
description
.
add
(
ObjectFlagProperty
<
List
<
ImageStreamListener
>>(
'listeners'
,
'listeners'
,
_listeners
,
_listeners
,
ifPresent:
'
${_listeners
.length}
listener
${_listeners
.length == 1 ? "" : "s" }
'
,
ifPresent:
'
${_listeners
?.length}
listener
${_listeners?
.length == 1 ? "" : "s" }
'
,
));
));
}
}
}
}
...
@@ -574,7 +575,7 @@ class OneFrameImageStreamCompleter extends ImageStreamCompleter {
...
@@ -574,7 +575,7 @@ class OneFrameImageStreamCompleter extends ImageStreamCompleter {
/// argument on [FlutterErrorDetails] set to true, meaning that by default the
/// argument on [FlutterErrorDetails] set to true, meaning that by default the
/// message is only dumped to the console in debug mode (see [new
/// message is only dumped to the console in debug mode (see [new
/// FlutterErrorDetails]).
/// FlutterErrorDetails]).
OneFrameImageStreamCompleter
(
Future
<
ImageInfo
>
image
,
{
InformationCollector
?
informationCollector
})
OneFrameImageStreamCompleter
(
Future
<
ImageInfo
>
image
,
{
InformationCollector
informationCollector
})
:
assert
(
image
!=
null
)
{
:
assert
(
image
!=
null
)
{
image
.
then
<
void
>(
setImage
,
onError:
(
dynamic
error
,
StackTrace
stack
)
{
image
.
then
<
void
>(
setImage
,
onError:
(
dynamic
error
,
StackTrace
stack
)
{
reportError
(
reportError
(
...
@@ -639,11 +640,11 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
...
@@ -639,11 +640,11 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
/// produced by the stream will be delivered to registered [ImageChunkListener]s
/// produced by the stream will be delivered to registered [ImageChunkListener]s
/// (see [addListener]).
/// (see [addListener]).
MultiFrameImageStreamCompleter
({
MultiFrameImageStreamCompleter
({
required
Future
<
ui
.
Codec
>
codec
,
@
required
Future
<
ui
.
Codec
>
codec
,
required
double
scale
,
@
required
double
scale
,
String
?
debugLabel
,
String
debugLabel
,
Stream
<
ImageChunkEvent
>
?
chunkEvents
,
Stream
<
ImageChunkEvent
>
chunkEvents
,
InformationCollector
?
informationCollector
,
InformationCollector
informationCollector
,
})
:
assert
(
codec
!=
null
),
})
:
assert
(
codec
!=
null
),
_informationCollector
=
informationCollector
,
_informationCollector
=
informationCollector
,
_scale
=
scale
{
_scale
=
scale
{
...
@@ -672,17 +673,17 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
...
@@ -672,17 +673,17 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
}
}
}
}
ui
.
Codec
?
_codec
;
ui
.
Codec
_codec
;
final
double
_scale
;
final
double
_scale
;
final
InformationCollector
?
_informationCollector
;
final
InformationCollector
_informationCollector
;
ui
.
FrameInfo
?
_nextFrame
;
ui
.
FrameInfo
_nextFrame
;
// When the current was first shown.
// When the current was first shown.
late
Duration
_shownTimestamp
;
Duration
_shownTimestamp
;
// The requested duration for the current frame;
// The requested duration for the current frame;
Duration
?
_frameDuration
;
Duration
_frameDuration
;
// How many frames have been emitted so far.
// How many frames have been emitted so far.
int
_framesEmitted
=
0
;
int
_framesEmitted
=
0
;
Timer
?
_timer
;
Timer
_timer
;
// Used to guard against registering multiple _handleAppFrame callbacks for the same frame.
// Used to guard against registering multiple _handleAppFrame callbacks for the same frame.
bool
_frameCallbackScheduled
=
false
;
bool
_frameCallbackScheduled
=
false
;
...
@@ -701,17 +702,17 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
...
@@ -701,17 +702,17 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
if
(!
hasListeners
)
if
(!
hasListeners
)
return
;
return
;
if
(
_isFirstFrame
()
||
_hasFrameDurationPassed
(
timestamp
))
{
if
(
_isFirstFrame
()
||
_hasFrameDurationPassed
(
timestamp
))
{
_emitFrame
(
ImageInfo
(
image:
_nextFrame
!
.
image
,
scale:
_scale
,
debugLabel:
debugLabel
));
_emitFrame
(
ImageInfo
(
image:
_nextFrame
.
image
,
scale:
_scale
,
debugLabel:
debugLabel
));
_shownTimestamp
=
timestamp
;
_shownTimestamp
=
timestamp
;
_frameDuration
=
_nextFrame
!
.
duration
;
_frameDuration
=
_nextFrame
.
duration
;
_nextFrame
=
null
;
_nextFrame
=
null
;
final
int
completedCycles
=
_framesEmitted
~/
_codec
!
.
frameCount
;
final
int
completedCycles
=
_framesEmitted
~/
_codec
.
frameCount
;
if
(
_codec
!.
repetitionCount
==
-
1
||
completedCycles
<=
_codec
!
.
repetitionCount
)
{
if
(
_codec
.
repetitionCount
==
-
1
||
completedCycles
<=
_codec
.
repetitionCount
)
{
_decodeNextFrameAndSchedule
();
_decodeNextFrameAndSchedule
();
}
}
return
;
return
;
}
}
final
Duration
delay
=
_frameDuration
!
-
(
timestamp
-
_shownTimestamp
);
final
Duration
delay
=
_frameDuration
-
(
timestamp
-
_shownTimestamp
);
_timer
=
Timer
(
delay
*
timeDilation
,
()
{
_timer
=
Timer
(
delay
*
timeDilation
,
()
{
_scheduleAppFrame
();
_scheduleAppFrame
();
});
});
...
@@ -722,12 +723,13 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
...
@@ -722,12 +723,13 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
}
}
bool
_hasFrameDurationPassed
(
Duration
timestamp
)
{
bool
_hasFrameDurationPassed
(
Duration
timestamp
)
{
return
timestamp
-
_shownTimestamp
>=
_frameDuration
!;
assert
(
_shownTimestamp
!=
null
);
return
timestamp
-
_shownTimestamp
>=
_frameDuration
;
}
}
Future
<
void
>
_decodeNextFrameAndSchedule
()
async
{
Future
<
void
>
_decodeNextFrameAndSchedule
()
async
{
try
{
try
{
_nextFrame
=
await
_codec
!
.
getNextFrame
();
_nextFrame
=
await
_codec
.
getNextFrame
();
}
catch
(
exception
,
stack
)
{
}
catch
(
exception
,
stack
)
{
reportError
(
reportError
(
context:
ErrorDescription
(
'resolving an image frame'
),
context:
ErrorDescription
(
'resolving an image frame'
),
...
@@ -738,10 +740,10 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
...
@@ -738,10 +740,10 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
);
);
return
;
return
;
}
}
if
(
_codec
!
.
frameCount
==
1
)
{
if
(
_codec
.
frameCount
==
1
)
{
// This is not an animated image, just return it and don't schedule more
// This is not an animated image, just return it and don't schedule more
// frames.
// frames.
_emitFrame
(
ImageInfo
(
image:
_nextFrame
!
.
image
,
scale:
_scale
,
debugLabel:
debugLabel
));
_emitFrame
(
ImageInfo
(
image:
_nextFrame
.
image
,
scale:
_scale
,
debugLabel:
debugLabel
));
return
;
return
;
}
}
_scheduleAppFrame
();
_scheduleAppFrame
();
...
@@ -752,7 +754,7 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
...
@@ -752,7 +754,7 @@ class MultiFrameImageStreamCompleter extends ImageStreamCompleter {
return
;
return
;
}
}
_frameCallbackScheduled
=
true
;
_frameCallbackScheduled
=
true
;
SchedulerBinding
.
instance
!
.
scheduleFrameCallback
(
_handleAppFrame
);
SchedulerBinding
.
instance
.
scheduleFrameCallback
(
_handleAppFrame
);
}
}
void
_emitFrame
(
ImageInfo
imageInfo
)
{
void
_emitFrame
(
ImageInfo
imageInfo
)
{
...
...
packages/flutter/lib/src/painting/shader_warm_up.dart
View file @
4c7fae93
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// found in the LICENSE file.
// @dart = 2.8
import
'dart:async'
;
import
'dart:async'
;
import
'dart:developer'
;
import
'dart:developer'
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment