Web Inspector: create protocol for recording Canvas contexts
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Jul 2017 21:45:22 +0000 (21:45 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 26 Jul 2017 21:45:22 +0000 (21:45 +0000)
commit3c345f9fffab30fb1c77e82e9ff5bd9b3dbc244e
tree580e87d12602bd3deeefe255fa316f1f26a4b55d
parentb5bc03a0f2c171908aef5148c602c5cabc5e8ccb
Web Inspector: create protocol for recording Canvas contexts
https://bugs.webkit.org/show_bug.cgi?id=174481

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

* inspector/protocol/Canvas.json:
 - Add `requestRecording` command to mark the provided canvas as having requested a recording.
 - Add `cancelRecording` command to clear a previously marked canvas and flush any recorded data.
 - Add `recordingFinished` event that is fired once a recording is finished.

* CMakeLists.txt:
* DerivedSources.make:
* inspector/protocol/Recording.json: Added.
 - Add `Type` enum that lists the types of recordings
 - Add `InitialState` type that contains information about the canvas context at the
   beginning of the recording.
 - Add `Frame` type that holds a list of actions that were recorded.
 - Add `Recording` type as the container object of recording data.

* inspector/scripts/codegen/generate_js_backend_commands.py:
(JSBackendCommandsGenerator.generate_domain):
Create an agent for domains with no events or commands.

* inspector/InspectorValues.h:
Make Array `get` public so that values can be retrieved if needed.

Source/WebCore:

Currently, a recording doesn't actually "start" until an action is performed on the context.
This change adds the recording logic, but it does not use it anywhere. Additonal tests will
be added in the patches that add uses:
 - <https://webkit.org/b/174482> Web Inspector: Record actions performed on CanvasRenderingContext2D
 - <https://webkit.org/b/174483> Web Inspector: Record actions performed on WebGLRenderingContext

Test: inspector/model/recording.html

* bindings/scripts/IDLAttributes.json:
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateAttributeGetterBodyDefinition):
(GenerateAttributeSetterBodyDefinition):
(GenerateImplementationFunctionCall):
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/CallTracer.h: Added.
* bindings/js/CallTracer.cpp: Added.
(WebCore::CallTracer::recordCanvasAction):
* bindings/js/CallTracerTypes.h: Added.
* bindings/scripts/test/TestCallTracer.idl: Added.
* bindings/scripts/test/JS/JSTestCallTracer.h: Added.
* bindings/scripts/test/JS/JSTestCallTracer.cpp: Added.

Create new IDL extended attribute called "CallTracingCallback" that will add code to call a
static function on CallTracer with the given extended attribute value as the function name,
the `impl` object as the first parameter, the name of the attribute/operation as the second,
and an optional object that accepts an initializer list of all the parameters as the third.

This function will not be called, however, unless a `callTracingActive` function on the
`impl` object returns true, and this is marked as UNLIKELY.

"CallTracingCallback" can be added to an Interface, in which case it will apply to all
attributes/operations of the generated class, or an individual Attribute/Operation.

* html/canvas/CanvasRenderingContext.h:
(WebCore::CanvasRenderingContext::callTracingActive):
(WebCore::CanvasRenderingContext::setCallTracingActive):

* inspector/InspectorCanvas.h:
* inspector/InspectorCanvas.cpp:
(WebCore::InspectorCanvas::~InspectorCanvas):
(WebCore::InspectorCanvas::resetRecordingData):
(WebCore::InspectorCanvas::hasRecordingData):
(WebCore::InspectorCanvas::recordAction):
(WebCore::InspectorCanvas::releaseInitialState):
(WebCore::InspectorCanvas::releaseFrames):
(WebCore::InspectorCanvas::releaseData):
(WebCore::InspectorCanvas::markNewFrame):
(WebCore::InspectorCanvas::markCurrentFrameIncomplete):
(WebCore::InspectorCanvas::setBufferLimit):
(WebCore::InspectorCanvas::hasBufferSpace):
(WebCore::InspectorCanvas::singleFrame):
(WebCore::InspectorCanvas::setSingleFrame):
(WebCore::InspectorCanvas::indexForData):
(WebCore::buildArrayForAffineTransform):
(WebCore::buildArrayForVector):
(WebCore::InspectorCanvas::buildInitialState):
(WebCore::InspectorCanvas::buildAction):
(WebCore::InspectorCanvas::buildArrayForCanvasGradient):
(WebCore::InspectorCanvas::buildArrayForCanvasPattern):
(WebCore::InspectorCanvas::buildArrayForImageData):

Hold the recording data on the corresponding InspectorCanvas. Recording Frames are
completed when the HTMLCanvasElement paints or a  0_s timer is fired. A recording is not
considered valid until at least one action is performed on the canvas context. Once that
condition is satisfied, canceling the recording will flush the data.

* inspector/InspectorCanvasAgent.h:
* inspector/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::InspectorCanvasAgent):
(WebCore::InspectorCanvasAgent::disable):
(WebCore::InspectorCanvasAgent::requestRecording):
(WebCore::InspectorCanvasAgent::cancelRecording):
(WebCore::InspectorCanvasAgent::recordCanvasAction):
(WebCore::InspectorCanvasAgent::didFinishRecordingCanvasFrame):
(WebCore::InspectorCanvasAgent::canvasDestroyed):
(WebCore::InspectorCanvasAgent::canvasRecordingTimerFired):
(WebCore::InspectorCanvasAgent::clearCanvasData):

* inspector/InspectorInstrumentation.h:
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::recordCanvasAction):
(WebCore::InspectorInstrumentation::recordCanvasActionImpl):
(WebCore::InspectorInstrumentation::didFinishRecordingCanvasFrameImpl):

* html/canvas/CanvasRenderingContext2D.h:
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::stringForWindingRule):
(WebCore::CanvasRenderingContext2D::stringForImageSmoothingQuality):

* platform/graphics/Gradient.h:
(WebCore::Gradient::stops):

* svg/SVGPathUtilities.h:
* svg/SVGPathUtilities.cpp:
(WebCore::buildStringFromPath):

Source/WebInspectorUI:

Create model objects that effectively mirror the protocol objects sent for Canvas recordings.

* .eslintrc:
* UserInterface/Main.html:
* UserInterface/Test.html:

* UserInterface/Controllers/CanvasManager.js:
(WebInspector.CanvasManager.prototype.recordingFinished):
* UserInterface/Protocol/CanvasObserver.js:
(WebInspector.CanvasObserver.prototype.recordingFinished):

* UserInterface/Models/Recording.js: Added.
(WebInspector.Recording):
(WebInspector.Recording.fromPayload):
(WebInspector.Recording.prototype.get type):
(WebInspector.Recording.prototype.get initialState):
(WebInspector.Recording.prototype.get frames):
(WebInspector.Recording.prototype.get data):
(WebInspector.Recording.prototype.toJSON):

* UserInterface/Models/RecordingAction.js: Added.
(WebInspector.RecordingAction):
(WebInspector.RecordingAction.fromPayload):
(WebInspector.RecordingAction.prototype.get name):
(WebInspector.RecordingAction.prototype.get parameters):
(WebInspector.RecordingAction.prototype.toJSON):

* UserInterface/Models/RecordingFrame.js: Added.
(WebInspector.RecordingFrame):
(WebInspector.RecordingFrame.fromPayload):
(WebInspector.RecordingFrame.prototype.get actions):
(WebInspector.RecordingFrame.prototype.get incomplete):
(WebInspector.RecordingFrame.prototype.toJSON):

LayoutTests:

* inspector/model/recording-expected.txt: Added.
* inspector/model/recording.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@219964 268f45cc-cd09-0410-ab3c-d52691b4dbfc
41 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/model/recording-expected.txt [new file with mode: 0644]
LayoutTests/inspector/model/recording.html [new file with mode: 0644]
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/DerivedSources.make
Source/JavaScriptCore/inspector/InspectorValues.h
Source/JavaScriptCore/inspector/protocol/Canvas.json
Source/JavaScriptCore/inspector/protocol/Recording.json [new file with mode: 0644]
Source/JavaScriptCore/inspector/scripts/codegen/generate_js_backend_commands.py
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/CallTracer.cpp [new file with mode: 0644]
Source/WebCore/bindings/js/CallTracer.h [new file with mode: 0644]
Source/WebCore/bindings/js/CallTracerTypes.h [new file with mode: 0644]
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/IDLAttributes.json
Source/WebCore/bindings/scripts/test/JS/JSTestCallTracer.cpp [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/JS/JSTestCallTracer.h [new file with mode: 0644]
Source/WebCore/bindings/scripts/test/TestCallTracer.idl [new file with mode: 0644]
Source/WebCore/html/canvas/CanvasRenderingContext.h
Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
Source/WebCore/html/canvas/CanvasRenderingContext2D.h
Source/WebCore/inspector/InspectorCanvas.cpp
Source/WebCore/inspector/InspectorCanvas.h
Source/WebCore/inspector/InspectorCanvasAgent.cpp
Source/WebCore/inspector/InspectorCanvasAgent.h
Source/WebCore/inspector/InspectorInstrumentation.cpp
Source/WebCore/inspector/InspectorInstrumentation.h
Source/WebCore/platform/graphics/Gradient.h
Source/WebCore/svg/SVGPathUtilities.cpp
Source/WebCore/svg/SVGPathUtilities.h
Source/WebInspectorUI/.eslintrc
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Models/Recording.js [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Models/RecordingAction.js [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Models/RecordingFrame.js [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js
Source/WebInspectorUI/UserInterface/Test.html