⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 236952 in webkit


Ignore:
Timestamp:
Oct 8, 2018, 5:14:52 PM (8 years ago)
Author:
Devin Rousso
Message:

Web Inspector: allow multiple canvases to be recorded at the same time
https://bugs.webkit.org/show_bug.cgi?id=190305

Reviewed by Brian Burg.

Source/WebInspectorUI:

Moved the logic for maintaining whether a canvas is actively recording from
WI.CanvasManager to WI.Canvas, meaning that each canvas can now record independently of
every other canvas in the page. If multiple recordings are all finished simultaneously, only
show the first one to be recieved by the frontend.

  • UserInterface/Controllers/CanvasManager.js:

(WI.CanvasManager):
(WI.CanvasManager.prototype.recordingProgress):
(WI.CanvasManager.prototype.recordingFinished):
(WI.CanvasManager.prototype.programCreated):
(WI.CanvasManager.prototype.programDeleted):
(WI.CanvasManager.prototype._removeCanvas):
(WI.CanvasManager.prototype._mainResourceDidChange):
(WI.CanvasManager.prototype.get recordingCanvas): Deleted.
(WI.CanvasManager.prototype.startRecording): Deleted.
(WI.CanvasManager.prototype.stopRecording): Deleted.
(WI.CanvasManager.prototype._dispatchShaderProgramRemoved): Deleted.

  • UserInterface/Models/Canvas.js:

(WI.Canvas.prototype.get recordingFrameCount): Added.
(WI.Canvas.prototype.get recordingBufferUsed): Added.
(WI.Canvas.prototype.get recordingActive): Added.
(WI.Canvas.prototype.get isRecording): Deleted.
(WI.Canvas.prototype.startRecording): Added.
(WI.Canvas.prototype.stopRecording): Added.
(WI.Canvas.prototype.recordingProgress): Added.
(WI.Canvas.prototype.recordingFinished): Added.

  • UserInterface/Views/CanvasTabContentView.js:

(WI.CanvasTabContentView.prototype.attached):
(WI.CanvasTabContentView.prototype.detached):
(WI.CanvasTabContentView.prototype._recordingImportedOrStopped):
(WI.CanvasTabContentView.prototype._handleSpace):
(WI.CanvasTabContentView):

  • UserInterface/Views/CanvasOverviewContentView.css:

(.content-view.canvas-overview .content-view.canvas.recording-active): Added.
(.content-view.canvas-overview .content-view.canvas.recording-active > header): Added.
(.content-view.canvas-overview .content-view.canvas.recording-active > header > .titles > .title): Added.
(.content-view.canvas-overview .content-view.canvas.recording-active > header > .titles > .subtitle): Added.
(.content-view.canvas-overview .content-view.canvas.recording-active > header > .navigation-bar > .item): Added.
(.content-view.canvas-overview .content-view.canvas:matches(:hover, .recording-active) > header > .navigation-bar): Added.
(.content-view.canvas-overview .content-view.canvas:not(.recording-active) > header > .navigation-bar > .item.record-start-stop.disabled): Added.
(.content-view.canvas-overview .content-view.canvas:not(.recording-active) > header > .navigation-bar > .item.record-start-stop:not(.disabled):hover): Added.
(.content-view.canvas-overview .content-view.canvas:not(.recording-active) > header > .navigation-bar > .item.record-start-stop:not(.disabled):active): Added.
(.content-view.canvas-overview .content-view.canvas.recording-active > .progress-vie): Added.
(.content-view.canvas-overview .content-view.canvas.recording-active > .preview): Added.
(.content-view.canvas-overview .content-view.canvas.recording-active): Added.
(.content-view.canvas-overview .content-view.canvas.recording-active > header): Added.
(.content-view.canvas-overview .content-view.canvas.recording-active > header > .titles > .subtitle): Added.
(.content-view.canvas-overview .content-view.canvas.is-recording): Deleted.
(.content-view.canvas-overview .content-view.canvas.is-recording > header): Deleted.
(.content-view.canvas-overview .content-view.canvas.is-recording > header > .titles > .title): Deleted.
(.content-view.canvas-overview .content-view.canvas.is-recording > header > .titles > .subtitle): Deleted.
(.content-view.canvas-overview .content-view.canvas.is-recording > header > .navigation-bar > .item): Deleted.
(.content-view.canvas-overview .content-view.canvas:matches(:hover, .is-recording) > header > .navigation-bar): Deleted.
(.content-view.canvas-overview .content-view.canvas:not(.is-recording) > header > .navigation-bar > .item.record-start-stop.disabled): Deleted.
(.content-view.canvas-overview .content-view.canvas:not(.is-recording) > header > .navigation-bar > .item.record-start-stop:not(.disabled):hover): Deleted.
(.content-view.canvas-overview .content-view.canvas:not(.is-recording) > header > .navigation-bar > .item.record-start-stop:not(.disabled):active): Deleted.
(.content-view.canvas-overview .content-view.canvas.is-recording > .progress-vie): Deleted.
(.content-view.canvas-overview .content-view.canvas.is-recording > .preview): Deleted.
(.content-view.canvas-overview .content-view.canvas.is-recording): Deleted.
(.content-view.canvas-overview .content-view.canvas.is-recording > header): Deleted.
(.content-view.canvas-overview .content-view.canvas.is-recording > header > .titles > .subtitle): Deleted.

  • UserInterface/Views/CanvasContentView.js:

(WI.CanvasContentView.prototype.attached):
(WI.CanvasContentView.prototype.detached):
(WI.CanvasContentView.prototype._toggleRecording):
(WI.CanvasContentView.prototype._recordingProgress):
(WI.CanvasContentView.prototype._recordingStopped):
(WI.CanvasContentView.prototype._shaderProgramAdded):
(WI.CanvasContentView.prototype._shaderProgramRemoved):
(WI.CanvasContentView.prototype._updateRecordNavigationItem):
(WI.CanvasContentView.prototype._updateProgressView):

  • UserInterface/Views/CanvasSidebarPanel.js:

(WI.CanvasSidebarPanel):
(WI.CanvasSidebarPanel.prototype.set canvas):
(WI.CanvasSidebarPanel.prototype._toggleRecording):
(WI.CanvasSidebarPanel.prototype._updateRecordNavigationItem):

  • UserInterface/Views/CanvasTreeElement.js:

(WI.CanvasTreeElement):
(WI.CanvasTreeElement.prototype._updateStatus):

LayoutTests:

  • inspector/canvas/recording-2d.html:
  • inspector/canvas/recording-bitmaprenderer.html:
  • inspector/canvas/recording-expected.html:
  • inspector/canvas/recording-webgl.html:
  • inspector/canvas/recording.html:
  • inspector/canvas/resources/recording-utilities.js:

(TestPage.registerInitializer.window.startRecording.handleRecordingProgress):
(TestPage.registerInitializer.window.startRecording):
(TestPage.registerInitializer.window.consoleRecord):
(TestPage.registerInitializer):

Location:
trunk
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r236945 r236952  
     12018-10-08  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: allow multiple canvases to be recorded at the same time
     4        https://bugs.webkit.org/show_bug.cgi?id=190305
     5
     6        Reviewed by Brian Burg.
     7
     8        * inspector/canvas/recording-2d.html:
     9        * inspector/canvas/recording-bitmaprenderer.html:
     10        * inspector/canvas/recording-expected.html:
     11        * inspector/canvas/recording-webgl.html:
     12        * inspector/canvas/recording.html:
     13        * inspector/canvas/resources/recording-utilities.js:
     14        (TestPage.registerInitializer.window.startRecording.handleRecordingProgress):
     15        (TestPage.registerInitializer.window.startRecording):
     16        (TestPage.registerInitializer.window.consoleRecord):
     17        (TestPage.registerInitializer):
     18
    1192018-10-08  Dean Jackson  <dino@apple.com>
    220
  • trunk/LayoutTests/inspector/canvas/recording-2d.html

    r229620 r236952  
    453453        description: "Check that a recording can be triggered by console.record().",
    454454        test(resolve, reject) {
    455             consoleRecord(resolve, reject);
     455            consoleRecord(WI.Canvas.ContextType.Canvas2D, resolve, reject);
    456456        },
    457457    });
     
    467467            }
    468468
    469             WI.canvasManager.awaitEvent(WI.CanvasManager.Event.RecordingStopped)
     469            canvas.awaitEvent(WI.Canvas.Event.RecordingStopped)
    470470            .then((event) => {
    471471                let recording = event.data.recording.toJSON();
     
    505505            let eventCount = 0;
    506506            function handleRecordingStopped(event) {
    507                 InspectorTest.assert(event.data.canvas === canvas, "We should have stopped recording the selected canvas.");
    508507                InspectorTest.assert(!event.data.recording, "The recording payload should be null.");
    509508
     
    512511                    InspectorTest.pass("A recording should have been started and stopped once.");
    513512
    514                     WI.canvasManager.startRecording(canvas);
    515                     WI.canvasManager.stopRecording();
     513                    canvas.startRecording();
     514                    canvas.stopRecording();
    516515                } else if (eventCount >= 2) {
    517516                    InspectorTest.pass("A recording should have been started and stopped twice.");
    518517
    519                     WI.canvasManager.removeEventListener(handleRecordingStopped);
     518                    canvas.removeEventListener(WI.Canvas.Event.RecordingStopped, handleRecordingStopped);
    520519                    resolve();
    521520                }
    522521            }
    523             WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingStopped, handleRecordingStopped);
    524 
    525             WI.canvasManager.startRecording(canvas);
    526             WI.canvasManager.stopRecording();
     522            canvas.addEventListener(WI.Canvas.Event.RecordingStopped, handleRecordingStopped);
     523
     524            canvas.startRecording();
     525            canvas.stopRecording();
    527526        },
    528527    });
  • trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html

    r236008 r236952  
    121121        description: "Check that a recording can be triggered by console.record().",
    122122        test(resolve, reject) {
    123             consoleRecord(resolve, reject);
     123            consoleRecord(WI.Canvas.ContextType.BitmapRenderer, resolve, reject);
    124124        },
    125125    });
  • trunk/LayoutTests/inspector/canvas/recording-expected.txt

    r222888 r236952  
    33
    44== Running test suite: Canvas.recording
     5-- Running test case: Canvas.multipleRecording
     6Starting a recording of canvas 1...
     7PASS: Recording started of canvas 1
     8Starting a recording of canvas 2...
     9PASS: Recording started of canvas 2
     10Performing actions...
     11PASS: Actions performed.
     12Stopping the recording of canvas 1...
     13PASS: There should be a recording for canvas 1.
     14Stopping the recording of canvas 2...
     15PASS: There should be a recording for canvas 2.
     16
    517-- Running test case: Canvas.startRecording.InvalidCanvasId
     18ERROR: No active recording for canvas
     19ERROR: No active recording for canvas
    620PASS: Should produce an error.
    721Error: No canvas for given identifier.
  • trunk/LayoutTests/inspector/canvas/recording-webgl.html

    r225488 r236952  
    547547        description: "Check that a recording can be triggered by console.record().",
    548548        test(resolve, reject) {
    549             consoleRecord(resolve, reject);
     549            consoleRecord(WI.Canvas.ContextType.WebGL, resolve, reject);
    550550        },
    551551    });
  • trunk/LayoutTests/inspector/canvas/recording.html

    r222888 r236952  
    44<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
    55<script>
     6let contextA = document.createElement("canvas").getContext("2d");
     7let contextB = document.createElement("canvas").getContext("2d");
     8
     9function performActions() {
     10    contextA.fill();
     11    contextB.fill();
     12
     13    TestPage.dispatchEventToFrontend("TestPage-performActions");
     14}
     15
    616function test() {
    717    let suite = InspectorTest.createAsyncSuite("Canvas.recording");
     18
     19    suite.addTestCase({
     20        name: "Canvas.multipleRecording",
     21        description: "Check that multiple recordings are able to be started/stopped at the same time.",
     22        test(resolve, reject) {
     23            let canvases = WI.canvasManager.canvases;
     24            InspectorTest.assert(canvases.length === 2, "There should be two canvas contexts.");
     25
     26            canvases[1].awaitEvent(WI.Canvas.Event.RecordingStopped)
     27            .then((event) => {
     28                InspectorTest.expectThat(event.data.recording, "There should be a recording for canvas 2.");
     29            })
     30            .then(resolve, reject);
     31
     32            canvases[0].awaitEvent(WI.Canvas.Event.RecordingStopped)
     33            .then((event) => {
     34                InspectorTest.expectThat(event.data.recording, "There should be a recording for canvas 1.");
     35
     36                InspectorTest.log("Stopping the recording of canvas 2...");
     37                canvases[1].stopRecording();
     38            });
     39
     40            InspectorTest.awaitEvent("TestPage-performActions")
     41            .then((event) => {
     42                InspectorTest.pass("Actions performed.");
     43
     44                InspectorTest.log("Stopping the recording of canvas 1...");
     45                canvases[0].stopRecording();
     46            });
     47
     48            canvases[1].awaitEvent(WI.Canvas.Event.RecordingStarted)
     49            .then((event) => {
     50                InspectorTest.expectThat(canvases[1].recordingActive, "Recording started of canvas 2");
     51
     52                InspectorTest.log("Performing actions...");
     53                InspectorTest.evaluateInPage(`performActions()`);
     54            });
     55
     56            canvases[0].awaitEvent(WI.Canvas.Event.RecordingStarted)
     57            .then((event) => {
     58                InspectorTest.expectThat(canvases[0].recordingActive, "Recording started of canvas 1");
     59
     60                InspectorTest.log("Starting a recording of canvas 2...");
     61                canvases[1].startRecording();
     62            });
     63
     64            InspectorTest.log("Starting a recording of canvas 1...");
     65            canvases[0].startRecording();
     66        },
     67    });
    868
    969    suite.addTestCase({
  • trunk/LayoutTests/inspector/canvas/resources/recording-utilities.js

    r236008 r236952  
    8585        let frameCount = 0;
    8686        function handleRecordingProgress(event) {
    87             InspectorTest.assert(event.data.frameCount > frameCount, "Additional frames were captured for this progress event.");
    88             frameCount = event.data.frameCount;
     87            InspectorTest.assert(canvas.recordingFrameCount > frameCount, "Additional frames were captured for this progress event.");
     88            frameCount = canvas.recordingFrameCount;
    8989
    90             InspectorTest.assert(event.data.bufferUsed > bufferUsed, "Total memory usage increases with each progress event.");
    91             bufferUsed = event.data.bufferUsed;
     90            InspectorTest.assert(canvas.recordingBufferUsed > bufferUsed, "Total memory usage increases with each progress event.");
     91            bufferUsed = canvas.recordingBufferUsed;
    9292        }
    93         WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingProgress, handleRecordingProgress);
     93        canvas.addEventListener(WI.Canvas.Event.RecordingProgress, handleRecordingProgress);
    9494
    95         WI.canvasManager.awaitEvent(WI.CanvasManager.Event.RecordingStopped).then((event) => {
    96             WI.canvasManager.removeEventListener(WI.CanvasManager.Event.RecordingProgress, handleRecordingProgress);
     95        canvas.awaitEvent(WI.Canvas.Event.RecordingStopped).then((event) => {
     96            canvas.removeEventListener(WI.Canvas.Event.RecordingProgress, handleRecordingProgress);
    9797
    9898            InspectorTest.evaluateInPage(`cancelActions()`);
     
    121121    };
    122122
    123     window.consoleRecord = function(resolve, reject) {
    124         WI.canvasManager.awaitEvent(WI.CanvasManager.Event.RecordingStopped).then((event) => {
     123    window.consoleRecord = function(type, resolve, reject) {
     124        let canvas = getCanvas(type);
     125        if (!canvas) {
     126            reject(`Missing canvas with type "${type}".`);
     127            return;
     128        }
     129
     130        canvas.awaitEvent(WI.Canvas.Event.RecordingStopped).then((event) => {
    125131            let recording = event.data.recording;
     132
     133            InspectorTest.assert(recording.source === canvas, "Recording should be of the given canvas.");
     134            InspectorTest.assert(recording.source.contextType === type, `Recording should be of a canvas with type "${type}".`);
     135            InspectorTest.assert(recording.source.recordingCollection.has(recording), "Recording should be in the canvas' list of recordings.");
     136
    126137            InspectorTest.expectEqual(recording.displayName, "TEST", "The recording should have the name \"TEST\".");
    127138            InspectorTest.expectEqual(recording.frames.length, 1, "The recording should have one frame.");
  • trunk/Source/WebInspectorUI/ChangeLog

    r236950 r236952  
     12018-10-08  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: allow multiple canvases to be recorded at the same time
     4        https://bugs.webkit.org/show_bug.cgi?id=190305
     5
     6        Reviewed by Brian Burg.
     7
     8        Moved the logic for maintaining whether a canvas is actively recording from
     9        `WI.CanvasManager` to `WI.Canvas`, meaning that each canvas can now record independently of
     10        every other canvas in the page. If multiple recordings are all finished simultaneously, only
     11        show the first one to be recieved by the frontend.
     12
     13        * UserInterface/Controllers/CanvasManager.js:
     14        (WI.CanvasManager):
     15        (WI.CanvasManager.prototype.recordingProgress):
     16        (WI.CanvasManager.prototype.recordingFinished):
     17        (WI.CanvasManager.prototype.programCreated):
     18        (WI.CanvasManager.prototype.programDeleted):
     19        (WI.CanvasManager.prototype._removeCanvas):
     20        (WI.CanvasManager.prototype._mainResourceDidChange):
     21        (WI.CanvasManager.prototype.get recordingCanvas): Deleted.
     22        (WI.CanvasManager.prototype.startRecording): Deleted.
     23        (WI.CanvasManager.prototype.stopRecording): Deleted.
     24        (WI.CanvasManager.prototype._dispatchShaderProgramRemoved): Deleted.
     25
     26        * UserInterface/Models/Canvas.js:
     27        (WI.Canvas.prototype.get recordingFrameCount): Added.
     28        (WI.Canvas.prototype.get recordingBufferUsed): Added.
     29        (WI.Canvas.prototype.get recordingActive): Added.
     30        (WI.Canvas.prototype.get isRecording): Deleted.
     31        (WI.Canvas.prototype.startRecording): Added.
     32        (WI.Canvas.prototype.stopRecording): Added.
     33        (WI.Canvas.prototype.recordingProgress): Added.
     34        (WI.Canvas.prototype.recordingFinished): Added.
     35
     36        * UserInterface/Views/CanvasTabContentView.js:
     37        (WI.CanvasTabContentView.prototype.attached):
     38        (WI.CanvasTabContentView.prototype.detached):
     39        (WI.CanvasTabContentView.prototype._recordingImportedOrStopped):
     40        (WI.CanvasTabContentView.prototype._handleSpace):
     41        (WI.CanvasTabContentView):
     42
     43        * UserInterface/Views/CanvasOverviewContentView.css:
     44        (.content-view.canvas-overview .content-view.canvas.recording-active): Added.
     45        (.content-view.canvas-overview .content-view.canvas.recording-active > header): Added.
     46        (.content-view.canvas-overview .content-view.canvas.recording-active > header > .titles > .title): Added.
     47        (.content-view.canvas-overview .content-view.canvas.recording-active > header > .titles > .subtitle): Added.
     48        (.content-view.canvas-overview .content-view.canvas.recording-active > header > .navigation-bar > .item): Added.
     49        (.content-view.canvas-overview .content-view.canvas:matches(:hover, .recording-active) > header > .navigation-bar): Added.
     50        (.content-view.canvas-overview .content-view.canvas:not(.recording-active) > header > .navigation-bar > .item.record-start-stop.disabled): Added.
     51        (.content-view.canvas-overview .content-view.canvas:not(.recording-active) > header > .navigation-bar > .item.record-start-stop:not(.disabled):hover): Added.
     52        (.content-view.canvas-overview .content-view.canvas:not(.recording-active) > header > .navigation-bar > .item.record-start-stop:not(.disabled):active): Added.
     53        (.content-view.canvas-overview .content-view.canvas.recording-active > .progress-vie): Added.
     54        (.content-view.canvas-overview .content-view.canvas.recording-active > .preview): Added.
     55        (.content-view.canvas-overview .content-view.canvas.recording-active): Added.
     56        (.content-view.canvas-overview .content-view.canvas.recording-active > header): Added.
     57        (.content-view.canvas-overview .content-view.canvas.recording-active > header > .titles > .subtitle): Added.
     58        (.content-view.canvas-overview .content-view.canvas.is-recording): Deleted.
     59        (.content-view.canvas-overview .content-view.canvas.is-recording > header): Deleted.
     60        (.content-view.canvas-overview .content-view.canvas.is-recording > header > .titles > .title): Deleted.
     61        (.content-view.canvas-overview .content-view.canvas.is-recording > header > .titles > .subtitle): Deleted.
     62        (.content-view.canvas-overview .content-view.canvas.is-recording > header > .navigation-bar > .item): Deleted.
     63        (.content-view.canvas-overview .content-view.canvas:matches(:hover, .is-recording) > header > .navigation-bar): Deleted.
     64        (.content-view.canvas-overview .content-view.canvas:not(.is-recording) > header > .navigation-bar > .item.record-start-stop.disabled): Deleted.
     65        (.content-view.canvas-overview .content-view.canvas:not(.is-recording) > header > .navigation-bar > .item.record-start-stop:not(.disabled):hover): Deleted.
     66        (.content-view.canvas-overview .content-view.canvas:not(.is-recording) > header > .navigation-bar > .item.record-start-stop:not(.disabled):active): Deleted.
     67        (.content-view.canvas-overview .content-view.canvas.is-recording > .progress-vie): Deleted.
     68        (.content-view.canvas-overview .content-view.canvas.is-recording > .preview): Deleted.
     69        (.content-view.canvas-overview .content-view.canvas.is-recording): Deleted.
     70        (.content-view.canvas-overview .content-view.canvas.is-recording > header): Deleted.
     71        (.content-view.canvas-overview .content-view.canvas.is-recording > header > .titles > .subtitle): Deleted.
     72
     73        * UserInterface/Views/CanvasContentView.js:
     74        (WI.CanvasContentView.prototype.attached):
     75        (WI.CanvasContentView.prototype.detached):
     76        (WI.CanvasContentView.prototype._toggleRecording):
     77        (WI.CanvasContentView.prototype._recordingProgress):
     78        (WI.CanvasContentView.prototype._recordingStopped):
     79        (WI.CanvasContentView.prototype._shaderProgramAdded):
     80        (WI.CanvasContentView.prototype._shaderProgramRemoved):
     81        (WI.CanvasContentView.prototype._updateRecordNavigationItem):
     82        (WI.CanvasContentView.prototype._updateProgressView):
     83
     84        * UserInterface/Views/CanvasSidebarPanel.js:
     85        (WI.CanvasSidebarPanel):
     86        (WI.CanvasSidebarPanel.prototype.set canvas):
     87        (WI.CanvasSidebarPanel.prototype._toggleRecording):
     88        (WI.CanvasSidebarPanel.prototype._updateRecordNavigationItem):
     89
     90        * UserInterface/Views/CanvasTreeElement.js:
     91        (WI.CanvasTreeElement):
     92        (WI.CanvasTreeElement.prototype._updateStatus):
     93
    1942018-10-08  Devin Rousso  <drousso@apple.com>
    295
  • trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js

    r235937 r236952  
    3535        this._shaderProgramIdentifierMap = new Map;
    3636
    37         this._recordingCanvas = null;
    38         this._recordingFrameMap = new Map;
    39 
    4037        if (window.CanvasAgent)
    4138            CanvasAgent.enable();
     
    5350        return [...this._shaderProgramIdentifierMap.values()];
    5451    }
    55 
    56     get recordingCanvas() { return this._recordingCanvas; }
    5752
    5853    importRecording()
     
    8580    }
    8681
    87     startRecording(canvas, singleFrame)
    88     {
    89         console.assert(!this._recordingCanvas, "Recording already started.");
    90         if (this._recordingCanvas)
    91             return;
    92 
    93         this._recordingCanvas = canvas;
    94 
    95         CanvasAgent.startRecording(canvas.identifier, singleFrame, (error) => {
    96             if (error) {
    97                 console.error(error);
    98                 this._recordingCanvas = null;
    99                 return;
    100             }
    101 
    102             this.dispatchEventToListeners(WI.CanvasManager.Event.RecordingStarted, {canvas});
    103         });
    104     }
    105 
    106     stopRecording()
    107     {
    108         console.assert(this._recordingCanvas, "No recording started.");
    109         if (!this._recordingCanvas)
    110             return;
    111 
    112         let canvas = this._recordingCanvas;
    113 
    114         CanvasAgent.stopRecording(canvas.identifier, (error) => {
    115             if (!error)
    116                 return;
    117 
    118             console.error(error);
    119             this._recordingCanvas = null;
    120             this.dispatchEventToListeners(WI.CanvasManager.Event.RecordingStopped, {canvas, recording: null});
    121         });
    122     }
    123 
    12482    canvasAdded(canvasPayload)
    12583    {
     
    179137            return;
    180138
    181         let existingFrames = this._recordingFrameMap.get(canvasIdentifier);
    182         if (!existingFrames) {
    183             existingFrames = [];
    184             this._recordingFrameMap.set(canvasIdentifier, existingFrames);
    185         }
    186 
    187         existingFrames.push(...framesPayload.map(WI.RecordingFrame.fromPayload));
    188 
    189         this.dispatchEventToListeners(WI.CanvasManager.Event.RecordingProgress, {
    190             canvas,
    191             frameCount: existingFrames.length,
    192             bufferUsed,
    193         });
     139        canvas.recordingProgress(framesPayload, bufferUsed);
    194140    }
    195141
     
    200146        let canvas = this._canvasIdentifierMap.get(canvasIdentifier);
    201147        console.assert(canvas);
    202 
    203         let fromConsole = canvas !== this._recordingCanvas;
    204         if (!fromConsole)
    205             this._recordingCanvas = null;
    206 
    207         if (!canvas)
    208             return;
    209 
    210         let frames = this._recordingFrameMap.take(canvasIdentifier);
    211         let recording = recordingPayload ? WI.Recording.fromPayload(recordingPayload, frames) : null;
    212         if (recording) {
    213             recording.source = canvas;
    214             recording.createDisplayName(recordingPayload.name);
    215 
    216             canvas.recordingCollection.add(recording);
    217         }
    218 
    219         this.dispatchEventToListeners(WI.CanvasManager.Event.RecordingStopped, {canvas, recording, fromConsole});
     148        if (!canvas)
     149            return;
     150
     151        canvas.recordingFinished(recordingPayload);
    220152    }
    221153
     
    247179
    248180        canvas.shaderProgramCollection.add(program);
    249 
    250         this.dispatchEventToListeners(WI.CanvasManager.Event.ShaderProgramAdded, {program});
    251181    }
    252182
     
    261191
    262192        program.canvas.shaderProgramCollection.remove(program);
    263 
    264         this._dispatchShaderProgramRemoved(program);
    265193    }
    266194
     
    269197    _removeCanvas(canvas)
    270198    {
    271         for (let program of canvas.shaderProgramCollection) {
     199        for (let program of canvas.shaderProgramCollection)
    272200            this._shaderProgramIdentifierMap.delete(program.identifier);
    273             this._dispatchShaderProgramRemoved(program);
    274         }
    275201
    276202        for (let recording of canvas.recordingCollection) {
     
    296222        this._canvasIdentifierMap.clear();
    297223    }
    298 
    299     _dispatchShaderProgramRemoved(program)
    300     {
    301         this.dispatchEventToListeners(WI.CanvasManager.Event.ShaderProgramRemoved, {program});
    302     }
    303224};
    304225
     
    307228    CanvasRemoved: "canvas-manager-canvas-was-removed",
    308229    RecordingImported: "canvas-manager-recording-imported",
    309     RecordingStarted: "canvas-manager-recording-started",
    310     RecordingProgress: "canvas-manager-recording-progress",
    311     RecordingStopped: "canvas-manager-recording-stopped",
    312     ShaderProgramAdded: "canvas-manager-shader-program-added",
    313     ShaderProgramRemoved: "canvas-manager-shader-program-removed",
    314230};
  • trunk/Source/WebInspectorUI/UserInterface/Models/Canvas.js

    r236766 r236952  
    4949
    5050        this._requestNodePromise = null;
     51
     52        this._recordingState = WI.Canvas.RecordingState.Inactive;
     53        this._recordingFrames = [];
     54        this._recordingBufferUsed = 0;
    5155    }
    5256
     
    118122    get shaderProgramCollection() { return this._shaderProgramCollection; }
    119123    get recordingCollection() { return this._recordingCollection; }
    120 
    121     get isRecording()
    122     {
    123         return WI.canvasManager.recordingCanvas === this;
     124    get recordingFrameCount() { return this._recordingFrames.length; }
     125    get recordingBufferUsed() { return this._recordingBufferUsed; }
     126
     127    get recordingActive()
     128    {
     129        return this._recordingState !== WI.Canvas.RecordingState.Inactive;
    124130    }
    125131
     
    258264    }
    259265
     266    startRecording(singleFrame)
     267    {
     268        CanvasAgent.startRecording(this._identifier, singleFrame, (error) => {
     269            if (error) {
     270                console.error(error);
     271                return;
     272            }
     273
     274            this._recordingState = WI.Canvas.RecordingState.Active;
     275            this._recordingFrames = [];
     276            this._recordingBufferUsed = 0;
     277
     278            this.dispatchEventToListeners(WI.Canvas.Event.RecordingStarted);
     279        });
     280    }
     281
     282    stopRecording()
     283    {
     284        CanvasAgent.stopRecording(this._identifier, (error) => {
     285            if (error)
     286                console.error(error);
     287        });
     288    }
     289
    260290    saveIdentityToCookie(cookie)
    261291    {
     
    286316
    287317        this.dispatchEventToListeners(WI.Canvas.Event.CSSCanvasClientNodesChanged);
     318    }
     319
     320    recordingProgress(framesPayload, bufferUsed)
     321    {
     322        // Called from WI.CanvasManager.
     323
     324        this._recordingFrames.push(...framesPayload.map(WI.RecordingFrame.fromPayload));
     325
     326        this._recordingBufferUsed = bufferUsed;
     327
     328        this.dispatchEventToListeners(WI.Canvas.Event.RecordingProgress);
     329    }
     330
     331    recordingFinished(recordingPayload)
     332    {
     333        // Called from WI.CanvasManager.
     334
     335        let fromConsole = !this.recordingActive;
     336
     337        let recording = recordingPayload ? WI.Recording.fromPayload(recordingPayload, this._recordingFrames) : null;
     338        if (recording) {
     339            recording.source = this;
     340            recording.createDisplayName(recordingPayload.name);
     341
     342            this._recordingCollection.add(recording);
     343        }
     344
     345        this._recordingState = WI.Canvas.RecordingState.Inactive;
     346        this._recordingFrames = [];
     347        this._recordingBufferUsed = 0;
     348
     349        this.dispatchEventToListeners(WI.Canvas.Event.RecordingStopped, {recording, fromConsole});
    288350    }
    289351
     
    309371};
    310372
     373WI.Canvas.RecordingState = {
     374    Inactive: "canvas-recording-state-inactive",
     375    Active: "canvas-recording-state-active",
     376};
     377
    311378WI.Canvas.Event = {
    312379    MemoryChanged: "canvas-memory-changed",
    313380    ExtensionEnabled: "canvas-extension-enabled",
    314381    CSSCanvasClientNodesChanged: "canvas-css-canvas-client-nodes-changed",
     382    RecordingStarted: "canvas-recording-started",
     383    RecordingProgress: "canvas-recording-progress",
     384    RecordingStopped: "canvas-recording-stopped",
    315385};
  • trunk/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js

    r236008 r236952  
    196196
    197197        this.representedObject.addEventListener(WI.Canvas.Event.MemoryChanged, this._updateMemoryCost, this);
     198        this.representedObject.addEventListener(WI.Canvas.Event.RecordingStarted, this._recordingStarted, this);
     199        this.representedObject.addEventListener(WI.Canvas.Event.RecordingProgress, this._recordingProgress, this);
     200        this.representedObject.addEventListener(WI.Canvas.Event.RecordingStopped, this._recordingStopped, this);
     201        this.representedObject.shaderProgramCollection.addEventListener(WI.Collection.Event.ItemAdded, this._shaderProgramAdded, this);
     202        this.representedObject.shaderProgramCollection.addEventListener(WI.Collection.Event.ItemRemoved, this._shaderProgramRemoved, this);
    198203
    199204        this.representedObject.requestNode().then((node) => {
     
    207212        });
    208213
    209         WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingStarted, this._recordingStarted, this);
    210         WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingProgress, this._recordingProgress, this);
    211         WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingStopped, this._recordingStopped, this);
    212         WI.canvasManager.addEventListener(WI.CanvasManager.Event.ShaderProgramAdded, this._shaderProgramAdded, this);
    213         WI.canvasManager.addEventListener(WI.CanvasManager.Event.ShaderProgramRemoved, this._shaderProgramRemoved, this);
    214 
    215214        WI.settings.showImageGrid.addEventListener(WI.Setting.Event.Changed, this._updateImageGrid, this);
    216215    }
     
    219218    {
    220219        this.representedObject.removeEventListener(null, null, this);
     220        this.representedObject.shaderProgramCollection.removeEventListener(null, null, this);
    221221
    222222        if (this._canvasNode) {
     
    225225        }
    226226
    227         WI.canvasManager.removeEventListener(null, null, this);
    228227        WI.settings.showImageGrid.removeEventListener(null, null, this);
    229228
     
    249248    _toggleRecording(event)
    250249    {
    251         if (this.representedObject.isRecording)
    252             WI.canvasManager.stopRecording();
    253         else if (!WI.canvasManager.recordingCanvas) {
     250        if (this.representedObject.recordingActive)
     251            this.representedObject.stopRecording();
     252        else {
    254253            let singleFrame = event.data.nativeEvent.shiftKey;
    255             WI.canvasManager.startRecording(this.representedObject, singleFrame);
     254            this.representedObject.startRecording(singleFrame);
    256255        }
    257256    }
     
    265264    _recordingProgress(event)
    266265    {
    267         let {canvas, frameCount, bufferUsed} = event.data;
    268         if (canvas !== this.representedObject)
    269             return;
    270 
    271         this._updateProgressView(frameCount, bufferUsed);
     266        this._updateProgressView();
    272267    }
    273268
     
    275270    {
    276271        this._updateRecordNavigationItem();
    277 
    278         let {canvas} = event.data;
    279         if (canvas !== this.representedObject)
    280             return;
    281 
    282272        this._updateProgressView();
    283 
    284273        this._updateViewRelatedItems();
    285274    }
     
    287276    _shaderProgramAdded(event)
    288277    {
    289         let {shaderProgram} = event.data;
    290         if (!shaderProgram || shaderProgram.canvas !== this.representedObject)
    291             return;
    292 
    293278        this._updateViewRelatedItems();
    294279    }
     
    296281    _shaderProgramRemoved(event)
    297282    {
    298         let {shaderProgram} = event.data;
    299         if (!shaderProgram || shaderProgram.canvas !== this.representedObject)
    300             return;
    301 
    302283        this._updateViewRelatedItems();
    303284    }
     
    383364            return;
    384365
    385         let isRecording = this.representedObject.isRecording;
    386         this._recordButtonNavigationItem.enabled = isRecording || !WI.canvasManager.recordingCanvas;
    387         this._recordButtonNavigationItem.toggled = isRecording;
    388 
    389         this._refreshButtonNavigationItem.enabled = !isRecording;
    390 
    391         this.element.classList.toggle("is-recording", isRecording);
    392     }
    393 
    394     _updateProgressView(frameCount, bufferUsed)
    395     {
    396         if (!this.representedObject.isRecording) {
     366        let recordingActive = this.representedObject.recordingActive;
     367        this._recordButtonNavigationItem.toggled = recordingActive;
     368        this._refreshButtonNavigationItem.enabled = !recordingActive;
     369        this.element.classList.toggle("recording-active", recordingActive);
     370    }
     371
     372    _updateProgressView()
     373    {
     374        if (!this.representedObject.recordingActive) {
    397375            if (this._progressView && this._progressView.parentView) {
    398376                this.removeSubview(this._progressView);
     
    408386        }
    409387
    410         let title;
    411         if (frameCount) {
    412             let formatString = frameCount === 1 ? WI.UIString("%d Frame") : WI.UIString("%d Frames");
    413             title = formatString.format(frameCount);
     388        let title = null;
     389        if (this.representedObject.recordingFrameCount) {
     390            let formatString = this.representedObject.recordingFrameCount === 1 ? WI.UIString("%d Frame") : WI.UIString("%d Frames");
     391            title = formatString.format(this.representedObject.recordingFrameCount);
    414392        } else
    415393            title = WI.UIString("Waiting for frames…");
    416394
    417395        this._progressView.title = title;
    418         this._progressView.subtitle = bufferUsed ? Number.bytesToString(bufferUsed) : "";
     396        this._progressView.subtitle = this.representedObject.recordingBufferUsed ? Number.bytesToString(this.representedObject.recordingBufferUsed) : "";
    419397    }
    420398
  • trunk/Source/WebInspectorUI/UserInterface/Views/CanvasOverviewContentView.css

    r236237 r236952  
    4444}
    4545
    46 .content-view.canvas-overview .content-view.canvas.is-recording {
     46.content-view.canvas-overview .content-view.canvas.recording-active {
    4747    border-color: red;
    4848}
     
    6363}
    6464
    65 .content-view.canvas-overview .content-view.canvas.is-recording > header {
     65.content-view.canvas-overview .content-view.canvas.recording-active > header {
    6666    background-color: red;
    6767}
     
    8585}
    8686
    87 .content-view.canvas-overview .content-view.canvas.is-recording > header > .titles > .title {
     87.content-view.canvas-overview .content-view.canvas.recording-active > header > .titles > .title {
    8888    color: white;
    8989}
    9090
    91 .content-view.canvas-overview .content-view.canvas.is-recording > header > .titles > .subtitle {
     91.content-view.canvas-overview .content-view.canvas.recording-active > header > .titles > .subtitle {
    9292    color: var(--selected-secondary-text-color);
    9393}
    9494
    95 .content-view.canvas-overview .content-view.canvas.is-recording > header > .navigation-bar > .item {
     95.content-view.canvas-overview .content-view.canvas.recording-active > header > .navigation-bar > .item {
    9696    filter: brightness(0) invert();
    9797}
     
    104104}
    105105
    106 .content-view.canvas-overview .content-view.canvas:matches(:hover, .is-recording) > header > .navigation-bar {
     106.content-view.canvas-overview .content-view.canvas:matches(:hover, .recording-active) > header > .navigation-bar {
    107107    opacity: 1;
    108108    transition: opacity 200ms ease-in-out;
    109109}
    110110
    111 .content-view.canvas-overview .content-view.canvas:not(.is-recording) > header > .navigation-bar > .item.record-start-stop.disabled {
     111.content-view.canvas-overview .content-view.canvas:not(.recording-active) > header > .navigation-bar > .item.record-start-stop.disabled {
    112112    filter: grayscale();
    113113    opacity: 0.5;
    114114}
    115115
    116 .content-view.canvas-overview .content-view.canvas:not(.is-recording) > header > .navigation-bar > .item.record-start-stop:not(.disabled):hover {
     116.content-view.canvas-overview .content-view.canvas:not(.recording-active) > header > .navigation-bar > .item.record-start-stop:not(.disabled):hover {
    117117    filter: brightness(95%);
    118118}
    119119
    120 .content-view.canvas-overview .content-view.canvas:not(.is-recording) > header > .navigation-bar > .item.record-start-stop:not(.disabled):active {
     120.content-view.canvas-overview .content-view.canvas:not(.recording-active) > header > .navigation-bar > .item.record-start-stop:not(.disabled):active {
    121121    filter: brightness(80%);
    122122}
    123123
    124 .content-view.canvas-overview .content-view.canvas.is-recording > .progress-view,
     124.content-view.canvas-overview .content-view.canvas.recording-active > .progress-view,
    125125.content-view.canvas-overview .content-view.canvas > .preview {
    126126    height: 280px;
    127127}
    128128
    129 .content-view.canvas-overview .content-view.canvas.is-recording > .preview {
     129.content-view.canvas-overview .content-view.canvas.recording-active > .preview {
    130130    display: none;
    131131}
     
    197197    }
    198198
    199     .content-view.canvas-overview .content-view.canvas.is-recording {
     199    .content-view.canvas-overview .content-view.canvas.recording-active {
    200200        --recording-color: hsl(0, 100%, 39%);
    201201        border-color: var(--recording-color);
    202202    }
    203203
    204     .content-view.canvas-overview .content-view.canvas.is-recording > header {
     204    .content-view.canvas-overview .content-view.canvas.recording-active > header {
    205205        background-color: var(--recording-color);
    206206    }
     
    219219    }
    220220
    221     .content-view.canvas-overview .content-view.canvas.is-recording > header > .titles > .subtitle {
     221    .content-view.canvas-overview .content-view.canvas.recording-active > header > .titles > .subtitle {
    222222        color: unset;
    223223        opacity: 0.5
  • trunk/Source/WebInspectorUI/UserInterface/Views/CanvasSidebarPanel.js

    r236539 r236952  
    6666        this._recordingTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._treeOutlineSelectionDidChange, this);
    6767
    68         WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingStarted, this._updateRecordNavigationItem, this);
    69         WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingStopped, this._updateRecordNavigationItem, this);
    70 
    7168        this._recordingProcessingOptionsContainer = null;
    7269
     
    8683            return;
    8784
    88         if (this._canvas)
     85        if (this._canvas) {
     86            this._canvas.removeEventListener(null, null, this);
    8987            this._canvas.recordingCollection.removeEventListener(null, null, this);
     88        }
    9089
    9190        this._canvas = canvas;
    9291        if (this._canvas) {
     92            this._canvas.addEventListener(WI.Canvas.Event.RecordingStarted, this._updateRecordNavigationItem, this);
     93            this._canvas.addEventListener(WI.Canvas.Event.RecordingStopped, this._updateRecordNavigationItem, this);
    9394            this._canvas.recordingCollection.addEventListener(WI.Collection.Event.ItemAdded, this._recordingAdded, this);
    9495            this._canvas.recordingCollection.addEventListener(WI.Collection.Event.ItemRemoved, this._recordingRemoved, this);
     
    284285            return;
    285286
    286         if (this._canvas.isRecording)
    287             WI.canvasManager.stopRecording();
    288         else if (!WI.canvasManager.recordingCanvas) {
     287        if (this._canvas.recordingActive)
     288            this._canvas.stopRecording();
     289        else {
    289290            let singleFrame = event.data.nativeEvent.shiftKey;
    290             WI.canvasManager.startRecording(this._canvas, singleFrame);
     291            this._canvas.startRecording(singleFrame);
    291292        }
    292293    }
     
    446447        }
    447448
    448         let isRecording = this._canvas.isRecording;
    449         this._recordButtonNavigationItem.enabled = isRecording || !WI.canvasManager.recordingCanvas;
    450         this._recordButtonNavigationItem.toggled = isRecording;
     449        this._recordButtonNavigationItem.toggled = this._canvas.recordingActive;
    451450    }
    452451
  • trunk/Source/WebInspectorUI/UserInterface/Views/CanvasTabContentView.js

    r235937 r236952  
    126126        WI.canvasManager.addEventListener(WI.CanvasManager.Event.CanvasRemoved, this._handleCanvasRemoved, this);
    127127        WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingImported, this._recordingImportedOrStopped, this);
    128         WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingStopped, this._recordingImportedOrStopped, this);
     128        WI.Canvas.addEventListener(WI.Canvas.Event.RecordingStopped, this._recordingImportedOrStopped, this);
    129129
    130130        let canvases = new Set([...this._canvasCollection, ...WI.canvasManager.canvases]);
     
    143143    detached()
    144144    {
     145        WI.Canvas.removeEventListener(null, null, this);
    145146        WI.canvasManager.removeEventListener(null, null, this);
    146         WI.RecordingContentView.removeEventListener(null, null, this);
    147147
    148148        super.detached();
     
    215215
    216216        this._recordingAdded(recording, {
    217             suppressShowRecording: event.data.fromConsole,
     217            suppressShowRecording: event.data.fromConsole || this.contentBrowser.currentRepresentedObjects.some((representedObject) => representedObject instanceof WI.Recording),
    218218        });
    219219    }
     
    244244            return;
    245245
    246         if (canvas.isRecording)
    247             WI.canvasManager.stopRecording();
    248         else if (!WI.canvasManager.recordingCanvas) {
     246        if (canvas.recordingActive)
     247            canvas.stopRecording();
     248        else {
    249249            let singleFrame = !!event.shiftKey;
    250             WI.canvasManager.startRecording(canvas, singleFrame);
     250            canvas.startRecording(singleFrame);
    251251        }
    252252
  • trunk/Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js

    r236766 r236952  
    3535        this.registerFolderizeSettings("shader-programs", WI.UIString("Shader Programs"), this.representedObject.shaderProgramCollection, WI.ShaderProgramTreeElement);
    3636
    37         WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingStarted, this._updateStatus, this);
    38         WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingStopped, this._updateStatus, this);
    39 
     37        this.representedObject.addEventListener(WI.Canvas.Event.RecordingStarted, this._updateStatus, this);
     38        this.representedObject.addEventListener(WI.Canvas.Event.RecordingStopped, this._updateStatus, this);
    4039        this.representedObject.shaderProgramCollection.addEventListener(WI.Collection.Event.ItemAdded, this._handleItemAdded, this);
    4140        this.representedObject.shaderProgramCollection.addEventListener(WI.Collection.Event.ItemRemoved, this._handleItemRemoved, this);
     
    138137    _updateStatus()
    139138    {
    140         if (this.representedObject.isRecording) {
    141             if (!this.status || !this.status[WI.CanvasTreeElement.SpinnerSymbol]) {
     139        if (this.representedObject.recordingActive) {
     140            if (!this.status || !this.status.__showingSpinner) {
    142141                let spinner = new WI.IndeterminateProgressSpinner;
    143142                this.status = spinner.element;
    144                 this.status[WI.CanvasTreeElement.SpinnerSymbol] = true;
     143                this.status.__showingSpinner = true;
    145144            }
    146145        } else {
    147             if (this.status && this.status[WI.CanvasTreeElement.SpinnerSymbol])
     146            if (this.status && this.status.__showingSpinner)
    148147                this.status = "";
    149148        }
Note: See TracChangeset for help on using the changeset viewer.