Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
37bbe444
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
37bbe444
编写于
2月 03, 2021
作者:
Y
Yegor
提交者:
GitHub
2月 03, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[canvaskit] update CSS size of the canvas when device-pixel ratio changes (#24160)
上级
edcca811
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
80 addition
and
25 deletion
+80
-25
lib/web_ui/lib/src/engine/canvaskit/surface.dart
lib/web_ui/lib/src/engine/canvaskit/surface.dart
+43
-25
lib/web_ui/test/canvaskit/surface_test.dart
lib/web_ui/test/canvaskit/surface_test.dart
+37
-0
未找到文件。
lib/web_ui/lib/src/engine/canvaskit/surface.dart
浏览文件 @
37bbe444
...
...
@@ -59,6 +59,11 @@ class Surface {
/// due to the browser tab becoming dormant.
final
html
.
Element
htmlElement
=
html
.
Element
.
tag
(
'flt-canvas-container'
);
/// The underlying `<canvas>` element used for this surface.
html
.
CanvasElement
?
htmlCanvas
;
int
_pixelWidth
=
-
1
;
int
_pixelHeight
=
-
1
;
/// Specify the GPU resource cache limits.
void
setSkiaResourceCacheMaxBytes
(
int
bytes
)
{
_skiaCacheBytes
=
bytes
;
...
...
@@ -102,6 +107,7 @@ class Surface {
}
ui
.
Size
?
_currentSize
;
double
_currentDevicePixelRatio
=
-
1
;
CkSurface
_createOrUpdateSurfaces
(
ui
.
Size
size
)
{
if
(
size
.
isEmpty
)
{
...
...
@@ -116,9 +122,13 @@ class Surface {
size
.
width
<=
previousSize
.
width
&&
size
.
height
<=
previousSize
.
height
)
{
// The existing surface is still reusable.
if
(
window
.
devicePixelRatio
!=
_currentDevicePixelRatio
)
{
_updateLogicalHtmlCanvasSize
();
}
return
_surface
!;
}
_currentDevicePixelRatio
=
window
.
devicePixelRatio
;
_currentSize
=
_currentSize
==
null
// First frame. Allocate a canvas of the exact size as the window. The
// window is frequently never resized, particularly on mobile, so using
...
...
@@ -131,36 +141,44 @@ class Surface {
_surface
=
null
;
_addedToScene
=
false
;
return
_surface
=
_
wrapHtmlCanvas
(
_currentSize
!);
return
_surface
=
_
createNewSurface
(
_currentSize
!);
}
CkSurface
_wrapHtmlCanvas
(
ui
.
Size
physicalSize
)
{
// Clear the container, if it's not empty.
while
(
htmlElement
.
firstChild
!=
null
)
{
htmlElement
.
firstChild
!.
remove
();
/// Sets the CSS size of the canvas so that canvas pixels are 1:1 with device
/// pixels.
///
/// 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.
void
_updateLogicalHtmlCanvasSize
()
{
final
double
logicalWidth
=
_pixelWidth
/
ui
.
window
.
devicePixelRatio
;
final
double
logicalHeight
=
_pixelHeight
/
ui
.
window
.
devicePixelRatio
;
htmlCanvas
!.
style
..
width
=
'
${logicalWidth}
px'
..
height
=
'
${logicalHeight}
px'
;
}
/// This function is expensive.
///
/// It's better to reuse surface if possible.
CkSurface
_createNewSurface
(
ui
.
Size
physicalSize
)
{
// Clear the container, if it's not empty. We're going to create a new <canvas>.
this
.
htmlCanvas
?.
remove
();
// 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
();
_
pixelWidth
=
physicalSize
.
width
.
ceil
();
_
pixelHeight
=
physicalSize
.
height
.
ceil
();
final
html
.
CanvasElement
htmlCanvas
=
html
.
CanvasElement
(
width:
pixelWidth
,
height:
pixelHeight
,
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
=
'
${logicalWidth}
px'
..
height
=
'
${logicalHeight}
px'
;
this
.
htmlCanvas
=
htmlCanvas
;
htmlCanvas
.
style
.
position
=
'absolute'
;
_updateLogicalHtmlCanvasSize
();
// When the browser tab using WebGL goes dormant the browser and/or OS may
// decide to clear GPU resources to let other tabs/programs use the GPU.
...
...
@@ -212,8 +230,8 @@ class Surface {
SkSurface
?
skSurface
=
canvasKit
.
MakeOnScreenGLSurface
(
_grContext
!,
pixelWidth
,
pixelHeight
,
_
pixelWidth
,
_
pixelHeight
,
SkColorSpaceSRGB
,
);
...
...
lib/web_ui/test/canvaskit/surface_test.dart
浏览文件 @
37bbe444
...
...
@@ -27,10 +27,14 @@ void testMain() {
// Expect exact requested dimensions.
expect
(
original
.
width
(),
9
);
expect
(
original
.
height
(),
19
);
expect
(
surface
.
htmlCanvas
!.
style
.
width
,
'9px'
);
expect
(
surface
.
htmlCanvas
!.
style
.
height
,
'19px'
);
// Shrinking reuses the existing surface straight-up.
final
CkSurface
shrunk
=
surface
.
acquireFrame
(
ui
.
Size
(
5
,
15
)).
skiaSurface
;
expect
(
shrunk
,
same
(
original
));
expect
(
surface
.
htmlCanvas
!.
style
.
width
,
'9px'
);
expect
(
surface
.
htmlCanvas
!.
style
.
height
,
'19px'
);
// The first increase will allocate a new surface, but will overallocate
// by 40% to accommodate future increases.
...
...
@@ -40,6 +44,8 @@ void testMain() {
// Expect overallocated dimensions
expect
(
firstIncrease
.
width
(),
14
);
expect
(
firstIncrease
.
height
(),
28
);
expect
(
surface
.
htmlCanvas
!.
style
.
width
,
'14px'
);
expect
(
surface
.
htmlCanvas
!.
style
.
height
,
'28px'
);
// Subsequent increases within 40% reuse the old surface.
final
CkSurface
secondIncrease
=
surface
.
acquireFrame
(
ui
.
Size
(
11
,
22
)).
skiaSurface
;
...
...
@@ -52,6 +58,8 @@ void testMain() {
// Also over-allocated
expect
(
huge
.
width
(),
28
);
expect
(
huge
.
height
(),
56
);
expect
(
surface
.
htmlCanvas
!.
style
.
width
,
'28px'
);
expect
(
surface
.
htmlCanvas
!.
style
.
height
,
'56px'
);
// Shrink again. Reuse the last allocated surface.
final
CkSurface
shrunk2
=
surface
.
acquireFrame
(
ui
.
Size
(
5
,
15
)).
skiaSurface
;
...
...
@@ -88,5 +96,34 @@ void testMain() {
// Firefox doesn't have the WEBGL_lose_context extension.
skip:
isFirefox
||
isIosSafari
,
);
// Regression test for https://github.com/flutter/flutter/issues/75286
test
(
'updates canvas logical size when device-pixel ratio changes'
,
()
{
final
Surface
surface
=
Surface
(
HtmlViewEmbedder
());
final
CkSurface
original
=
surface
.
acquireFrame
(
ui
.
Size
(
10
,
16
)).
skiaSurface
;
expect
(
original
.
width
(),
10
);
expect
(
original
.
height
(),
16
);
expect
(
surface
.
htmlCanvas
!.
style
.
width
,
'10px'
);
expect
(
surface
.
htmlCanvas
!.
style
.
height
,
'16px'
);
// Increase device-pixel ratio: this makes CSS pixels bigger, so we need
// fewer of them to cover the browser window.
window
.
debugOverrideDevicePixelRatio
(
2.0
);
final
CkSurface
highDpr
=
surface
.
acquireFrame
(
ui
.
Size
(
10
,
16
)).
skiaSurface
;
expect
(
highDpr
.
width
(),
10
);
expect
(
highDpr
.
height
(),
16
);
expect
(
surface
.
htmlCanvas
!.
style
.
width
,
'5px'
);
expect
(
surface
.
htmlCanvas
!.
style
.
height
,
'8px'
);
// Decrease device-pixel ratio: this makes CSS pixels smaller, so we need
// more of them to cover the browser window.
window
.
debugOverrideDevicePixelRatio
(
0.5
);
final
CkSurface
lowDpr
=
surface
.
acquireFrame
(
ui
.
Size
(
10
,
16
)).
skiaSurface
;
expect
(
lowDpr
.
width
(),
10
);
expect
(
lowDpr
.
height
(),
16
);
expect
(
surface
.
htmlCanvas
!.
style
.
width
,
'20px'
);
expect
(
surface
.
htmlCanvas
!.
style
.
height
,
'32px'
);
});
},
skip:
isIosSafari
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录