Support canvas captureStream
https://bugs.webkit.org/show_bug.cgi?id=169192

Patch by Youenn Fablet <youenn@apple.com> on 2017-03-08
Reviewed by Dean Jackson.

Source/WebCore:

Tests: fast/mediacapturefromelement/CanvasCaptureMediaStream-2d-events.html
       fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html
       fast/mediacapturefromelement/CanvasCaptureMediaStream-clone-track.html
       fast/mediacapturefromelement/CanvasCaptureMediaStream-creation.html
       fast/mediacapturefromelement/CanvasCaptureMediaStream-exceptions.html
       fast/mediacapturefromelement/CanvasCaptureMediaStream-framerate-0.html
       fast/mediacapturefromelement/CanvasCaptureMediaStream-imagebitmaprenderingcontext.html
       fast/mediacapturefromelement/CanvasCaptureMediaStream-offscreencanvas.html
       fast/mediacapturefromelement/CanvasCaptureMediaStream-request-frame-events.html
       fast/mediacapturefromelement/CanvasCaptureMediaStream-webgl-events.html

Adding canvas captureStream as defined in https://w3c.github.io/mediacapture-fromelement/#html-canvas-element-media-capture-extensions
This allows creating a video MediaStreamTrack fed by canvas taken frames.
Frames are produced when canvas get changed.

Tests taken from Chromium.

* CMakeLists.txt:
* DerivedSources.make:
* Modules/mediastream/CanvasCaptureMediaStreamTrack.cpp: Added.
(WebCore::CanvasCaptureMediaStreamTrack::create):
(WebCore::CanvasCaptureMediaStreamTrack::CanvasCaptureMediaStreamTrack):
(WebCore::CanvasCaptureMediaStreamTrack::Source::create):
(WebCore::CanvasCaptureMediaStreamTrack::Source::Source):
(WebCore::CanvasCaptureMediaStreamTrack::Source::startProducingData):
(WebCore::CanvasCaptureMediaStreamTrack::Source::stopProducingData):
(WebCore::CanvasCaptureMediaStreamTrack::Source::requestFrameTimerFired):
(WebCore::CanvasCaptureMediaStreamTrack::Source::canvasDestroyed):
(WebCore::CanvasCaptureMediaStreamTrack::Source::canvasResized):
(WebCore::CanvasCaptureMediaStreamTrack::Source::canvasChanged):
(WebCore::CanvasCaptureMediaStreamTrack::Source::captureCanvas):
(WebCore::CanvasCaptureMediaStreamTrack::Source::paintCurrentFrameInContext):
(WebCore::CanvasCaptureMediaStreamTrack::Source::currentFrameImage):
* Modules/mediastream/CanvasCaptureMediaStreamTrack.h: Added.
(isType):
* Modules/mediastream/CanvasCaptureMediaStreamTrack.idl: Added.
* Modules/mediastream/MediaStreamTrack.h:
(WebCore::MediaStreamTrack::isCanvas):
* Modules/mediastream/MediaStreamTrack.idl:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSMediaStreamTrackCustom.cpp:
(WebCore::toJSNewlyCreated):
(WebCore::toJS):
* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::toMediaSample):
(WebCore::HTMLCanvasElement::captureStream):
* html/HTMLCanvasElement.h:
* html/HTMLCanvasElement.idl:
* html/canvas/WebGL2RenderingContext.cpp:
(WebCore::WebGL2RenderingContext::clear):
* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::markContextChangedAndNotifyCanvasObserver):
(WebCore::WebGLRenderingContextBase::drawArrays):
(WebCore::WebGLRenderingContextBase::drawElements):
(WebCore::WebGLRenderingContextBase::drawArraysInstanced):
(WebCore::WebGLRenderingContextBase::drawElementsInstanced):
* html/canvas/WebGLRenderingContextBase.h:
* platform/graphics/ImageBuffer.cpp:
(WebCore::ImageBuffer::toBGRAData):
* platform/graphics/ImageBuffer.h:
* platform/graphics/avfoundation/MediaSampleAVFObjC.h:
* platform/graphics/avfoundation/objc/MediaSampleAVFObjC.mm:
(WebCore::releaseUint8Vector):
(WebCore::MediaSampleAVFObjC::createImageSample):
* platform/graphics/cg/ImageBufferCG.cpp:
* platform/graphics/cg/ImageBufferDataCG.cpp:
(WebCore::transferData):
(WebCore::ImageBufferData::toBGRAData):
* platform/graphics/cg/ImageBufferDataCG.h:

LayoutTests:

* fast/mediacapturefromelement/CanvasCaptureMediaStream-2d-events-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-2d-events.html: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-clone-track-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-clone-track.html: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-creation-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-creation.html: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-exceptions-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-exceptions.html: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-framerate-0-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-framerate-0.html: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-imagebitmaprenderingcontext-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-imagebitmaprenderingcontext.html: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-offscreencanvas-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-offscreencanvas.html: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-request-frame-events-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-request-frame-events.html: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-webgl-events-expected.txt: Added.
* fast/mediacapturefromelement/CanvasCaptureMediaStream-webgl-events.html: Added.
* fast/mediacapturefromelement/resources/svg-with-image-with-foreignobject.svg: Added.
* fast/mediacapturefromelement/resources/webgl-test.js: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@213598 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html b/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html
new file mode 100644
index 0000000..aef33f3
--- /dev/null
+++ b/LayoutTests/fast/mediacapturefromelement/CanvasCaptureMediaStream-capture-out-of-DOM-element.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<script src =../../resources/testharness.js></script>
+<script src =../../resources/testharnessreport.js></script>
+<script>
+
+async_test(t => {
+  var canvas = document.createElement('canvas');
+  var ctx = canvas.getContext('2d');
+  ctx.fillStyle = 'green';
+  var recorder = new MediaRecorder(canvas.captureStream());
+  var frameCount = 0;
+
+  recorder.ondataavailable = function() {
+    t.step(function() {
+      assert_true(event.data.size > 0, 'Recorded data size should be > 0');
+    });
+
+    frameCount = frameCount + 1;
+    if (frameCount > 3) {
+      recorder.stop();
+      t.done();
+    } else {
+      ctx.fillRect(0, 0, canvas.width, canvas.height);
+    }
+  }
+
+  recorder.start(0);
+  ctx.fillRect(0, 0, canvas.width, canvas.height);
+}, "Verify that drawing to a 2D canvas that is not attached to the DOM dispatches frames to an attached MediaRecorder." );
+
+async_test(t => {
+  var canvas = document.createElement('canvas');
+  var gl = canvas.getContext('webgl');
+  gl.clearColor(0, 1, 0, 1);
+  var recorder = new MediaRecorder(canvas.captureStream());
+  var frameCount = 0;
+
+  recorder.ondataavailable = function() {
+    t.step(function() {
+      assert_true(event.data.size > 0, 'Recorded data size should be > 0');
+    });
+
+    frameCount = frameCount + 1;
+    if (frameCount > 3) {
+      recorder.stop();
+      t.done();
+    } else {
+      gl.clear(gl.COLOR_BUFFER_BIT);
+    }
+  }
+  recorder.start(0);
+
+  gl.clear(gl.COLOR_BUFFER_BIT);
+}, "Verify that drawing to a webgl canvas that is not attached to the DOM dispatches frames to an attached MediaRecorder." );
+</script>
\ No newline at end of file