Diff
Modified: trunk/LayoutTests/ChangeLog (221931 => 221932)
--- trunk/LayoutTests/ChangeLog 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/LayoutTests/ChangeLog 2017-09-12 19:28:29 UTC (rev 221932)
@@ -1,3 +1,25 @@
+2017-09-12 Dean Jackson <d...@apple.com>
+
+ [WebGL] accelerated texImage2D for video doesn't respect flipY
+ https://bugs.webkit.org/show_bug.cgi?id=176491
+ <rdar://problem/33833511>
+
+ Reviewed by Jer Noble.
+
+ (Take 2 - this was rolled out due to a test failure, but the following
+ commit will fix that)
+
+ Test that exercises UNPACK_FLIP_Y_WEBGL for video on the accelerated
+ path.
+
+ * fast/canvas/webgl/resources/orientation-flipped.mp4: Added.
+ * fast/canvas/webgl/resources/orientation-normal.mp4: Added.
+ * fast/canvas/webgl/texImage2D-video-flipY-false-expected.txt: Added.
+ * fast/canvas/webgl/texImage2D-video-flipY-false.html: Added.
+ * fast/canvas/webgl/texImage2D-video-flipY-true-expected.txt: Added.
+ * fast/canvas/webgl/texImage2D-video-flipY-true.html: Added.
+ * platform/ios/TestExpectations:
+
2017-09-12 Carlos Garcia Campos <cgar...@igalia.com>
Remove duplicated test results from LayoutTest platform directories
Added: trunk/LayoutTests/fast/canvas/webgl/resources/orientation-flipped.mp4
(Binary files differ)
Index: trunk/LayoutTests/fast/canvas/webgl/resources/orientation-flipped.mp4
===================================================================
--- trunk/LayoutTests/fast/canvas/webgl/resources/orientation-flipped.mp4 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/LayoutTests/fast/canvas/webgl/resources/orientation-flipped.mp4 2017-09-12 19:28:29 UTC (rev 221932)
Property changes on: trunk/LayoutTests/fast/canvas/webgl/resources/orientation-flipped.mp4
___________________________________________________________________
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
Added: trunk/LayoutTests/fast/canvas/webgl/resources/orientation-normal.mp4
(Binary files differ)
Index: trunk/LayoutTests/fast/canvas/webgl/resources/orientation-normal.mp4
===================================================================
--- trunk/LayoutTests/fast/canvas/webgl/resources/orientation-normal.mp4 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/LayoutTests/fast/canvas/webgl/resources/orientation-normal.mp4 2017-09-12 19:28:29 UTC (rev 221932)
Property changes on: trunk/LayoutTests/fast/canvas/webgl/resources/orientation-normal.mp4
___________________________________________________________________
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
Added: trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false-expected.txt (0 => 221932)
--- trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false-expected.txt 2017-09-12 19:28:29 UTC (rev 221932)
@@ -0,0 +1,6 @@
+Setting video src.
+Video can play.
+Checking the canvas pixels.
+PASS: Bottom edge is red.
+PASS: Top edge is blue.
+
Property changes on: trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false-expected.txt
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Revision
\ No newline at end of property
Added: svn:mime-type
+text/plain
\ No newline at end of property
Added: trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false.html (0 => 221932)
--- trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false.html 2017-09-12 19:28:29 UTC (rev 221932)
@@ -0,0 +1,209 @@
+<style>
+canvas {
+ width: 300px;
+ height: 300px;
+}
+</style>
+</head>
+<script id="vertexShaderSource" type="text/glsl">
+attribute vec4 a_position;
+varying vec2 v_texturePosition;
+
+void main() {
+ v_texturePosition = vec2((a_position.x + 1.0) / 2.0, (a_position.y + 1.0) / 2.0);
+ gl_Position = a_position;
+}
+</script>
+<script id="fragmentShaderSource" type="text/glsl">
+precision mediump float;
+
+varying vec2 v_texturePosition;
+
+uniform sampler2D texture;
+
+void main() {
+ gl_FragColor = texture2D(texture, v_texturePosition);
+}
+</script>
+<script>
+
+if (window.testRunner) {
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+}
+
+const width = 300;
+const height = 300;
+let canvas;
+let gl;
+let animationFrame = null;
+let tested = false;
+let drawFunction = null;
+let video;
+
+function output(msg) {
+ const div = document.getElementById("output");
+ div.innerHTML += `${msg}<br>`;
+}
+
+function isMostlyRed(buffer, x, y) {
+ let offset = (y * width + x) * 4;
+ return buffer[offset] > 240 && buffer[offset+1] < 20 && buffer[offset+2] < 20 && buffer[offset+3] > 240;
+}
+
+function isMostlyBlue(buffer, x, y) {
+ let offset = (y * width + x) * 4;
+ return buffer[offset] < 20 && buffer[offset+1] < 20 && buffer[offset+2] > 240 && buffer[offset+3] > 240;
+}
+
+function runTest() {
+ output("Checking the canvas pixels.");
+
+ drawFunction();
+ let pixels = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+
+ if (isMostlyRed(pixels, 2, 2))
+ output("PASS: Bottom edge is red.");
+ else
+ output("FAIL: Bottom edge is not red.");
+
+ if (isMostlyBlue(pixels, 2, height - 2))
+ output("PASS: Top edge is blue.");
+ else
+ output("FAIL: Top edge is not blue.");
+
+ cancelAnimationFrame(animationFrame);
+ video.pause();
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+
+function init() {
+
+ canvas = document.querySelector("canvas");
+ canvas.width = width;
+ canvas.height = height;
+
+ gl = canvas.getContext("webgl");
+
+ gl.clearColor(0, 0, 0, 1);
+
+ let vertexShader = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vertexShader, document.getElementById("vertexShaderSource").textContent);
+ gl.compileShader(vertexShader);
+ if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
+ console.error("Vertex Shader failed to compile.");
+ console.log(gl.getShaderInfoLog(vertexShader));
+ return;
+ }
+
+ let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fragmentShader, document.getElementById("fragmentShaderSource").textContent);
+ gl.compileShader(fragmentShader);
+ if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
+ console.error("Fragment Shader failed to compile.");
+ console.log(gl.getShaderInfoLog(fragmentShader));
+ return;
+ }
+
+ let program = gl.createProgram();
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
+ console.error("Unable to link shaders into program.");
+ return;
+ }
+
+ gl.useProgram(program);
+ let textureUniform = gl.getUniformLocation(program, "texture");
+ let positionAttribute = gl.getAttribLocation(program, "a_position");
+ gl.enableVertexAttribArray(positionAttribute);
+
+ let vertices = new Float32Array([
+ -1, -1,
+ 1, -1,
+ 1, 1,
+ 1, 1,
+ -1, 1,
+ -1, -1
+ ]);
+
+ let buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+
+ let updateTexture = function (texture, data) {
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, data);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ 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.bindTexture(gl.TEXTURE_2D, null);
+ }
+
+ let texture = gl.createTexture();
+
+ video = document.createElement("video");
+ video.loop = true;
+ video.playsInline = true;
+
+ video.addEventListener("canplay", function () {
+ output("Video can play.");
+ }, false);
+
+ video.addEventListener("timeupdate", function () {
+ // If we've just started, jump forward to 3 seconds. If we've played a bit after
+ // that, check the pixels.
+ if (video.currentTime < 1) {
+ video.currentTime = 3;
+ return;
+ } else if (video.currentTime > 3.1) {
+ if (!tested)
+ runTest();
+ tested = true;
+ }
+ }, false);
+
+ /* Since the texImage2D call isn't flipping in Y, we'll load a
+ video that is already flipped. */
+ output("Setting video src.");
+ video.src = ""
+ video.load();
+ video.play();
+
+ drawFunction = function () {
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ if (video.currentTime > 0) {
+ updateTexture(texture, video);
+ }
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.uniform1i(textureUniform, 0);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 0, 0);
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ animationFrame = requestAnimationFrame(drawFunction);
+ };
+
+ drawFunction();
+}
+
+window.addEventListener("load", init, false);
+</script>
+<body>
+ <canvas></canvas>
+ <div id="output">
+ </div>
+</body>
\ No newline at end of file
Property changes on: trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false.html
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Revision
\ No newline at end of property
Added: svn:mime-type
+text/html
\ No newline at end of property
Added: trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true-expected.txt (0 => 221932)
--- trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true-expected.txt 2017-09-12 19:28:29 UTC (rev 221932)
@@ -0,0 +1,6 @@
+Setting video src.
+Video can play.
+Checking the canvas pixels.
+PASS: Bottom edge is red.
+PASS: Top edge is blue.
+
Property changes on: trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true-expected.txt
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Revision
\ No newline at end of property
Added: svn:mime-type
+text/plain
\ No newline at end of property
Added: trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true.html (0 => 221932)
--- trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true.html (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true.html 2017-09-12 19:28:29 UTC (rev 221932)
@@ -0,0 +1,207 @@
+<style>
+canvas {
+ width: 300px;
+ height: 300px;
+}
+</style>
+</head>
+<script id="vertexShaderSource" type="text/glsl">
+attribute vec4 a_position;
+varying vec2 v_texturePosition;
+
+void main() {
+ v_texturePosition = vec2((a_position.x + 1.0) / 2.0, (a_position.y + 1.0) / 2.0);
+ gl_Position = a_position;
+}
+</script>
+<script id="fragmentShaderSource" type="text/glsl">
+precision mediump float;
+
+varying vec2 v_texturePosition;
+
+uniform sampler2D texture;
+
+void main() {
+ gl_FragColor = texture2D(texture, v_texturePosition);
+}
+</script>
+<script>
+
+if (window.testRunner) {
+ testRunner.waitUntilDone();
+ testRunner.dumpAsText();
+}
+
+const width = 300;
+const height = 300;
+let canvas;
+let gl;
+let animationFrame = null;
+let tested = false;
+let drawFunction = null;
+let video;
+
+function output(msg) {
+ const div = document.getElementById("output");
+ div.innerHTML += `${msg}<br>`;
+}
+
+function isMostlyRed(buffer, x, y) {
+ let offset = (y * width + x) * 4;
+ return buffer[offset] > 240 && buffer[offset+1] < 20 && buffer[offset+2] < 20 && buffer[offset+3] > 240;
+}
+
+function isMostlyBlue(buffer, x, y) {
+ let offset = (y * width + x) * 4;
+ return buffer[offset] < 20 && buffer[offset+1] < 20 && buffer[offset+2] > 240 && buffer[offset+3] > 240;
+}
+
+function runTest() {
+ output("Checking the canvas pixels.");
+
+ drawFunction();
+ let pixels = new Uint8Array(width * height * 4);
+ gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+
+ if (isMostlyRed(pixels, 2, 2))
+ output("PASS: Bottom edge is red.");
+ else
+ output("FAIL: Bottom edge is not red.");
+
+ if (isMostlyBlue(pixels, 2, height - 2))
+ output("PASS: Top edge is blue.");
+ else
+ output("FAIL: Top edge is not blue.");
+
+ cancelAnimationFrame(animationFrame);
+ video.pause();
+
+ if (window.testRunner)
+ testRunner.notifyDone();
+}
+
+function init() {
+
+ canvas = document.querySelector("canvas");
+ canvas.width = width;
+ canvas.height = height;
+
+ gl = canvas.getContext("webgl");
+
+ gl.clearColor(0, 0, 0, 1);
+
+ let vertexShader = gl.createShader(gl.VERTEX_SHADER);
+ gl.shaderSource(vertexShader, document.getElementById("vertexShaderSource").textContent);
+ gl.compileShader(vertexShader);
+ if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
+ console.error("Vertex Shader failed to compile.");
+ console.log(gl.getShaderInfoLog(vertexShader));
+ return;
+ }
+
+ let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
+ gl.shaderSource(fragmentShader, document.getElementById("fragmentShaderSource").textContent);
+ gl.compileShader(fragmentShader);
+ if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
+ console.error("Fragment Shader failed to compile.");
+ console.log(gl.getShaderInfoLog(fragmentShader));
+ return;
+ }
+
+ let program = gl.createProgram();
+ gl.attachShader(program, vertexShader);
+ gl.attachShader(program, fragmentShader);
+ gl.linkProgram(program);
+
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
+ console.error("Unable to link shaders into program.");
+ return;
+ }
+
+ gl.useProgram(program);
+ let textureUniform = gl.getUniformLocation(program, "texture");
+ let positionAttribute = gl.getAttribLocation(program, "a_position");
+ gl.enableVertexAttribArray(positionAttribute);
+
+ let vertices = new Float32Array([
+ -1, -1,
+ 1, -1,
+ 1, 1,
+ 1, 1,
+ -1, 1,
+ -1, -1
+ ]);
+
+ let buffer = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
+
+ let updateTexture = function (texture, data) {
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, data);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+ 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.bindTexture(gl.TEXTURE_2D, null);
+ }
+
+ let texture = gl.createTexture();
+
+ video = document.createElement("video");
+ video.loop = true;
+ video.playsInline = true;
+
+ video.addEventListener("canplay", function () {
+ output("Video can play.");
+ }, false);
+
+ video.addEventListener("timeupdate", function () {
+ // If we've just started, jump forward to 3 seconds. If we've played a bit after
+ // that, check the pixels.
+ if (video.currentTime < 1) {
+ video.currentTime = 3;
+ return;
+ } else if (video.currentTime > 3.1) {
+ if (!tested)
+ runTest();
+ tested = true;
+ }
+ }, false);
+
+ output("Setting video src.");
+ video.src = ""
+ video.load();
+ video.play();
+
+ drawFunction = function () {
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ if (video.currentTime > 0) {
+ updateTexture(texture, video);
+ }
+
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ gl.uniform1i(textureUniform, 0);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
+ gl.vertexAttribPointer(positionAttribute, 2, gl.FLOAT, false, 0, 0);
+
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
+
+ animationFrame = requestAnimationFrame(drawFunction);
+ };
+
+ drawFunction();
+}
+
+window.addEventListener("load", init, false);
+</script>
+<body>
+ <canvas></canvas>
+ <div id="output">
+ </div>
+</body>
\ No newline at end of file
Property changes on: trunk/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true.html
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Revision
\ No newline at end of property
Added: svn:mime-type
+text/html
\ No newline at end of property
Modified: trunk/LayoutTests/platform/ios/TestExpectations (221931 => 221932)
--- trunk/LayoutTests/platform/ios/TestExpectations 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/LayoutTests/platform/ios/TestExpectations 2017-09-12 19:28:29 UTC (rev 221932)
@@ -2865,6 +2865,9 @@
webgl/1.0.2/conformance/rendering/multisample-corruption.html [ Skip ]
webgl/1.0.2/conformance/uniforms/out-of-bounds-uniform-array-access.html [ Skip ]
+fast/canvas/webgl/texImage2D-video-flipY-false.html [ Skip ]
+fast/canvas/webgl/texImage2D-video-flipY-true.html [ Skip ]
+
webkit.org/b/174120 http/tests/loading/resourceLoadStatistics/user-interaction-in-cross-origin-sub-frame.html [ Skip ]
webkit.org/b/175273 imported/w3c/web-platform-tests/html/browsers/windows/noreferrer-window-name.html [ Failure ]
Modified: trunk/Source/WebCore/ChangeLog (221931 => 221932)
--- trunk/Source/WebCore/ChangeLog 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/Source/WebCore/ChangeLog 2017-09-12 19:28:29 UTC (rev 221932)
@@ -1,3 +1,58 @@
+2017-09-12 Dean Jackson <d...@apple.com>
+
+ [WebGL] accelerated texImage2D for video doesn't respect flipY
+ https://bugs.webkit.org/show_bug.cgi?id=176491
+ <rdar://problem/33833511>
+
+ Reviewed by Jer Noble.
+
+ (Take 2 - this was rolled out due to a test failure, but the following
+ commit will fix that)
+
+ Previously, if UNPACK_FLIP_Y_WEBGL was set to true, we'd either fall
+ back to software or fail to upload texture data. Fix this by intercepting
+ the texImage2D call, checking the orientation of the video, and running
+ a small shader program to flip it if necessary.
+
+ While there, implement UNPACK_PREMULTIPLY_ALPHA_WEBGL as well, although
+ none of our media decoders support video with alpha, so unfortunately
+ this will have no visible change.
+
+ Tests: fast/canvas/webgl/texImage2D-video-flipY-false.html
+ fast/canvas/webgl/texImage2D-video-flipY-true.html
+
+ * platform/cocoa/CoreVideoSoftLink.cpp: Add link to CVOpenGL(ES)TextureGetCleanTexCoords,
+ which is used to check the orientation of the source video.
+ * platform/cocoa/CoreVideoSoftLink.h:
+
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
+ (WebCore::MediaPlayerPrivateAVFoundationObjC::copyVideoTextureToPlatformTexture): We can
+ now handle flipped or premultiplied requests.
+ * platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm:
+ (WebCore::MediaPlayerPrivateMediaSourceAVFObjC::copyVideoTextureToPlatformTexture): Ditto.
+
+ * platform/graphics/cv/VideoTextureCopierCV.cpp:
+ (WebCore::VideoTextureCopierCV::VideoTextureCopierCV): Rename readFramebuffer to
+ simply framebuffer.
+ (WebCore::VideoTextureCopierCV::~VideoTextureCopierCV): Delete the program and buffer
+ if they were created.
+ (WebCore::VideoTextureCopierCV::initializeContextObjects): Sets up the shader program
+ and the vertex buffer for drawing. Also records the location of the uniforms.
+ (WebCore::VideoTextureCopierCV::copyVideoTextureToPlatformTexture): Create a new
+ framebuffer object, and render the video texture into that framebuffer using a
+ shader that can flip the coordinates.
+ (WebCore::VideoTextureCopierCV::GC3DStateSaver::GC3DStateSaver): Helper to restore
+ the state of the user's GraphicsContext3D while we're intercepting calls.
+ (WebCore::VideoTextureCopierCV::GC3DStateSaver::~GC3DStateSaver):
+ * platform/graphics/cv/VideoTextureCopierCV.h:
+
+ * platform/graphics/GraphicsContext3D.h: Add two new entry points, for direct shader
+ compilation and attribute access. This avoids going through ANGLE.
+ * platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp:
+ (WebCore::GraphicsContext3D::compileShader):
+ (WebCore::GraphicsContext3D::compileShaderDirect):
+ (WebCore::GraphicsContext3D::getAttribLocationDirect):
+
2017-09-12 Manuel Rego Casasnovas <r...@igalia.com>
[css-grid] Stretching auto tracks should be done as part of the track sizing algorithm
Modified: trunk/Source/WebCore/platform/cocoa/CoreVideoSoftLink.cpp (221931 => 221932)
--- trunk/Source/WebCore/platform/cocoa/CoreVideoSoftLink.cpp 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/Source/WebCore/platform/cocoa/CoreVideoSoftLink.cpp 2017-09-12 19:28:29 UTC (rev 221932)
@@ -61,6 +61,7 @@
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLESTextureGetName, GLuint, (CVOpenGLESTextureRef image), (image))
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVPixelBufferCreate, CVReturn, (CFAllocatorRef allocator, size_t width, size_t height, OSType pixelFormatType, CFDictionaryRef pixelBufferAttributes, CVPixelBufferRef *pixelBufferOut), (allocator, width, height, pixelFormatType, pixelBufferAttributes, pixelBufferOut))
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVPixelBufferCreateWithBytes, CVReturn, (CFAllocatorRef allocator, size_t width, size_t height, OSType pixelFormatType, void* data, size_t bytesPerRow, void (*releaseCallback)(void*, const void*), void* releasePointer, CFDictionaryRef pixelBufferAttributes, CVPixelBufferRef *pixelBufferOut), (allocator, width, height, pixelFormatType, data, bytesPerRow, releaseCallback, releasePointer, pixelBufferAttributes, pixelBufferOut))
+SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLESTextureGetCleanTexCoords, void, (CVOpenGLESTextureRef image, GLfloat lowerLeft[2], GLfloat lowerRight[2], GLfloat upperLeft[2], GLfloat upperRight[2]), (image, lowerLeft, lowerRight, upperLeft, upperRight))
#else
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLTextureCacheCreate, CVReturn, (CFAllocatorRef allocator, CFDictionaryRef cacheAttributes, CGLContextObj cglContext, CGLPixelFormatObj cglPixelFormat, CFDictionaryRef textureAttributes, CVOpenGLTextureCacheRef* cacheOut), (allocator, cacheAttributes, cglContext, cglPixelFormat, textureAttributes, cacheOut))
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLTextureCacheCreateTextureFromImage, CVReturn, (CFAllocatorRef allocator, CVOpenGLTextureCacheRef textureCache, CVImageBufferRef sourceImage, CFDictionaryRef attributes, CVOpenGLTextureRef* textureOut), (allocator, textureCache, sourceImage, attributes, textureOut))
@@ -67,5 +68,6 @@
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLTextureCacheFlush, void, (CVOpenGLTextureCacheRef textureCache, CVOptionFlags options), (textureCache, options))
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLTextureGetTarget, GLenum, (CVOpenGLTextureRef image), (image))
SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLTextureGetName, GLuint, (CVOpenGLTextureRef image), (image))
+SOFT_LINK_FUNCTION_FOR_SOURCE(WebCore, CoreVideo, CVOpenGLTextureGetCleanTexCoords, void, (CVOpenGLTextureRef image, GLfloat lowerLeft[2], GLfloat lowerRight[2], GLfloat upperLeft[2], GLfloat upperRight[2]), (image, lowerLeft, lowerRight, upperLeft, upperRight))
SOFT_LINK_CONSTANT_FOR_SOURCE(WebCore, CoreVideo, kCVPixelBufferIOSurfaceOpenGLFBOCompatibilityKey, CFStringRef)
#endif
Modified: trunk/Source/WebCore/platform/cocoa/CoreVideoSoftLink.h (221931 => 221932)
--- trunk/Source/WebCore/platform/cocoa/CoreVideoSoftLink.h 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/Source/WebCore/platform/cocoa/CoreVideoSoftLink.h 2017-09-12 19:28:29 UTC (rev 221932)
@@ -86,6 +86,8 @@
#define CVPixelBufferCreate softLink_CoreVideo_CVPixelBufferCreate
SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreVideo, CVPixelBufferCreateWithBytes, CVReturn, (CFAllocatorRef allocator, size_t width, size_t height, OSType pixelFormatType, void* data, size_t bytesPerRow, void (*releaseCallback)(void*, const void*), void* releasePointer, CFDictionaryRef pixelBufferAttributes, CVPixelBufferRef *pixelBufferOut), (allocator, width, height, pixelFormatType, data, bytesPerRow, releaseCallback, releasePointer, pixelBufferAttributes, pixelBufferOut))
#define CVPixelBufferCreateWithBytes softLink_CoreVideo_CVPixelBufferCreateWithBytes
+SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreVideo, CVOpenGLESTextureGetCleanTexCoords, void, (CVOpenGLESTextureRef image, GLfloat lowerLeft[2], GLfloat lowerRight[2], GLfloat upperLeft[2], GLfloat upperRight[2]), (image, lowerLeft, lowerRight, upperLeft, upperRight))
+#define CVOpenGLESTextureGetCleanTexCoords softLink_CoreVideo_CVOpenGLESTextureGetCleanTexCoords
SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreVideo, kCVPixelBufferCGBitmapContextCompatibilityKey, CFStringRef)
#define kCVPixelBufferCGBitmapContextCompatibilityKey get_CoreVideo_kCVPixelBufferCGBitmapContextCompatibilityKey()
@@ -104,6 +106,8 @@
#define CVOpenGLTextureGetTarget softLink_CoreVideo_CVOpenGLTextureGetTarget
SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreVideo, CVOpenGLTextureGetName, GLuint, (CVOpenGLTextureRef image), (image))
#define CVOpenGLTextureGetName softLink_CoreVideo_CVOpenGLTextureGetName
+SOFT_LINK_FUNCTION_FOR_HEADER(WebCore, CoreVideo, CVOpenGLTextureGetCleanTexCoords, void, (CVOpenGLTextureRef image, GLfloat lowerLeft[2], GLfloat lowerRight[2], GLfloat upperLeft[2], GLfloat upperRight[2]), (image, lowerLeft, lowerRight, upperLeft, upperRight))
+#define CVOpenGLTextureGetCleanTexCoords softLink_CoreVideo_CVOpenGLTextureGetCleanTexCoords
SOFT_LINK_CONSTANT_FOR_HEADER(WebCore, CoreVideo, kCVPixelBufferIOSurfaceOpenGLFBOCompatibilityKey, CFStringRef)
#define kCVPixelBufferIOSurfaceOpenGLFBOCompatibilityKey get_CoreVideo_kCVPixelBufferIOSurfaceOpenGLFBOCompatibilityKey()
Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (221931 => 221932)
--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h 2017-09-12 19:28:29 UTC (rev 221932)
@@ -764,6 +764,12 @@
// Equivalent to ::glTexImage2D(). Allows pixels==0 with no allocation.
void texImage2DDirect(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Denum format, GC3Denum type, const void* pixels);
+ // Get an attribute location without checking the name -> mangledname mapping.
+ int getAttribLocationDirect(Platform3DObject program, const String& name);
+
+ // Compile a shader without going through ANGLE.
+ void compileShaderDirect(Platform3DObject);
+
// Helper to texImage2D with pixel==0 case: pixels are initialized to 0.
// Return true if no GL error is synthesized.
// By default, alignment is 4, the OpenGL default setting.
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (221931 => 221932)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm 2017-09-12 19:28:29 UTC (rev 221932)
@@ -2465,9 +2465,6 @@
bool MediaPlayerPrivateAVFoundationObjC::copyVideoTextureToPlatformTexture(GraphicsContext3D* context, Platform3DObject outputTexture, GC3Denum outputTarget, GC3Dint level, GC3Denum internalFormat, GC3Denum format, GC3Denum type, bool premultiplyAlpha, bool flipY)
{
- if (flipY || premultiplyAlpha)
- return false;
-
ASSERT(context);
if (!m_openGLVideoOutput)
Modified: trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (221931 => 221932)
--- trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm 2017-09-12 19:28:29 UTC (rev 221932)
@@ -599,9 +599,6 @@
bool MediaPlayerPrivateMediaSourceAVFObjC::copyVideoTextureToPlatformTexture(GraphicsContext3D* context, Platform3DObject outputTexture, GC3Denum outputTarget, GC3Dint level, GC3Denum internalFormat, GC3Denum format, GC3Denum type, bool premultiplyAlpha, bool flipY)
{
- if (flipY || premultiplyAlpha)
- return false;
-
// We have been asked to paint into a WebGL canvas, so take that as a signal to create
// a decompression session, even if that means the native video can't also be displayed
// in page.
Modified: trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.cpp (221931 => 221932)
--- trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.cpp 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.cpp 2017-09-12 19:28:29 UTC (rev 221932)
@@ -28,6 +28,7 @@
#include "Logging.h"
#include <wtf/NeverDestroyed.h>
+#include <wtf/text/StringBuilder.h>
#if PLATFORM(IOS)
#include <OpenGLES/ES3/glext.h>
@@ -39,13 +40,17 @@
VideoTextureCopierCV::VideoTextureCopierCV(GraphicsContext3D& context)
: m_context(context)
- , m_readFramebuffer(context.createFramebuffer())
+ , m_framebuffer(context.createFramebuffer())
{
}
VideoTextureCopierCV::~VideoTextureCopierCV()
{
- m_context->deleteFramebuffer(m_readFramebuffer);
+ if (m_vertexBuffer)
+ m_context->deleteProgram(m_vertexBuffer);
+ if (m_program)
+ m_context->deleteProgram(m_program);
+ m_context->deleteFramebuffer(m_framebuffer);
}
#if !LOG_DISABLED
@@ -152,61 +157,211 @@
#endif
-bool VideoTextureCopierCV::copyVideoTextureToPlatformTexture(TextureType inputTexture, size_t width, size_t height, Platform3DObject outputTexture, GC3Denum outputTarget, GC3Dint level, GC3Denum internalFormat, GC3Denum format, GC3Denum type, bool premultiplyAlpha, bool flipY)
+bool VideoTextureCopierCV::initializeContextObjects()
{
- if (flipY || premultiplyAlpha)
+ StringBuilder vertexShaderSource;
+ vertexShaderSource.appendLiteral("attribute vec4 a_position;\n");
+ vertexShaderSource.appendLiteral("uniform int u_flipY;\n");
+ vertexShaderSource.appendLiteral("varying vec2 v_texturePosition;\n");
+ vertexShaderSource.appendLiteral("void main() {\n");
+ vertexShaderSource.appendLiteral(" v_texturePosition = vec2((a_position.x + 1.0) / 2.0, (a_position.y + 1.0) / 2.0);\n");
+ vertexShaderSource.appendLiteral(" if (u_flipY == 1) {\n");
+ vertexShaderSource.appendLiteral(" v_texturePosition.y = 1.0 - v_texturePosition.y;\n");
+ vertexShaderSource.appendLiteral(" }\n");
+ vertexShaderSource.appendLiteral(" gl_Position = a_position;\n");
+ vertexShaderSource.appendLiteral("}\n");
+
+ Platform3DObject vertexShader = m_context->createShader(GraphicsContext3D::VERTEX_SHADER);
+ m_context->shaderSource(vertexShader, vertexShaderSource.toString());
+ m_context->compileShaderDirect(vertexShader);
+
+ GC3Dint value = 0;
+ m_context->getShaderiv(vertexShader, GraphicsContext3D::COMPILE_STATUS, &value);
+ if (!value) {
+ LOG(WebGL, "VideoTextureCopierCV::copyVideoTextureToPlatformTexture(%p) - Vertex shader failed to compile.", this);
+ m_context->deleteShader(vertexShader);
return false;
+ }
- if (!inputTexture)
+ StringBuilder fragmentShaderSource;
+
+#if PLATFORM(IOS)
+ fragmentShaderSource.appendLiteral("precision mediump float;\n");
+ fragmentShaderSource.appendLiteral("uniform sampler2D u_texture;\n");
+#else
+ fragmentShaderSource.appendLiteral("uniform sampler2DRect u_texture;\n");
+#endif
+ fragmentShaderSource.appendLiteral("varying vec2 v_texturePosition;\n");
+ fragmentShaderSource.appendLiteral("uniform int u_premultiply;\n");
+ fragmentShaderSource.appendLiteral("uniform vec2 u_textureDimensions;\n");
+ fragmentShaderSource.appendLiteral("void main() {\n");
+ fragmentShaderSource.appendLiteral(" vec2 texPos = vec2(v_texturePosition.x * u_textureDimensions.x, v_texturePosition.y * u_textureDimensions.y);\n");
+#if PLATFORM(IOS)
+ fragmentShaderSource.appendLiteral(" vec4 color = texture2D(u_texture, texPos);\n");
+#else
+ fragmentShaderSource.appendLiteral(" vec4 color = texture2DRect(u_texture, texPos);\n");
+#endif
+ fragmentShaderSource.appendLiteral(" if (u_premultiply == 1) {\n");
+ fragmentShaderSource.appendLiteral(" gl_FragColor = vec4(color.r * color.a, color.g * color.a, color.b * color.a, color.a);\n");
+ fragmentShaderSource.appendLiteral(" } else {\n");
+ fragmentShaderSource.appendLiteral(" gl_FragColor = color;\n");
+ fragmentShaderSource.appendLiteral(" }\n");
+ fragmentShaderSource.appendLiteral("}\n");
+
+ Platform3DObject fragmentShader = m_context->createShader(GraphicsContext3D::FRAGMENT_SHADER);
+ m_context->shaderSource(fragmentShader, fragmentShaderSource.toString());
+ m_context->compileShaderDirect(fragmentShader);
+
+ m_context->getShaderiv(fragmentShader, GraphicsContext3D::COMPILE_STATUS, &value);
+ if (!value) {
+ LOG(WebGL, "VideoTextureCopierCV::copyVideoTextureToPlatformTexture(%p) - Fragment shader failed to compile.", this);
+ m_context->deleteShader(vertexShader);
+ m_context->deleteShader(fragmentShader);
return false;
+ }
+ m_program = m_context->createProgram();
+ m_context->attachShader(m_program, vertexShader);
+ m_context->attachShader(m_program, fragmentShader);
+ m_context->linkProgram(m_program);
+
+ m_context->getProgramiv(m_program, GraphicsContext3D::LINK_STATUS, &value);
+ if (!value) {
+ LOG(WebGL, "VideoTextureCopierCV::copyVideoTextureToPlatformTexture(%p) - Program failed to link.", this);
+ m_context->deleteShader(vertexShader);
+ m_context->deleteShader(fragmentShader);
+ m_context->deleteProgram(m_program);
+ m_program = 0;
+ return false;
+ }
+
+ m_textureUniformLocation = m_context->getUniformLocation(m_program, ASCIILiteral("u_texture"));
+ m_textureDimensionsUniformLocation = m_context->getUniformLocation(m_program, ASCIILiteral("u_textureDimensions"));
+ m_flipYUniformLocation = m_context->getUniformLocation(m_program, ASCIILiteral("u_flipY"));
+ m_premultiplyUniformLocation = m_context->getUniformLocation(m_program, ASCIILiteral("u_premultiply"));
+ m_positionAttributeLocation = m_context->getAttribLocationDirect(m_program, ASCIILiteral("a_position"));
+
+ m_context->detachShader(m_program, vertexShader);
+ m_context->detachShader(m_program, fragmentShader);
+ m_context->deleteShader(vertexShader);
+ m_context->deleteShader(fragmentShader);
+
+ LOG(WebGL, "Uniform and Attribute locations: u_texture = %d, u_textureDimensions = %d, u_flipY = %d, u_premultiply = %d, a_position = %d", m_textureUniformLocation, m_textureDimensionsUniformLocation, m_flipYUniformLocation, m_premultiplyUniformLocation, m_positionAttributeLocation);
+ m_context->enableVertexAttribArray(m_positionAttributeLocation);
+
+ m_vertexBuffer = m_context->createBuffer();
+ float vertices[12] = { -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1 };
+
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexBuffer);
+ m_context->bufferData(GraphicsContext3D::ARRAY_BUFFER, sizeof(float) * 12, vertices, GraphicsContext3D::STATIC_DRAW);
+
+ return true;
+}
+
+bool VideoTextureCopierCV::copyVideoTextureToPlatformTexture(TextureType inputVideoTexture, size_t width, size_t height, Platform3DObject outputTexture, GC3Denum outputTarget, GC3Dint level, GC3Denum internalFormat, GC3Denum format, GC3Denum type, bool premultiplyAlpha, bool flipY)
+{
+ if (!inputVideoTexture)
+ return false;
+
+ GC3DStateSaver stateSaver(&m_context.get());
+
+ if (!m_program) {
+ if (!initializeContextObjects()) {
+ LOG(WebGL, "VideoTextureCopierCV::copyVideoTextureToPlatformTexture(%p) - Unable to initialize OpenGL context objects.", this);
+ return false;
+ }
+ }
+
+ GLfloat lowerLeft[2] = { 0, 0 };
+ GLfloat lowerRight[2] = { 0, 0 };
+ GLfloat upperRight[2] = { 0, 0 };
+ GLfloat upperLeft[2] = { 0, 0 };
#if PLATFORM(IOS)
- Platform3DObject videoTextureName = CVOpenGLESTextureGetName(inputTexture);
- GC3Denum videoTextureTarget = CVOpenGLESTextureGetTarget(inputTexture);
+ Platform3DObject videoTextureName = CVOpenGLESTextureGetName(inputVideoTexture);
+ GC3Denum videoTextureTarget = CVOpenGLESTextureGetTarget(inputVideoTexture);
+ CVOpenGLESTextureGetCleanTexCoords(inputVideoTexture, lowerLeft, lowerRight, upperRight, upperLeft);
#else
- Platform3DObject videoTextureName = CVOpenGLTextureGetName(inputTexture);
- GC3Denum videoTextureTarget = CVOpenGLTextureGetTarget(inputTexture);
+ Platform3DObject videoTextureName = CVOpenGLTextureGetName(inputVideoTexture);
+ GC3Denum videoTextureTarget = CVOpenGLTextureGetTarget(inputVideoTexture);
+ CVOpenGLTextureGetCleanTexCoords(inputVideoTexture, lowerLeft, lowerRight, upperRight, upperLeft);
#endif
- LOG(Media, "VideoTextureCopierCV::copyVideoTextureToPlatformTexture(%p) - internalFormat: %s, format: %s, type: %s", this, enumToStringMap()[internalFormat], enumToStringMap()[format], enumToStringMap()[type]);
+ LOG(WebGL, "VideoTextureCopierCV::copyVideoTextureToPlatformTexture(%p) - internalFormat: %s, format: %s, type: %s flipY: %s, premultiplyAlpha: %s", this, enumToStringMap()[internalFormat], enumToStringMap()[format], enumToStringMap()[type], flipY ? "true" : "false", premultiplyAlpha ? "true" : "false");
- // Save the origial bound texture & framebuffer names so we can re-bind them after copying the video texture.
- GC3Dint boundTexture = 0;
- GC3Dint boundReadFramebuffer = 0;
- m_context->getIntegerv(GraphicsContext3D::TEXTURE_BINDING_2D, &boundTexture);
- m_context->getIntegerv(GraphicsContext3D::READ_FRAMEBUFFER_BINDING, &boundReadFramebuffer);
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebuffer);
+
+ // Allocate memory for the output texture.
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, outputTexture);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context->texImage2DDirect(GraphicsContext3D::TEXTURE_2D, level, internalFormat, width, height, 0, format, type, nullptr);
+ m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, outputTexture, level);
+ GC3Denum status = m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER);
+ if (status != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
+ LOG(WebGL, "VideoTextureCopierCV::copyVideoTextureToPlatformTexture(%p) - Unable to create framebuffer for outputTexture.", this);
+ return false;
+ }
+
+ m_context->useProgram(m_program);
+ m_context->viewport(0, 0, width, height);
+
+ // Bind and set up the texture for the video source.
+ m_context->activeTexture(GraphicsContext3D::TEXTURE0);
m_context->bindTexture(videoTextureTarget, videoTextureName);
- m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
- m_context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
- m_context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context->texParameteri(videoTextureTarget, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR);
+ m_context->texParameteri(videoTextureTarget, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
+ m_context->texParameteri(videoTextureTarget, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
+ m_context->texParameteri(videoTextureTarget, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
- // Make that framebuffer the read source from which drawing commands will read voxels.
- m_context->bindFramebuffer(GraphicsContext3D::READ_FRAMEBUFFER, m_readFramebuffer);
+ // Configure the drawing parameters.
+ m_context->uniform1i(m_textureUniformLocation, 0);
+#if PLATFORM(IOS)
+ m_context->uniform2f(m_textureDimensionsUniformLocation, 1, 1);
+#else
+ m_context->uniform2f(m_textureDimensionsUniformLocation, width, height);
+#endif
- // Allocate uninitialized memory for the output texture.
- m_context->bindTexture(outputTarget, outputTexture);
- m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
- m_context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
- m_context->texParameterf(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
- m_context->texImage2DDirect(outputTarget, level, internalFormat, width, height, 0, format, type, nullptr);
+ if (lowerLeft[1] < upperRight[1])
+ flipY = !flipY;
- // Attach the video texture to the framebuffer.
- m_context->framebufferTexture2D(GraphicsContext3D::READ_FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, videoTextureTarget, videoTextureName, level);
+ m_context->uniform1i(m_flipYUniformLocation, flipY);
+ m_context->uniform1i(m_premultiplyUniformLocation, premultiplyAlpha);
- GC3Denum status = m_context->checkFramebufferStatus(GraphicsContext3D::READ_FRAMEBUFFER);
- if (status != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
- return false;
+ // Do the actual drawing.
+ m_context->enableVertexAttribArray(m_positionAttributeLocation);
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_vertexBuffer);
+ m_context->vertexAttribPointer(m_positionAttributeLocation, 2, GraphicsContext3D::FLOAT, false, 0, 0);
+ m_context->drawArrays(GraphicsContext3D::TRIANGLES, 0, 6);
- // Copy texture from the read framebuffer (and thus the video texture) to the output texture.
- m_context->copyTexImage2D(outputTarget, level, internalFormat, 0, 0, width, height, 0);
+ // Clean-up.
+ m_context->bindTexture(videoTextureTarget, 0);
+ m_context->bindTexture(outputTarget, outputTexture);
- // Restore the previous texture and framebuffer bindings.
- m_context->bindTexture(outputTarget, boundTexture);
- m_context->bindFramebuffer(GraphicsContext3D::READ_FRAMEBUFFER, boundReadFramebuffer);
+ return true;
+}
- return !m_context->getError();
+VideoTextureCopierCV::GC3DStateSaver::GC3DStateSaver(GraphicsContext3D* context)
+ : m_context(context)
+{
+ ASSERT(context);
+ m_context->getIntegerv(GraphicsContext3D::TEXTURE_BINDING_2D, &m_texture);
+ m_context->getIntegerv(GraphicsContext3D::FRAMEBUFFER_BINDING, &m_framebuffer);
+ m_context->getIntegerv(GraphicsContext3D::CURRENT_PROGRAM, &m_program);
+ m_context->getIntegerv(GraphicsContext3D::ARRAY_BUFFER_BINDING, &m_arrayBuffer);
+ m_context->getIntegerv(GraphicsContext3D::VIEWPORT, m_viewport);
}
+VideoTextureCopierCV::GC3DStateSaver::~GC3DStateSaver()
+{
+ m_context->bindTexture(GraphicsContext3D::TEXTURE_BINDING_2D, m_texture);
+ m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebuffer);
+ m_context->useProgram(m_program);
+ m_context->bindBuffer(GraphicsContext3D::ARRAY_BUFFER, m_arrayBuffer);
+ m_context->viewport(m_viewport[0], m_viewport[1], m_viewport[2], m_viewport[3]);
+}
+
}
Modified: trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.h (221931 => 221932)
--- trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.h 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.h 2017-09-12 19:28:29 UTC (rev 221932)
@@ -28,7 +28,7 @@
#import "GraphicsContext3D.h"
-typedef struct __CVBuffer* CVImageBufferRef;
+typedef struct __CVBuffer* CVImageBufferRef;
typedef CVImageBufferRef CVOpenGLTextureRef;
typedef CVImageBufferRef CVOpenGLESTextureRef;
@@ -50,8 +50,31 @@
GraphicsContext3D& context() { return m_context.get(); }
private:
+ class GC3DStateSaver {
+ public:
+ GC3DStateSaver(GraphicsContext3D*);
+ ~GC3DStateSaver();
+
+ private:
+ GraphicsContext3D* m_context;
+ GC3Dint m_texture { 0 };
+ GC3Dint m_framebuffer { 0 };
+ GC3Dint m_program { 0 };
+ GC3Dint m_arrayBuffer { 0 };
+ GC3Dint m_viewport[4] { 0, 0, 0, 0 };
+ };
+
+ bool initializeContextObjects();
+
Ref<GraphicsContext3D> m_context;
- Platform3DObject m_readFramebuffer;
+ Platform3DObject m_framebuffer { 0 };
+ Platform3DObject m_program { 0 };
+ Platform3DObject m_vertexBuffer { 0 };
+ GC3Dint m_textureUniformLocation { -1 };
+ GC3Dint m_textureDimensionsUniformLocation { -1 };
+ GC3Dint m_flipYUniformLocation { -1 };
+ GC3Dint m_premultiplyUniformLocation { -1 };
+ GC3Dint m_positionAttributeLocation { -1 };
};
}
Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp (221931 => 221932)
--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp 2017-09-12 19:19:45 UTC (rev 221931)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp 2017-09-12 19:28:29 UTC (rev 221932)
@@ -666,9 +666,9 @@
::glCompileShader(shader);
- int GLCompileSuccess;
+ int compileStatus;
- ::glGetShaderiv(shader, COMPILE_STATUS, &GLCompileSuccess);
+ ::glGetShaderiv(shader, COMPILE_STATUS, &compileStatus);
ShaderSourceMap::iterator result = m_shaderSourceMap.find(shader);
GraphicsContext3D::ShaderSourceEntry& entry = result->value;
@@ -686,12 +686,47 @@
entry.log = getUnmangledInfoLog(shaders, 1, String(info.get()));
}
- if (GLCompileSuccess != GL_TRUE) {
+ if (compileStatus != GL_TRUE) {
entry.isValid = false;
LOG(WebGL, "Error: shader translator produced a shader that OpenGL would not compile.");
}
}
+void GraphicsContext3D::compileShaderDirect(Platform3DObject shader)
+{
+ ASSERT(shader);
+ makeContextCurrent();
+
+ HashMap<Platform3DObject, ShaderSourceEntry>::iterator result = m_shaderSourceMap.find(shader);
+
+ if (result == m_shaderSourceMap.end())
+ return;
+
+ ShaderSourceEntry& entry = result->value;
+
+ const CString& shaderSourceCString = entry.source.utf8();
+ const char* shaderSourcePtr = shaderSourceCString.data();
+ int shaderSourceLength = shaderSourceCString.length();
+
+ LOG(WebGL, "--- begin direct shader source ---\n%s\n--- end direct shader source ---\n", shaderSourcePtr);
+
+ ::glShaderSource(shader, 1, &shaderSourcePtr, &shaderSourceLength);
+
+ ::glCompileShader(shader);
+
+ int compileStatus;
+
+ ::glGetShaderiv(shader, COMPILE_STATUS, &compileStatus);
+
+ if (compileStatus == GL_TRUE) {
+ entry.isValid = true;
+ LOG(WebGL, "Direct compilation of shader succeeded.");
+ } else {
+ entry.isValid = false;
+ LOG(WebGL, "Error: direct compilation of shader failed.");
+ }
+}
+
void GraphicsContext3D::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
{
makeContextCurrent();
@@ -1068,6 +1103,16 @@
return ::glGetAttribLocation(program, mappedName.utf8().data());
}
+int GraphicsContext3D::getAttribLocationDirect(Platform3DObject program, const String& name)
+{
+ if (!program)
+ return -1;
+
+ makeContextCurrent();
+
+ return ::glGetAttribLocation(program, name.utf8().data());
+}
+
GraphicsContext3DAttributes GraphicsContext3D::getContextAttributes()
{
return m_attrs;