Title: [223244] branches/safari-604-branch

Diff

Modified: branches/safari-604-branch/LayoutTests/ChangeLog (223243 => 223244)


--- branches/safari-604-branch/LayoutTests/ChangeLog	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/LayoutTests/ChangeLog	2017-10-12 18:31:15 UTC (rev 223244)
@@ -1,3 +1,26 @@
+2017-10-12  Dean Jackson  <[email protected]>
+
+        [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 3 - this was rolled out due to a test failure)
+
+        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: This test is macOS only.
+        * platform/mac/TestExpectations: Mark an existing WebGL test as flakey, while
+          a bug exposed here is investigated.
+
 2017-10-10  Jason Marcell  <[email protected]>
 
         Cherry-pick r222788. rdar://problem/34771440

Added: branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false-expected.txt (0 => 223244)


--- branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false-expected.txt	                        (rev 0)
+++ branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false-expected.txt	2017-10-12 18:31:15 UTC (rev 223244)
@@ -0,0 +1,6 @@
+Setting video src.
+Video can play.
+Checking the canvas pixels.
+PASS: Bottom edge is red.
+PASS: Top edge is blue.
+

Added: branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false.html (0 => 223244)


--- branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false.html	                        (rev 0)
+++ branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-false.html	2017-10-12 18:31:15 UTC (rev 223244)
@@ -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

Added: branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true-expected.txt (0 => 223244)


--- branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true-expected.txt	                        (rev 0)
+++ branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true-expected.txt	2017-10-12 18:31:15 UTC (rev 223244)
@@ -0,0 +1,6 @@
+Setting video src.
+Video can play.
+Checking the canvas pixels.
+PASS: Bottom edge is red.
+PASS: Top edge is blue.
+

Added: branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true.html (0 => 223244)


--- branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true.html	                        (rev 0)
+++ branches/safari-604-branch/LayoutTests/fast/canvas/webgl/texImage2D-video-flipY-true.html	2017-10-12 18:31:15 UTC (rev 223244)
@@ -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

Modified: branches/safari-604-branch/LayoutTests/platform/mac/TestExpectations (223243 => 223244)


--- branches/safari-604-branch/LayoutTests/platform/mac/TestExpectations	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/LayoutTests/platform/mac/TestExpectations	2017-10-12 18:31:15 UTC (rev 223244)
@@ -1616,3 +1616,6 @@
 webkit.org/b/173068 imported/w3c/web-platform-tests/IndexedDB/idbobjectstore_getKey.html [ Pass Failure ]
 
 webkit.org/b/176878 [ Debug ] fast/multicol/spanner-crash-when-adding-summary.html [ Crash ]
+
+# <rdar://problem/34507977>
+webkit.org/b/177119 webgl/1.0.2/conformance/textures/tex-image-and-sub-image-2d-with-video.html [ Pass Failure ]

Modified: branches/safari-604-branch/Source/WebCore/ChangeLog (223243 => 223244)


--- branches/safari-604-branch/Source/WebCore/ChangeLog	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/Source/WebCore/ChangeLog	2017-10-12 18:31:15 UTC (rev 223244)
@@ -1,3 +1,57 @@
+2017-10-12  Dean Jackson  <[email protected]>
+
+        [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 3 - this was rolled out due to a test failure)
+
+        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-10-11  Jason Marcell  <[email protected]>
 
         Cherry-pick r222963. rdar://problem/34891307

Modified: branches/safari-604-branch/Source/WebCore/platform/cocoa/CoreVideoSoftLink.cpp (223243 => 223244)


--- branches/safari-604-branch/Source/WebCore/platform/cocoa/CoreVideoSoftLink.cpp	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/Source/WebCore/platform/cocoa/CoreVideoSoftLink.cpp	2017-10-12 18:31:15 UTC (rev 223244)
@@ -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: branches/safari-604-branch/Source/WebCore/platform/cocoa/CoreVideoSoftLink.h (223243 => 223244)


--- branches/safari-604-branch/Source/WebCore/platform/cocoa/CoreVideoSoftLink.h	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/Source/WebCore/platform/cocoa/CoreVideoSoftLink.h	2017-10-12 18:31:15 UTC (rev 223244)
@@ -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: branches/safari-604-branch/Source/WebCore/platform/graphics/GraphicsContext3D.h (223243 => 223244)


--- branches/safari-604-branch/Source/WebCore/platform/graphics/GraphicsContext3D.h	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/GraphicsContext3D.h	2017-10-12 18:31:15 UTC (rev 223244)
@@ -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: branches/safari-604-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm (223243 => 223244)


--- branches/safari-604-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm	2017-10-12 18:31:15 UTC (rev 223244)
@@ -2487,9 +2487,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: branches/safari-604-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm (223243 => 223244)


--- branches/safari-604-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateMediaSourceAVFObjC.mm	2017-10-12 18:31:15 UTC (rev 223244)
@@ -591,9 +591,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: branches/safari-604-branch/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.cpp (223243 => 223244)


--- branches/safari-604-branch/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.cpp	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.cpp	2017-10-12 18:31:15 UTC (rev 223244)
@@ -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: branches/safari-604-branch/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.h (223243 => 223244)


--- branches/safari-604-branch/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.h	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/cv/VideoTextureCopierCV.h	2017-10-12 18:31:15 UTC (rev 223244)
@@ -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: branches/safari-604-branch/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp (223243 => 223244)


--- branches/safari-604-branch/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp	2017-10-12 18:29:23 UTC (rev 223243)
+++ branches/safari-604-branch/Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGLCommon.cpp	2017-10-12 18:31:15 UTC (rev 223244)
@@ -658,9 +658,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;
@@ -678,12 +678,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();
@@ -1060,6 +1095,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;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to