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
32c2e2ba
Unverified
Commit
32c2e2ba
authored
Jul 27, 2021
by
Dan Field
Committed by
GitHub
Jul 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Perform no shader warm-up by default (#87126)
parent
05e84254
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
20 additions
and
265 deletions
+20
-265
image_cache_tracing_test.dart
dev/tracing_tests/test/image_cache_tracing_test.dart
+1
-1
shader_warm_up.dart
examples/layers/raw/shader_warm_up.dart
+0
-35
shader_warm_up_test.dart
examples/layers/test/smoketests/raw/shader_warm_up_test.dart
+0
-14
binding.dart
packages/flutter/lib/src/painting/binding.dart
+10
-10
shader_warm_up.dart
packages/flutter/lib/src/painting/shader_warm_up.dart
+5
-144
binding_test.dart
packages/flutter/test/painting/binding_test.dart
+4
-0
shader_warm_up_test.dart
packages/flutter/test/painting/shader_warm_up_test.dart
+0
-61
No files found.
dev/tracing_tests/test/image_cache_tracing_test.dart
View file @
32c2e2ba
...
@@ -55,7 +55,7 @@ void main() {
...
@@ -55,7 +55,7 @@ void main() {
},
},
<
String
,
dynamic
>{
<
String
,
dynamic
>{
'name'
:
'listener'
,
'name'
:
'listener'
,
'args'
:
<
String
,
dynamic
>{
'parentId'
:
'
1
'
,
'isolateId'
:
isolateId
}
'args'
:
<
String
,
dynamic
>{
'parentId'
:
'
0
'
,
'isolateId'
:
isolateId
}
},
},
<
String
,
dynamic
>{
<
String
,
dynamic
>{
'name'
:
'ImageCache.clear'
,
'name'
:
'ImageCache.clear'
,
...
...
examples/layers/raw/shader_warm_up.dart
deleted
100644 → 0
View file @
05e84254
// 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.
// This example shows the draw operations to warm up the GPU shaders by default.
import
'dart:ui'
as
ui
;
import
'package:flutter/material.dart'
;
Future
<
void
>
beginFrame
(
Duration
timeStamp
)
async
{
// PAINT
final
ui
.
PictureRecorder
recorder
=
ui
.
PictureRecorder
();
const
ui
.
Rect
paintBounds
=
ui
.
Rect
.
fromLTRB
(
0
,
0
,
1000
,
1000
);
final
ui
.
Canvas
canvas
=
ui
.
Canvas
(
recorder
,
paintBounds
);
final
ui
.
Paint
backgroundPaint
=
ui
.
Paint
()..
color
=
Colors
.
white
;
canvas
.
drawRect
(
paintBounds
,
backgroundPaint
);
await
const
DefaultShaderWarmUp
(
drawCallSpacing:
80.0
,
canvasSize:
ui
.
Size
(
1024
,
1024
),
).
warmUpOnCanvas
(
canvas
);
final
ui
.
Picture
picture
=
recorder
.
endRecording
();
// COMPOSITE
final
ui
.
SceneBuilder
sceneBuilder
=
ui
.
SceneBuilder
()
..
pushClipRect
(
paintBounds
)
..
addPicture
(
ui
.
Offset
.
zero
,
picture
)
..
pop
();
ui
.
window
.
render
(
sceneBuilder
.
build
());
}
Future
<
void
>
main
()
async
{
ui
.
window
.
onBeginFrame
=
beginFrame
;
ui
.
window
.
scheduleFrame
();
}
examples/layers/test/smoketests/raw/shader_warm_up_test.dart
deleted
100644 → 0
View file @
05e84254
// 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.
// ignore: deprecated_member_use
import
'package:test_api/test_api.dart'
hide
TypeMatcher
,
isInstanceOf
;
import
'../../../raw/shader_warm_up.dart'
as
demo
;
void
main
(
)
{
test
(
'layers smoketest for raw/shader_warm_up.dart'
,
()
{
demo
.
main
();
});
}
packages/flutter/lib/src/painting/binding.dart
View file @
32c2e2ba
...
@@ -31,17 +31,17 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
...
@@ -31,17 +31,17 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
/// [ShaderWarmUp] instance to be executed during [initInstances].
/// [ShaderWarmUp] instance to be executed during [initInstances].
///
///
/// Defaults to an instance of [DefaultShaderWarmUp].
/// Defaults to `null`, meaning no shader warm-up is done. Some platforms may
/// not support shader warm-up before at least one frame has been displayed.
///
///
/// If the application has scenes that require the compilation of complex
/// If the application has scenes that require the compilation of complex
/// shaders that are not covered by [DefaultShaderWarmUp], it may cause jank
/// shaders, it may cause jank in the middle of an animation or interaction.
/// in the middle of an animation or interaction. In that case, setting
/// In that case, setting [shaderWarmUp] to a custom [ShaderWarmUp] before
/// [shaderWarmUp] to a custom [ShaderWarmUp] before creating the binding
/// creating the binding (usually before [runApp] for normal Flutter apps, and
/// (usually before [runApp] for normal Flutter apps, and before
/// before [enableFlutterDriverExtension] for Flutter driver tests) may help
/// [enableFlutterDriverExtension] for Flutter driver tests) may help if that
/// if that object paints the difficult scene in its
/// object paints the difficult scene in its [ShaderWarmUp.warmUpOnCanvas]
/// [ShaderWarmUp.warmUpOnCanvas] method, as this allows Flutter to
/// method, as this allows Flutter to pre-compile and cache the required
/// pre-compile and cache the required shaders during startup.
/// shaders during startup.
///
///
/// Currently the warm-up happens synchronously on the raster thread which
/// Currently the warm-up happens synchronously on the raster thread which
/// means the rendering of the first frame on the raster thread will be
/// means the rendering of the first frame on the raster thread will be
...
@@ -58,7 +58,7 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
...
@@ -58,7 +58,7 @@ mixin PaintingBinding on BindingBase, ServicesBinding {
///
///
/// * [ShaderWarmUp], the interface for implementing custom warm-up scenes.
/// * [ShaderWarmUp], the interface for implementing custom warm-up scenes.
/// * <https://flutter.dev/docs/perf/rendering/shader>
/// * <https://flutter.dev/docs/perf/rendering/shader>
static
ShaderWarmUp
?
shaderWarmUp
=
const
DefaultShaderWarmUp
()
;
static
ShaderWarmUp
?
shaderWarmUp
;
/// The singleton that implements the Flutter framework's image cache.
/// The singleton that implements the Flutter framework's image cache.
///
///
...
...
packages/flutter/lib/src/painting/shader_warm_up.dart
View file @
32c2e2ba
...
@@ -17,12 +17,11 @@ import 'debug.dart';
...
@@ -17,12 +17,11 @@ import 'debug.dart';
/// jank in the middle of an animation.
/// jank in the middle of an animation.
///
///
/// Therefore, we use this during the [PaintingBinding.initInstances] call to
/// Therefore, we use this during the [PaintingBinding.initInstances] call to
/// move common shader compilations from animation time to startup time. By
/// move common shader compilations from animation time to startup time. If
/// default, a [DefaultShaderWarmUp] is used. If needed, app developers can
/// needed, app developers can create a custom [ShaderWarmUp] subclass and
/// create a custom [ShaderWarmUp] subclass and hand it to
/// hand it to [PaintingBinding.shaderWarmUp] before
/// [PaintingBinding.shaderWarmUp] (so it replaces [DefaultShaderWarmUp])
/// [PaintingBinding.initInstances] is called. Usually, that can be done before
/// before [PaintingBinding.initInstances] is called. Usually, that can be
/// calling [runApp].
/// done before calling [runApp].
///
///
/// To determine whether a draw operation is useful for warming up shaders,
/// To determine whether a draw operation is useful for warming up shaders,
/// check whether it improves the slowest frame rasterization time. Also,
/// check whether it improves the slowest frame rasterization time. Also,
...
@@ -102,141 +101,3 @@ abstract class ShaderWarmUp {
...
@@ -102,141 +101,3 @@ abstract class ShaderWarmUp {
picture
.
dispose
();
picture
.
dispose
();
}
}
}
}
/// Default way of warming up Skia shader compilations.
///
/// The draw operations being warmed up here are decided according to Flutter
/// engineers' observation and experience based on the apps and the performance
/// issues seen so far.
///
/// This is used for the default value of [PaintingBinding.shaderWarmUp].
/// Consider setting that static property to a different value before the
/// binding is initialized to change the warm-up sequence.
///
/// See also:
///
/// * [ShaderWarmUp], the base class for shader warm-up objects.
/// * <https://flutter.dev/docs/perf/rendering/shader>
class
DefaultShaderWarmUp
extends
ShaderWarmUp
{
/// Create an instance of the default shader warm-up logic.
///
/// Since this constructor is `const`, [DefaultShaderWarmUp] can be used as
/// the default value of parameters.
const
DefaultShaderWarmUp
({
this
.
drawCallSpacing
=
0.0
,
this
.
canvasSize
=
const
ui
.
Size
(
100.0
,
100.0
),
});
/// Distance to place between draw calls for visualizing the draws for
/// debugging purposes (e.g. 80.0).
///
/// Defaults to 0.0.
///
/// When changing this value, the [canvasSize] must also be changed to
/// accommodate the bigger canvas.
final
double
drawCallSpacing
;
/// The [size] of the canvas required to paint the shapes in [warmUpOnCanvas].
///
/// When [drawCallSpacing] is 0.0, this should be at least 100.0 by 100.0.
final
ui
.
Size
canvasSize
;
@override
ui
.
Size
get
size
=>
canvasSize
;
/// Trigger common draw operations on a canvas to warm up GPU shader
/// compilation cache.
@override
Future
<
void
>
warmUpOnCanvas
(
ui
.
Canvas
canvas
)
async
{
const
ui
.
RRect
rrect
=
ui
.
RRect
.
fromLTRBXY
(
20.0
,
20.0
,
60.0
,
60.0
,
10.0
,
10.0
);
final
ui
.
Path
rrectPath
=
ui
.
Path
()..
addRRect
(
rrect
);
final
ui
.
Path
circlePath
=
ui
.
Path
()..
addOval
(
ui
.
Rect
.
fromCircle
(
center:
const
ui
.
Offset
(
40.0
,
40.0
),
radius:
20.0
),
);
// The following path is based on
// https://skia.org/user/api/SkCanvas_Reference#SkCanvas_drawPath
final
ui
.
Path
path
=
ui
.
Path
();
path
.
moveTo
(
20.0
,
60.0
);
path
.
quadraticBezierTo
(
60.0
,
20.0
,
60.0
,
60.0
);
path
.
close
();
path
.
moveTo
(
60.0
,
20.0
);
path
.
quadraticBezierTo
(
60.0
,
60.0
,
20.0
,
60.0
);
final
ui
.
Path
convexPath
=
ui
.
Path
();
convexPath
.
moveTo
(
20.0
,
30.0
);
convexPath
.
lineTo
(
40.0
,
20.0
);
convexPath
.
lineTo
(
60.0
,
30.0
);
convexPath
.
lineTo
(
60.0
,
60.0
);
convexPath
.
lineTo
(
20.0
,
60.0
);
convexPath
.
close
();
// Skia uses different shaders based on the kinds of paths being drawn and
// the associated paint configurations. According to our experience and
// tracing, drawing the following paths/paints generates various of
// shaders that are commonly used.
final
List
<
ui
.
Path
>
paths
=
<
ui
.
Path
>[
rrectPath
,
circlePath
,
path
,
convexPath
];
final
List
<
ui
.
Paint
>
paints
=
<
ui
.
Paint
>[
ui
.
Paint
()
..
isAntiAlias
=
true
..
style
=
ui
.
PaintingStyle
.
fill
,
ui
.
Paint
()
..
isAntiAlias
=
false
..
style
=
ui
.
PaintingStyle
.
fill
,
ui
.
Paint
()
..
isAntiAlias
=
true
..
style
=
ui
.
PaintingStyle
.
stroke
..
strokeWidth
=
10
,
ui
.
Paint
()
..
isAntiAlias
=
true
..
style
=
ui
.
PaintingStyle
.
stroke
..
strokeWidth
=
0.1
,
// hairline
];
// Warm up path stroke and fill shaders.
for
(
int
i
=
0
;
i
<
paths
.
length
;
i
+=
1
)
{
canvas
.
save
();
for
(
final
ui
.
Paint
paint
in
paints
)
{
canvas
.
drawPath
(
paths
[
i
],
paint
);
canvas
.
translate
(
drawCallSpacing
,
0.0
);
}
canvas
.
restore
();
canvas
.
translate
(
0.0
,
drawCallSpacing
);
}
// Warm up shadow shaders.
const
ui
.
Color
black
=
ui
.
Color
(
0xFF000000
);
canvas
.
save
();
canvas
.
drawShadow
(
rrectPath
,
black
,
10.0
,
true
);
canvas
.
translate
(
drawCallSpacing
,
0.0
);
canvas
.
drawShadow
(
rrectPath
,
black
,
10.0
,
false
);
canvas
.
restore
();
// Warm up text shaders.
canvas
.
translate
(
0.0
,
drawCallSpacing
);
final
ui
.
ParagraphBuilder
paragraphBuilder
=
ui
.
ParagraphBuilder
(
ui
.
ParagraphStyle
(
textDirection:
ui
.
TextDirection
.
ltr
),
)..
pushStyle
(
ui
.
TextStyle
(
color:
black
))..
addText
(
'_'
);
final
ui
.
Paragraph
paragraph
=
paragraphBuilder
.
build
()
..
layout
(
const
ui
.
ParagraphConstraints
(
width:
60.0
));
canvas
.
drawParagraph
(
paragraph
,
const
ui
.
Offset
(
20.0
,
20.0
));
// Draw a rect inside a rrect with a non-trivial intersection. If the
// intersection is trivial (e.g., equals the rrect clip), Skia will optimize
// the clip out.
//
// Add an integral or fractional translation to trigger Skia's non-AA or AA
// optimizations (as did before in normal FillRectOp in rrect clip cases).
for
(
final
double
fraction
in
<
double
>[
0.0
,
0.5
])
{
canvas
..
save
()
..
translate
(
fraction
,
fraction
)
..
clipRRect
(
ui
.
RRect
.
fromLTRBR
(
8
,
8
,
328
,
248
,
const
ui
.
Radius
.
circular
(
16
)))
..
drawRect
(
const
ui
.
Rect
.
fromLTRB
(
10
,
10
,
320
,
240
),
ui
.
Paint
())
..
restore
();
canvas
.
translate
(
drawCallSpacing
,
0.0
);
}
canvas
.
translate
(
0.0
,
drawCallSpacing
);
}
}
packages/flutter/test/painting/binding_test.dart
View file @
32c2e2ba
...
@@ -38,6 +38,10 @@ Future<void> main() async {
...
@@ -38,6 +38,10 @@ Future<void> main() async {
expect
(
binding
.
imageCache
.
clearCount
,
1
);
expect
(
binding
.
imageCache
.
clearCount
,
1
);
expect
(
binding
.
imageCache
.
liveClearCount
,
1
);
expect
(
binding
.
imageCache
.
liveClearCount
,
1
);
});
});
test
(
'ShaderWarmUp is null by default'
,
()
{
expect
(
PaintingBinding
.
shaderWarmUp
,
null
);
});
}
}
class
TestBindingBase
implements
BindingBase
{
class
TestBindingBase
implements
BindingBase
{
...
...
packages/flutter/test/painting/shader_warm_up_test.dart
deleted
100644 → 0
View file @
05e84254
// 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:ui'
as
ui
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/painting.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
class
TestCanvas
implements
Canvas
{
TestCanvas
();
final
List
<
Invocation
>
invocations
=
<
Invocation
>[];
@override
void
noSuchMethod
(
Invocation
invocation
)
{
invocations
.
add
(
invocation
);
}
}
void
main
(
)
{
test
(
'DefaultShaderWarmUp has expected canvas invocations'
,
()
{
final
TestCanvas
canvas
=
TestCanvas
();
const
DefaultShaderWarmUp
s
=
DefaultShaderWarmUp
();
s
.
warmUpOnCanvas
(
canvas
);
bool
hasDrawRectAfterClipRRect
=
false
;
for
(
int
i
=
0
;
i
<
canvas
.
invocations
.
length
-
1
;
i
+=
1
)
{
if
(
canvas
.
invocations
[
i
].
memberName
==
#clipRRect
&&
canvas
.
invocations
[
i
+
1
].
memberName
==
#drawRect
)
{
hasDrawRectAfterClipRRect
=
true
;
break
;
}
}
expect
(
hasDrawRectAfterClipRRect
,
true
);
});
test
(
'ShaderWarmUp.execute disposes the image and picture'
,
()
async
{
const
DefaultShaderWarmUp
shaderWarmUp
=
DefaultShaderWarmUp
();
late
ui
.
Picture
capturedPicture
;
late
ui
.
Image
capturedImage
;
debugCaptureShaderWarmUpPicture
=
(
ui
.
Picture
picture
)
{
capturedPicture
=
picture
;
expect
(
picture
.
approximateBytesUsed
,
greaterThan
(
0
));
return
true
;
};
debugCaptureShaderWarmUpImage
=
(
ui
.
Image
image
)
{
capturedImage
=
image
;
expect
(
image
.
width
,
100
);
expect
(
image
.
height
,
100
);
return
true
;
};
await
shaderWarmUp
.
execute
();
expect
(
()
=>
capturedPicture
.
approximateBytesUsed
,
throwsA
(
isA
<
String
>().
having
((
String
message
)
=>
message
,
'message'
,
'Object has been disposed.'
)),
);
expect
(
capturedImage
.
debugDisposed
,
true
);
},
skip:
kIsWeb
);
// Browser doesn't support approximateBytesUsed and doesn't rasterize the picture at this time.
}
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