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
65b19560
Unverified
Commit
65b19560
authored
Jun 19, 2020
by
Tong Mu
Committed by
GitHub
Jun 19, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add benchmark for Mouse region (web) (#59803)
parent
e48b7e99
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
358 additions
and
6 deletions
+358
-6
bench_mouse_region_grid_hover.dart
...benchmarks/lib/src/web/bench_mouse_region_grid_hover.dart
+170
-0
bench_mouse_region_grid_scroll.dart
...enchmarks/lib/src/web/bench_mouse_region_grid_scroll.dart
+178
-0
web_benchmarks.dart
dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
+4
-0
test_pointer.dart
packages/flutter_test/lib/src/test_pointer.dart
+6
-6
No files found.
dev/benchmarks/macrobenchmarks/lib/src/web/bench_mouse_region_grid_hover.dart
0 → 100644
View file @
65b19560
// 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'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/scheduler.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'recorder.dart'
;
class
_NestedMouseRegion
extends
StatelessWidget
{
const
_NestedMouseRegion
({
this
.
nests
,
this
.
child
});
final
int
nests
;
final
Widget
child
;
@override
Widget
build
(
BuildContext
context
)
{
Widget
current
=
child
;
for
(
int
i
=
0
;
i
<
nests
;
i
++)
{
current
=
MouseRegion
(
onEnter:
(
_
)
{},
child:
child
,
);
}
return
current
;
}
}
/// Creates a grid of mouse regions, then continuously hover over them.
///
/// Measures our ability to hit test mouse regions.
class
BenchMouseRegionGridHover
extends
WidgetRecorder
{
BenchMouseRegionGridHover
()
:
super
(
name:
benchmarkName
);
static
const
String
benchmarkName
=
'bench_mouse_region_grid_hover'
;
final
_Tester
tester
=
_Tester
();
// Use a non-trivial border to force Web to switch painter
Border
_getBorder
(
int
columnIndex
,
int
rowIndex
)
{
const
BorderSide
defaultBorderSide
=
BorderSide
();
return
Border
(
left:
columnIndex
==
0
?
defaultBorderSide
:
BorderSide
.
none
,
top:
rowIndex
==
0
?
defaultBorderSide
:
BorderSide
.
none
,
right:
defaultBorderSide
,
bottom:
defaultBorderSide
,
);
}
bool
started
=
false
;
@override
void
frameDidDraw
()
{
if
(!
started
)
{
started
=
true
;
SchedulerBinding
.
instance
.
addPostFrameCallback
((
Duration
timeStamp
)
async
{
tester
.
start
();
});
}
super
.
frameDidDraw
();
}
@override
Widget
createWidget
()
{
const
int
rowsCount
=
60
;
const
int
columnsCount
=
20
;
const
double
containerSize
=
20
;
return
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Align
(
alignment:
Alignment
.
topLeft
,
child:
SizedBox
(
width:
400
,
height:
400
,
child:
ListView
.
builder
(
itemCount:
rowsCount
,
cacheExtent:
rowsCount
*
containerSize
,
physics:
const
ClampingScrollPhysics
(),
itemBuilder:
(
BuildContext
context
,
int
rowIndex
)
=>
_NestedMouseRegion
(
nests:
10
,
child:
Row
(
children:
List
<
Widget
>.
generate
(
columnsCount
,
(
int
columnIndex
)
=>
_NestedMouseRegion
(
nests:
10
,
child:
Container
(
decoration:
BoxDecoration
(
border:
_getBorder
(
columnIndex
,
rowIndex
),
color:
Color
.
fromARGB
(
255
,
rowIndex
*
20
%
256
,
127
,
127
),
),
width:
containerSize
,
height:
containerSize
,
),
),
),
),
),
),
),
),
);
}
}
class
_UntilNextFrame
{
_UntilNextFrame
.
_
();
static
Completer
<
void
>
_completer
;
static
Future
<
void
>
wait
()
{
if
(
_UntilNextFrame
.
_completer
==
null
)
{
_UntilNextFrame
.
_completer
=
Completer
<
void
>();
SchedulerBinding
.
instance
.
addPostFrameCallback
((
_
)
{
_UntilNextFrame
.
_completer
.
complete
(
null
);
_UntilNextFrame
.
_completer
=
null
;
});
}
return
_UntilNextFrame
.
_completer
.
future
;
}
}
class
_Tester
{
static
const
Duration
hoverDuration
=
Duration
(
milliseconds:
20
);
bool
_stopped
=
false
;
TestGesture
get
gesture
{
return
_gesture
??=
TestGesture
(
dispatcher:
(
PointerEvent
event
,
HitTestResult
result
)
async
{
RendererBinding
.
instance
.
dispatchEvent
(
event
,
result
);
},
hitTester:
(
Offset
location
)
{
final
HitTestResult
result
=
HitTestResult
();
RendererBinding
.
instance
.
hitTest
(
result
,
location
);
return
result
;
},
kind:
PointerDeviceKind
.
mouse
,
);
}
TestGesture
_gesture
;
Duration
currentTime
=
Duration
.
zero
;
Future
<
void
>
_hoverTo
(
Offset
location
,
Duration
duration
)
async
{
currentTime
+=
duration
;
await
gesture
.
moveTo
(
location
,
timeStamp:
currentTime
);
await
_UntilNextFrame
.
wait
();
}
Future
<
void
>
start
()
async
{
await
Future
<
void
>.
delayed
(
Duration
.
zero
);
while
(!
_stopped
)
{
await
_hoverTo
(
const
Offset
(
30
,
10
),
hoverDuration
);
await
_hoverTo
(
const
Offset
(
10
,
370
),
hoverDuration
);
await
_hoverTo
(
const
Offset
(
370
,
390
),
hoverDuration
);
await
_hoverTo
(
const
Offset
(
390
,
30
),
hoverDuration
);
}
}
void
stop
()
{
_stopped
=
true
;
}
}
dev/benchmarks/macrobenchmarks/lib/src/web/bench_mouse_region_grid_scroll.dart
0 → 100644
View file @
65b19560
// 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'
;
import
'package:flutter/gestures.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:flutter/scheduler.dart'
;
import
'package:flutter_test/flutter_test.dart'
;
import
'recorder.dart'
;
/// Creates a grid of mouse regions, then continuously scrolls them up and down.
///
/// Measures our ability to render mouse regions.
class
BenchMouseRegionGridScroll
extends
WidgetRecorder
{
BenchMouseRegionGridScroll
()
:
super
(
name:
benchmarkName
);
static
const
String
benchmarkName
=
'bench_mouse_region_grid_scroll'
;
final
_Tester
tester
=
_Tester
();
// Use a non-trivial border to force Web to switch painter
Border
_getBorder
(
int
columnIndex
,
int
rowIndex
)
{
const
BorderSide
defaultBorderSide
=
BorderSide
();
return
Border
(
left:
columnIndex
==
0
?
defaultBorderSide
:
BorderSide
.
none
,
top:
rowIndex
==
0
?
defaultBorderSide
:
BorderSide
.
none
,
right:
defaultBorderSide
,
bottom:
defaultBorderSide
,
);
}
bool
started
=
false
;
@override
void
frameDidDraw
()
{
if
(!
started
)
{
started
=
true
;
SchedulerBinding
.
instance
.
addPostFrameCallback
((
Duration
timeStamp
)
async
{
tester
.
start
();
final
VoidCallback
localDidStop
=
didStop
;
didStop
=
()
{
if
(
localDidStop
!=
null
)
localDidStop
();
tester
.
stop
();
};
});
}
super
.
frameDidDraw
();
}
@override
Widget
createWidget
()
{
const
int
rowsCount
=
60
;
const
int
columnsCount
=
20
;
const
double
containerSize
=
20
;
return
Directionality
(
textDirection:
TextDirection
.
ltr
,
child:
Align
(
alignment:
Alignment
.
topLeft
,
child:
SizedBox
(
width:
400
,
height:
400
,
child:
ListView
.
builder
(
itemCount:
rowsCount
,
cacheExtent:
rowsCount
*
containerSize
,
physics:
const
ClampingScrollPhysics
(),
itemBuilder:
(
BuildContext
context
,
int
rowIndex
)
=>
Row
(
children:
List
<
Widget
>.
generate
(
columnsCount
,
(
int
columnIndex
)
=>
MouseRegion
(
onEnter:
(
_
)
{},
child:
Container
(
decoration:
BoxDecoration
(
border:
_getBorder
(
columnIndex
,
rowIndex
),
color:
Color
.
fromARGB
(
255
,
rowIndex
*
20
%
256
,
127
,
127
),
),
width:
containerSize
,
height:
containerSize
,
),
),
),
),
),
),
),
);
}
}
class
_UntilNextFrame
{
_UntilNextFrame
.
_
();
static
Completer
<
void
>
_completer
;
static
Future
<
void
>
wait
()
{
if
(
_UntilNextFrame
.
_completer
==
null
)
{
_UntilNextFrame
.
_completer
=
Completer
<
void
>();
SchedulerBinding
.
instance
.
addPostFrameCallback
((
_
)
{
_UntilNextFrame
.
_completer
.
complete
(
null
);
_UntilNextFrame
.
_completer
=
null
;
});
}
return
_UntilNextFrame
.
_completer
.
future
;
}
}
class
_Tester
{
static
const
int
scrollFrequency
=
60
;
static
const
Offset
dragStartLocation
=
Offset
(
200
,
200
);
static
const
Offset
dragUpOffset
=
Offset
(
0
,
200
);
static
const
Offset
dragDownOffset
=
Offset
(
0
,
-
200
);
static
const
Duration
dragDuration
=
Duration
(
milliseconds:
200
);
bool
_stopped
=
false
;
TestGesture
get
gesture
{
return
_gesture
??=
TestGesture
(
dispatcher:
(
PointerEvent
event
,
HitTestResult
result
)
async
{
RendererBinding
.
instance
.
dispatchEvent
(
event
,
result
);
},
hitTester:
(
Offset
location
)
{
final
HitTestResult
result
=
HitTestResult
();
RendererBinding
.
instance
.
hitTest
(
result
,
location
);
return
result
;
},
kind:
PointerDeviceKind
.
mouse
,
);
}
TestGesture
_gesture
;
Duration
currentTime
=
Duration
.
zero
;
Future
<
void
>
_scroll
(
Offset
start
,
Offset
offset
,
Duration
duration
)
async
{
final
int
durationMs
=
duration
.
inMilliseconds
;
final
Duration
fullFrameDuration
=
const
Duration
(
seconds:
1
)
~/
scrollFrequency
;
final
int
frameDurationMs
=
fullFrameDuration
.
inMilliseconds
;
final
int
fullFrames
=
duration
.
inMilliseconds
~/
frameDurationMs
;
final
Offset
fullFrameOffset
=
offset
*
((
frameDurationMs
as
double
)
/
durationMs
);
final
Duration
finalFrameDuration
=
duration
-
fullFrameDuration
*
fullFrames
;
final
Offset
finalFrameOffset
=
offset
-
fullFrameOffset
*
(
fullFrames
as
double
);
await
gesture
.
down
(
start
,
timeStamp:
currentTime
);
for
(
int
frame
=
0
;
frame
<
fullFrames
;
frame
+=
1
)
{
currentTime
+=
fullFrameDuration
;
await
gesture
.
moveBy
(
fullFrameOffset
,
timeStamp:
currentTime
);
await
_UntilNextFrame
.
wait
();
}
if
(
finalFrameOffset
!=
Offset
.
zero
)
{
currentTime
+=
finalFrameDuration
;
await
gesture
.
moveBy
(
finalFrameOffset
,
timeStamp:
currentTime
);
await
_UntilNextFrame
.
wait
();
}
await
gesture
.
up
(
timeStamp:
currentTime
);
}
Future
<
void
>
start
()
async
{
await
Future
<
void
>.
delayed
(
Duration
.
zero
);
while
(!
_stopped
)
{
await
_scroll
(
dragStartLocation
,
dragUpOffset
,
dragDuration
);
await
_scroll
(
dragStartLocation
,
dragDownOffset
,
dragDuration
);
}
}
void
stop
()
{
_stopped
=
true
;
}
}
dev/benchmarks/macrobenchmarks/lib/web_benchmarks.dart
View file @
65b19560
...
...
@@ -16,6 +16,8 @@ import 'src/web/bench_child_layers.dart';
import
'src/web/bench_clipped_out_pictures.dart'
;
import
'src/web/bench_draw_rect.dart'
;
import
'src/web/bench_dynamic_clip_on_static_picture.dart'
;
import
'src/web/bench_mouse_region_grid_hover.dart'
;
import
'src/web/bench_mouse_region_grid_scroll.dart'
;
import
'src/web/bench_paths.dart'
;
import
'src/web/bench_picture_recording.dart'
;
import
'src/web/bench_simple_lazy_text_scroll.dart'
;
...
...
@@ -42,6 +44,8 @@ final Map<String, RecorderFactory> benchmarks = <String, RecorderFactory>{
BenchDynamicClipOnStaticPicture
.
benchmarkName
:
()
=>
BenchDynamicClipOnStaticPicture
(),
BenchPictureRecording
.
benchmarkName
:
()
=>
BenchPictureRecording
(),
BenchUpdateManyChildLayers
.
benchmarkName
:
()
=>
BenchUpdateManyChildLayers
(),
BenchMouseRegionGridScroll
.
benchmarkName
:
()
=>
BenchMouseRegionGridScroll
(),
BenchMouseRegionGridHover
.
benchmarkName
:
()
=>
BenchMouseRegionGridHover
(),
if
(
isCanvasKit
)
BenchBuildColorsGrid
.
canvasKitBenchmarkName
:
()
=>
BenchBuildColorsGrid
.
canvasKit
(),
...
...
packages/flutter_test/lib/src/test_pointer.dart
View file @
65b19560
...
...
@@ -341,10 +341,10 @@ class TestGesture {
/// Dispatch a pointer down event at the given `downLocation`, caching the
/// hit test result.
Future
<
void
>
down
(
Offset
downLocation
)
async
{
Future
<
void
>
down
(
Offset
downLocation
,
{
Duration
timeStamp
=
Duration
.
zero
}
)
async
{
return
TestAsyncUtils
.
guard
<
void
>(()
async
{
_result
=
_hitTester
(
downLocation
);
return
_dispatcher
(
_pointer
.
down
(
downLocation
),
_result
);
return
_dispatcher
(
_pointer
.
down
(
downLocation
,
timeStamp:
timeStamp
),
_result
);
});
}
...
...
@@ -416,10 +416,10 @@ class TestGesture {
}
/// End the gesture by releasing the pointer.
Future
<
void
>
up
()
{
Future
<
void
>
up
(
{
Duration
timeStamp
=
Duration
.
zero
}
)
{
return
TestAsyncUtils
.
guard
<
void
>(()
async
{
assert
(
_pointer
.
_isDown
);
await
_dispatcher
(
_pointer
.
up
(),
_result
);
await
_dispatcher
(
_pointer
.
up
(
timeStamp:
timeStamp
),
_result
);
assert
(!
_pointer
.
_isDown
);
_result
=
null
;
});
...
...
@@ -428,10 +428,10 @@ class TestGesture {
/// End the gesture by canceling the pointer (as would happen if the
/// system showed a modal dialog on top of the Flutter application,
/// for instance).
Future
<
void
>
cancel
()
{
Future
<
void
>
cancel
(
{
Duration
timeStamp
=
Duration
.
zero
}
)
{
return
TestAsyncUtils
.
guard
<
void
>(()
async
{
assert
(
_pointer
.
_isDown
);
await
_dispatcher
(
_pointer
.
cancel
(),
_result
);
await
_dispatcher
(
_pointer
.
cancel
(
timeStamp:
timeStamp
),
_result
);
assert
(!
_pointer
.
_isDown
);
_result
=
null
;
});
...
...
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