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

Commit ec1d111

Browse files
authored
[web] Add ShaderBuilder, change drawVertices to use builder. (#21716)
* Move shader.dart into shaders directory * Add Shader builder basic structure and decls * rewrite drawVertices with ShaderBuilder * Fix in parameters in fragment shader to use varying for webgl1
1 parent 5aed0ee commit ec1d111

File tree

6 files changed

+667
-59
lines changed

6 files changed

+667
-59
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,8 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/recording_canvas.dart
489489
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/render_vertices.dart
490490
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/scene.dart
491491
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/scene_builder.dart
492-
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/shader.dart
492+
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/shaders/shader.dart
493+
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/shaders/shader_builder.dart
493494
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/surface.dart
494495
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/surface_stats.dart
495496
FILE: ../../../flutter/lib/web_ui/lib/src/engine/html/transform.dart

lib/web_ui/lib/src/engine.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ part 'engine/html/recording_canvas.dart';
8989
part 'engine/html/render_vertices.dart';
9090
part 'engine/html/scene.dart';
9191
part 'engine/html/scene_builder.dart';
92-
part 'engine/html/shader.dart';
92+
part 'engine/html/shaders/shader.dart';
93+
part 'engine/html/shaders/shader_builder.dart';
9394
part 'engine/html/surface.dart';
9495
part 'engine/html/surface_stats.dart';
9596
part 'engine/html/transform.dart';

lib/web_ui/lib/src/engine/html/render_vertices.dart

Lines changed: 68 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -77,51 +77,6 @@ abstract class _GlRenderer {
7777
/// This class gets instantiated on demand by Vertices constructor. For apps
7878
/// that don't use Vertices WebGlRenderer will be removed from release binary.
7979
class _WebGlRenderer implements _GlRenderer {
80-
// Vertex shader transforms pixel space [Vertices.positions] to
81-
// final clipSpace -1..1 coordinates with inverted Y Axis.
82-
static const _vertexShaderTriangle = '''
83-
#version 300 es
84-
layout (location=0) in vec4 position;
85-
layout (location=1) in vec4 color;
86-
uniform mat4 u_ctransform;
87-
uniform vec4 u_scale;
88-
uniform vec4 u_shift;
89-
out vec4 vColor;
90-
void main() {
91-
gl_Position = ((u_ctransform * position) * u_scale) + u_shift;
92-
vColor = color.zyxw;
93-
}''';
94-
// This fragment shader enables Int32List of colors to be passed directly
95-
// to gl context buffer for rendering by decoding RGBA8888.
96-
static const _fragmentShaderTriangle = '''
97-
#version 300 es
98-
precision highp float;
99-
in vec4 vColor;
100-
out vec4 fragColor;
101-
void main() {
102-
fragColor = vColor;
103-
}''';
104-
105-
// WebGL 1 version of shaders above for compatibility with Safari.
106-
static const _vertexShaderTriangleEs1 = '''
107-
attribute vec4 position;
108-
attribute vec4 color;
109-
uniform mat4 u_ctransform;
110-
uniform vec4 u_scale;
111-
uniform vec4 u_shift;
112-
varying vec4 vColor;
113-
void main() {
114-
gl_Position = ((u_ctransform * position) * u_scale) + u_shift;
115-
vColor = color.zyxw;
116-
}''';
117-
// WebGL 1 version of shaders above for compatibility with Safari.
118-
static const _fragmentShaderTriangleEs1 = '''
119-
precision highp float;
120-
varying vec4 vColor;
121-
void main() {
122-
gl_FragColor = vColor;
123-
}''';
124-
12580
@override
12681
void drawVertices(
12782
html.CanvasRenderingContext2D? context,
@@ -161,16 +116,16 @@ class _WebGlRenderer implements _GlRenderer {
161116
if (widthInPixels == 0 || heightInPixels == 0) {
162117
return;
163118
}
119+
final String vertexShader = _writeVerticesVertexShader();
120+
final String fragmentShader = _writeVerticesFragmentShader();
164121
_GlContext gl =
165122
_OffscreenCanvas.createGlContext(widthInPixels, heightInPixels)!;
166-
_GlProgram glProgram = webGLVersion == 1
167-
? gl.useAndCacheProgram(
168-
_vertexShaderTriangleEs1, _fragmentShaderTriangleEs1)!
169-
: gl.useAndCacheProgram(
170-
_vertexShaderTriangle, _fragmentShaderTriangle)!;
171-
172-
Object? transformUniform = gl.getUniformLocation(glProgram.program, 'u_ctransform');
173-
Matrix4 transformAtOffset = transform.clone()..translate(-offsetX, -offsetY);
123+
_GlProgram glProgram = gl.useAndCacheProgram(vertexShader, fragmentShader)!;
124+
125+
Object? transformUniform = gl.getUniformLocation(glProgram.program,
126+
'u_ctransform');
127+
Matrix4 transformAtOffset = transform.clone()
128+
..translate(-offsetX, -offsetY);
174129
gl.setUniformMatrix4fv(transformUniform, false, transformAtOffset.storage);
175130

176131
// Set uniform to scale 0..width/height pixels coordinates to -1..1
@@ -186,18 +141,21 @@ class _WebGlRenderer implements _GlRenderer {
186141
assert(positionsBuffer != null); // ignore: unnecessary_null_comparison
187142
gl.bindArrayBuffer(positionsBuffer);
188143
gl.bufferData(positions, gl.kStaticDraw);
144+
Object? positionLoc = gl.getAttribLocation(glProgram.program, 'position');
189145
js_util.callMethod(
190-
gl.glContext!, 'vertexAttribPointer', <dynamic>[0, 2, gl.kFloat, false, 0, 0]);
146+
gl.glContext!, 'vertexAttribPointer', <dynamic>[
147+
positionLoc, 2, gl.kFloat, false, 0, 0,
148+
]);
191149
gl.enableVertexAttribArray(0);
192150

193151
// Setup color buffer.
194152
Object? colorsBuffer = gl.createBuffer();
195153
gl.bindArrayBuffer(colorsBuffer);
196154
// Buffer kBGRA_8888.
197155
gl.bufferData(vertices._colors, gl.kStaticDraw);
198-
156+
Object? colorLoc = gl.getAttribLocation(glProgram.program, 'color');
199157
js_util.callMethod(gl.glContext!, 'vertexAttribPointer',
200-
<dynamic>[1, 4, gl.kUnsignedByte, true, 0, 0]);
158+
<dynamic>[colorLoc, 4, gl.kUnsignedByte, true, 0, 0]);
201159
gl.enableVertexAttribArray(1);
202160
gl.clear();
203161
final int vertexCount = positions.length ~/ 2;
@@ -209,6 +167,51 @@ class _WebGlRenderer implements _GlRenderer {
209167
context.restore();
210168
}
211169

170+
/// Vertex shader transforms pixel space [Vertices.positions] to
171+
/// final clipSpace -1..1 coordinates with inverted Y Axis.
172+
/// #version 300 es
173+
/// layout (location=0) in vec4 position;
174+
/// layout (location=1) in vec4 color;
175+
/// uniform mat4 u_ctransform;
176+
/// uniform vec4 u_scale;
177+
/// uniform vec4 u_shift;
178+
/// out vec4 vColor;
179+
/// void main() {
180+
/// gl_Position = ((u_ctransform * position) * u_scale) + u_shift;
181+
/// v_color = color.zyxw;
182+
/// }
183+
String _writeVerticesVertexShader() {
184+
ShaderBuilder builder = ShaderBuilder(webGLVersion);
185+
builder.addIn(ShaderType.kVec4, name: 'position');
186+
builder.addIn(ShaderType.kVec4, name: 'color');
187+
builder.addUniform(ShaderType.kMat4, name: 'u_ctransform');
188+
builder.addUniform(ShaderType.kVec4, name: 'u_scale');
189+
builder.addUniform(ShaderType.kVec4, name: 'u_shift');
190+
builder.addOut(ShaderType.kVec4, name: 'v_color');
191+
ShaderMethod method = builder.addMethod('main');
192+
method.addStatement('gl_Position = ((u_ctransform * position) * u_scale) + u_shift;');
193+
method.addStatement('v_color = color.zyxw;');
194+
return builder.build();
195+
}
196+
197+
/// This fragment shader enables Int32List of colors to be passed directly
198+
/// to gl context buffer for rendering by decoding RGBA8888.
199+
/// #version 300 es
200+
/// precision mediump float;
201+
/// in vec4 vColor;
202+
/// out vec4 fragColor;
203+
/// void main() {
204+
/// fragColor = vColor;
205+
/// }
206+
String _writeVerticesFragmentShader() {
207+
ShaderBuilder builder = ShaderBuilder.fragment(webGLVersion);
208+
builder.floatPrecision = ShaderPrecision.kMedium;
209+
builder.addIn(ShaderType.kVec4, name:'v_color');
210+
ShaderMethod method = builder.addMethod('main');
211+
method.addStatement('${builder.fragmentColor.name} = v_color;');
212+
return builder.build();
213+
}
214+
212215
@override
213216
void drawHairline(html.CanvasRenderingContext2D? _ctx, Float32List positions) {
214217
assert(positions != null); // ignore: unnecessary_null_comparison
@@ -547,7 +550,15 @@ class _GlContext {
547550
/// Returns reference to uniform in program.
548551
Object? getUniformLocation(Object? program, String uniformName) {
549552
return js_util
550-
.callMethod(glContext!, 'getUniformLocation', <dynamic>[program, uniformName]);
553+
.callMethod(glContext!, 'getUniformLocation',
554+
<dynamic>[program, uniformName]);
555+
}
556+
557+
/// Returns reference to attribute in program.
558+
Object? getAttribLocation(Object? program, String uniformName) {
559+
return js_util
560+
.callMethod(glContext!, 'getAttribLocation',
561+
<dynamic>[program, uniformName]);
551562
}
552563

553564
/// Sets vec2 uniform values.

0 commit comments

Comments
 (0)