Skip to content

Commit f1855fb

Browse files
authored
Clean-up CanvasKit canvas sizing. (#20387)
* Clean-up CanvasKit canvas sizing. * cache size correctly
1 parent eef639c commit f1855fb

File tree

4 files changed

+32
-28
lines changed

4 files changed

+32
-28
lines changed

lib/web_ui/lib/src/engine/compositor/canvaskit_api.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ class CanvasKit {
7676
external SkGrContext MakeGrContext(int glContext);
7777
external SkSurface MakeOnScreenGLSurface(
7878
SkGrContext grContext,
79-
double width,
80-
double height,
79+
int width,
80+
int height,
8181
SkColorSpace colorSpace,
8282
);
8383
external SkSurface MakeSWCanvasSurface(html.CanvasElement canvas);

lib/web_ui/lib/src/engine/compositor/embedded_views.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class HtmlViewEmbedder {
4949
Map<int, int> _clipCount = <int, int>{};
5050

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

5454
void set frameSize(ui.Size size) {
5555
if (_frameSize == size) {

lib/web_ui/lib/src/engine/compositor/layer_tree.dart

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class LayerTree {
1111
Layer? rootLayer;
1212

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

1616
/// The devicePixelRatio of the frame to paint this layer tree into.
1717
double? devicePixelRatio;
@@ -54,14 +54,6 @@ class LayerTree {
5454
}
5555
}
5656

57-
ui.Size _computeFrameSize() {
58-
final ui.Size physicalSize = ui.window.physicalSize;
59-
return ui.Size(
60-
physicalSize.width.truncate().toDouble(),
61-
physicalSize.height.truncate().toDouble(),
62-
);
63-
}
64-
6557
/// A single frame to be rendered.
6658
class Frame {
6759
/// The canvas to render this frame to.

lib/web_ui/lib/src/engine/compositor/surface.dart

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -89,22 +89,20 @@ class Surface {
8989
_addedToScene = true;
9090
}
9191

92+
ui.Size? _currentSize;
93+
9294
void _createOrUpdateSurfaces(ui.Size size) {
9395
if (size.isEmpty) {
9496
throw CanvasKitError('Cannot create surfaces of empty size.');
9597
}
9698

97-
final CkSurface? currentSurface = _surface;
98-
if (currentSurface != null) {
99-
final bool isSameSize = size.width == currentSurface.width() &&
100-
size.height == currentSurface.height();
101-
if (isSameSize) {
102-
// The existing surface is still reusable.
103-
return;
104-
}
99+
if (size == _currentSize) {
100+
// The existing surface is still reusable.
101+
return;
105102
}
106103

107-
currentSurface?.dispose();
104+
_currentSize = size;
105+
_surface?.dispose();
108106
_surface = null;
109107
htmlElement?.remove();
110108
htmlElement = null;
@@ -113,14 +111,28 @@ class Surface {
113111
_surface = _wrapHtmlCanvas(size);
114112
}
115113

116-
CkSurface _wrapHtmlCanvas(ui.Size size) {
117-
final ui.Size logicalSize = size / ui.window.devicePixelRatio;
114+
CkSurface _wrapHtmlCanvas(ui.Size physicalSize) {
115+
// If `physicalSize` is not precise, use a slightly bigger canvas. This way
116+
// we ensure that the rendred picture covers the entire browser window.
117+
final int pixelWidth = physicalSize.width.ceil();
118+
final int pixelHeight = physicalSize.height.ceil();
118119
final html.CanvasElement htmlCanvas = html.CanvasElement(
119-
width: size.width.ceil(), height: size.height.ceil());
120+
width: pixelWidth,
121+
height: pixelHeight,
122+
);
123+
124+
// The logical size of the canvas is not based on the size of the window
125+
// but on the size of the canvas, which, due to `ceil()` above, may not be
126+
// the same as the window. We do not round/floor/ceil the logical size as
127+
// CSS pixels can contain more than one physical pixel and therefore to
128+
// match the size of the window precisely we use the most precise floating
129+
// point value we can get.
130+
final double logicalWidth = pixelWidth / ui.window.devicePixelRatio;
131+
final double logicalHeight = pixelHeight / ui.window.devicePixelRatio;
120132
htmlCanvas.style
121133
..position = 'absolute'
122-
..width = '${logicalSize.width.ceil()}px'
123-
..height = '${logicalSize.height.ceil()}px';
134+
..width = '${logicalWidth}px'
135+
..height = '${logicalHeight}px';
124136

125137
htmlElement = htmlCanvas;
126138
if (webGLVersion == -1 || canvasKitForceCpuOnly) {
@@ -153,8 +165,8 @@ class Surface {
153165

154166
SkSurface? skSurface = canvasKit.MakeOnScreenGLSurface(
155167
_grContext!,
156-
size.width,
157-
size.height,
168+
pixelWidth,
169+
pixelHeight,
158170
SkColorSpaceSRGB,
159171
);
160172

0 commit comments

Comments
 (0)