Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lib/ui/compositing.dart
Original file line number Diff line number Diff line change
Expand Up @@ -814,11 +814,14 @@ class SceneBuilder extends NativeFieldWrapperClass1 {
/// synchronized with the UIView frames adding additional performance overhead.
///
/// The `offset` argument is not used for iOS and Android.
/// The `zIndex` argument is only used by the CanvasKit renderer. Negative values render behind the
/// canvas and will not require additional WebGL contexts.
void addPlatformView(
int viewId, {
Offset offset = Offset.zero,
double width = 0.0,
double height = 0.0,
int? zIndex,
}) {
_addPlatformView(offset.dx, offset.dy, width, height, viewId);
}
Expand Down
1 change: 1 addition & 0 deletions lib/web_ui/lib/compositing.dart
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ abstract class SceneBuilder {
Offset offset = Offset.zero,
double width = 0.0,
double height = 0.0,
int zIndex,
});
void setRasterizerTracingThreshold(int frameInterval);
void setCheckerboardRasterCacheImages(bool checkerboard);
Expand Down
75 changes: 47 additions & 28 deletions lib/web_ui/lib/src/engine/canvaskit/embedded_views.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ import '../vector_math.dart';
import '../window.dart';
import 'canvas.dart';
import 'embedded_views_diff.dart';
import 'layer_scene_builder.dart';
import 'path.dart';
import 'picture_recorder.dart';
import 'renderer.dart';
import 'surface.dart';
import 'surface_factory.dart';


/// This composites HTML views into the [ui.Scene].
class HtmlViewEmbedder {
HtmlViewEmbedder._();
Expand Down Expand Up @@ -123,24 +125,27 @@ class HtmlViewEmbedder {
}

void prerollCompositeEmbeddedView(int viewId, EmbeddedViewParams params) {
final bool hasAvailableOverlay =
_context.pictureRecordersCreatedDuringPreroll.length <
SurfaceFactory.instance.maximumOverlays;
if (!hasAvailableOverlay && !_warnedAboutTooManySurfaces) {
_warnedAboutTooManySurfaces = true;
printWarning('Flutter was unable to create enough overlay surfaces. '
'This is usually caused by too many platform views being '
'displayed at once. '
'You may experience incorrect rendering.');
}
// We need an overlay for each visible platform view. Invisible platform
// views will be grouped with (at most) one visible platform view later.
final bool needNewOverlay = platformViewManager.isVisible(viewId);
if (needNewOverlay && hasAvailableOverlay) {
final CkPictureRecorder pictureRecorder = CkPictureRecorder();
pictureRecorder.beginRecording(ui.Offset.zero & _frameSize);
pictureRecorder.recordingCanvas!.clear(const ui.Color(0x00000000));
_context.pictureRecordersCreatedDuringPreroll.add(pictureRecorder);
if (params.zIndex >= 0) {

final bool hasAvailableOverlay =
_context.pictureRecordersCreatedDuringPreroll.length <
SurfaceFactory.instance.maximumOverlays;
if (!hasAvailableOverlay && !_warnedAboutTooManySurfaces) {
_warnedAboutTooManySurfaces = true;
printWarning('Flutter was unable to create enough overlay surfaces. '
'This is usually caused by too many platform views being '
'displayed at once. '
'You may experience incorrect rendering.');
}
// We need an overlay for each visible platform view. Invisible platform
// views will be grouped with (at most) one visible platform view later.
final bool needNewOverlay = platformViewManager.isVisible(viewId);
if (needNewOverlay && hasAvailableOverlay) {
final CkPictureRecorder pictureRecorder = CkPictureRecorder();
pictureRecorder.beginRecording(ui.Offset.zero & _frameSize);
pictureRecorder.recordingCanvas!.clear(const ui.Color(0x00000000));
_context.pictureRecordersCreatedDuringPreroll.add(pictureRecorder);
}
}

// Do nothing if the params didn't change.
Expand All @@ -167,14 +172,18 @@ class HtmlViewEmbedder {
if (platformViewManager.isVisible(viewId)) {
_context.visibleViewCount++;
}
// We need a new overlay if this is a visible view.
final bool needNewOverlay = platformViewManager.isVisible(viewId);

CkPictureRecorder? recorderToUseForRendering;
if (needNewOverlay) {
if (overlayIndex < _context.pictureRecordersCreatedDuringPreroll.length) {
recorderToUseForRendering =
_context.pictureRecordersCreatedDuringPreroll[overlayIndex];
_context.pictureRecorders.add(recorderToUseForRendering);
if((_currentCompositionParams[viewId]?.zIndex ?? defaultPlatformViewLayerZIndex) >= 0) {
// We need a new overlay if this is a visible view.
final bool needNewOverlay = platformViewManager.isVisible(viewId);

if (needNewOverlay) {
if (overlayIndex < _context.pictureRecordersCreatedDuringPreroll.length) {
recorderToUseForRendering =
_context.pictureRecordersCreatedDuringPreroll[overlayIndex];
_context.pictureRecorders.add(recorderToUseForRendering);
}
}
}

Expand Down Expand Up @@ -215,6 +224,10 @@ class HtmlViewEmbedder {
root: newPlatformViewRoot,
clipCount: currentClippingCount,
);

if(params.zIndex != 0) {
newPlatformViewRoot.style.zIndex = params.zIndex.toString();
}
}

// Apply mutators to the slot
Expand Down Expand Up @@ -646,6 +659,10 @@ class HtmlViewEmbedder {

for (int i = 0; i < views.length; i++) {
final int view = views[i];
if((_currentCompositionParams[view]?.zIndex ?? defaultPlatformViewLayerZIndex) < 0) {
// If view will be rendered behind canvas we don't need an overlay
continue;
}
if (platformViewManager.isInvisible(view)) {
// We add as many invisible views as we find to the current group.
currentGroup.add(view);
Expand Down Expand Up @@ -785,12 +802,13 @@ class ViewClipChain {

/// The parameters passed to the view embedder.
class EmbeddedViewParams {
EmbeddedViewParams(this.offset, this.size, MutatorsStack mutators)
EmbeddedViewParams(this.offset, this.size, MutatorsStack mutators, this.zIndex)
: mutators = MutatorsStack._copy(mutators);

final ui.Offset offset;
final ui.Size size;
final MutatorsStack mutators;
final int zIndex;

@override
bool operator ==(Object other) {
Expand All @@ -800,11 +818,12 @@ class EmbeddedViewParams {
return other is EmbeddedViewParams &&
other.offset == offset &&
other.size == size &&
other.mutators == mutators;
other.mutators == mutators &&
other.zIndex == zIndex;
}

@override
int get hashCode => Object.hash(offset, size, mutators);
int get hashCode => Object.hash(offset, size, mutators, zIndex);
}

enum MutatorType {
Expand Down
11 changes: 9 additions & 2 deletions lib/web_ui/lib/src/engine/canvaskit/layer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,8 @@ class PhysicalShapeEngineLayer extends ContainerLayer

final double _elevation;
final ui.Color _color;
final ui.Color? _shadowColor; // ignore: use_late_for_private_fields_and_variables
final ui.Color?
_shadowColor; // ignore: use_late_for_private_fields_and_variables
final CkPath _path;
final ui.Clip _clipBehavior;

Expand Down Expand Up @@ -583,12 +584,13 @@ class ColorFilterEngineLayer extends ContainerLayer

/// A layer which renders a platform view (an HTML element in this case).
class PlatformViewLayer extends Layer {
PlatformViewLayer(this.viewId, this.offset, this.width, this.height);
PlatformViewLayer(this.viewId, this.offset, this.width, this.height, this.zIndex);

final int viewId;
final ui.Offset offset;
final double width;
final double height;
final int zIndex;

@override
void preroll(PrerollContext prerollContext, Matrix4 matrix) {
Expand All @@ -602,6 +604,7 @@ class PlatformViewLayer extends Layer {
offset,
ui.Size(width, height),
prerollContext.mutatorsStack,
zIndex,
),
);
}
Expand All @@ -613,5 +616,9 @@ class PlatformViewLayer extends Layer {
if (canvas != null) {
paintContext.leafNodesCanvas = canvas;
}

if (zIndex < 0) {
paintContext.leafNodesCanvas?.clear(const ui.Color.fromARGB(0, 0, 0, 0));
}
}
}
5 changes: 4 additions & 1 deletion lib/web_ui/lib/src/engine/canvaskit/layer_scene_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import 'layer_tree.dart';
import 'path.dart';
import 'picture.dart';

const int defaultPlatformViewLayerZIndex = -1;

class LayerScene implements ui.Scene {
LayerScene(RootLayer rootLayer) : layerTree = LayerTree(rootLayer);

Expand Down Expand Up @@ -82,8 +84,9 @@ class LayerSceneBuilder implements ui.SceneBuilder {
double width = 0.0,
double height = 0.0,
Object? webOnlyPaintedBy,
int? zIndex,
}) {
currentLayer.add(PlatformViewLayer(viewId, offset, width, height));
currentLayer.add(PlatformViewLayer(viewId, offset, width, height, zIndex ?? defaultPlatformViewLayerZIndex));
}

@override
Expand Down
1 change: 1 addition & 0 deletions lib/web_ui/lib/src/engine/html/scene_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ class SurfaceSceneBuilder implements ui.SceneBuilder {
ui.Offset offset = ui.Offset.zero,
double width = 0.0,
double height = 0.0,
int? zIndex
}) {
_addPlatformView(offset.dx, offset.dy, width, height, viewId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ class SkwasmSceneBuilder implements ui.SceneBuilder {
int viewId, {
ui.Offset offset = ui.Offset.zero,
double width = 0.0,
double height = 0.0
double height = 0.0,
int? zIndex
}) {
throw UnimplementedError('Platform view not yet implemented with skwasm renderer.');
}
Expand Down