Changeset 237777 in webkit


Ignore:
Timestamp:
Nov 3, 2018 4:24:35 PM (5 years ago)
Author:
Devin Rousso
Message:

Web Inspector: Canvas: capture changes to <canvas> that would affect the recorded context
https://bugs.webkit.org/show_bug.cgi?id=190854

Reviewed by Matt Baker.

Source/WebCore:

Updated existing tests: inspector/canvas/recording-2d.html

inspector/canvas/recording-bitmaprenderer.html
inspector/canvas/recording-webgl.html

  • html/HTMLCanvasElement.idl:

Apply CallTracingCallback=recordCanvasAction to the width and height attributes so
that they are recorded through the same path as CanvasRenderingContext.

  • html/CanvasBase.h:
  • html/CanvasBase.cpp:

(WebCore::CanvasBase::callTracingActive const): Added.

  • bindings/js/CallTracer.h:
  • bindings/js/CallTracer.cpp:

(WebCore::CallTracer::recordCanvasAction):

Source/WebInspectorUI:

  • UserInterface/Models/RecordingAction.js:

(WI.RecordingAction):
(WI.RecordingAction.isFunctionForType):
(WI.RecordingAction.constantNameForParameter):
(WI.RecordingAction.prototype.get contextReplacer): Added.
(WI.RecordingAction.prototype.async.swizzle):
(WI.RecordingAction.prototype.apply):
Create a constant list of actions for each recording type that need to replace the context
with a different value before being applied (e.g. width should be applied to the
context's canvas instead of directly to the context).

  • UserInterface/Views/RecordingContentView.js:

(WI.RecordingContentView.prototype._generateContentCanvas2D.actionModifiesPath): Added.
(WI.RecordingContentView.prototype._generateContentCanvas2D):
(WI.RecordingContentView._actionModifiesPath): Deleted.
Generate the path context after the actions are applied to the preview context so that the
final width/height are known and can be used. This is needed because changing the
width/height causes the content to be erased.

  • UserInterface/Views/RecordingActionTreeElement.js:

(WI.RecordingActionTreeElement._generateDOM):
(WI.RecordingActionTreeElement._classNameForAction):

  • UserInterface/Views/RecordingActionTreeElement.css:

(.tree-outline:focus .item.action.selected:not(.invalid, .initial-state, .has-context-replacer) > .icon): Added.
(.item.action > .titles .context-replacer::after): Added.
(.item.action.has-context-replacer > .icon): Added.
(@media (prefers-dark-interface) .item.action:not(.invalid, .initial-state, .has-context-replacer) > .icon): Added.
(.tree-outline:focus .item.action.selected:not(.initial-state, .invalid) > .icon): Deleted.
(@media (prefers-dark-interface) .item.action:not(.initial-state) > .icon): Deleted.
(@media (prefers-dark-interface) .tree-outline:not(.hide-disclosure-buttons) .item.action:not(.initial-state, .parent) > .icon): Deleted.
Add the context replacer text to the beginning of the action's name if it exists.

  • UserInterface/Views/CanvasContentView.js:

(WI.CanvasContentView.prototype._refreshPixelSize):
(WI.CanvasContentView.prototype._updatePixelSize): Deleted.
Update preview image when the canvas' size changes.

LayoutTests:

  • inspector/canvas/recording-2d-expected.txt:
  • inspector/canvas/recording-2d.html:
  • inspector/canvas/recording-bitmaprenderer-expected.txt:
  • inspector/canvas/recording-bitmaprenderer.html:
  • inspector/canvas/recording-webgl-expected.txt:
  • inspector/canvas/recording-webgl.html:
Location:
trunk
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r237776 r237777  
     12018-11-03  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Canvas: capture changes to <canvas> that would affect the recorded context
     4        https://bugs.webkit.org/show_bug.cgi?id=190854
     5
     6        Reviewed by Matt Baker.
     7
     8        * inspector/canvas/recording-2d-expected.txt:
     9        * inspector/canvas/recording-2d.html:
     10        * inspector/canvas/recording-bitmaprenderer-expected.txt:
     11        * inspector/canvas/recording-bitmaprenderer.html:
     12        * inspector/canvas/recording-webgl-expected.txt:
     13        * inspector/canvas/recording-webgl.html:
     14
    1152018-11-03  Andy Estes  <aestes@apple.com>
    216
  • trunk/LayoutTests/inspector/canvas/recording-2d-expected.txt

    r237198 r237777  
    10681068        0: (anonymous function)
    10691069        1: executeFrameFunction
     1070  73: (duration)
     1071    0: width
     1072      trace:
     1073        0: (anonymous function)
     1074        1: executeFrameFunction
     1075    1: width = 2
     1076      swizzleTypes: [Number]
     1077      trace:
     1078        0: (anonymous function)
     1079        1: executeFrameFunction
     1080  74: (duration)
     1081    0: height
     1082      trace:
     1083        0: (anonymous function)
     1084        1: executeFrameFunction
     1085    1: height = 2
     1086      swizzleTypes: [Number]
     1087      trace:
     1088        0: (anonymous function)
     1089        1: executeFrameFunction
    10701090
    10711091-- Running test case: Canvas.recording2D.memoryLimit
  • trunk/LayoutTests/inspector/canvas/recording-2d.html

    r237670 r237777  
    383383            ctx.webkitLineDashOffset;
    384384            ctx.webkitLineDashOffset = 1;
     385        },
     386        () => {
     387            ctx.canvas.width;
     388            ctx.canvas.width = 2;
     389        },
     390        () => {
     391            ctx.canvas.height;
     392            ctx.canvas.height = 2;
    385393        },
    386394        () => {
  • trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer-expected.txt

    r236008 r237777  
    4444        6: promiseReactionJob
    4545      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAABNJREFUCB1j/M/AAEQMDEwgAgQAHxcCAmtAm/sAAAAASUVORK5CYII="
     46  1: (duration)
     47    0: width
     48      trace:
     49        0: (anonymous function)
     50        1: executeFrameFunction
     51    1: width = 2
     52      swizzleTypes: [Number]
     53      trace:
     54        0: (anonymous function)
     55        1: executeFrameFunction
     56  2: (duration)
     57    0: height
     58      trace:
     59        0: (anonymous function)
     60        1: executeFrameFunction
     61    1: height = 2
     62      swizzleTypes: [Number]
     63      trace:
     64        0: (anonymous function)
     65        1: executeFrameFunction
    4666
    4767-- Running test case: Canvas.recordingBitmapRenderer.memoryLimit
  • trunk/LayoutTests/inspector/canvas/recording-bitmaprenderer.html

    r237670 r237777  
    5252        () => {
    5353            ctx.transferFromImageBitmap(redBitmap);
     54        },
     55        () => {
     56            ctx.canvas.width;
     57            ctx.canvas.width = 2;
     58        },
     59        () => {
     60            ctx.canvas.height;
     61            ctx.canvas.height = 2;
    5462        },
    5563        () => {
  • trunk/LayoutTests/inspector/canvas/recording-webgl-expected.txt

    r236008 r237777  
    66initialState:
    77  attributes:
    8     width: 300
    9     height: 150
     8    width: 2
     9    height: 2
    1010  parameters:
    1111    0: {"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
    12   content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
     12  content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
    1313frames:
    1414  0: (duration)
     
    2828initialState:
    2929  attributes:
    30     width: 300
    31     height: 150
     30    width: 2
     31    height: 2
    3232  parameters:
    3333    0: {"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
    34   content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
     34  content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
    3535frames:
    3636  0: (duration)
     
    157157        1: (anonymous function)
    158158        2: executeFrameFunction
    159       snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
     159      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
    160160  16: (duration)
    161161    0: clearColor(1, 2, 3, 4)
     
    356356        1: (anonymous function)
    357357        2: executeFrameFunction
    358       snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
     358      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
    359359  45: (duration)
    360360    0: drawElements(1, 2, 3, 4)
     
    364364        1: (anonymous function)
    365365        2: executeFrameFunction
    366       snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
     366      snapshot: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
    367367  46: (duration)
    368368    0: enable(1)
     
    10071007        1: (anonymous function)
    10081008        2: executeFrameFunction
     1009  137: (duration)
     1010    0: width
     1011      trace:
     1012        0: (anonymous function)
     1013        1: executeFrameFunction
     1014    1: width = 2
     1015      swizzleTypes: [Number]
     1016      trace:
     1017        0: (anonymous function)
     1018        1: executeFrameFunction
     1019  138: (duration)
     1020    0: height
     1021      trace:
     1022        0: (anonymous function)
     1023        1: executeFrameFunction
     1024    1: height = 2
     1025      swizzleTypes: [Number]
     1026      trace:
     1027        0: (anonymous function)
     1028        1: executeFrameFunction
    10091029
    10101030-- Running test case: Canvas.recordingWebGL.memoryLimit
    10111031initialState:
    10121032  attributes:
    1013     width: 300
    1014     height: 150
     1033    width: 2
     1034    height: 2
    10151035  parameters:
    10161036    0: {"alpha":true,"depth":true,"stencil":false,"antialias":true,"premultipliedAlpha":true,"preserveDrawingBuffer":false,"failIfMajorPerformanceCaveat":false}
    1017   content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAACWCAYAAABkW7XSAAAAAXNSR0IArs4c6QAAAylJREFUeAHt0DEBAAAAwqD1T20IX4hAYcCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYMCAAQMGDBgwYOAdGL/UAAEPpnR6AAAAAElFTkSuQmCC"
     1037  content: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAAAtJREFUCB1jYEAHAAASAAGAFMrMAAAAAElFTkSuQmCC"
    10181038frames:
    10191039  0: (duration) (incomplete)
  • trunk/LayoutTests/inspector/canvas/recording-webgl.html

    r237670 r237777  
    4040    linkProgram("vertex-shader", "fragment-shader");
    4141
     42    context.canvas.width = 2;
     43    context.canvas.height = 2;
     44
    4245    buffer = context.createBuffer();
    4346    framebuffer = context.createFramebuffer();
     
    483486        () => {
    484487            context.viewport(1, 2, 3, 4);
     488        },
     489        () => {
     490            context.canvas.width;
     491            context.canvas.width = 2;
     492        },
     493        () => {
     494            context.canvas.height;
     495            context.canvas.height = 2;
    485496        },
    486497        () => {
  • trunk/Source/WebCore/ChangeLog

    r237776 r237777  
     12018-11-03  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Canvas: capture changes to <canvas> that would affect the recorded context
     4        https://bugs.webkit.org/show_bug.cgi?id=190854
     5
     6        Reviewed by Matt Baker.
     7
     8        Updated existing tests: inspector/canvas/recording-2d.html
     9                                inspector/canvas/recording-bitmaprenderer.html
     10                                inspector/canvas/recording-webgl.html
     11
     12        * html/HTMLCanvasElement.idl:
     13        Apply `CallTracingCallback=recordCanvasAction` to the `width` and `height` attributes so
     14        that they are recorded through the same path as `CanvasRenderingContext`.
     15
     16        * html/CanvasBase.h:
     17        * html/CanvasBase.cpp:
     18        (WebCore::CanvasBase::callTracingActive const): Added.
     19
     20        * bindings/js/CallTracer.h:
     21        * bindings/js/CallTracer.cpp:
     22        (WebCore::CallTracer::recordCanvasAction):
     23
     24
    1252018-11-03  Andy Estes  <aestes@apple.com>
    226
  • trunk/Source/WebCore/bindings/js/CallTracer.cpp

    r220008 r237777  
    2828
    2929#include "CanvasRenderingContext.h"
     30#include "HTMLCanvasElement.h"
    3031#include "InspectorInstrumentation.h"
    3132
    3233namespace WebCore {
     34
     35void CallTracer::recordCanvasAction(const HTMLCanvasElement& canvasElement, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
     36{
     37    if (auto* canvasRenderingContext = canvasElement.renderingContext())
     38        InspectorInstrumentation::recordCanvasAction(*canvasRenderingContext, name, WTFMove(parameters));
     39}
    3340
    3441void CallTracer::recordCanvasAction(CanvasRenderingContext& canvasRenderingContext, const String& name, Vector<RecordCanvasActionVariant>&& parameters)
  • trunk/Source/WebCore/bindings/js/CallTracer.h

    r220008 r237777  
    3333
    3434class CanvasRenderingContext;
     35class HTMLCanvasElement;
    3536
    3637class CallTracer {
    3738public:
     39    static void recordCanvasAction(const HTMLCanvasElement&, const String&, Vector<RecordCanvasActionVariant>&& = { });
    3840    static void recordCanvasAction(CanvasRenderingContext&, const String&, Vector<RecordCanvasActionVariant>&& = { });
    3941};
  • trunk/Source/WebCore/html/CanvasBase.cpp

    r237409 r237777  
    110110}
    111111
     112bool CanvasBase::callTracingActive() const
     113{
     114    return m_context && m_context->callTracingActive();
    112115}
     116
     117}
  • trunk/Source/WebCore/html/CanvasBase.h

    r237409 r237777  
    9696    virtual Image* copiedImage() const = 0;
    9797
     98    bool callTracingActive() const;
     99
    98100protected:
    99101    CanvasBase(ScriptExecutionContext*);
  • trunk/Source/WebCore/html/HTMLCanvasElement.idl

    r237717 r237777  
    4646    ReportExternalMemoryCost,
    4747] interface HTMLCanvasElement : HTMLElement {
    48     attribute unsigned long width;
    49     attribute unsigned long height;
     48    [CallTracingCallback=recordCanvasAction] attribute unsigned long width;
     49    [CallTracingCallback=recordCanvasAction] attribute unsigned long height;
    5050
    5151    [CallWith=ExecState, MayThrowException] RenderingContext? getContext(DOMString contextId, any... arguments);
  • trunk/Source/WebInspectorUI/ChangeLog

    r237746 r237777  
     12018-11-03  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Canvas: capture changes to <canvas> that would affect the recorded context
     4        https://bugs.webkit.org/show_bug.cgi?id=190854
     5
     6        Reviewed by Matt Baker.
     7
     8        * UserInterface/Models/RecordingAction.js:
     9        (WI.RecordingAction):
     10        (WI.RecordingAction.isFunctionForType):
     11        (WI.RecordingAction.constantNameForParameter):
     12        (WI.RecordingAction.prototype.get contextReplacer): Added.
     13        (WI.RecordingAction.prototype.async.swizzle):
     14        (WI.RecordingAction.prototype.apply):
     15        Create a constant list of actions for each recording type that need to replace the context
     16        with a different value before being applied (e.g. `width` should be applied to the
     17        `context`'s `canvas` instead of directly to the `context`).
     18
     19        * UserInterface/Views/RecordingContentView.js:
     20        (WI.RecordingContentView.prototype._generateContentCanvas2D.actionModifiesPath): Added.
     21        (WI.RecordingContentView.prototype._generateContentCanvas2D):
     22        (WI.RecordingContentView._actionModifiesPath): Deleted.
     23        Generate the path context after the actions are applied to the preview context so that the
     24        final width/height are known and can be used. This is needed because changing the
     25        width/height causes the content to be erased.
     26
     27        * UserInterface/Views/RecordingActionTreeElement.js:
     28        (WI.RecordingActionTreeElement._generateDOM):
     29        (WI.RecordingActionTreeElement._classNameForAction):
     30        * UserInterface/Views/RecordingActionTreeElement.css:
     31        (.tree-outline:focus .item.action.selected:not(.invalid, .initial-state, .has-context-replacer) > .icon): Added.
     32        (.item.action > .titles .context-replacer::after): Added.
     33        (.item.action.has-context-replacer > .icon): Added.
     34        (@media (prefers-dark-interface) .item.action:not(.invalid, .initial-state, .has-context-replacer) > .icon): Added.
     35        (.tree-outline:focus .item.action.selected:not(.initial-state, .invalid) > .icon): Deleted.
     36        (@media (prefers-dark-interface) .item.action:not(.initial-state) > .icon): Deleted.
     37        (@media (prefers-dark-interface) .tree-outline:not(.hide-disclosure-buttons) .item.action:not(.initial-state, .parent) > .icon): Deleted.
     38        Add the context replacer text to the beginning of the action's name if it exists.
     39
     40        * UserInterface/Views/CanvasContentView.js:
     41        (WI.CanvasContentView.prototype._refreshPixelSize):
     42        (WI.CanvasContentView.prototype._updatePixelSize): Deleted.
     43        Update preview image when the canvas' size changes.
     44
    1452018-11-02  Matt Baker  <mattbaker@apple.com>
    246
  • trunk/Source/WebInspectorUI/UserInterface/Models/RecordingAction.js

    r237574 r237777  
    4646        this._isVisual = false;
    4747
     48        this._contextReplacer = null;
     49
    4850        this._states = [];
    4951        this._stateModifiers = new Set;
     
    8587        if (!prototype)
    8688            return false;
    87         return typeof Object.getOwnPropertyDescriptor(prototype, name).value === "function";
     89        let propertyDescriptor = Object.getOwnPropertyDescriptor(prototype, name);
     90        if (!propertyDescriptor)
     91            return false;
     92        return typeof propertyDescriptor.value === "function";
    8893    }
    8994
     
    124129        for (let key in prototype) {
    125130            let descriptor = Object.getOwnPropertyDescriptor(prototype, key);
    126             if (descriptor.value === value)
     131            if (descriptor && descriptor.value === value)
    127132                return key;
    128133        }
     
    199204    get isGetter() { return this._isGetter; }
    200205    get isVisual() { return this._isVisual; }
     206    get contextReplacer() { return this._contextReplacer; }
    201207    get states() { return this._states; }
    202208    get stateModifiers() { return this._stateModifiers; }
     
    331337            this._snapshot = snapshot;
    332338
    333         this._isFunction = WI.RecordingAction.isFunctionForType(recording.type, this._name);
    334         this._isGetter = !this._isFunction && !this._parameters.length;
    335 
    336         let visualNames = WI.RecordingAction._visualNames[recording.type];
    337         this._isVisual = visualNames ? visualNames.has(this._name) : false;
    338 
    339         if (this._valid) {
    340             let prototype = WI.RecordingAction._prototypeForType(recording.type);
    341             if (prototype && !(name in prototype)) {
    342                 this.markInvalid();
    343 
    344                 WI.Recording.synthesizeError(WI.UIString("“%s” is invalid.").format(name));
     339        if (recording.type === WI.Recording.Type.Canvas2D || recording.type === WI.Recording.Type.CanvasBitmapRenderer || recording.type === WI.Recording.Type.CanvasWebGL) {
     340            if (this._name === "width" || this._name === "height") {
     341                this._contextReplacer = "canvas";
     342                this._isFunction = false;
     343                this._isGetter = !this._parameters.length;
     344                this._isVisual = !this._isGetter;
     345            }
     346
     347            // FIXME: <https://webkit.org/b/180833>
     348        }
     349
     350        if (!this._contextReplacer) {
     351            this._isFunction = WI.RecordingAction.isFunctionForType(recording.type, this._name);
     352            this._isGetter = !this._isFunction && !this._parameters.length;
     353
     354            let visualNames = WI.RecordingAction._visualNames[recording.type];
     355            this._isVisual = visualNames ? visualNames.has(this._name) : false;
     356
     357            if (this._valid) {
     358                let prototype = WI.RecordingAction._prototypeForType(recording.type);
     359                if (prototype && !(name in prototype)) {
     360                    this.markInvalid();
     361
     362                    WI.Recording.synthesizeError(WI.UIString("“%s” is invalid.").format(name));
     363                }
    345364            }
    346365        }
     
    376395        try {
    377396            let name = options.nameOverride || this._name;
     397
     398            if (this._contextReplacer)
     399                context = context[this._contextReplacer];
     400
    378401            if (this.isFunction)
    379402                context[name](...this._parameters);
  • trunk/Source/WebInspectorUI/UserInterface/Views/CanvasContentView.js

    r237670 r237777  
    288288    _refreshPixelSize()
    289289    {
    290         this._pixelSize = null;
    291 
    292         this.representedObject.requestSize().then((size) => {
     290        let updatePixelSize = (size) => {
     291            if (this._pixelSize && size.width === this._pixelSize.width && size.height === this._pixelSize.height)
     292                return;
     293
    293294            this._pixelSize = size;
    294             this._updatePixelSize();
    295         }).catch((error) => {
    296             this._updatePixelSize();
     295
     296            if (this._pixelSizeElement) {
     297                if (this._pixelSize)
     298                    this._pixelSizeElement.textContent = `${this._pixelSize.width} ${multiplicationSign} ${this._pixelSize.height}`;
     299                else
     300                    this._pixelSizeElement.textContent = emDash;
     301            }
     302
     303            this.refresh();
     304        };
     305
     306        this.representedObject.requestSize()
     307        .then((size) => {
     308            updatePixelSize(size);
     309        })
     310        .catch((error) => {
     311            updatePixelSize(null);
    297312        });
    298313    }
     
    350365    }
    351366
    352     _updatePixelSize()
    353     {
    354         if (!this._pixelSizeElement)
    355             return;
    356 
    357         if (this._pixelSize)
    358             this._pixelSizeElement.textContent = `${this._pixelSize.width} ${multiplicationSign} ${this._pixelSize.height}`;
    359         else
    360             this._pixelSizeElement.textContent = emDash;
    361     }
    362 
    363367    _updateRecordNavigationItem()
    364368    {
  • trunk/Source/WebInspectorUI/UserInterface/Views/RecordingActionTreeElement.css

    r237574 r237777  
    5353}
    5454
    55 .tree-outline:focus .item.action.selected:not(.initial-state, .invalid) > .icon {
     55.tree-outline:focus .item.action.selected:not(.invalid, .initial-state, .has-context-replacer) > .icon {
    5656    filter: invert();
    5757    opacity: 1;
     
    110110}
    111111
     112.item.action > .titles .context-replacer::after {
     113    content: ".";
     114}
     115
    112116.item.action.attribute > .titles .parameters::before {
    113117    content: " = ";
     
    132136.item.action > .titles .parameters > .inline-swatch {
    133137    vertical-align: -1px;
     138}
     139
     140.item.action.has-context-replacer > .icon {
     141    content: url("../Images/Source.svg");
    134142}
    135143
     
    237245    }
    238246
    239     .item.action:not(.initial-state) > .icon {
    240         filter: invert();
    241     }
    242 
    243     .tree-outline:not(.hide-disclosure-buttons) .item.action:not(.initial-state, .parent) > .icon {
     247    .item.action:not(.invalid, .initial-state, .has-context-replacer) > .icon {
    244248        filter: invert();
    245249        opacity: 0.8;
  • trunk/Source/WebInspectorUI/UserInterface/Views/RecordingActionTreeElement.js

    r237574 r237777  
    106106        let copyText = recordingAction.name;
    107107
     108        let contextReplacer = recordingAction.contextReplacer;
     109        if (contextReplacer) {
     110            copyText = contextReplacer + "." + copyText;
     111
     112            let contextReplacerContainer = titleFragment.appendChild(document.createElement("span"));
     113            contextReplacerContainer.classList.add("context-replacer");
     114            contextReplacerContainer.textContent = contextReplacer;
     115        }
     116
    108117        let nameContainer = titleFragment.appendChild(document.createElement("span"));
    109118        nameContainer.classList.add("name");
     
    248257    static _classNameForAction(recordingAction)
    249258    {
     259        if (recordingAction.contextReplacer)
     260            return "has-context-replacer";
     261
    250262        function classNameForActionName(name) {
    251263            switch (name) {
  • trunk/Source/WebInspectorUI/UserInterface/Views/RecordingContentView.js

    r237198 r237777  
    6565    }
    6666
    67     // Static
    68 
    69     static _actionModifiesPath(recordingAction)
    70     {
    71         switch (recordingAction.name) {
    72         case "arc":
    73         case "arcTo":
    74         case "beginPath":
    75         case "bezierCurveTo":
    76         case "closePath":
    77         case "ellipse":
    78         case "lineTo":
    79         case "moveTo":
    80         case "quadraticCurveTo":
    81         case "rect":
    82             return true;
    83         }
    84 
    85         return false;
    86     }
    87 
    8867    // Public
    8968
     
    241220            let saveCount = 0;
    242221            snapshot.context.save();
     222
     223            for (let attribute in snapshot.attributes)
     224                snapshot.element[attribute] = snapshot.attributes[attribute];
    243225
    244226            if (snapshot.content) {
     
    270252            }
    271253
    272             let shouldDrawCanvasPath = showCanvasPath && indexOfLastBeginPathAction <= to;
    273             if (shouldDrawCanvasPath) {
    274                 if (!this._pathContext) {
    275                     let pathCanvas = document.createElement("canvas");
    276                     pathCanvas.classList.add("path");
    277                     this._pathContext = pathCanvas.getContext("2d");
    278                 }
    279 
    280                 this._pathContext.canvas.width = snapshot.element.width;
    281                 this._pathContext.canvas.height = snapshot.element.height;
    282                 this._pathContext.clearRect(0, 0, snapshot.element.width, snapshot.element.height);
    283 
    284                 this._pathContext.save();
    285 
    286                 this._pathContext.fillStyle = "hsla(0, 0%, 100%, 0.75)";
    287                 this._pathContext.fillRect(0, 0, snapshot.element.width, snapshot.element.height);
    288             }
    289 
    290254            let lastPathPoint = {};
    291255            let subPathStartPoint = {};
     
    300264
    301265                actions[i].apply(snapshot.context);
    302 
    303                 if (shouldDrawCanvasPath && i >= indexOfLastBeginPathAction && WI.RecordingContentView._actionModifiesPath(actions[i])) {
     266            }
     267
     268            if (showCanvasPath && indexOfLastBeginPathAction <= to) {
     269                if (!this._pathContext) {
     270                    let pathCanvas = document.createElement("canvas");
     271                    pathCanvas.classList.add("path");
     272                    this._pathContext = pathCanvas.getContext("2d");
     273                }
     274
     275                this._pathContext.canvas.width = snapshot.element.width;
     276                this._pathContext.canvas.height = snapshot.element.height;
     277                this._pathContext.clearRect(0, 0, snapshot.element.width, snapshot.element.height);
     278
     279                this._pathContext.save();
     280
     281                this._pathContext.fillStyle = "hsla(0, 0%, 100%, 0.75)";
     282                this._pathContext.fillRect(0, 0, snapshot.element.width, snapshot.element.height);
     283
     284                function actionModifiesPath(action) {
     285                    switch (action.name) {
     286                    case "arc":
     287                    case "arcTo":
     288                    case "beginPath":
     289                    case "bezierCurveTo":
     290                    case "closePath":
     291                    case "ellipse":
     292                    case "lineTo":
     293                    case "moveTo":
     294                    case "quadraticCurveTo":
     295                    case "rect":
     296                        return true;
     297                    }
     298
     299                    return false;
     300                }
     301
     302                for (let i = indexOfLastBeginPathAction; i <= to; ++i) {
     303                    if (!actionModifiesPath(actions[i]))
     304                        continue;
     305
    304306                    lastPathPoint = {x: this._pathContext.currentX, y: this._pathContext.currentY};
    305307
     
    327329                    this._pathContext.stroke();
    328330                }
    329             }
    330 
    331             if (shouldDrawCanvasPath) {
     331
    332332                this._pathContext.restore();
    333333                this._previewContainer.appendChild(this._pathContext.canvas);
     
    359359                snapshot.content = this._initialContent;
    360360                snapshot.states = actions[0].states;
     361                snapshot.attributes = Object.shallowCopy(initialState.attributes);
    361362            } else {
    362                 snapshot.content = this._snapshots[lastSnapshotIndex].content;
    363                 snapshot.states = this._snapshots[lastSnapshotIndex].states;
    364                 startIndex = this._snapshots[lastSnapshotIndex].index;
     363                let lastSnapshot = this._snapshots[lastSnapshotIndex];
     364                snapshot.content = lastSnapshot.content;
     365                snapshot.states = lastSnapshot.states;
     366                snapshot.attributes = {};
     367                for (let attribute in initialState.attributes)
     368                    snapshot.attributes[attribute] = lastSnapshot.element[attribute];
     369
     370                startIndex = lastSnapshot.index;
    365371            }
    366372
Note: See TracChangeset for help on using the changeset viewer.