Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
5fe6083d
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
5fe6083d
编写于
10月 15, 2019
作者:
Y
Yegor
提交者:
GitHub
10月 15, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Move surface-based SceneBuilder implementation under surface/ (#13159)
Move surface-based SceneBuilder implementation under surface/
上级
c979817b
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
575 addition
and
300 deletion
+575
-300
ci/licenses_golden/licenses_flutter
ci/licenses_golden/licenses_flutter
+1
-0
lib/web_ui/lib/src/engine.dart
lib/web_ui/lib/src/engine.dart
+1
-0
lib/web_ui/lib/src/engine/surface/scene.dart
lib/web_ui/lib/src/engine/surface/scene.dart
+21
-0
lib/web_ui/lib/src/engine/surface/scene_builder.dart
lib/web_ui/lib/src/engine/surface/scene_builder.dart
+482
-0
lib/web_ui/lib/src/engine/surface/surface.dart
lib/web_ui/lib/src/engine/surface/surface.dart
+8
-12
lib/web_ui/lib/src/engine/window.dart
lib/web_ui/lib/src/engine/window.dart
+14
-3
lib/web_ui/lib/src/ui/compositing.dart
lib/web_ui/lib/src/ui/compositing.dart
+27
-251
lib/web_ui/lib/src/ui/window.dart
lib/web_ui/lib/src/ui/window.dart
+1
-15
lib/web_ui/test/compositing_test.dart
lib/web_ui/test/compositing_test.dart
+1
-1
lib/web_ui/test/engine/surface/surface_test.dart
lib/web_ui/test/engine/surface/surface_test.dart
+1
-1
lib/web_ui/test/golden_tests/engine/compositing_golden_test.dart
..._ui/test/golden_tests/engine/compositing_golden_test.dart
+14
-13
lib/web_ui/test/matchers.dart
lib/web_ui/test/matchers.dart
+4
-4
未找到文件。
ci/licenses_golden/licenses_flutter
浏览文件 @
5fe6083d
...
...
@@ -415,6 +415,7 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/opacity.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/picture.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/platform_view.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/scene.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/scene_builder.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/surface.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/transform.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/test_embedding.dart
...
...
lib/web_ui/lib/src/engine.dart
浏览文件 @
5fe6083d
...
...
@@ -82,6 +82,7 @@ part 'engine/surface/opacity.dart';
part
'engine/surface/picture.dart'
;
part
'engine/surface/platform_view.dart'
;
part
'engine/surface/scene.dart'
;
part
'engine/surface/scene_builder.dart'
;
part
'engine/surface/surface.dart'
;
part
'engine/surface/transform.dart'
;
part
'engine/test_embedding.dart'
;
...
...
lib/web_ui/lib/src/engine/surface/scene.dart
浏览文件 @
5fe6083d
...
...
@@ -4,6 +4,27 @@
part of
engine
;
class
SurfaceScene
implements
ui
.
Scene
{
/// This class is created by the engine, and should not be instantiated
/// or extended directly.
///
/// To create a Scene object, use a [SceneBuilder].
SurfaceScene
(
this
.
webOnlyRootElement
);
final
html
.
Element
webOnlyRootElement
;
/// Creates a raster image representation of the current state of the scene.
/// This is a slow operation that is performed on a background thread.
Future
<
ui
.
Image
>
toImage
(
int
width
,
int
height
)
{
throw
UnsupportedError
(
'toImage is not supported on the Web'
);
}
/// Releases the resources used by this scene.
///
/// After calling this function, the scene is cannot be used further.
void
dispose
()
{}
}
/// A surface that creates a DOM element for whole app.
class
PersistedScene
extends
PersistedContainerSurface
{
PersistedScene
(
PersistedScene
oldLayer
)
:
super
(
oldLayer
)
{
...
...
lib/web_ui/lib/src/engine/surface/scene_builder.dart
0 → 100644
浏览文件 @
5fe6083d
// Copyright 2013 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.
part of
engine
;
class
SurfaceSceneBuilder
implements
ui
.
SceneBuilder
{
SurfaceSceneBuilder
()
{
_surfaceStack
.
add
(
PersistedScene
(
_lastFrameScene
));
}
final
List
<
PersistedContainerSurface
>
_surfaceStack
=
<
PersistedContainerSurface
>[];
/// The scene built by this scene builder.
///
/// This getter should only be called after all surfaces are built.
PersistedScene
get
_persistedScene
{
assert
(()
{
if
(
_surfaceStack
.
length
!=
1
)
{
final
String
surfacePrintout
=
_surfaceStack
.
map
<
Type
>((
PersistedContainerSurface
surface
)
=>
surface
.
runtimeType
)
.
toList
()
.
join
(
', '
);
throw
Exception
(
'Incorrect sequence of push/pop operations while '
'building scene surfaces. After building the scene the persisted '
'surface stack must contain a single element which corresponds '
'to the scene itself (_PersistedScene). All other surfaces '
'should have been popped off the stack. Found the following '
'surfaces in the stack:
\n
$surfacePrintout
'
);
}
return
true
;
}());
return
_surfaceStack
.
first
;
}
/// The surface currently being built.
PersistedContainerSurface
get
_currentSurface
=>
_surfaceStack
.
last
;
ui
.
EngineLayer
_pushSurface
(
PersistedContainerSurface
surface
)
{
// Only attempt to update if the update is requested and the surface is in
// the live tree.
if
(
surface
.
oldLayer
!=
null
)
{
assert
(
surface
.
oldLayer
.
runtimeType
==
surface
.
runtimeType
);
assert
(
surface
.
oldLayer
.
isActive
);
surface
.
oldLayer
.
state
=
PersistedSurfaceState
.
pendingUpdate
;
}
_adoptSurface
(
surface
);
_surfaceStack
.
add
(
surface
);
return
surface
;
}
void
_addSurface
(
PersistedSurface
surface
)
{
_adoptSurface
(
surface
);
}
void
_adoptSurface
(
PersistedSurface
surface
)
{
_currentSurface
.
appendChild
(
surface
);
}
/// Pushes an offset operation onto the operation stack.
///
/// This is equivalent to [pushTransform] with a matrix with only translation.
///
/// See [pop] for details about the operation stack.
@override
ui
.
OffsetEngineLayer
pushOffset
(
double
dx
,
double
dy
,
{
ui
.
OffsetEngineLayer
oldLayer
})
{
return
_pushSurface
(
PersistedOffset
(
oldLayer
,
dx
,
dy
));
}
/// Pushes a transform operation onto the operation stack.
///
/// The objects are transformed by the given matrix before rasterization.
///
/// See [pop] for details about the operation stack.
@override
ui
.
TransformEngineLayer
pushTransform
(
Float64List
matrix4
,
{
ui
.
TransformEngineLayer
oldLayer
})
{
if
(
matrix4
==
null
)
{
throw
ArgumentError
(
'"matrix4" argument cannot be null'
);
}
if
(
matrix4
.
length
!=
16
)
{
throw
ArgumentError
(
'"matrix4" must have 16 entries.'
);
}
return
_pushSurface
(
PersistedTransform
(
oldLayer
,
matrix4
));
}
/// Pushes a rectangular clip operation onto the operation stack.
///
/// Rasterization outside the given rectangle is discarded.
///
/// See [pop] for details about the operation stack, and [Clip] for different clip modes.
/// By default, the clip will be anti-aliased (clip = [Clip.antiAlias]).
@override
ui
.
ClipRectEngineLayer
pushClipRect
(
ui
.
Rect
rect
,
{
ui
.
Clip
clipBehavior
=
ui
.
Clip
.
antiAlias
,
ui
.
ClipRectEngineLayer
oldLayer
})
{
assert
(
clipBehavior
!=
null
);
assert
(
clipBehavior
!=
ui
.
Clip
.
none
);
return
_pushSurface
(
PersistedClipRect
(
oldLayer
,
rect
));
}
/// Pushes a rounded-rectangular clip operation onto the operation stack.
///
/// Rasterization outside the given rounded rectangle is discarded.
///
/// See [pop] for details about the operation stack.
@override
ui
.
ClipRRectEngineLayer
pushClipRRect
(
ui
.
RRect
rrect
,
{
ui
.
Clip
clipBehavior
,
ui
.
ClipRRectEngineLayer
oldLayer
})
{
return
_pushSurface
(
PersistedClipRRect
(
oldLayer
,
rrect
,
clipBehavior
));
}
/// Pushes a path clip operation onto the operation stack.
///
/// Rasterization outside the given path is discarded.
///
/// See [pop] for details about the operation stack.
@override
ui
.
ClipPathEngineLayer
pushClipPath
(
ui
.
Path
path
,
{
ui
.
Clip
clipBehavior
=
ui
.
Clip
.
antiAlias
,
ui
.
ClipPathEngineLayer
oldLayer
})
{
assert
(
clipBehavior
!=
null
);
assert
(
clipBehavior
!=
ui
.
Clip
.
none
);
return
_pushSurface
(
PersistedClipPath
(
oldLayer
,
path
,
clipBehavior
));
}
/// Pushes an opacity operation onto the operation stack.
///
/// The given alpha value is blended into the alpha value of the objects'
/// rasterization. An alpha value of 0 makes the objects entirely invisible.
/// An alpha value of 255 has no effect (i.e., the objects retain the current
/// opacity).
///
/// See [pop] for details about the operation stack.
@override
ui
.
OpacityEngineLayer
pushOpacity
(
int
alpha
,
{
ui
.
Offset
offset
=
ui
.
Offset
.
zero
,
ui
.
OpacityEngineLayer
oldLayer
})
{
return
_pushSurface
(
PersistedOpacity
(
oldLayer
,
alpha
,
offset
));
}
/// Pushes a color filter operation onto the operation stack.
///
/// The given color is applied to the objects' rasterization using the given
/// blend mode.
///
/// {@macro dart.ui.sceneBuilder.oldLayer}
///
/// {@macro dart.ui.sceneBuilder.oldLayerVsRetained}
///
/// See [pop] for details about the operation stack.
@override
ui
.
ColorFilterEngineLayer
pushColorFilter
(
ui
.
ColorFilter
filter
,
{
ui
.
ColorFilterEngineLayer
oldLayer
})
{
assert
(
filter
!=
null
);
throw
UnimplementedError
();
}
/// Pushes a backdrop filter operation onto the operation stack.
///
/// The given filter is applied to the current contents of the scene prior to
/// rasterizing the given objects.
///
/// See [pop] for details about the operation stack.
@override
ui
.
BackdropFilterEngineLayer
pushBackdropFilter
(
ui
.
ImageFilter
filter
,
{
ui
.
BackdropFilterEngineLayer
oldLayer
})
{
return
_pushSurface
(
PersistedBackdropFilter
(
oldLayer
,
filter
));
}
/// Pushes a shader mask operation onto the operation stack.
///
/// The given shader is applied to the object's rasterization in the given
/// rectangle using the given blend mode.
///
/// See [pop] for details about the operation stack.
@override
ui
.
ShaderMaskEngineLayer
pushShaderMask
(
ui
.
Shader
shader
,
ui
.
Rect
maskRect
,
ui
.
BlendMode
blendMode
,
{
ui
.
ShaderMaskEngineLayer
oldLayer
})
{
throw
UnimplementedError
();
}
/// Pushes a physical layer operation for an arbitrary shape onto the
/// operation stack.
///
/// By default, the layer's content will not be clipped (clip = [Clip.none]).
/// If clip equals [Clip.hardEdge], [Clip.antiAlias], or [Clip.antiAliasWithSaveLayer],
/// then the content is clipped to the given shape defined by [path].
///
/// If [elevation] is greater than 0.0, then a shadow is drawn around the layer.
/// [shadowColor] defines the color of the shadow if present and [color] defines the
/// color of the layer background.
///
/// See [pop] for details about the operation stack, and [Clip] for different clip modes.
@override
ui
.
PhysicalShapeEngineLayer
pushPhysicalShape
({
ui
.
Path
path
,
double
elevation
,
ui
.
Color
color
,
ui
.
Color
shadowColor
,
ui
.
Clip
clipBehavior
=
ui
.
Clip
.
none
,
ui
.
PhysicalShapeEngineLayer
oldLayer
,
})
{
return
_pushSurface
(
PersistedPhysicalShape
(
oldLayer
,
path
,
elevation
,
color
.
value
,
shadowColor
?.
value
??
0xFF000000
,
clipBehavior
,
));
}
/// Add a retained engine layer subtree from previous frames.
///
/// All the engine layers that are in the subtree of the retained layer will
/// be automatically appended to the current engine layer tree.
///
/// Therefore, when implementing a subclass of the [Layer] concept defined in
/// the rendering layer of Flutter's framework, once this is called, there's
/// no need to call [addToScene] for its children layers.
@override
void
addRetained
(
ui
.
EngineLayer
retainedLayer
)
{
final
PersistedContainerSurface
retainedSurface
=
retainedLayer
;
assert
(
retainedSurface
.
isActive
||
retainedSurface
.
isReleased
);
retainedSurface
.
tryRetain
();
_adoptSurface
(
retainedSurface
);
}
/// Ends the effect of the most recently pushed operation.
///
/// Internally the scene builder maintains a stack of operations. Each of the
/// operations in the stack applies to each of the objects added to the scene.
/// Calling this function removes the most recently added operation from the
/// stack.
@override
void
pop
()
{
assert
(
_surfaceStack
.
isNotEmpty
);
_surfaceStack
.
removeLast
();
}
/// Adds an object to the scene that displays performance statistics.
///
/// Useful during development to assess the performance of the application.
/// The enabledOptions controls which statistics are displayed. The bounds
/// controls where the statistics are displayed.
///
/// enabledOptions is a bit field with the following bits defined:
/// - 0x01: displayRasterizerStatistics - show GPU thread frame time
/// - 0x02: visualizeRasterizerStatistics - graph GPU thread frame times
/// - 0x04: displayEngineStatistics - show UI thread frame time
/// - 0x08: visualizeEngineStatistics - graph UI thread frame times
/// Set enabledOptions to 0x0F to enable all the currently defined features.
///
/// The "UI thread" is the thread that includes all the execution of
/// the main Dart isolate (the isolate that can call
/// [Window.render]). The UI thread frame time is the total time
/// spent executing the [Window.onBeginFrame] callback. The "GPU
/// thread" is the thread (running on the CPU) that subsequently
/// processes the [Scene] provided by the Dart code to turn it into
/// GPU commands and send it to the GPU.
///
/// See also the [PerformanceOverlayOption] enum in the rendering library.
/// for more details.
@override
void
addPerformanceOverlay
(
int
enabledOptions
,
ui
.
Rect
bounds
)
{
_addPerformanceOverlay
(
enabledOptions
,
bounds
.
left
,
bounds
.
right
,
bounds
.
top
,
bounds
.
bottom
);
}
/// Whether we've already warned the user about the lack of the performance
/// overlay or not.
///
/// We use this to avoid spamming the console with redundant warning messages.
static
bool
_webOnlyDidWarnAboutPerformanceOverlay
=
false
;
void
_addPerformanceOverlay
(
int
enabledOptions
,
double
left
,
double
right
,
double
top
,
double
bottom
)
{
if
(!
_webOnlyDidWarnAboutPerformanceOverlay
)
{
_webOnlyDidWarnAboutPerformanceOverlay
=
true
;
html
.
window
.
console
.
warn
(
'The performance overlay isn
\'
t supported on the web'
);
}
}
/// Adds a [Picture] to the scene.
///
/// The picture is rasterized at the given offset.
@override
void
addPicture
(
ui
.
Offset
offset
,
ui
.
Picture
picture
,
{
bool
isComplexHint
=
false
,
bool
willChangeHint
=
false
,
})
{
int
hints
=
0
;
if
(
isComplexHint
)
{
hints
|=
1
;
}
if
(
willChangeHint
)
{
hints
|=
2
;
}
_addSurface
(
persistedPictureFactory
(
offset
.
dx
,
offset
.
dy
,
picture
,
hints
));
}
/// Adds a backend texture to the scene.
///
/// The texture is scaled to the given size and rasterized at the given
/// offset.
@override
void
addTexture
(
int
textureId
,
{
ui
.
Offset
offset
=
ui
.
Offset
.
zero
,
double
width
=
0.0
,
double
height
=
0.0
,
bool
freeze
=
false
})
{
assert
(
offset
!=
null
,
'Offset argument was null'
);
_addTexture
(
offset
.
dx
,
offset
.
dy
,
width
,
height
,
textureId
);
}
void
_addTexture
(
double
dx
,
double
dy
,
double
width
,
double
height
,
int
textureId
)
{
// In test mode, allow this to be a no-op.
if
(!
ui
.
debugEmulateFlutterTesterEnvironment
)
{
throw
UnimplementedError
(
'Textures are not supported in Flutter Web'
);
}
}
/// Adds a platform view (e.g an iOS UIView) to the scene.
///
/// Only supported on iOS, this is currently a no-op on other platforms.
///
/// On iOS this layer splits the current output surface into two surfaces, one for the scene nodes
/// preceding the platform view, and one for the scene nodes following the platform view.
///
/// ## Performance impact
///
/// Adding an additional surface doubles the amount of graphics memory directly used by Flutter
/// for output buffers. Quartz might allocated extra buffers for compositing the Flutter surfaces
/// and the platform view.
///
/// With a platform view in the scene, Quartz has to composite the two Flutter surfaces and the
/// embedded UIView. In addition to that, on iOS versions greater than 9, the Flutter frames are
/// synchronized with the UIView frames adding additional performance overhead.
@override
void
addPlatformView
(
int
viewId
,
{
ui
.
Offset
offset
=
ui
.
Offset
.
zero
,
double
width
=
0.0
,
double
height
=
0.0
,
})
{
assert
(
offset
!=
null
,
'Offset argument was null'
);
_addPlatformView
(
offset
.
dx
,
offset
.
dy
,
width
,
height
,
viewId
);
}
void
_addPlatformView
(
double
dx
,
double
dy
,
double
width
,
double
height
,
int
viewId
,
)
{
_addSurface
(
PersistedPlatformView
(
viewId
,
dx
,
dy
,
width
,
height
));
}
/// (Fuchsia-only) Adds a scene rendered by another application to the scene
/// for this application.
@override
void
addChildScene
(
{
ui
.
Offset
offset
=
ui
.
Offset
.
zero
,
double
width
=
0.0
,
double
height
=
0.0
,
ui
.
SceneHost
sceneHost
,
bool
hitTestable
=
true
})
{
_addChildScene
(
offset
.
dx
,
offset
.
dy
,
width
,
height
,
sceneHost
,
hitTestable
);
}
void
_addChildScene
(
double
dx
,
double
dy
,
double
width
,
double
height
,
ui
.
SceneHost
sceneHost
,
bool
hitTestable
)
{
throw
UnimplementedError
();
}
/// Sets a threshold after which additional debugging information should be
/// recorded.
///
/// Currently this interface is difficult to use by end-developers. If you're
/// interested in using this feature, please contact [flutter-dev](https://groups.google.com/forum/#!forum/flutter-dev).
/// We'll hopefully be able to figure out how to make this feature more useful
/// to you.
@override
void
setRasterizerTracingThreshold
(
int
frameInterval
)
{}
/// Sets whether the raster cache should checkerboard cached entries. This is
/// only useful for debugging purposes.
///
/// The compositor can sometimes decide to cache certain portions of the
/// widget hierarchy. Such portions typically don't change often from frame to
/// frame and are expensive to render. This can speed up overall rendering.
/// However, there is certain upfront cost to constructing these cache
/// entries. And, if the cache entries are not used very often, this cost may
/// not be worth the speedup in rendering of subsequent frames. If the
/// developer wants to be certain that populating the raster cache is not
/// causing stutters, this option can be set. Depending on the observations
/// made, hints can be provided to the compositor that aid it in making better
/// decisions about caching.
///
/// Currently this interface is difficult to use by end-developers. If you're
/// interested in using this feature, please contact [flutter-dev](https://groups.google.com/forum/#!forum/flutter-dev).
@override
void
setCheckerboardRasterCacheImages
(
bool
checkerboard
)
{}
/// Sets whether the compositor should checkerboard layers that are rendered
/// to offscreen bitmaps.
///
/// This is only useful for debugging purposes.
@override
void
setCheckerboardOffscreenLayers
(
bool
checkerboard
)
{}
/// The scene recorded in the last frame.
///
/// This is a surface tree that holds onto the DOM elements that can be reused
/// on the next frame.
static
PersistedScene
_lastFrameScene
;
/// Returns the computed persisted scene graph recorded in the last frame.
///
/// This is only available in debug mode. It returns `null` in profile and
/// release modes.
static
PersistedScene
get
debugLastFrameScene
{
PersistedScene
result
;
assert
(()
{
result
=
_lastFrameScene
;
return
true
;
}());
return
result
;
}
/// Discards information about previously rendered frames, including DOM
/// elements and cached canvases.
///
/// After calling this function new canvases will be created for the
/// subsequent scene. This is useful when tests need predictable canvas
/// sizes. If the cache is not cleared, then canvases allocated in one test
/// may be reused in another test.
static
void
debugForgetFrameScene
()
{
_lastFrameScene
?.
rootElement
?.
remove
();
_lastFrameScene
=
null
;
_clipIdCounter
=
0
;
_recycledCanvases
.
clear
();
}
/// Finishes building the scene.
///
/// Returns a [Scene] containing the objects that have been added to
/// this scene builder. The [Scene] can then be displayed on the
/// screen with [Window.render].
///
/// After calling this function, the scene builder object is invalid and
/// cannot be used further.
@override
SurfaceScene
build
()
{
_persistedScene
.
preroll
();
if
(
_lastFrameScene
==
null
)
{
_persistedScene
.
build
();
}
else
{
_persistedScene
.
update
(
_lastFrameScene
);
}
commitScene
(
_persistedScene
);
_lastFrameScene
=
_persistedScene
;
return
SurfaceScene
(
_persistedScene
.
rootElement
);
}
/// Set properties on the linked scene. These properties include its bounds,
/// as well as whether it can be the target of focus events or not.
@override
void
setProperties
(
double
width
,
double
height
,
double
insetTop
,
double
insetRight
,
double
insetBottom
,
double
insetLeft
,
bool
focusable
)
{
throw
UnimplementedError
();
}
}
lib/web_ui/lib/src/engine/surface/surface.dart
浏览文件 @
5fe6083d
...
...
@@ -111,18 +111,6 @@ void commitScene(PersistedScene scene) {
}());
}
/// Discards information about previously rendered frames, including DOM
/// elements and cached canvases.
///
/// After calling this function new canvases will be created for the
/// subsequent scene. This is useful when tests need predictable canvas
/// sizes. If the cache is not cleared, then canvases allocated in one test
/// may be reused in another test.
void
debugForgetFrameScene
(
)
{
_clipIdCounter
=
0
;
_recycledCanvases
.
clear
();
}
/// Surfaces that were retained this frame.
///
/// Surfaces should be added to this list directly. Instead, if a surface needs
...
...
@@ -639,6 +627,14 @@ abstract class PersistedSurface implements ui.EngineLayer {
@protected
@mustCallSuper
void
build
()
{
if
(
rootElement
!=
null
)
{
try
{
throw
null
;
}
catch
(
_
,
stack
)
{
print
(
'Attempted to build a
$runtimeType
, but it already has an HTML element
${rootElement.tagName}
.'
);
print
(
stack
.
toString
().
split
(
'
\n
'
).
take
(
20
).
join
(
'
\n
'
));
}
}
assert
(
rootElement
==
null
);
assert
(
isCreated
);
rootElement
=
createElement
();
...
...
lib/web_ui/lib/src/engine/window.dart
浏览文件 @
5fe6083d
...
...
@@ -248,12 +248,23 @@ class EngineWindow extends ui.Window {
_brightnessMediaQueryListener
=
null
;
}
@override
void
dispose
()
{
_removeBrightnessMediaQueryListener
();
void
render
(
ui
.
Scene
scene
)
{
if
(
experimentalUseSkia
)
{
final
LayerScene
layerScene
=
scene
;
_rasterizer
.
draw
(
layerScene
.
layerTree
);
}
else
{
final
SurfaceScene
surfaceScene
=
scene
;
domRenderer
.
renderScene
(
surfaceScene
.
webOnlyRootElement
);
}
}
final
Rasterizer
_rasterizer
=
experimentalUseSkia
?
Rasterizer
(
Surface
((
SkCanvas
canvas
)
{
domRenderer
.
renderScene
(
canvas
.
htmlCanvas
);
canvas
.
skSurface
.
callMethod
(
'flush'
);
}))
:
null
;
}
/// The window singleton.
...
...
lib/web_ui/lib/src/ui/compositing.dart
浏览文件 @
5fe6083d
...
...
@@ -10,33 +10,15 @@ part of ui;
///
/// Scene objects can be displayed on the screen using the
/// [Window.render] method.
class
Scene
{
/// This class is created by the engine, and should not be instantiated
/// or extended directly.
///
/// To create a Scene object, use a [SceneBuilder].
Scene
.
_
(
this
.
webOnlyRootElement
);
final
html
.
Element
webOnlyRootElement
;
abstract
class
Scene
{
/// Creates a raster image representation of the current state of the scene.
/// This is a slow operation that is performed on a background thread.
Future
<
Image
>
toImage
(
int
width
,
int
height
)
{
if
(
width
<=
0
||
height
<=
0
)
{
throw
Exception
(
'Invalid image dimensions.'
);
}
throw
UnsupportedError
(
'toImage is not supported on the Web'
);
// TODO(flutter_web): Implement [_toImage].
// return futurize(
// (Callback<Image> callback) => _toImage(width, height, callback));
}
// String _toImage(int width, int height, Callback<Image> callback) => null;
Future
<
Image
>
toImage
(
int
width
,
int
height
);
/// Releases the resources used by this scene.
///
/// After calling this function, the scene is cannot be used further.
void
dispose
()
{}
void
dispose
()
;
}
/// An opaque handle to a transform engine layer.
...
...
@@ -120,81 +102,23 @@ abstract class PhysicalShapeEngineLayer implements EngineLayer {}
/// To draw graphical operations onto a [Scene], first create a
/// [Picture] using a [PictureRecorder] and a [Canvas], and then add
/// it to the scene using [addPicture].
class
SceneBuilder
{
abstract
class
SceneBuilder
{
/// Creates an empty [SceneBuilder] object.
factory
SceneBuilder
()
{
if
(
engine
.
experimentalUseSkia
)
{
return
engine
.
LayerSceneBuilder
();
}
else
{
return
SceneBuilder
.
_
();
return
engine
.
SurfaceSceneBuilder
();
}
}
SceneBuilder
.
_
()
{
_surfaceStack
.
add
(
engine
.
PersistedScene
(
_lastFrameScene
));
}
factory
SceneBuilder
.
layer
()
=
engine
.
LayerSceneBuilder
;
final
List
<
engine
.
PersistedContainerSurface
>
_surfaceStack
=
<
engine
.
PersistedContainerSurface
>[];
/// The scene built by this scene builder.
///
/// This getter should only be called after all surfaces are built.
engine
.
PersistedScene
get
_persistedScene
{
assert
(()
{
if
(
_surfaceStack
.
length
!=
1
)
{
final
String
surfacePrintout
=
_surfaceStack
.
map
<
Type
>((
engine
.
PersistedContainerSurface
surface
)
=>
surface
.
runtimeType
)
.
toList
()
.
join
(
', '
);
throw
Exception
(
'Incorrect sequence of push/pop operations while '
'building scene surfaces. After building the scene the persisted '
'surface stack must contain a single element which corresponds '
'to the scene itself (_PersistedScene). All other surfaces '
'should have been popped off the stack. Found the following '
'surfaces in the stack:
\n
$surfacePrintout
'
);
}
return
true
;
}());
return
_surfaceStack
.
first
;
}
/// The surface currently being built.
engine
.
PersistedContainerSurface
get
_currentSurface
=>
_surfaceStack
.
last
;
EngineLayer
_pushSurface
(
engine
.
PersistedContainerSurface
surface
)
{
// Only attempt to update if the update is requested and the surface is in
// the live tree.
if
(
surface
.
oldLayer
!=
null
)
{
assert
(
surface
.
oldLayer
.
runtimeType
==
surface
.
runtimeType
);
assert
(
surface
.
oldLayer
.
isActive
);
surface
.
oldLayer
.
state
=
engine
.
PersistedSurfaceState
.
pendingUpdate
;
}
_adoptSurface
(
surface
);
_surfaceStack
.
add
(
surface
);
return
surface
;
}
void
_addSurface
(
engine
.
PersistedSurface
surface
)
{
_adoptSurface
(
surface
);
}
void
_adoptSurface
(
engine
.
PersistedSurface
surface
)
{
_currentSurface
.
appendChild
(
surface
);
}
/// Pushes an offset operation onto the operation stack.
///
/// This is equivalent to [pushTransform] with a matrix with only translation.
///
/// See [pop] for details about the operation stack.
OffsetEngineLayer
pushOffset
(
double
dx
,
double
dy
,
{
OffsetEngineLayer
oldLayer
})
{
return
_pushSurface
(
engine
.
PersistedOffset
(
oldLayer
,
dx
,
dy
));
}
{
OffsetEngineLayer
oldLayer
});
/// Pushes a transform operation onto the operation stack.
///
...
...
@@ -202,15 +126,7 @@ class SceneBuilder {
///
/// See [pop] for details about the operation stack.
TransformEngineLayer
pushTransform
(
Float64List
matrix4
,
{
TransformEngineLayer
oldLayer
})
{
if
(
matrix4
==
null
)
{
throw
ArgumentError
(
'"matrix4" argument cannot be null'
);
}
if
(
matrix4
.
length
!=
16
)
{
throw
ArgumentError
(
'"matrix4" must have 16 entries.'
);
}
return
_pushSurface
(
engine
.
PersistedTransform
(
oldLayer
,
matrix4
));
}
{
TransformEngineLayer
oldLayer
});
/// Pushes a rectangular clip operation onto the operation stack.
///
...
...
@@ -219,11 +135,7 @@ class SceneBuilder {
/// See [pop] for details about the operation stack, and [Clip] for different clip modes.
/// By default, the clip will be anti-aliased (clip = [Clip.antiAlias]).
ClipRectEngineLayer
pushClipRect
(
Rect
rect
,
{
Clip
clipBehavior
=
Clip
.
antiAlias
,
ClipRectEngineLayer
oldLayer
})
{
assert
(
clipBehavior
!=
null
);
assert
(
clipBehavior
!=
Clip
.
none
);
return
_pushSurface
(
engine
.
PersistedClipRect
(
oldLayer
,
rect
));
}
{
Clip
clipBehavior
=
Clip
.
antiAlias
,
ClipRectEngineLayer
oldLayer
});
/// Pushes a rounded-rectangular clip operation onto the operation stack.
///
...
...
@@ -231,10 +143,7 @@ class SceneBuilder {
///
/// See [pop] for details about the operation stack.
ClipRRectEngineLayer
pushClipRRect
(
RRect
rrect
,
{
Clip
clipBehavior
,
ClipRRectEngineLayer
oldLayer
})
{
return
_pushSurface
(
engine
.
PersistedClipRRect
(
oldLayer
,
rrect
,
clipBehavior
));
}
{
Clip
clipBehavior
,
ClipRRectEngineLayer
oldLayer
});
/// Pushes a path clip operation onto the operation stack.
///
...
...
@@ -242,11 +151,7 @@ class SceneBuilder {
///
/// See [pop] for details about the operation stack.
ClipPathEngineLayer
pushClipPath
(
Path
path
,
{
Clip
clipBehavior
=
Clip
.
antiAlias
,
ClipPathEngineLayer
oldLayer
})
{
assert
(
clipBehavior
!=
null
);
assert
(
clipBehavior
!=
Clip
.
none
);
return
_pushSurface
(
engine
.
PersistedClipPath
(
oldLayer
,
path
,
clipBehavior
));
}
{
Clip
clipBehavior
=
Clip
.
antiAlias
,
ClipPathEngineLayer
oldLayer
});
/// Pushes an opacity operation onto the operation stack.
///
...
...
@@ -257,9 +162,7 @@ class SceneBuilder {
///
/// See [pop] for details about the operation stack.
OpacityEngineLayer
pushOpacity
(
int
alpha
,
{
Offset
offset
=
Offset
.
zero
,
OpacityEngineLayer
oldLayer
})
{
return
_pushSurface
(
engine
.
PersistedOpacity
(
oldLayer
,
alpha
,
offset
));
}
{
Offset
offset
=
Offset
.
zero
,
OpacityEngineLayer
oldLayer
});
/// Pushes a color filter operation onto the operation stack.
///
...
...
@@ -272,10 +175,7 @@ class SceneBuilder {
///
/// See [pop] for details about the operation stack.
ColorFilterEngineLayer
pushColorFilter
(
ColorFilter
filter
,
{
ColorFilterEngineLayer
oldLayer
})
{
assert
(
filter
!=
null
);
throw
UnimplementedError
();
}
{
ColorFilterEngineLayer
oldLayer
});
/// Pushes a backdrop filter operation onto the operation stack.
///
...
...
@@ -284,9 +184,7 @@ class SceneBuilder {
///
/// See [pop] for details about the operation stack.
BackdropFilterEngineLayer
pushBackdropFilter
(
ImageFilter
filter
,
{
BackdropFilterEngineLayer
oldLayer
})
{
return
_pushSurface
(
engine
.
PersistedBackdropFilter
(
oldLayer
,
filter
));
}
{
BackdropFilterEngineLayer
oldLayer
});
/// Pushes a shader mask operation onto the operation stack.
///
...
...
@@ -296,9 +194,7 @@ class SceneBuilder {
/// See [pop] for details about the operation stack.
ShaderMaskEngineLayer
pushShaderMask
(
Shader
shader
,
Rect
maskRect
,
BlendMode
blendMode
,
{
ShaderMaskEngineLayer
oldLayer
})
{
throw
UnimplementedError
();
}
{
ShaderMaskEngineLayer
oldLayer
});
/// Pushes a physical layer operation for an arbitrary shape onto the
/// operation stack.
...
...
@@ -319,16 +215,7 @@ class SceneBuilder {
Color
shadowColor
,
Clip
clipBehavior
=
Clip
.
none
,
PhysicalShapeEngineLayer
oldLayer
,
})
{
return
_pushSurface
(
engine
.
PersistedPhysicalShape
(
oldLayer
,
path
,
elevation
,
color
.
value
,
shadowColor
?.
value
??
0xFF000000
,
clipBehavior
,
));
}
});
/// Add a retained engine layer subtree from previous frames.
///
...
...
@@ -338,12 +225,7 @@ class SceneBuilder {
/// Therefore, when implementing a subclass of the [Layer] concept defined in
/// the rendering layer of Flutter's framework, once this is called, there's
/// no need to call [addToScene] for its children layers.
void
addRetained
(
EngineLayer
retainedLayer
)
{
final
engine
.
PersistedContainerSurface
retainedSurface
=
retainedLayer
;
assert
(
retainedSurface
.
isActive
||
retainedSurface
.
isReleased
);
retainedSurface
.
tryRetain
();
_adoptSurface
(
retainedSurface
);
}
void
addRetained
(
EngineLayer
retainedLayer
);
/// Ends the effect of the most recently pushed operation.
///
...
...
@@ -351,10 +233,7 @@ class SceneBuilder {
/// operations in the stack applies to each of the objects added to the scene.
/// Calling this function removes the most recently added operation from the
/// stack.
void
pop
()
{
assert
(
_surfaceStack
.
isNotEmpty
);
_surfaceStack
.
removeLast
();
}
void
pop
();
/// Adds an object to the scene that displays performance statistics.
///
...
...
@@ -379,25 +258,7 @@ class SceneBuilder {
///
/// See also the [PerformanceOverlayOption] enum in the rendering library.
/// for more details.
void
addPerformanceOverlay
(
int
enabledOptions
,
Rect
bounds
)
{
_addPerformanceOverlay
(
enabledOptions
,
bounds
.
left
,
bounds
.
right
,
bounds
.
top
,
bounds
.
bottom
);
}
/// Whether we've already warned the user about the lack of the performance
/// overlay or not.
///
/// We use this to avoid spamming the console with redundant warning messages.
static
bool
_webOnlyDidWarnAboutPerformanceOverlay
=
false
;
void
_addPerformanceOverlay
(
int
enabledOptions
,
double
left
,
double
right
,
double
top
,
double
bottom
)
{
if
(!
_webOnlyDidWarnAboutPerformanceOverlay
)
{
_webOnlyDidWarnAboutPerformanceOverlay
=
true
;
html
.
window
.
console
.
warn
(
'The performance overlay isn
\'
t supported on the web'
);
}
}
void
addPerformanceOverlay
(
int
enabledOptions
,
Rect
bounds
);
/// Adds a [Picture] to the scene.
///
...
...
@@ -407,17 +268,7 @@ class SceneBuilder {
Picture
picture
,
{
bool
isComplexHint
=
false
,
bool
willChangeHint
=
false
,
})
{
int
hints
=
0
;
if
(
isComplexHint
)
{
hints
|=
1
;
}
if
(
willChangeHint
)
{
hints
|=
2
;
}
_addSurface
(
engine
.
persistedPictureFactory
(
offset
.
dx
,
offset
.
dy
,
picture
,
hints
));
}
});
/// Adds a backend texture to the scene.
///
...
...
@@ -427,18 +278,7 @@ class SceneBuilder {
{
Offset
offset
=
Offset
.
zero
,
double
width
=
0.0
,
double
height
=
0.0
,
bool
freeze
=
false
})
{
assert
(
offset
!=
null
,
'Offset argument was null'
);
_addTexture
(
offset
.
dx
,
offset
.
dy
,
width
,
height
,
textureId
);
}
void
_addTexture
(
double
dx
,
double
dy
,
double
width
,
double
height
,
int
textureId
)
{
// In test mode, allow this to be a no-op.
if
(!
debugEmulateFlutterTesterEnvironment
)
{
throw
UnimplementedError
(
'Textures are not supported in Flutter Web'
);
}
}
bool
freeze
=
false
});
/// Adds a platform view (e.g an iOS UIView) to the scene.
///
...
...
@@ -461,20 +301,7 @@ class SceneBuilder {
Offset
offset
=
Offset
.
zero
,
double
width
=
0.0
,
double
height
=
0.0
,
})
{
assert
(
offset
!=
null
,
'Offset argument was null'
);
_addPlatformView
(
offset
.
dx
,
offset
.
dy
,
width
,
height
,
viewId
);
}
void
_addPlatformView
(
double
dx
,
double
dy
,
double
width
,
double
height
,
int
viewId
,
)
{
_addSurface
(
engine
.
PersistedPlatformView
(
viewId
,
dx
,
dy
,
width
,
height
));
}
});
/// (Fuchsia-only) Adds a scene rendered by another application to the scene
/// for this application.
...
...
@@ -483,14 +310,7 @@ class SceneBuilder {
double
width
=
0.0
,
double
height
=
0.0
,
SceneHost
sceneHost
,
bool
hitTestable
=
true
})
{
_addChildScene
(
offset
.
dx
,
offset
.
dy
,
width
,
height
,
sceneHost
,
hitTestable
);
}
void
_addChildScene
(
double
dx
,
double
dy
,
double
width
,
double
height
,
SceneHost
sceneHost
,
bool
hitTestable
)
{
throw
UnimplementedError
();
}
bool
hitTestable
=
true
});
/// Sets a threshold after which additional debugging information should be
/// recorded.
...
...
@@ -499,7 +319,7 @@ class SceneBuilder {
/// interested in using this feature, please contact [flutter-dev](https://groups.google.com/forum/#!forum/flutter-dev).
/// We'll hopefully be able to figure out how to make this feature more useful
/// to you.
void
setRasterizerTracingThreshold
(
int
frameInterval
)
{}
void
setRasterizerTracingThreshold
(
int
frameInterval
)
;
/// Sets whether the raster cache should checkerboard cached entries. This is
/// only useful for debugging purposes.
...
...
@@ -517,45 +337,13 @@ class SceneBuilder {
///
/// Currently this interface is difficult to use by end-developers. If you're
/// interested in using this feature, please contact [flutter-dev](https://groups.google.com/forum/#!forum/flutter-dev).
void
setCheckerboardRasterCacheImages
(
bool
checkerboard
)
{}
void
setCheckerboardRasterCacheImages
(
bool
checkerboard
)
;
/// Sets whether the compositor should checkerboard layers that are rendered
/// to offscreen bitmaps.
///
/// This is only useful for debugging purposes.
void
setCheckerboardOffscreenLayers
(
bool
checkerboard
)
{}
/// The scene recorded in the last frame.
///
/// This is a surface tree that holds onto the DOM elements that can be reused
/// on the next frame.
static
engine
.
PersistedScene
_lastFrameScene
;
/// Returns the computed persisted scene graph recorded in the last frame.
///
/// This is only available in debug mode. It returns `null` in profile and
/// release modes.
static
engine
.
PersistedScene
get
debugLastFrameScene
{
engine
.
PersistedScene
result
;
assert
(()
{
result
=
_lastFrameScene
;
return
true
;
}());
return
result
;
}
/// Discards information about previously rendered frames, including DOM
/// elements and cached canvases.
///
/// After calling this function new canvases will be created for the
/// subsequent scene. This is useful when tests need predictable canvas
/// sizes. If the cache is not cleared, then canvases allocated in one test
/// may be reused in another test.
static
void
debugForgetFrameScene
()
{
_lastFrameScene
?.
rootElement
?.
remove
();
_lastFrameScene
=
null
;
engine
.
debugForgetFrameScene
();
}
void
setCheckerboardOffscreenLayers
(
bool
checkerboard
);
/// Finishes building the scene.
///
...
...
@@ -565,24 +353,12 @@ class SceneBuilder {
///
/// After calling this function, the scene builder object is invalid and
/// cannot be used further.
Scene
build
()
{
_persistedScene
.
preroll
();
if
(
_lastFrameScene
==
null
)
{
_persistedScene
.
build
();
}
else
{
_persistedScene
.
update
(
_lastFrameScene
);
}
engine
.
commitScene
(
_persistedScene
);
_lastFrameScene
=
_persistedScene
;
return
Scene
.
_
(
_persistedScene
.
rootElement
);
}
Scene
build
();
/// Set properties on the linked scene. These properties include its bounds,
/// as well as whether it can be the target of focus events or not.
void
setProperties
(
double
width
,
double
height
,
double
insetTop
,
double
insetRight
,
double
insetBottom
,
double
insetLeft
,
bool
focusable
)
{
throw
UnimplementedError
();
}
double
insetRight
,
double
insetBottom
,
double
insetLeft
,
bool
focusable
);
}
/// A handle for the framework to hold and retain an engine layer across frames.
...
...
lib/web_ui/lib/src/ui/window.dart
浏览文件 @
5fe6083d
...
...
@@ -974,21 +974,7 @@ abstract class Window {
/// scheduling of frames.
/// * [RendererBinding], the Flutter framework class which manages layout and
/// painting.
void
render
(
Scene
scene
)
{
if
(
engine
.
experimentalUseSkia
)
{
final
engine
.
LayerScene
layerScene
=
scene
;
_rasterizer
.
draw
(
layerScene
.
layerTree
);
}
else
{
engine
.
domRenderer
.
renderScene
(
scene
.
webOnlyRootElement
);
}
}
final
engine
.
Rasterizer
_rasterizer
=
engine
.
experimentalUseSkia
?
engine
.
Rasterizer
(
engine
.
Surface
((
engine
.
SkCanvas
canvas
)
{
engine
.
domRenderer
.
renderScene
(
canvas
.
htmlCanvas
);
canvas
.
skSurface
.
callMethod
(
'flush'
);
}))
:
null
;
void
render
(
Scene
scene
);
String
get
initialLifecycleState
=>
_initialLifecycleState
;
...
...
lib/web_ui/test/compositing_test.dart
浏览文件 @
5fe6083d
...
...
@@ -185,7 +185,7 @@ void testLayerLifeCycle(
TestLayerBuilder
layerBuilder
,
ExpectedHtmlGetter
expectedHtmlGetter
)
{
// Force scene builder to start from scratch. This guarantees that the first
// scene starts from the "build" phase.
SceneBuilder
.
debugForgetFrameScene
();
S
urfaceS
ceneBuilder
.
debugForgetFrameScene
();
// Build: builds a brand new layer.
SceneBuilder
sceneBuilder
=
SceneBuilder
();
...
...
lib/web_ui/test/engine/surface/surface_test.dart
浏览文件 @
5fe6083d
...
...
@@ -12,7 +12,7 @@ import 'package:test/test.dart';
void
main
(
)
{
group
(
'Surface'
,
()
{
setUp
(()
{
SceneBuilder
.
debugForgetFrameScene
();
S
urfaceS
ceneBuilder
.
debugForgetFrameScene
();
});
test
(
'is created'
,
()
{
...
...
lib/web_ui/test/golden_tests/engine/compositing_golden_test.dart
浏览文件 @
5fe6083d
...
...
@@ -18,14 +18,14 @@ void main() async {
debugShowClipLayers
=
true
;
setUp
(()
{
SceneBuilder
.
debugForgetFrameScene
();
S
urfaceS
ceneBuilder
.
debugForgetFrameScene
();
for
(
html
.
Node
scene
in
html
.
document
.
querySelectorAll
(
'flt-scene'
))
{
scene
.
remove
();
}
});
test
(
'pushClipRect'
,
()
async
{
final
S
ceneBuilder
builder
=
SceneBuilder
();
final
S
urfaceSceneBuilder
builder
=
Surface
SceneBuilder
();
builder
.
pushClipRect
(
const
Rect
.
fromLTRB
(
10
,
10
,
60
,
60
),
);
...
...
@@ -38,7 +38,7 @@ void main() async {
},
timeout:
const
Timeout
(
Duration
(
seconds:
10
)));
test
(
'pushClipRect with offset and transform'
,
()
async
{
final
S
ceneBuilder
builder
=
SceneBuilder
();
final
S
urfaceSceneBuilder
builder
=
Surface
SceneBuilder
();
builder
.
pushOffset
(
0
,
60
);
builder
.
pushTransform
(
...
...
@@ -58,7 +58,7 @@ void main() async {
},
timeout:
const
Timeout
(
Duration
(
seconds:
10
)));
test
(
'pushClipRRect'
,
()
async
{
final
S
ceneBuilder
builder
=
SceneBuilder
();
final
S
urfaceSceneBuilder
builder
=
Surface
SceneBuilder
();
builder
.
pushClipRRect
(
RRect
.
fromLTRBR
(
10
,
10
,
60
,
60
,
const
Radius
.
circular
(
5
)),
);
...
...
@@ -71,7 +71,7 @@ void main() async {
},
timeout:
const
Timeout
(
Duration
(
seconds:
10
)));
test
(
'pushPhysicalShape'
,
()
async
{
final
S
ceneBuilder
builder
=
SceneBuilder
();
final
S
urfaceSceneBuilder
builder
=
Surface
SceneBuilder
();
builder
.
pushPhysicalShape
(
path:
Path
()..
addRect
(
const
Rect
.
fromLTRB
(
10
,
10
,
60
,
60
)),
clipBehavior:
Clip
.
hardEdge
,
...
...
@@ -204,7 +204,7 @@ void _testCullRectComputation() {
// Draw a picture inside a layer clip but fill all available space inside it.
// Verify that the cull rect is equal to the layer clip.
test
(
'fills layer clip rect'
,
()
async
{
final
S
ceneBuilder
builder
=
SceneBuilder
();
final
S
urfaceSceneBuilder
builder
=
Surface
SceneBuilder
();
builder
.
pushClipRect
(
const
Rect
.
fromLTWH
(
10
,
10
,
60
,
60
),
);
...
...
@@ -232,7 +232,7 @@ void _testCullRectComputation() {
// paint bounds overflow the layer clip. Verify that the cull rect is the
// intersection between the layer clip and paint bounds.
test
(
'intersects layer clip rect and paint bounds'
,
()
async
{
final
S
ceneBuilder
builder
=
SceneBuilder
();
final
S
urfaceSceneBuilder
builder
=
Surface
SceneBuilder
();
builder
.
pushClipRect
(
const
Rect
.
fromLTWH
(
10
,
10
,
60
,
60
),
);
...
...
@@ -260,7 +260,7 @@ void _testCullRectComputation() {
// an offset layer. Verify that the cull rect is the intersection between the
// layer clip and the offset paint bounds.
test
(
'offsets picture inside layer clip rect'
,
()
async
{
final
S
ceneBuilder
builder
=
SceneBuilder
();
final
S
urfaceSceneBuilder
builder
=
Surface
SceneBuilder
();
builder
.
pushClipRect
(
const
Rect
.
fromLTWH
(
10
,
10
,
60
,
60
),
);
...
...
@@ -320,7 +320,7 @@ void _testCullRectComputation() {
// Draw a picture inside a rotated clip. Verify that the cull rect is big
// enough to fit the rotated clip.
test
(
'rotates clip and the picture'
,
()
async
{
final
S
ceneBuilder
builder
=
SceneBuilder
();
final
S
urfaceSceneBuilder
builder
=
Surface
SceneBuilder
();
builder
.
pushOffset
(
80
,
50
);
builder
.
pushTransform
(
...
...
@@ -364,7 +364,7 @@ void _testCullRectComputation() {
},
timeout:
const
Timeout
(
Duration
(
seconds:
10
)));
test
(
'pushClipPath'
,
()
async
{
final
S
ceneBuilder
builder
=
SceneBuilder
();
final
S
urfaceSceneBuilder
builder
=
Surface
SceneBuilder
();
final
Path
path
=
Path
();
path
..
addRect
(
const
Rect
.
fromLTRB
(
10
,
10
,
60
,
60
));
builder
.
pushClipPath
(
...
...
@@ -381,9 +381,10 @@ void _testCullRectComputation() {
// Draw a picture inside a rotated clip. Verify that the cull rect is big
// enough to fit the rotated clip.
test
(
'clips correctly when using 3d transforms'
,
()
async
{
final
SceneBuilder
builder
=
SceneBuilder
();
final
double
screenWidth
=
html
.
window
.
innerWidth
.
toDouble
();
final
double
screenHeight
=
html
.
window
.
innerHeight
.
toDouble
();
final
SurfaceSceneBuilder
builder
=
SurfaceSceneBuilder
();
// TODO(yjbanov): see the TODO below.
// final double screenWidth = html.window.innerWidth.toDouble();
// final double screenHeight = html.window.innerHeight.toDouble();
final
Matrix4
scaleTransform
=
Matrix4
.
identity
().
scaled
(
0.5
,
0.2
);
builder
.
pushTransform
(
...
...
lib/web_ui/test/matchers.dart
浏览文件 @
5fe6083d
...
...
@@ -23,7 +23,7 @@ import 'package:ui/src/engine.dart';
///
/// Surfaces are returned in a depth-first order.
Iterable
<
PersistedSurface
>
enumerateSurfaces
([
PersistedSurface
root
])
{
root
??=
SceneBuilder
.
debugLastFrameScene
;
root
??=
S
urfaceS
ceneBuilder
.
debugLastFrameScene
;
final
List
<
PersistedSurface
>
surfaces
=
<
PersistedSurface
>[
root
];
root
.
visitChildren
((
PersistedSurface
surface
)
{
...
...
@@ -37,7 +37,7 @@ Iterable<PersistedSurface> enumerateSurfaces([PersistedSurface root]) {
///
/// If [root] is `null` returns all pictures from the last rendered scene.
Iterable
<
PersistedPicture
>
enumeratePictures
([
PersistedSurface
root
])
{
root
??=
SceneBuilder
.
debugLastFrameScene
;
root
??=
S
urfaceS
ceneBuilder
.
debugLastFrameScene
;
return
enumerateSurfaces
(
root
).
whereType
<
PersistedPicture
>();
}
...
...
@@ -45,7 +45,7 @@ Iterable<PersistedPicture> enumeratePictures([PersistedSurface root]) {
///
/// If [root] is `null` returns all pictures from the last rendered scene.
Iterable
<
PersistedOffset
>
enumerateOffsets
([
PersistedSurface
root
])
{
root
??=
SceneBuilder
.
debugLastFrameScene
;
root
??=
S
urfaceS
ceneBuilder
.
debugLastFrameScene
;
return
enumerateSurfaces
(
root
).
whereType
<
PersistedOffset
>();
}
...
...
@@ -459,7 +459,7 @@ String get currentHtml {
class
SceneTester
{
SceneTester
(
this
.
scene
);
final
Scene
scene
;
final
S
urfaceS
cene
scene
;
void
expectSceneHtml
(
String
expectedHtml
)
{
expectHtml
(
scene
.
webOnlyRootElement
,
expectedHtml
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录