blob: f05bd910bdbdd5d973a6d289895b2cd8c42e6919 [file] [log] [blame]
// 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.
import 'dart:typed_data';
import 'package:ui/ui.dart' as ui;
import '../../engine.dart' show toMatrix32;
import '../vector_math.dart';
import 'layer.dart';
import 'layer_tree.dart';
import 'path.dart';
import 'picture.dart';
class LayerScene implements ui.Scene {
final LayerTree layerTree;
LayerScene(RootLayer rootLayer) : layerTree = LayerTree(rootLayer);
@override
void dispose() {}
@override
Future<ui.Image> toImage(int width, int height) {
final ui.Picture picture = layerTree.flatten();
return picture.toImage(width, height);
}
}
class LayerSceneBuilder implements ui.SceneBuilder {
LayerSceneBuilder() : rootLayer = RootLayer() {
currentLayer = rootLayer;
}
final RootLayer rootLayer;
late ContainerLayer currentLayer;
@override
void addPerformanceOverlay(int enabledOptions, ui.Rect bounds) {
// We don't plan to implement this on the web.
throw UnimplementedError();
}
@override
void addPicture(
ui.Offset offset,
ui.Picture picture, {
bool isComplexHint = false,
bool willChangeHint = false,
}) {
currentLayer.add(PictureLayer(
picture as CkPicture, offset, isComplexHint, willChangeHint));
}
@override
void addRetained(ui.EngineLayer retainedLayer) {
currentLayer.add(retainedLayer as Layer);
}
@override
void addTexture(
int textureId, {
ui.Offset offset = ui.Offset.zero,
double width = 0.0,
double height = 0.0,
bool freeze = false,
ui.FilterQuality filterQuality = ui.FilterQuality.low,
}) {
// TODO(b/128315641): implement addTexture.
}
@override
void addPlatformView(
int viewId, {
ui.Offset offset = ui.Offset.zero,
double width = 0.0,
double height = 0.0,
Object? webOnlyPaintedBy,
}) {
currentLayer.add(PlatformViewLayer(viewId, offset, width, height));
}
@override
LayerScene build() {
return LayerScene(rootLayer);
}
@override
void pop() {
if (currentLayer == rootLayer) {
// Don't pop the root layer. It must always be there.
return;
}
currentLayer = currentLayer.parent!;
}
@override
BackdropFilterEngineLayer pushBackdropFilter(
ui.ImageFilter filter, {
ui.BlendMode blendMode = ui.BlendMode.srcOver,
ui.EngineLayer? oldLayer,
}) {
return pushLayer<BackdropFilterEngineLayer>(BackdropFilterEngineLayer(
filter,
blendMode,
));
}
@override
ClipPathEngineLayer pushClipPath(
ui.Path path, {
ui.Clip clipBehavior = ui.Clip.antiAlias,
ui.EngineLayer? oldLayer,
}) {
return pushLayer<ClipPathEngineLayer>(
ClipPathEngineLayer(path as CkPath, clipBehavior));
}
@override
ClipRRectEngineLayer pushClipRRect(
ui.RRect rrect, {
ui.Clip? clipBehavior,
ui.EngineLayer? oldLayer,
}) {
return pushLayer<ClipRRectEngineLayer>(
ClipRRectEngineLayer(rrect, clipBehavior));
}
@override
ClipRectEngineLayer pushClipRect(
ui.Rect rect, {
ui.Clip clipBehavior = ui.Clip.antiAlias,
ui.EngineLayer? oldLayer,
}) {
return pushLayer<ClipRectEngineLayer>(
ClipRectEngineLayer(rect, clipBehavior));
}
@override
ColorFilterEngineLayer pushColorFilter(
ui.ColorFilter filter, {
ui.ColorFilterEngineLayer? oldLayer,
}) {
assert(filter != null); // ignore: unnecessary_null_comparison
return pushLayer<ColorFilterEngineLayer>(ColorFilterEngineLayer(filter));
}
@override
ImageFilterEngineLayer pushImageFilter(
ui.ImageFilter filter, {
ui.ImageFilterEngineLayer? oldLayer,
}) {
assert(filter != null); // ignore: unnecessary_null_comparison
return pushLayer<ImageFilterEngineLayer>(ImageFilterEngineLayer(filter));
}
@override
OffsetEngineLayer pushOffset(
double dx,
double dy, {
ui.EngineLayer? oldLayer,
}) {
return pushLayer<OffsetEngineLayer>(OffsetEngineLayer(dx, dy));
}
@override
OpacityEngineLayer pushOpacity(
int alpha, {
ui.EngineLayer? oldLayer,
ui.Offset offset = ui.Offset.zero,
}) {
return pushLayer<OpacityEngineLayer>(OpacityEngineLayer(alpha, offset));
}
@override
PhysicalShapeEngineLayer pushPhysicalShape({
required ui.Path path,
required double elevation,
required ui.Color color,
ui.Color? shadowColor,
ui.Clip clipBehavior = ui.Clip.none,
ui.EngineLayer? oldLayer,
}) {
return pushLayer<PhysicalShapeEngineLayer>(PhysicalShapeEngineLayer(
elevation,
color,
shadowColor,
path as CkPath,
clipBehavior,
));
}
@override
ShaderMaskEngineLayer pushShaderMask(
ui.Shader shader,
ui.Rect maskRect,
ui.BlendMode blendMode, {
ui.EngineLayer? oldLayer,
ui.FilterQuality filterQuality = ui.FilterQuality.low,
}) {
return pushLayer<ShaderMaskEngineLayer>(
ShaderMaskEngineLayer(shader, maskRect, blendMode, filterQuality));
}
@override
TransformEngineLayer pushTransform(
Float64List matrix4, {
ui.EngineLayer? oldLayer,
}) {
final Matrix4 matrix = Matrix4.fromFloat32List(toMatrix32(matrix4));
return pushLayer<TransformEngineLayer>(TransformEngineLayer(matrix));
}
@override
void setCheckerboardOffscreenLayers(bool checkerboard) {
// TODO: implement setCheckerboardOffscreenLayers
}
@override
void setCheckerboardRasterCacheImages(bool checkerboard) {
// TODO: implement setCheckerboardRasterCacheImages
}
@override
void setRasterizerTracingThreshold(int frameInterval) {
// TODO: implement setRasterizerTracingThreshold
}
T pushLayer<T extends ContainerLayer>(T layer) {
currentLayer.add(layer);
currentLayer = layer;
return layer;
}
@override
void setProperties(
double width,
double height,
double insetTop,
double insetRight,
double insetBottom,
double insetLeft,
bool focusable,
) {
throw UnimplementedError();
}
}