Skip to content

Commit

Permalink
Adds API for retaining intermediate engine layers (#9461)
Browse files Browse the repository at this point in the history
Add new optional named oldLayer arguments to all push* methods of the SceneBuilder class.

When not null oldLayer signals to the engine that the intent is to update a layer rendered in a previous frame. The engine may optionally use that signal to reuse the resources allocated for that layer in the previous frame. For example, on the Web we can reuse existing DOM nodes and some of their properties and move fewer nodes around the tree.

The return type of each push method has been tightened up. Instead of having all methods return the same EngineLayer type, each method has its own unique layer type, e.g. OffsetEngineLayer. oldLayer parameters match the returned type. This prevents the framework (and other developers using dart:ui directly) from accidentally supplying an engine layer of the wrong type.
  • Loading branch information
yjbanov authored Jun 28, 2019
1 parent 7d1508d commit 94bb7a7
Show file tree
Hide file tree
Showing 9 changed files with 707 additions and 77 deletions.
6 changes: 3 additions & 3 deletions lib/stub_ui/lib/src/engine/compositor/layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ part of engine;
///
/// A layer is the lowest-level rendering primitive. It represents an atomic
/// painting command.
abstract class Layer {
abstract class Layer implements ui.EngineLayer {
/// The layer that contains us as a child.
ContainerLayer parent;

Expand Down Expand Up @@ -173,7 +173,7 @@ class ClipRRectLayer extends ContainerLayer {
}

/// A layer that transforms its child layers by the given transform matrix.
class TransformLayer extends ContainerLayer {
class TransformLayer extends ContainerLayer implements ui.OffsetEngineLayer, ui.TransformEngineLayer {
/// The matrix with which to transform the child layers.
final Matrix4 _transform;

Expand Down Expand Up @@ -287,7 +287,7 @@ class PictureLayer extends Layer {
///
/// The shape clips its children to a given [Path], and casts a shadow based
/// on the given elevation.
class PhysicalShapeLayer extends ContainerLayer {
class PhysicalShapeLayer extends ContainerLayer implements ui.PhysicalShapeEngineLayer {
final double _elevation;
final ui.Color _color;
final ui.Color _shadowColor;
Expand Down
55 changes: 25 additions & 30 deletions lib/stub_ui/lib/src/engine/compositor/layer_scene_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@

part of engine;

class EngineLayerImpl extends ui.EngineLayer {
final ContainerLayer _layer;

EngineLayerImpl(this._layer);
}

class LayerScene implements ui.Scene {
final LayerTree layerTree;

Expand Down Expand Up @@ -60,7 +54,7 @@ class LayerSceneBuilder implements ui.SceneBuilder {
@override
void addRetained(ui.EngineLayer retainedLayer) {
if (currentLayer == null) return;
currentLayer.add((retainedLayer as EngineLayerImpl)._layer);
currentLayer.add(retainedLayer);
}

@override
Expand Down Expand Up @@ -95,80 +89,81 @@ class LayerSceneBuilder implements ui.SceneBuilder {
}

@override
ui.EngineLayer pushBackdropFilter(ui.ImageFilter filter,
{Object webOnlyPaintedBy}) {
ui.BackdropFilterEngineLayer pushBackdropFilter(ui.ImageFilter filter,
{ui.BackdropFilterEngineLayer oldLayer}) {
throw new UnimplementedError();
}

@override
ui.EngineLayer pushClipPath(ui.Path path,
{ui.Clip clipBehavior = ui.Clip.antiAlias, Object webOnlyPaintedBy}) {
ui.ClipPathEngineLayer pushClipPath(ui.Path path,
{ui.Clip clipBehavior = ui.Clip.antiAlias, ui.ClipPathEngineLayer oldLayer}) {
pushLayer(ClipPathLayer(path));
return null;
}

@override
ui.EngineLayer pushClipRRect(ui.RRect rrect,
{ui.Clip clipBehavior, Object webOnlyPaintedBy}) {
ui.ClipRRectEngineLayer pushClipRRect(ui.RRect rrect,
{ui.Clip clipBehavior, ui.ClipRRectEngineLayer oldLayer}) {
pushLayer(ClipRRectLayer(rrect));
return null;
}

@override
ui.EngineLayer pushClipRect(ui.Rect rect,
{ui.Clip clipBehavior = ui.Clip.antiAlias, Object webOnlyPaintedBy}) {
ui.ClipRectEngineLayer pushClipRect(ui.Rect rect,
{ui.Clip clipBehavior = ui.Clip.antiAlias, ui.ClipRectEngineLayer oldLayer}) {
pushLayer(ClipRectLayer(rect));
return null;
}

@override
ui.EngineLayer pushColorFilter(ui.Color color, ui.BlendMode blendMode,
{Object webOnlyPaintedBy}) {
ui.ColorFilterEngineLayer pushColorFilter(ui.Color color, ui.BlendMode blendMode,
{ui.ColorFilterEngineLayer oldLayer}) {
throw new UnimplementedError();
}

@override
ui.EngineLayer pushOffset(double dx, double dy, {Object webOnlyPaintedBy}) {
ui.OffsetEngineLayer pushOffset(double dx, double dy, {ui.OffsetEngineLayer oldLayer}) {
final matrix = Matrix4.translationValues(dx, dy, 0.0);
final layer = TransformLayer(matrix);
pushLayer(layer);
return EngineLayerImpl(layer);
return layer;
}

@override
ui.EngineLayer pushOpacity(int alpha,
{Object webOnlyPaintedBy, ui.Offset offset = ui.Offset.zero}) {
ui.OpacityEngineLayer pushOpacity(int alpha,
{ui.OpacityEngineLayer oldLayer, ui.Offset offset = ui.Offset.zero}) {
// TODO(het): Implement opacity
pushOffset(0.0, 0.0);
return null;
}

@override
ui.EngineLayer pushPhysicalShape(
ui.PhysicalShapeEngineLayer pushPhysicalShape(
{ui.Path path,
double elevation,
ui.Color color,
ui.Color shadowColor,
ui.Clip clipBehavior = ui.Clip.none,
Object webOnlyPaintedBy}) {
ui.PhysicalShapeEngineLayer oldLayer}) {
final layer =
PhysicalShapeLayer(elevation, color, shadowColor, path, clipBehavior);
pushLayer(layer);
return EngineLayerImpl(layer);
return layer;
}

@override
ui.EngineLayer pushShaderMask(
ui.ShaderMaskEngineLayer pushShaderMask(
ui.Shader shader, ui.Rect maskRect, ui.BlendMode blendMode,
{Object webOnlyPaintedBy}) {
{ui.ShaderMaskEngineLayer oldLayer}) {
throw new UnimplementedError();
}

@override
ui.EngineLayer pushTransform(Float64List matrix4, {Object webOnlyPaintedBy}) {
final matrix = Matrix4.fromList(matrix4);
pushLayer(TransformLayer(matrix));
return null;
ui.TransformEngineLayer pushTransform(Float64List matrix4, {ui.TransformEngineLayer oldLayer}) {
final Matrix4 matrix = Matrix4.fromList(matrix4);
final TransformLayer layer = TransformLayer(matrix);
pushLayer(layer);
return layer;
}

@override
Expand Down
8 changes: 4 additions & 4 deletions lib/stub_ui/lib/src/engine/surface/clip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ mixin _DomClip on PersistedContainerSurface {
}

/// A surface that creates a rectangular clip.
class PersistedClipRect extends PersistedContainerSurface with _DomClip {
class PersistedClipRect extends PersistedContainerSurface with _DomClip implements ui.ClipRectEngineLayer {
PersistedClipRect(Object paintedBy, this.rect) : super(paintedBy);

final ui.Rect rect;
Expand Down Expand Up @@ -99,7 +99,7 @@ class PersistedClipRect extends PersistedContainerSurface with _DomClip {
}

/// A surface that creates a rounded rectangular clip.
class PersistedClipRRect extends PersistedContainerSurface with _DomClip {
class PersistedClipRRect extends PersistedContainerSurface with _DomClip implements ui.ClipRRectEngineLayer {
PersistedClipRRect(Object paintedBy, this.rrect, this.clipBehavior)
: super(paintedBy);

Expand Down Expand Up @@ -148,7 +148,7 @@ class PersistedClipRRect extends PersistedContainerSurface with _DomClip {
}
}

class PersistedPhysicalShape extends PersistedContainerSurface with _DomClip {
class PersistedPhysicalShape extends PersistedContainerSurface with _DomClip implements ui.PhysicalShapeEngineLayer {
PersistedPhysicalShape(Object paintedBy, this.path, this.elevation, int color,
int shadowColor, this.clipBehavior)
: this.color = ui.Color(color),
Expand Down Expand Up @@ -313,7 +313,7 @@ class PersistedPhysicalShape extends PersistedContainerSurface with _DomClip {
}

/// A surface that clips it's children.
class PersistedClipPath extends PersistedContainerSurface {
class PersistedClipPath extends PersistedContainerSurface implements ui.ClipPathEngineLayer {
PersistedClipPath(Object paintedBy, this.clipPath, this.clipBehavior)
: super(paintedBy);

Expand Down
2 changes: 1 addition & 1 deletion lib/stub_ui/lib/src/engine/surface/offset.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
part of engine;

/// A surface that translates its children using CSS transform and translate.
class PersistedOffset extends PersistedContainerSurface {
class PersistedOffset extends PersistedContainerSurface implements ui.OffsetEngineLayer {
PersistedOffset(Object paintedBy, this.dx, this.dy) : super(paintedBy);

/// Horizontal displacement.
Expand Down
2 changes: 1 addition & 1 deletion lib/stub_ui/lib/src/engine/surface/opacity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
part of engine;

/// A surface that makes its children transparent.
class PersistedOpacity extends PersistedContainerSurface {
class PersistedOpacity extends PersistedContainerSurface implements ui.OpacityEngineLayer {
PersistedOpacity(Object paintedBy, this.alpha, this.offset)
: super(paintedBy);

Expand Down
2 changes: 1 addition & 1 deletion lib/stub_ui/lib/src/engine/surface/transform.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
part of engine;

/// A surface that transforms its children using CSS transform.
class PersistedTransform extends PersistedContainerSurface {
class PersistedTransform extends PersistedContainerSurface implements ui.TransformEngineLayer {
PersistedTransform(Object paintedBy, this.matrix4) : super(paintedBy);

final Float64List matrix4;
Expand Down
Loading

0 comments on commit 94bb7a7

Please sign in to comment.