Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Clean-up CanvasKit canvas sizing. #20387

Merged
merged 2 commits into from
Aug 13, 2020
Merged
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
4 changes: 2 additions & 2 deletions lib/web_ui/lib/src/engine/compositor/canvaskit_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ class CanvasKit {
external SkGrContext MakeGrContext(int glContext);
external SkSurface MakeOnScreenGLSurface(
SkGrContext grContext,
double width,
double height,
int width,
int height,
SkColorSpace colorSpace,
);
external SkSurface MakeSWCanvasSurface(html.CanvasElement canvas);
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/compositor/embedded_views.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class HtmlViewEmbedder {
Map<int, int> _clipCount = <int, int>{};

/// The size of the frame, in physical pixels.
ui.Size _frameSize = _computeFrameSize();
ui.Size _frameSize = ui.window.physicalSize;

void set frameSize(ui.Size size) {
if (_frameSize == size) {
Expand Down
10 changes: 1 addition & 9 deletions lib/web_ui/lib/src/engine/compositor/layer_tree.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class LayerTree {
Layer? rootLayer;

/// The size (in physical pixels) of the frame to paint this layer tree into.
final ui.Size frameSize = _computeFrameSize();
final ui.Size frameSize = ui.window.physicalSize;

/// The devicePixelRatio of the frame to paint this layer tree into.
double? devicePixelRatio;
Expand Down Expand Up @@ -54,14 +54,6 @@ class LayerTree {
}
}

ui.Size _computeFrameSize() {
final ui.Size physicalSize = ui.window.physicalSize;
return ui.Size(
physicalSize.width.truncate().toDouble(),
physicalSize.height.truncate().toDouble(),
);
}

/// A single frame to be rendered.
class Frame {
/// The canvas to render this frame to.
Expand Down
44 changes: 28 additions & 16 deletions lib/web_ui/lib/src/engine/compositor/surface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -89,22 +89,20 @@ class Surface {
_addedToScene = true;
}

ui.Size? _currentSize;

void _createOrUpdateSurfaces(ui.Size size) {
if (size.isEmpty) {
throw CanvasKitError('Cannot create surfaces of empty size.');
}

final CkSurface? currentSurface = _surface;
if (currentSurface != null) {
final bool isSameSize = size.width == currentSurface.width() &&
size.height == currentSurface.height();
if (isSameSize) {
// The existing surface is still reusable.
return;
}
if (size == _currentSize) {
// The existing surface is still reusable.
return;
}

currentSurface?.dispose();
_currentSize = size;
_surface?.dispose();
_surface = null;
htmlElement?.remove();
htmlElement = null;
Expand All @@ -113,14 +111,28 @@ class Surface {
_surface = _wrapHtmlCanvas(size);
}

CkSurface _wrapHtmlCanvas(ui.Size size) {
final ui.Size logicalSize = size / ui.window.devicePixelRatio;
CkSurface _wrapHtmlCanvas(ui.Size physicalSize) {
// If `physicalSize` is not precise, use a slightly bigger canvas. This way
// we ensure that the rendred picture covers the entire browser window.
final int pixelWidth = physicalSize.width.ceil();
final int pixelHeight = physicalSize.height.ceil();
final html.CanvasElement htmlCanvas = html.CanvasElement(
width: size.width.ceil(), height: size.height.ceil());
width: pixelWidth,
height: pixelHeight,
);

// The logical size of the canvas is not based on the size of the window
// but on the size of the canvas, which, due to `ceil()` above, may not be
// the same as the window. We do not round/floor/ceil the logical size as
// CSS pixels can contain more than one physical pixel and therefore to
// match the size of the window precisely we use the most precise floating
// point value we can get.
final double logicalWidth = pixelWidth / ui.window.devicePixelRatio;
final double logicalHeight = pixelHeight / ui.window.devicePixelRatio;
htmlCanvas.style
..position = 'absolute'
..width = '${logicalSize.width.ceil()}px'
..height = '${logicalSize.height.ceil()}px';
..width = '${logicalWidth}px'
..height = '${logicalHeight}px';

htmlElement = htmlCanvas;
if (webGLVersion == -1 || canvasKitForceCpuOnly) {
Expand Down Expand Up @@ -153,8 +165,8 @@ class Surface {

SkSurface? skSurface = canvasKit.MakeOnScreenGLSurface(
_grContext!,
size.width,
size.height,
pixelWidth,
pixelHeight,
SkColorSpaceSRGB,
);

Expand Down