Skip to content

Commit c81a2ec

Browse files
authored
[web]Update @Dart annotation. Change shaders to allocate smaller canvas (flutter#22481)
1 parent 34938c4 commit c81a2ec

File tree

155 files changed

+302
-193
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+302
-193
lines changed

ci/analyze.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,6 @@ analyze \
9595
"$FLUTTER_DIR/testing/scenario_app"
9696

9797
# Check that dart libraries conform.
98+
echo "Checking web_ui api conformance..."
9899
(cd "$FLUTTER_DIR/web_sdk"; pub get)
99100
(cd "$FLUTTER_DIR"; dart "web_sdk/test/api_conform_test.dart")

lib/web_ui/lib/src/engine.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.10
5+
// @dart = 2.12
66
@JS()
77
library engine;
88

lib/web_ui/lib/src/engine/alarm_clock.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.10
5+
// @dart = 2.12
66
part of engine;
77

88
/// A function that returns current system time.

lib/web_ui/lib/src/engine/assets.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.10
5+
// @dart = 2.12
66
part of engine;
77

88
/// This class downloads assets over the network.

lib/web_ui/lib/src/engine/bitmap_canvas.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.10
5+
// @dart = 2.12
66
part of engine;
77

88
/// A raw HTML canvas that is directly written to.

lib/web_ui/lib/src/engine/browser_detection.dart

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.10
5+
// @dart = 2.12
66
part of engine;
77

88
/// The HTML engine used by the current browser.
@@ -27,6 +27,14 @@ enum BrowserEngine {
2727
unknown,
2828
}
2929

30+
/// html webgl version qualifier constants.
31+
abstract class WebGLVersion {
32+
// WebGL 1.0 is based on OpenGL ES 2.0 / GLSL 1.00
33+
static const int webgl1 = 1;
34+
// WebGL 2.0 is based on OpenGL ES 3.0 / GLSL 3.00
35+
static const int webgl2 = 2;
36+
}
37+
3038
/// Lazily initialized current browser engine.
3139
late final BrowserEngine _browserEngine = _detectBrowserEngine();
3240

@@ -181,10 +189,10 @@ int _detectWebGLVersion() {
181189
height: 1,
182190
);
183191
if (canvas.getContext('webgl2') != null) {
184-
return 2;
192+
return WebGLVersion.webgl2;
185193
}
186194
if (canvas.getContext('webgl') != null) {
187-
return 1;
195+
return WebGLVersion.webgl1;
188196
}
189197
return -1;
190198
}

lib/web_ui/lib/src/engine/canvas_pool.dart

Lines changed: 119 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.10
5+
// @dart = 2.12
66
part of engine;
77

88
/// Allocates and caches 0 or more canvas(s) for [BitmapCanvas].
@@ -515,19 +515,28 @@ class _CanvasPool extends _SaveStackTracking {
515515
void strokeLine(ui.Offset p1, ui.Offset p2) {
516516
html.CanvasRenderingContext2D ctx = context;
517517
ctx.beginPath();
518-
ctx.moveTo(p1.dx, p1.dy);
519-
ctx.lineTo(p2.dx, p2.dy);
518+
final ui.Rect? shaderBounds = contextHandle._shaderBounds;
519+
if (shaderBounds == null) {
520+
ctx.moveTo(p1.dx, p1.dy);
521+
ctx.lineTo(p2.dx, p2.dy);
522+
} else {
523+
ctx.moveTo(p1.dx - shaderBounds.left, p1.dy - shaderBounds.top);
524+
ctx.lineTo(p2.dx - shaderBounds.left, p2.dy - shaderBounds.top);
525+
}
520526
ctx.stroke();
521527
}
522528

523529
void drawPoints(ui.PointMode pointMode, Float32List points, double radius) {
524530
html.CanvasRenderingContext2D ctx = context;
525531
final int len = points.length;
532+
final ui.Rect? shaderBounds = contextHandle._shaderBounds;
533+
double offsetX = shaderBounds == null ? 0 : -shaderBounds.left;
534+
double offsetY = shaderBounds == null ? 0 : -shaderBounds.top;
526535
switch (pointMode) {
527536
case ui.PointMode.points:
528537
for (int i = 0; i < len; i += 2) {
529-
final double x = points[i];
530-
final double y = points[i + 1];
538+
final double x = points[i] + offsetX;
539+
final double y = points[i + 1] + offsetY;
531540
ctx.beginPath();
532541
ctx.arc(x, y, radius, 0, 2.0 * math.pi);
533542
ctx.fill();
@@ -536,16 +545,16 @@ class _CanvasPool extends _SaveStackTracking {
536545
case ui.PointMode.lines:
537546
ctx.beginPath();
538547
for (int i = 0; i < (len - 2); i += 4) {
539-
ctx.moveTo(points[i], points[i + 1]);
540-
ctx.lineTo(points[i + 2], points[i + 3]);
548+
ctx.moveTo(points[i] + offsetX, points[i + 1] + offsetY);
549+
ctx.lineTo(points[i + 2] + offsetX, points[i + 3] + offsetY);
541550
ctx.stroke();
542551
}
543552
break;
544553
case ui.PointMode.polygon:
545554
ctx.beginPath();
546-
ctx.moveTo(points[0], points[1]);
555+
ctx.moveTo(points[0] + offsetX, points[1] + offsetY);
547556
for (int i = 2; i < len; i += 2) {
548-
ctx.lineTo(points[i], points[i + 1]);
557+
ctx.lineTo(points[i] + offsetX, points[i + 1] + offsetY);
549558
}
550559
ctx.stroke();
551560
break;
@@ -597,39 +606,117 @@ class _CanvasPool extends _SaveStackTracking {
597606
}
598607
}
599608

609+
/// Applies path to drawing context, preparing for fill and other operations.
610+
///
611+
/// WARNING: Don't refactor _runPath/_runPathWithOffset. Latency sensitive
612+
void _runPathWithOffset(html.CanvasRenderingContext2D ctx, SurfacePath path,
613+
double offsetX, double offsetY) {
614+
ctx.beginPath();
615+
final Float32List p = _runBuffer;
616+
final PathRefIterator iter = PathRefIterator(path.pathRef);
617+
int verb = 0;
618+
while ((verb = iter.next(p)) != SPath.kDoneVerb) {
619+
switch (verb) {
620+
case SPath.kMoveVerb:
621+
ctx.moveTo(p[0] + offsetX, p[1] + offsetY);
622+
break;
623+
case SPath.kLineVerb:
624+
ctx.lineTo(p[2] + offsetX, p[3] + offsetY);
625+
break;
626+
case SPath.kCubicVerb:
627+
ctx.bezierCurveTo(p[2] + offsetX, p[3] + offsetY,
628+
p[4] + offsetX, p[5] + offsetY, p[6] + offsetX, p[7] + offsetY);
629+
break;
630+
case SPath.kQuadVerb:
631+
ctx.quadraticCurveTo(p[2] + offsetX, p[3] + offsetY,
632+
p[4] + offsetX, p[5] + offsetY);
633+
break;
634+
case SPath.kConicVerb:
635+
final double w = iter.conicWeight;
636+
Conic conic = Conic(p[0], p[1], p[2], p[3], p[4], p[5], w);
637+
List<ui.Offset> points = conic.toQuads();
638+
final int len = points.length;
639+
for (int i = 1; i < len; i += 2) {
640+
final double p1x = points[i].dx;
641+
final double p1y = points[i].dy;
642+
final double p2x = points[i + 1].dx;
643+
final double p2y = points[i + 1].dy;
644+
ctx.quadraticCurveTo(p1x + offsetX, p1y + offsetY,
645+
p2x + offsetX, p2y + offsetY);
646+
}
647+
break;
648+
case SPath.kCloseVerb:
649+
ctx.closePath();
650+
break;
651+
default:
652+
throw UnimplementedError('Unknown path verb $verb');
653+
}
654+
}
655+
}
656+
600657
void drawRect(ui.Rect rect, ui.PaintingStyle? style) {
601658
context.beginPath();
602-
context.rect(rect.left, rect.top, rect.width, rect.height);
659+
final ui.Rect? shaderBounds = contextHandle._shaderBounds;
660+
if (shaderBounds == null) {
661+
context.rect(rect.left, rect.top, rect.width, rect.height);
662+
} else {
663+
context.rect(rect.left - shaderBounds.left, rect.top - shaderBounds.top,
664+
rect.width, rect.height);
665+
}
603666
contextHandle.paint(style);
604667
}
605668

606669
void drawRRect(ui.RRect roundRect, ui.PaintingStyle? style) {
607-
_RRectToCanvasRenderer(context).render(roundRect);
670+
final ui.Rect? shaderBounds = contextHandle._shaderBounds;
671+
_RRectToCanvasRenderer(context).render(
672+
shaderBounds == null ? roundRect
673+
: roundRect.shift(ui.Offset(-shaderBounds.left, -shaderBounds.top)));
608674
contextHandle.paint(style);
609675
}
610676

611677
void drawDRRect(ui.RRect outer, ui.RRect inner, ui.PaintingStyle? style) {
612678
_RRectRenderer renderer = _RRectToCanvasRenderer(context);
613-
renderer.render(outer);
614-
renderer.render(inner, startNewPath: false, reverse: true);
679+
final ui.Rect? shaderBounds = contextHandle._shaderBounds;
680+
if (shaderBounds == null) {
681+
renderer.render(outer);
682+
renderer.render(inner, startNewPath: false, reverse: true);
683+
} else {
684+
final ui.Offset shift = ui.Offset(-shaderBounds.left, -shaderBounds.top);
685+
renderer.render(outer.shift(shift));
686+
renderer.render(inner.shift(shift), startNewPath: false, reverse: true);
687+
}
615688
contextHandle.paint(style);
616689
}
617690

618691
void drawOval(ui.Rect rect, ui.PaintingStyle? style) {
619692
context.beginPath();
620-
DomRenderer.ellipse(context, rect.center.dx, rect.center.dy, rect.width / 2,
693+
ui.Rect? shaderBounds = contextHandle._shaderBounds;
694+
final double cx = shaderBounds == null ? rect.center.dx :
695+
rect.center.dx - shaderBounds.left;
696+
final double cy = shaderBounds == null ? rect.center.dy :
697+
rect.center.dy - shaderBounds.top;
698+
DomRenderer.ellipse(context, cx, cy, rect.width / 2,
621699
rect.height / 2, 0, 0, 2.0 * math.pi, false);
622700
contextHandle.paint(style);
623701
}
624702

625703
void drawCircle(ui.Offset c, double radius, ui.PaintingStyle? style) {
626704
context.beginPath();
627-
DomRenderer.ellipse(context, c.dx, c.dy, radius, radius, 0, 0, 2.0 * math.pi, false);
705+
final ui.Rect? shaderBounds = contextHandle._shaderBounds;
706+
final double cx = shaderBounds == null ? c.dx : c.dx - shaderBounds.left;
707+
final double cy = shaderBounds == null ? c.dy : c.dy - shaderBounds.top;
708+
DomRenderer.ellipse(context, cx, cy, radius, radius, 0, 0, 2.0 * math.pi, false);
628709
contextHandle.paint(style);
629710
}
630711

631712
void drawPath(ui.Path path, ui.PaintingStyle? style) {
632-
_runPath(context, path as SurfacePath);
713+
final ui.Rect? shaderBounds = contextHandle._shaderBounds;
714+
if (shaderBounds == null) {
715+
_runPath(context, path as SurfacePath);
716+
} else {
717+
_runPathWithOffset(context, path as SurfacePath,
718+
-shaderBounds.left, -shaderBounds.top);
719+
}
633720
contextHandle.paintPath(style, path.fillType);
634721
}
635722

@@ -789,6 +876,14 @@ class ContextStateHandle {
789876
ui.MaskFilter? _currentFilter;
790877
SurfacePaintData? _lastUsedPaint;
791878

879+
/// Currently active shader bounds.
880+
///
881+
/// When a paint style uses a shader that produces a pattern, the pattern
882+
/// origin is relative to current transform. Therefore any painting operations
883+
/// will have to reverse the transform to correctly align pattern with
884+
/// drawing bounds.
885+
ui.Rect? _shaderBounds;
886+
792887
/// The painting state.
793888
///
794889
/// Used to validate that the [setUpPaint] and [tearDownPaint] are called in
@@ -824,6 +919,9 @@ class ContextStateHandle {
824919
density);
825920
fillStyle = paintStyle;
826921
strokeStyle = paintStyle;
922+
_shaderBounds = shaderBounds;
923+
// Align pattern origin to destination.
924+
context.translate(shaderBounds!.left, shaderBounds.top);
827925
} else if (paint.color != null) {
828926
final String? colorString = colorToCssString(paint.color);
829927
fillStyle = colorString;
@@ -906,6 +1004,10 @@ class ContextStateHandle {
9061004
// shadow attributes.
9071005
context.restore();
9081006
}
1007+
if (_shaderBounds != null) {
1008+
context.translate(-_shaderBounds!.left, -_shaderBounds!.top);
1009+
_shaderBounds = null;
1010+
}
9091011
}
9101012

9111013
void paint(ui.PaintingStyle? style) {
@@ -948,6 +1050,7 @@ class ContextStateHandle {
9481050
_currentStrokeCap = ui.StrokeCap.butt;
9491051
context.lineJoin = 'miter';
9501052
_currentStrokeJoin = ui.StrokeJoin.miter;
1053+
_shaderBounds = null;
9511054
}
9521055
}
9531056

lib/web_ui/lib/src/engine/canvaskit/canvas.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.10
5+
// @dart = 2.12
66
part of engine;
77

88
/// A Dart wrapper around Skia's [SkCanvas].

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
/// Prefer keeping the original CanvasKit names so it is easier to locate
88
/// the API behind these bindings in the Skia source code.
99
10-
// @dart = 2.10
10+
// @dart = 2.12
1111
part of engine;
1212

1313
/// Entrypoint into the CanvasKit API.

lib/web_ui/lib/src/engine/canvaskit/canvaskit_canvas.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
// @dart = 2.10
5+
// @dart = 2.12
66
part of engine;
77

88
/// An implementation of [ui.Canvas] that is backed by a CanvasKit canvas.

0 commit comments

Comments
 (0)