Rendering SVG images with same size as WebGL texture doesn't work correctly
https://bugs.webkit.org/show_bug.cgi?id=182367
Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2018-02-06
Reviewed by Dean Jackson.
Source/WebCore:
If am image buffer is created for a webgl texture and then it is reused
for another texture, it has to be cleared before drawing.
Test: webgl/webgl-texture-image-buffer-reuse.html
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer):
LayoutTests:
* webgl/webgl-texture-image-buffer-reuse-expected.html: Added.
* webgl/webgl-texture-image-buffer-reuse.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@228213 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index d04b60a..68a815c 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2018-02-06 Said Abou-Hallawa <sabouhallawa@apple.com>
+
+ Rendering SVG images with same size as WebGL texture doesn't work correctly
+ https://bugs.webkit.org/show_bug.cgi?id=182367
+
+ Reviewed by Dean Jackson.
+
+ * webgl/webgl-texture-image-buffer-reuse-expected.html: Added.
+ * webgl/webgl-texture-image-buffer-reuse.html: Added.
+
2018-02-06 Matt Lewis <jlewis3@apple.com>
Marked transitions/transition-display-property.html as flaky.
diff --git a/LayoutTests/webgl/webgl-texture-image-buffer-reuse-expected.html b/LayoutTests/webgl/webgl-texture-image-buffer-reuse-expected.html
new file mode 100644
index 0000000..aec216a
--- /dev/null
+++ b/LayoutTests/webgl/webgl-texture-image-buffer-reuse-expected.html
@@ -0,0 +1,17 @@
+<style>
+ canvas {
+ width: 100px;
+ height: 100px;
+ border: 1px solid green;
+ }
+</style>
+<body>
+ <p>Ensure if an image buffer is reused for a webgl texture, it will be cleared before drawing.</p>
+ <canvas width="100" height="100"/>
+ <script>
+ const canvas = document.querySelector('canvas');
+ const ctx = canvas.getContext('2d');
+ ctx.fillStyle = 'green';
+ ctx.fillRect(canvas.width / 4, canvas.height / 4, canvas.width / 2, canvas.height / 2);
+ </script>
+</body>
diff --git a/LayoutTests/webgl/webgl-texture-image-buffer-reuse.html b/LayoutTests/webgl/webgl-texture-image-buffer-reuse.html
new file mode 100644
index 0000000..f6e43bd
--- /dev/null
+++ b/LayoutTests/webgl/webgl-texture-image-buffer-reuse.html
@@ -0,0 +1,112 @@
+<style>
+ canvas {
+ width: 100px;
+ height: 100px;
+ border: 1px green solid;
+ }
+</style>
+<body>
+ <p>Ensure if an image buffer is reused for a webgl texture, it will be cleared before drawing.</p>
+ <canvas width="100" height="100"></canvas>
+ <script>
+ (function() {
+ const canvas = document.querySelector('canvas');
+ const gl = canvas.getContext("webgl");
+ const program = createProgram(gl);
+ gl.useProgram(program);
+
+ createTextureBuffer(program, gl, new Float32Array([ 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1]), "a_texCoord");
+
+ const images = [
+ 'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100"><rect width="100%" height="100%" fill="green"/></svg>',
+ 'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100"><rect x="25%" y="25%" width="50%" height="50%" fill="green"/></svg>',
+ ];
+
+ const promises = [];
+ for (var index = 0; index < images.length; ++index)
+ promises.push(drawTexture(program, gl, images[index]));
+
+ if (window.testRunner) {
+ testRunner.waitUntilDone();
+ Promise.all(promises).then(() => {
+ testRunner.notifyDone();
+ });
+ }
+ })();
+
+ function createProgram(gl) {
+ const vsSource = `
+ attribute vec4 a_position;
+ uniform vec2 u_resolution;
+ attribute vec2 a_texCoord;
+ varying vec2 v_texCoord;
+
+ void main() {
+ gl_Position = a_position;
+ v_texCoord = a_texCoord;
+ }
+ `;
+
+ const fsSource = `
+ precision mediump float;
+
+ uniform sampler2D u_sampler;
+ varying vec2 v_texCoord;
+
+ void main() {
+ gl_FragColor = texture2D(u_sampler, v_texCoord);
+ }
+ `;
+
+ const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
+ const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);
+
+ const program = gl.createProgram();
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+ return program;
+ }
+
+ function loadShader(gl, type, source) {
+ const shader = gl.createShader(type);
+ gl.shaderSource(shader, source);
+ gl.compileShader(shader);
+ return shader;
+ }
+
+ function drawTexture(program, gl, url) {
+ return loadTexture(gl, url).then(function() {
+ createTextureBuffer(program, gl, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), "a_position");
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+ });
+ }
+
+ function loadTexture(gl, url) {
+ return new Promise((resolve) => {
+ const image = new Image();
+ image.onload = function() {
+ const texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ resolve();
+ };
+ image.src = url;
+ });
+ }
+
+ function createTextureBuffer(program, gl, bufferData, positionAttribute) {
+ const buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, bufferData, gl.STATIC_DRAW);
+
+ const positionLocation = gl.getAttribLocation(program, positionAttribute);
+ gl.enableVertexAttribArray(positionLocation);
+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
+ }
+ </script>
+</body>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 2847f0e..c929766 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,18 @@
+2018-02-06 Said Abou-Hallawa <sabouhallawa@apple.com>
+
+ Rendering SVG images with same size as WebGL texture doesn't work correctly
+ https://bugs.webkit.org/show_bug.cgi?id=182367
+
+ Reviewed by Dean Jackson.
+
+ If am image buffer is created for a webgl texture and then it is reused
+ for another texture, it has to be cleared before drawing.
+
+ Test: webgl/webgl-texture-image-buffer-reuse.html
+
+ * html/canvas/WebGLRenderingContextBase.cpp:
+ (WebCore::WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer):
+
2018-02-06 Youenn Fablet <youenn@apple.com>
Use downcast in createLinkPreloadResourceClient
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp b/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
index 8fc871f..61031c4 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp
@@ -5922,6 +5922,7 @@
if (buf->logicalSize() != size)
continue;
bubbleToFront(i);
+ buf->context().clearRect(FloatRect({ }, FloatSize(size)));
return buf;
}