<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[182186] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/182186">182186</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-03-31 10:23:12 -0700 (Tue, 31 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: add 2D/WebGL canvas instrumentation infrastructure
https://bugs.webkit.org/show_bug.cgi?id=137278

Patch by Matt Baker &lt;mattbaker@apple.com&gt; on 2015-03-31
Reviewed by Timothy Hatcher.

Source/JavaScriptCore:

Added Canvas protocol which defines types used by InspectorCanvasAgent.

* CMakeLists.txt:
* DerivedSources.make:
* inspector/protocol/Canvas.json: Added.

* inspector/scripts/codegen/generator.py:
(Generator.stylized_name_for_enum_value):
Added special handling for 2D (always uppercase) and WebGL (rename mapping) enum strings.

Source/WebCore:

Added backend agent for canvas inspection. A canvas is instrumented once its CanvasRenderingContext has been
created. WebGLRenderingContext is instrumented to track the lifetime of shader program objects.

To instrument off-screen rendering contexts (CSS canvases and detached canvas elements), the canvas agent must
track all CanvasRenderingContexts as they are created, even in the absense of the frontend. As far as I know,
there is no practical way to identify rendering contexts belonging to a frame that are not in the DOM. In the
absence of the inspector frontend the agent does only the minimum required to track the lifetime of rendering
contexts and their resources, to avoid creating a negative performance impact.

Tests: inspector/canvas/canvas-add-remove-events.html
       inspector/canvas/canvas-context-attributes.html
       inspector/canvas/canvas-css-name.html

* CMakeLists.txt:
* WebCore.xcodeproj/project.pbxproj:

* dom/Document.cpp:
(WebCore::Document::getCSSCanvasElement):
Instrumentation for CSS canvases.

* html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::getContext):
Instrumentation for context creation.

* html/canvas/WebGLRenderingContextBase.cpp:
(WebCore::WebGLRenderingContextBase::attachShader):
(WebCore::WebGLRenderingContextBase::createProgram):
(WebCore::WebGLRenderingContextBase::deleteProgram):
(WebCore::WebGLRenderingContextBase::detachShader):
Instrumentation for programs and shaders.

* inspector/InspectorAllInOne.cpp:

* inspector/InspectorCanvasAgent.cpp: Added.
(WebCore::InspectorCanvasAgent::InspectorCanvasAgent):
(WebCore::InspectorCanvasAgent::didCreateFrontendAndBackend):
(WebCore::InspectorCanvasAgent::willDestroyFrontendAndBackend):
(WebCore::InspectorCanvasAgent::frameNavigated):
(WebCore::InspectorCanvasAgent::didCreateCSSCanvas):
(WebCore::InspectorCanvasAgent::didCreateCanvasRenderingContext):
(WebCore::InspectorCanvasAgent::didAttachShader):
(WebCore::InspectorCanvasAgent::didDetachShader):
(WebCore::InspectorCanvasAgent::didCreateProgram):
(WebCore::InspectorCanvasAgent::didDeleteProgram):
(WebCore::InspectorCanvasAgent::getCanvases):
(WebCore::InspectorCanvasAgent::canvasDestroyed):
(WebCore::InspectorCanvasAgent::canvasDestroyedTimerFired):
(WebCore::InspectorCanvasAgent::reset):
(WebCore::InspectorCanvasAgent::getCanvasEntry):
(WebCore::InspectorCanvasAgent::getProgramEntry):
(WebCore::InspectorCanvasAgent::removeShaderFromShaderMap):
(WebCore::InspectorCanvasAgent::contextTypeJson):
(WebCore::InspectorCanvasAgent::buildObjectForCanvas):
* inspector/InspectorCanvasAgent.h: Added.
New backend agent.

* inspector/InspectorController.cpp:
(WebCore::InspectorController::InspectorController):
Support for new backend agent.

* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::didCommitLoadImpl):
(WebCore::InspectorInstrumentation::didCreateCSSCanvasImpl):
(WebCore::InspectorInstrumentation::didCreateCanvasRenderingContextImpl):
(WebCore::InspectorInstrumentation::didAttachShaderImpl):
(WebCore::InspectorInstrumentation::didDetachShaderImpl):
(WebCore::InspectorInstrumentation::didCreateProgramImpl):
(WebCore::InspectorInstrumentation::didDeleteProgramImpl):
(WebCore::InspectorInstrumentation::instrumentingAgentsForRenderingContext):
Plumbing for canvas instrumentation.

* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::didCreateCSSCanvas):
(WebCore::InspectorInstrumentation::didCreateCanvasRenderingContext):
(WebCore::InspectorInstrumentation::didAttachShader):
(WebCore::InspectorInstrumentation::didDetachShader):
(WebCore::InspectorInstrumentation::didCreateProgram):
(WebCore::InspectorInstrumentation::didDeleteProgram):

* inspector/InstrumentingAgents.cpp:
(WebCore::InstrumentingAgents::InstrumentingAgents):
(WebCore::InstrumentingAgents::reset):
* inspector/InstrumentingAgents.h:
(WebCore::InstrumentingAgents::inspectorCanvasAgent):
(WebCore::InstrumentingAgents::setInspectorCanvasAgent):
Support for new backend agent.

Source/WebInspectorUI:

Added models, views, and controller classes for 2D and WebGL canvas inspection. Each canvas is shown in the
Resources navigation sidebar under its parent frame. Shader programs are displayed as child nodes of
their respective canvas. Canvases will get an associated content view and details sidebar in a later patch
(see https://bugs.webkit.org/show_bug.cgi?id=138941).

Shader programs will get an associated content view for editing shader source in a later patch (see
https://bugs.webkit.org/show_bug.cgi?id=138593). Individual shaders are not shown in the Resource navigation
sidebar, and at this time there are no plans to instrument shaders that aren't attached to a program.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Base/Main.js:
(WebInspector.loaded):
(WebInspector.sidebarPanelForRepresentedObject):
* UserInterface/Base/Test.js:
(WebInspector.loaded):
* UserInterface/Main.html:
* UserInterface/Test.html:
Updated for new canvas/shader program types.

* UserInterface/Controllers/CanvasManager.js: Added.
(WebInspector.CanvasManager):
(WebInspector.CanvasManager.prototype.canvasesForFrame):
(WebInspector.CanvasManager.prototype.canvasAdded.set this):
(WebInspector.CanvasManager.prototype.canvasAdded):
(WebInspector.CanvasManager.prototype.canvasRemoved):
(WebInspector.CanvasManager.programDeleted.get console):
(WebInspector.CanvasManager.prototype.programCreated.get console):
(WebInspector.CanvasManager.prototype.programCreated):
(WebInspector.CanvasManager.prototype._mainResourceDidChange):
Frontend controller for canvases and their shader programs.

* UserInterface/Images/Canvas.svg: Added.
* UserInterface/Images/DocumentGL.png: Added.
* UserInterface/Images/DocumentGL@2x.png: Added.
New art for canvas and shader program tree elements.

* UserInterface/Models/Canvas.js: Added.
(WebInspector.Canvas):
(WebInspector.Canvas.prototype.set fromPayload):
(WebInspector.Canvas.displayNameForContextType):
(WebInspector.Canvas.resetUniqueDisplayNameNumbers):
(WebInspector.Canvas.prototype.get id):
(WebInspector.Canvas.prototype.get parentFrame):
(WebInspector.Canvas.prototype.get name):
(WebInspector.Canvas.prototype.get cssCanvas):
(WebInspector.Canvas.prototype.get contextType):
(WebInspector.Canvas.prototype.get contextAttributes):
(WebInspector.Canvas.prototype.get programs):
(WebInspector.Canvas.prototype.get displayName):
(WebInspector.Canvas.programForId):
(WebInspector.Canvas.get programWasCreated.set this):
(WebInspector.Canvas.prototype.get programWasCreated):
(WebInspector.Canvas.prototype.programWasDeleted):
(WebInspector.Canvas.prototype.saveIdentityToCookie):
Model for DOM or CSS canvas (2D or WebGL).

* UserInterface/Models/ShaderProgram.js: Added.
(WebInspector.ShaderProgram):
(WebInspector.ShaderProgram.prototype.get id):
(WebInspector.ShaderProgram.prototype.get canvas):
(WebInspector.ShaderProgram.prototype.get displayName):
(WebInspector.ShaderProgram.prototype.saveIdentityToCookie):
(WebInspector.ShaderProgram.prototype.updateCanvas):
* UserInterface/Models/WebGLContextAttributes.js: Added.
(WebInspector.WebGLContextAttributes):
(WebInspector.WebGLContextAttributes.fromPayload):
(WebInspector.WebGLContextAttributes.prototype.get alpha):
(WebInspector.WebGLContextAttributes.prototype.get depth):
(WebInspector.WebGLContextAttributes.prototype.get stencil):
(WebInspector.WebGLContextAttributes.prototype.get antialias):
(WebInspector.WebGLContextAttributes.prototype.get premultipliedAlpha):
(WebInspector.WebGLContextAttributes.prototype.get preserveDrawingBuffer):
Model for WebGL canvas context attributes.

* UserInterface/Protocol/CanvasObserver.js: Added.
(WebInspector.CanvasObserver.prototype.canvasAdded):
(WebInspector.CanvasObserver.prototype.canvasRemoved):
(WebInspector.CanvasObserver.prototype.programCreated):
(WebInspector.CanvasObserver.prototype.programDeleted):
(WebInspector.CanvasObserver):
Model for WebGL canvas shader program.

* UserInterface/Views/CanvasTreeElement.js: Added.
(WebInspector.CanvasTreeElement.validateRepresentedObject):
(WebInspector.CanvasTreeElement.countChildren):
(WebInspector.CanvasTreeElement):
(WebInspector.CanvasTreeElement.prototype.onexpand):
(WebInspector.CanvasTreeElement.prototype.oncollapse):
(WebInspector.CanvasTreeElement.prototype.onpopulate):
(WebInspector.CanvasTreeElement.prototype._programWasCreated):
(WebInspector.CanvasTreeElement.prototype._programWasDeleted):
Folderized tree element for canvases and their child objects (shader programs).

* UserInterface/Views/FrameTreeElement.js:
(WebInspector.FrameTreeElement.prototype.onattach):
(WebInspector.FrameTreeElement.prototype.ondetach):
(WebInspector.FrameTreeElement.prototype.onpopulate):
(WebInspector.FrameTreeElement.prototype._canvasesAvailable):
(WebInspector.FrameTreeElement.prototype._canvasWasAdded):
(WebInspector.FrameTreeElement.prototype._canvasWasRemoved):
Updated to support canvas tree elements.

* UserInterface/Views/ResourceIcons.css:
(.canvas-icon .icon):
(.shader-program-icon .icon):
Styles for new canvas and shader program icons.

* UserInterface/Views/ResourceSidebarPanel.js:
(WebInspector.ResourceSidebarPanel.prototype._treeElementSelected):
Updated for new tree element types.

* UserInterface/Views/ShaderProgramTreeElement.js: Added.
(WebInspector.ShaderProgramTreeElement):
Tree element for shader programs. Shown as children of CanvasTreeElement.

* WebInspectorUI.vcxproj/WebInspectorUI.vcxproj:
* WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreDerivedSourcesmake">trunk/Source/JavaScriptCore/DerivedSources.make</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorscriptscodegengeneratorpy">trunk/Source/JavaScriptCore/inspector/scripts/codegen/generator.py</a></li>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoredomDocumentcpp">trunk/Source/WebCore/dom/Document.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlHTMLCanvasElementcpp">trunk/Source/WebCore/html/HTMLCanvasElement.cpp</a></li>
<li><a href="#trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp">trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorAllInOnecpp">trunk/Source/WebCore/inspector/InspectorAllInOne.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorControllercpp">trunk/Source/WebCore/inspector/InspectorController.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorInstrumentationcpp">trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorInstrumentationh">trunk/Source/WebCore/inspector/InspectorInstrumentation.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorInstrumentingAgentscpp">trunk/Source/WebCore/inspector/InstrumentingAgents.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInstrumentingAgentsh">trunk/Source/WebCore/inspector/InstrumentingAgents.h</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs">trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceBaseMainjs">trunk/Source/WebInspectorUI/UserInterface/Base/Main.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceBaseTestjs">trunk/Source/WebInspectorUI/UserInterface/Base/Test.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceMainhtml">trunk/Source/WebInspectorUI/UserInterface/Main.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTesthtml">trunk/Source/WebInspectorUI/UserInterface/Test.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsFrameTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/FrameTreeElement.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsResourceIconscss">trunk/Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsResourceSidebarPaneljs">trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSidebarPanel.js</a></li>
<li><a href="#trunkSourceWebInspectorUIWebInspectorUIvcxprojWebInspectorUIvcxproj">trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj</a></li>
<li><a href="#trunkSourceWebInspectorUIWebInspectorUIvcxprojWebInspectorUIvcxprojfilters">trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreinspectorprotocolCanvasjson">trunk/Source/JavaScriptCore/inspector/protocol/Canvas.json</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorCanvasAgentcpp">trunk/Source/WebCore/inspector/InspectorCanvasAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorCanvasAgenth">trunk/Source/WebCore/inspector/InspectorCanvasAgent.h</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersCanvasManagerjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceImagesCanvassvg">trunk/Source/WebInspectorUI/UserInterface/Images/Canvas.svg</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceImagesDocumentGLpng">trunk/Source/WebInspectorUI/UserInterface/Images/DocumentGL.png</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceImagesDocumentGL2xpng">trunk/Source/WebInspectorUI/UserInterface/Images/DocumentGL@2x.png</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsCanvasjs">trunk/Source/WebInspectorUI/UserInterface/Models/Canvas.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsShaderProgramjs">trunk/Source/WebInspectorUI/UserInterface/Models/ShaderProgram.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsWebGLContextAttributesjs">trunk/Source/WebInspectorUI/UserInterface/Models/WebGLContextAttributes.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolCanvasObserverjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsCanvasTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsShaderProgramTreeElementjs">trunk/Source/WebInspectorUI/UserInterface/Views/ShaderProgramTreeElement.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -1041,6 +1041,7 @@
</span><span class="cx"> set(JavaScriptCore_INSPECTOR_DOMAINS
</span><span class="cx">     ${JAVASCRIPTCORE_DIR}/inspector/protocol/ApplicationCache.json
</span><span class="cx">     ${JAVASCRIPTCORE_DIR}/inspector/protocol/CSS.json
</span><ins>+    ${JAVASCRIPTCORE_DIR}/inspector/protocol/Canvas.json
</ins><span class="cx">     ${JAVASCRIPTCORE_DIR}/inspector/protocol/Console.json
</span><span class="cx">     ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOM.json
</span><span class="cx">     ${JAVASCRIPTCORE_DIR}/inspector/protocol/DOMDebugger.json
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2015-03-31  Matt Baker  &lt;mattbaker@apple.com&gt;
+
+        Web Inspector: add 2D/WebGL canvas instrumentation infrastructure
+        https://bugs.webkit.org/show_bug.cgi?id=137278
+
+        Reviewed by Timothy Hatcher.
+
+        Added Canvas protocol which defines types used by InspectorCanvasAgent.
+
+        * CMakeLists.txt:
+        * DerivedSources.make:
+        * inspector/protocol/Canvas.json: Added.
+
+        * inspector/scripts/codegen/generator.py:
+        (Generator.stylized_name_for_enum_value):
+        Added special handling for 2D (always uppercase) and WebGL (rename mapping) enum strings.
+
</ins><span class="cx"> 2015-03-30  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Extending null should set __proto__ to null
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreDerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/DerivedSources.make (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/DerivedSources.make        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/JavaScriptCore/DerivedSources.make        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -117,6 +117,7 @@
</span><span class="cx"> INSPECTOR_DOMAINS = \
</span><span class="cx">     $(JavaScriptCore)/inspector/protocol/ApplicationCache.json \
</span><span class="cx">     $(JavaScriptCore)/inspector/protocol/CSS.json \
</span><ins>+    $(JavaScriptCore)/inspector/protocol/Canvas.json \
</ins><span class="cx">     $(JavaScriptCore)/inspector/protocol/Console.json \
</span><span class="cx">     $(JavaScriptCore)/inspector/protocol/DOM.json \
</span><span class="cx">     $(JavaScriptCore)/inspector/protocol/DOMDebugger.json \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorprotocolCanvasjson"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/inspector/protocol/Canvas.json (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/protocol/Canvas.json                                (rev 0)
+++ trunk/Source/JavaScriptCore/inspector/protocol/Canvas.json        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,94 @@
</span><ins>+{
+    &quot;domain&quot;: &quot;Canvas&quot;,
+    &quot;availability&quot;: &quot;web&quot;,
+    &quot;description&quot;: &quot;Canvas domain allows tracking of 2D and WebGL canvases that have an associated graphics context. Tracks canvases belonging to a frame as well as CSS canvases created with -webkit-canvas.&quot;,
+    &quot;types&quot;: [
+        {
+            &quot;id&quot;: &quot;CanvasId&quot;,
+            &quot;type&quot;: &quot;integer&quot;
+        },
+        {
+            &quot;id&quot;: &quot;ProgramId&quot;,
+            &quot;type&quot;: &quot;object&quot;,
+            &quot;properties&quot;: [
+                { &quot;name&quot;: &quot;canvasId&quot;, &quot;$ref&quot;: &quot;CanvasId&quot;, &quot;description&quot;: &quot;Parent canvas identifier.&quot; },
+                { &quot;name&quot;: &quot;objectId&quot;, &quot;type&quot;: &quot;integer&quot;, &quot;description&quot;: &quot;Uniquely identifies shader program within parent canvas.&quot; }
+            ]
+        },
+        {
+            &quot;id&quot;: &quot;ContextType&quot;,
+            &quot;type&quot;: &quot;string&quot;,
+            &quot;enum&quot;: [&quot;canvas-2d&quot;, &quot;webgl&quot;],
+            &quot;description&quot;: &quot;The type of rendering context backing the canvas element.&quot;
+        },
+        {
+            &quot;id&quot;: &quot;ShaderType&quot;,
+            &quot;type&quot;: &quot;string&quot;,
+            &quot;enum&quot;: [&quot;fragment&quot;, &quot;vertex&quot;],
+            &quot;description&quot;: &quot;Shader type. WebGL 1.0 supports VERTEX_SHADER and FRAGMENT_SHADER types.&quot;
+        },
+        {
+            &quot;id&quot;: &quot;ContextAttributes&quot;,
+            &quot;type&quot;: &quot;object&quot;,
+            &quot;description&quot;: &quot;WebGL drawing surface attributes.&quot;,
+            &quot;properties&quot;: [
+                { &quot;name&quot;: &quot;alpha&quot;, &quot;type&quot;: &quot;boolean&quot; },
+                { &quot;name&quot;: &quot;depth&quot;, &quot;type&quot;: &quot;boolean&quot; },
+                { &quot;name&quot;: &quot;stencil&quot;, &quot;type&quot;: &quot;boolean&quot; },
+                { &quot;name&quot;: &quot;antialias&quot;, &quot;type&quot;: &quot;boolean&quot; },
+                { &quot;name&quot;: &quot;premultipliedAlpha&quot;, &quot;type&quot;: &quot;boolean&quot; },
+                { &quot;name&quot;: &quot;preserveDrawingBuffer&quot;, &quot;type&quot;: &quot;boolean&quot; }
+            ]
+        },
+        {
+            &quot;id&quot;: &quot;Canvas&quot;,
+            &quot;type&quot;: &quot;object&quot;,
+            &quot;description&quot;: &quot;Information about a 2D/WebGL canvas for which a rendering context has been created.&quot;,
+            &quot;properties&quot;: [
+                { &quot;name&quot;: &quot;canvasId&quot;, &quot;$ref&quot;: &quot;CanvasId&quot;, &quot;description&quot;: &quot;The id for the canvas.&quot; },
+                { &quot;name&quot;: &quot;frameId&quot;, &quot;$ref&quot;: &quot;Network.FrameId&quot;, &quot;description&quot;: &quot;Parent frame identifier.&quot; },
+                { &quot;name&quot;: &quot;name&quot;, &quot;type&quot;: &quot;string&quot;, &quot;description&quot;: &quot;The CSS canvas identifier, or the canvas element id attribute.&quot; },
+                { &quot;name&quot;: &quot;cssCanvas&quot;, &quot;type&quot;: &quot;boolean&quot;, &quot;description&quot;: &quot;True for canvases created with -webkit-canvas.&quot; },
+                { &quot;name&quot;: &quot;contextType&quot;, &quot;$ref&quot;: &quot;ContextType&quot;, &quot;description&quot;: &quot;The type of rendering context backing the canvas.&quot; },
+                { &quot;name&quot;: &quot;contextAttributes&quot;, &quot;$ref&quot;: &quot;ContextAttributes&quot;, &quot;optional&quot;: true, &quot;description&quot;: &quot;Context attributes for WebGL rendering contexts.&quot; },
+                { &quot;name&quot;: &quot;programIds&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;$ref&quot;: &quot;ProgramId&quot; }, &quot;description&quot;: &quot;Array of program IDs for linked programs belonging to the canvas rendering context.&quot; }
+            ]
+        }
+    ],
+    &quot;commands&quot;: [
+        {
+            &quot;name&quot;: &quot;getCanvases&quot;,
+            &quot;description&quot;: &quot;Returns available canvases for all frames.&quot;,
+            &quot;returns&quot;: [
+                { &quot;name&quot;: &quot;result&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: { &quot;$ref&quot;: &quot;Canvas&quot; }, &quot;description&quot;: &quot;Array of canvas objects.&quot; }
+            ]
+        }
+    ],
+    &quot;events&quot;: [
+        {
+            &quot;name&quot;: &quot;canvasAdded&quot;,
+            &quot;parameters&quot;: [
+                { &quot;name&quot;: &quot;canvas&quot;, &quot;$ref&quot;: &quot;Canvas&quot;, &quot;description&quot;: &quot;Canvas object.&quot; }
+            ]
+        },
+        {
+            &quot;name&quot;: &quot;canvasRemoved&quot;,
+            &quot;parameters&quot;: [
+                { &quot;name&quot;: &quot;canvasId&quot;, &quot;$ref&quot;: &quot;CanvasId&quot;, &quot;description&quot;: &quot;Id of the canvas that was removed.&quot; }
+            ]
+        },
+        {
+            &quot;name&quot;: &quot;programCreated&quot;,
+            &quot;description&quot;: &quot;Fired when a program is created. Does not imply that link was successful.&quot;,
+            &quot;parameters&quot;: [
+                { &quot;name&quot;: &quot;programId&quot;, &quot;$ref&quot;: &quot;ProgramId&quot;, &quot;description&quot;: &quot;Id of the program.&quot; }
+            ]
+        },
+        {
+            &quot;name&quot;: &quot;programDeleted&quot;,
+            &quot;parameters&quot;: [
+                { &quot;name&quot;: &quot;programId&quot;, &quot;$ref&quot;: &quot;ProgramId&quot;, &quot;description&quot;: &quot;Id of the program.&quot; }
+            ]
+        }
+    ]
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorscriptscodegengeneratorpy"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/scripts/codegen/generator.py (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/scripts/codegen/generator.py        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/JavaScriptCore/inspector/scripts/codegen/generator.py        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -38,8 +38,12 @@
</span><span class="cx"> def ucfirst(str):
</span><span class="cx">     return str[:1].upper() + str[1:]
</span><span class="cx"> 
</span><del>-_ALWAYS_UPPERCASED_ENUM_VALUE_SUBSTRINGS = set(['API', 'CSS', 'DOM', 'HTML', 'XHR', 'XML'])
</del><ins>+_ALWAYS_UPPERCASED_ENUM_VALUE_SUBSTRINGS = set(['2D', 'API', 'CSS', 'DOM', 'HTML', 'XHR', 'XML'])
</ins><span class="cx"> 
</span><ins>+_ENUM_IDENTIFIER_RENAME_MAP = {
+    'webgl': 'WebGL',  # Canvas.ContextType.webgl
+}
+
</ins><span class="cx"> # These objects are built manually by creating and setting InspectorValues.
</span><span class="cx"> # Before sending these over the protocol, their shapes are checked against the specification.
</span><span class="cx"> # So, any types referenced by these types require debug-only assertions that check values.
</span><span class="lines">@@ -219,7 +223,7 @@
</span><span class="cx">             return match.group(1).upper()
</span><span class="cx"> 
</span><span class="cx">         # Split on hyphen, introduce camelcase, and force uppercasing of acronyms.
</span><del>-        subwords = map(ucfirst, enum_value.split('-'))
</del><ins>+        subwords = map(ucfirst, _ENUM_IDENTIFIER_RENAME_MAP.get(enum_value, enum_value).split('-'))
</ins><span class="cx">         return re.sub(re.compile(regex, re.IGNORECASE), replaceCallback, &quot;&quot;.join(subwords))
</span><span class="cx"> 
</span><span class="cx">     @staticmethod
</span></span></pre></div>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/CMakeLists.txt        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -1786,6 +1786,7 @@
</span><span class="cx">     inspector/DOMPatchSupport.cpp
</span><span class="cx">     inspector/InspectorApplicationCacheAgent.cpp
</span><span class="cx">     inspector/InspectorCSSAgent.cpp
</span><ins>+    inspector/InspectorCanvasAgent.cpp
</ins><span class="cx">     inspector/InspectorClient.cpp
</span><span class="cx">     inspector/InspectorController.cpp
</span><span class="cx">     inspector/InspectorDOMAgent.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/ChangeLog        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -1,3 +1,97 @@
</span><ins>+2015-03-31  Matt Baker  &lt;mattbaker@apple.com&gt;
+
+        Web Inspector: add 2D/WebGL canvas instrumentation infrastructure
+        https://bugs.webkit.org/show_bug.cgi?id=137278
+
+        Reviewed by Timothy Hatcher.
+
+        Added backend agent for canvas inspection. A canvas is instrumented once its CanvasRenderingContext has been
+        created. WebGLRenderingContext is instrumented to track the lifetime of shader program objects.
+
+        To instrument off-screen rendering contexts (CSS canvases and detached canvas elements), the canvas agent must
+        track all CanvasRenderingContexts as they are created, even in the absense of the frontend. As far as I know,
+        there is no practical way to identify rendering contexts belonging to a frame that are not in the DOM. In the
+        absence of the inspector frontend the agent does only the minimum required to track the lifetime of rendering
+        contexts and their resources, to avoid creating a negative performance impact.
+
+        Tests: inspector/canvas/canvas-add-remove-events.html
+               inspector/canvas/canvas-context-attributes.html
+               inspector/canvas/canvas-css-name.html
+
+        * CMakeLists.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+
+        * dom/Document.cpp:
+        (WebCore::Document::getCSSCanvasElement):
+        Instrumentation for CSS canvases.
+
+        * html/HTMLCanvasElement.cpp:
+        (WebCore::HTMLCanvasElement::getContext):
+        Instrumentation for context creation.
+
+        * html/canvas/WebGLRenderingContextBase.cpp:
+        (WebCore::WebGLRenderingContextBase::attachShader):
+        (WebCore::WebGLRenderingContextBase::createProgram):
+        (WebCore::WebGLRenderingContextBase::deleteProgram):
+        (WebCore::WebGLRenderingContextBase::detachShader):
+        Instrumentation for programs and shaders.
+
+        * inspector/InspectorAllInOne.cpp:
+
+        * inspector/InspectorCanvasAgent.cpp: Added.
+        (WebCore::InspectorCanvasAgent::InspectorCanvasAgent):
+        (WebCore::InspectorCanvasAgent::didCreateFrontendAndBackend):
+        (WebCore::InspectorCanvasAgent::willDestroyFrontendAndBackend):
+        (WebCore::InspectorCanvasAgent::frameNavigated):
+        (WebCore::InspectorCanvasAgent::didCreateCSSCanvas):
+        (WebCore::InspectorCanvasAgent::didCreateCanvasRenderingContext):
+        (WebCore::InspectorCanvasAgent::didAttachShader):
+        (WebCore::InspectorCanvasAgent::didDetachShader):
+        (WebCore::InspectorCanvasAgent::didCreateProgram):
+        (WebCore::InspectorCanvasAgent::didDeleteProgram):
+        (WebCore::InspectorCanvasAgent::getCanvases):
+        (WebCore::InspectorCanvasAgent::canvasDestroyed):
+        (WebCore::InspectorCanvasAgent::canvasDestroyedTimerFired):
+        (WebCore::InspectorCanvasAgent::reset):
+        (WebCore::InspectorCanvasAgent::getCanvasEntry):
+        (WebCore::InspectorCanvasAgent::getProgramEntry):
+        (WebCore::InspectorCanvasAgent::removeShaderFromShaderMap):
+        (WebCore::InspectorCanvasAgent::contextTypeJson):
+        (WebCore::InspectorCanvasAgent::buildObjectForCanvas):
+        * inspector/InspectorCanvasAgent.h: Added.
+        New backend agent.
+
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::InspectorController):
+        Support for new backend agent.
+
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::didCommitLoadImpl):
+        (WebCore::InspectorInstrumentation::didCreateCSSCanvasImpl):
+        (WebCore::InspectorInstrumentation::didCreateCanvasRenderingContextImpl):
+        (WebCore::InspectorInstrumentation::didAttachShaderImpl):
+        (WebCore::InspectorInstrumentation::didDetachShaderImpl):
+        (WebCore::InspectorInstrumentation::didCreateProgramImpl):
+        (WebCore::InspectorInstrumentation::didDeleteProgramImpl):
+        (WebCore::InspectorInstrumentation::instrumentingAgentsForRenderingContext):
+        Plumbing for canvas instrumentation.
+
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::didCreateCSSCanvas):
+        (WebCore::InspectorInstrumentation::didCreateCanvasRenderingContext):
+        (WebCore::InspectorInstrumentation::didAttachShader):
+        (WebCore::InspectorInstrumentation::didDetachShader):
+        (WebCore::InspectorInstrumentation::didCreateProgram):
+        (WebCore::InspectorInstrumentation::didDeleteProgram):
+
+        * inspector/InstrumentingAgents.cpp:
+        (WebCore::InstrumentingAgents::InstrumentingAgents):
+        (WebCore::InstrumentingAgents::reset):
+        * inspector/InstrumentingAgents.h:
+        (WebCore::InstrumentingAgents::inspectorCanvasAgent):
+        (WebCore::InstrumentingAgents::setInspectorCanvasAgent):
+        Support for new backend agent.
+
</ins><span class="cx"> 2015-03-31  Xabier Rodriguez Calvar &lt;calvaris@igalia.com&gt; and Youenn Fablet  &lt;youenn.fablet@crf.canon.fr&gt;
</span><span class="cx"> 
</span><span class="cx">         [Streams API] Implement a barebone ReadableStreamReader interface
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -2287,6 +2287,8 @@
</span><span class="cx">                 65FD466519B596F0001E2B4D /* WebVideoFullscreenModelVideoElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 6586FE3C19B548BD005C3C82 /* WebVideoFullscreenModelVideoElement.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 65FD466619B596F6001E2B4D /* WebVideoFullscreenModelVideoElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6586FE3D19B548BD005C3C82 /* WebVideoFullscreenModelVideoElement.mm */; };
</span><span class="cx">                 65FEA86909833ADE00BED4AB /* Page.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65FEA86809833ADE00BED4AB /* Page.cpp */; };
</span><ins>+                6A32D7CE1A16D8C000412F0B /* InspectorCanvasAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6A4B6D6619D225D8006F11D3 /* InspectorCanvasAgent.cpp */; };
+                6A4B6D6519D22519006F11D3 /* InspectorCanvasAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 6A4B6D6419D22519006F11D3 /* InspectorCanvasAgent.h */; };
</ins><span class="cx">                 6B3480940EEF50D400AC1B41 /* NativeImagePtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 6B3480920EEF50D400AC1B41 /* NativeImagePtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 6C568CB019DAFEA000430CA2 /* MaskImageOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6C568CAE19DAFEA000430CA2 /* MaskImageOperation.cpp */; };
</span><span class="cx">                 6C568CB119DAFEA000430CA2 /* MaskImageOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C568CAF19DAFEA000430CA2 /* MaskImageOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -9506,6 +9508,8 @@
</span><span class="cx">                 65E0E9431133C89F00B4CB10 /* JSDOMWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMWrapper.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 65F80697054D9F86008BF776 /* BlockExceptions.mm */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = BlockExceptions.mm; sourceTree = &quot;&lt;group&gt;&quot;; tabWidth = 8; usesTabs = 0; };
</span><span class="cx">                 65FEA86809833ADE00BED4AB /* Page.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Page.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                6A4B6D6419D22519006F11D3 /* InspectorCanvasAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorCanvasAgent.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                6A4B6D6619D225D8006F11D3 /* InspectorCanvasAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorCanvasAgent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 6B3480920EEF50D400AC1B41 /* NativeImagePtr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = NativeImagePtr.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 6C568CAE19DAFEA000430CA2 /* MaskImageOperation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MaskImageOperation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 6C568CAF19DAFEA000430CA2 /* MaskImageOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MaskImageOperation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -15378,6 +15382,8 @@
</span><span class="cx">                                 7A54881514E432A1006AE05A /* DOMPatchSupport.h */,
</span><span class="cx">                                 B885E8D211E06DD2009FFBF4 /* InspectorApplicationCacheAgent.cpp */,
</span><span class="cx">                                 B885E8D311E06DD2009FFBF4 /* InspectorApplicationCacheAgent.h */,
</span><ins>+                                6A4B6D6619D225D8006F11D3 /* InspectorCanvasAgent.cpp */,
+                                6A4B6D6419D22519006F11D3 /* InspectorCanvasAgent.h */,
</ins><span class="cx">                                 7A1F2B51126C61B20006A7E6 /* InspectorClient.cpp */,
</span><span class="cx">                                 1C81B9580E97330800266E07 /* InspectorClient.h */,
</span><span class="cx">                                 F3F5CF1012ED81A80084C569 /* InspectorConsoleInstrumentation.h */,
</span><span class="lines">@@ -24778,6 +24784,7 @@
</span><span class="cx">                                 A871DE2B0A152AC800B12A68 /* HTMLFrameElement.h in Headers */,
</span><span class="cx">                                 14FFE31D0AE1963300136BF5 /* HTMLFrameElementBase.h in Headers */,
</span><span class="cx">                                 93E241FF0B2B4E4000C732A1 /* HTMLFrameOwnerElement.h in Headers */,
</span><ins>+                                6A4B6D6519D22519006F11D3 /* InspectorCanvasAgent.h in Headers */,
</ins><span class="cx">                                 A871DE280A152AC800B12A68 /* HTMLFrameSetElement.h in Headers */,
</span><span class="cx">                                 A871DE2D0A152AC800B12A68 /* HTMLHeadElement.h in Headers */,
</span><span class="cx">                                 A8EA7CB80A192B9C00A8EF5F /* HTMLHeadingElement.h in Headers */,
</span><span class="lines">@@ -27396,6 +27403,7 @@
</span><span class="cx">                         isa = PBXSourcesBuildPhase;
</span><span class="cx">                         buildActionMask = 2147483647;
</span><span class="cx">                         files = (
</span><ins>+                                6A32D7CE1A16D8C000412F0B /* InspectorCanvasAgent.cpp in Sources */,
</ins><span class="cx">                                 41E1B1D00FF5986900576B3B /* AbstractWorker.cpp in Sources */,
</span><span class="cx">                                 37F57AB91A50726900876F98 /* AccessibilityARIAGrid.cpp in Sources */,
</span><span class="cx">                                 37F57ABA1A50726F00876F98 /* AccessibilityARIAGridCell.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoredomDocumentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Document.cpp (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Document.cpp        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/dom/Document.cpp        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -5053,8 +5053,10 @@
</span><span class="cx"> HTMLCanvasElement* Document::getCSSCanvasElement(const String&amp; name)
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;HTMLCanvasElement&gt;&amp; element = m_cssCanvasElements.add(name, nullptr).iterator-&gt;value;
</span><del>-    if (!element)
</del><ins>+    if (!element) {
</ins><span class="cx">         element = HTMLCanvasElement::create(*this);
</span><ins>+        InspectorInstrumentation::didCreateCSSCanvas(*element, name);
+    }
</ins><span class="cx">     return element.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlHTMLCanvasElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/HTMLCanvasElement.cpp (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/HTMLCanvasElement.cpp        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/html/HTMLCanvasElement.cpp        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> #include &quot;GraphicsContext.h&quot;
</span><span class="cx"> #include &quot;HTMLNames.h&quot;
</span><span class="cx"> #include &quot;ImageData.h&quot;
</span><ins>+#include &quot;InspectorInstrumentation.h&quot;
</ins><span class="cx"> #include &quot;MIMETypeRegistry.h&quot;
</span><span class="cx"> #include &quot;Page.h&quot;
</span><span class="cx"> #include &quot;RenderHTMLCanvas.h&quot;
</span><span class="lines">@@ -193,6 +194,7 @@
</span><span class="cx">                 usesDashbardCompatibilityMode = settings-&gt;usesDashboardBackwardCompatibilityMode();
</span><span class="cx"> #endif
</span><span class="cx">             m_context = std::make_unique&lt;CanvasRenderingContext2D&gt;(this, document().inQuirksMode(), usesDashbardCompatibilityMode);
</span><ins>+            InspectorInstrumentation::didCreateCanvasRenderingContext(*this);
</ins><span class="cx"> #if USE(IOSURFACE_CANVAS_BACKING_STORE) || ENABLE(ACCELERATED_2D_CANVAS)
</span><span class="cx">             // Need to make sure a RenderLayer and compositing layer get created for the Canvas
</span><span class="cx">             setNeedsStyleRecalc(SyntheticStyleChange);
</span><span class="lines">@@ -209,6 +211,7 @@
</span><span class="cx">             if (!m_context) {
</span><span class="cx">                 m_context = WebGLRenderingContextBase::create(this, static_cast&lt;WebGLContextAttributes*&gt;(attrs), type);
</span><span class="cx">                 if (m_context) {
</span><ins>+                    InspectorInstrumentation::didCreateCanvasRenderingContext(*this);
</ins><span class="cx">                     // Need to make sure a RenderLayer and compositing layer get created for the Canvas
</span><span class="cx">                     setNeedsStyleRecalc(SyntheticStyleChange);
</span><span class="cx">                 }
</span></span></pre></div>
<a id="trunkSourceWebCorehtmlcanvasWebGLRenderingContextBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContextBase.cpp        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> #include &quot;HTMLVideoElement.h&quot;
</span><span class="cx"> #include &quot;ImageBuffer.h&quot;
</span><span class="cx"> #include &quot;ImageData.h&quot;
</span><ins>+#include &quot;InspectorInstrumentation.h&quot;
</ins><span class="cx"> #include &quot;IntSize.h&quot;
</span><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> #include &quot;MainFrame.h&quot;
</span><span class="lines">@@ -833,6 +834,8 @@
</span><span class="cx">     }
</span><span class="cx">     m_context-&gt;attachShader(objectOrZero(program), objectOrZero(shader));
</span><span class="cx">     shader-&gt;onAttached();
</span><ins>+
+    InspectorInstrumentation::didAttachShader(*this, *program, *shader);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String&amp; name, ExceptionCode&amp; ec)
</span><span class="lines">@@ -1408,6 +1411,9 @@
</span><span class="cx">         return nullptr;
</span><span class="cx">     RefPtr&lt;WebGLProgram&gt; o = WebGLProgram::create(this);
</span><span class="cx">     addSharedObject(o.get());
</span><ins>+
+    InspectorInstrumentation::didCreateProgram(*this, *o);
+
</ins><span class="cx">     return o;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1482,6 +1488,8 @@
</span><span class="cx">     deleteObject(program);
</span><span class="cx">     // We don't reset m_currentProgram to 0 here because the deletion of the
</span><span class="cx">     // current program is delayed.
</span><ins>+
+    InspectorInstrumentation::didDeleteProgram(*this, *program);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
</span><span class="lines">@@ -1550,6 +1558,8 @@
</span><span class="cx">     }
</span><span class="cx">     m_context-&gt;detachShader(objectOrZero(program), objectOrZero(shader));
</span><span class="cx">     shader-&gt;onDetached(graphicsContext3D());
</span><ins>+
+    InspectorInstrumentation::didDetachShader(*this, *program, *shader);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebGLRenderingContextBase::disable(GC3Denum cap)
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorAllInOnecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorAllInOne.cpp (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorAllInOne.cpp        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/inspector/InspectorAllInOne.cpp        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -31,6 +31,7 @@
</span><span class="cx"> #include &quot;DOMPatchSupport.cpp&quot;
</span><span class="cx"> #include &quot;InspectorApplicationCacheAgent.cpp&quot;
</span><span class="cx"> #include &quot;InspectorCSSAgent.cpp&quot;
</span><ins>+#include &quot;InspectorCanvasAgent.cpp&quot;
</ins><span class="cx"> #include &quot;InspectorClient.cpp&quot;
</span><span class="cx"> #include &quot;InspectorController.cpp&quot;
</span><span class="cx"> #include &quot;InspectorDOMAgent.cpp&quot;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorCanvasAgentcpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/inspector/InspectorCanvasAgent.cpp (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorCanvasAgent.cpp                                (rev 0)
+++ trunk/Source/WebCore/inspector/InspectorCanvasAgent.cpp        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,346 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;InspectorCanvasAgent.h&quot;
+
+#include &quot;CanvasRenderingContext2D.h&quot;
+#include &quot;Document.h&quot;
+#include &quot;DocumentLoader.h&quot;
+#include &quot;Event.h&quot;
+#include &quot;EventListener.h&quot;
+#include &quot;EventTarget.h&quot;
+#include &quot;ExceptionCode.h&quot;
+#include &quot;Frame.h&quot;
+#include &quot;GraphicsContext3D.h&quot;
+#include &quot;GraphicsTypes3D.h&quot;
+#include &quot;InspectorPageAgent.h&quot;
+#include &quot;InstrumentingAgents.h&quot;
+#include &quot;JSMainThreadExecState.h&quot;
+#include &quot;MainFrame.h&quot;
+#include &quot;WebGLContextAttributes.h&quot;
+#include &quot;WebGLProgram.h&quot;
+#include &quot;WebGLRenderingContextBase.h&quot;
+#include &quot;WebGLShader.h&quot;
+#include &lt;inspector/InspectorValues.h&gt;
+#include &lt;inspector/ScriptCallStack.h&gt;
+#include &lt;inspector/ScriptCallStackFactory.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+using namespace Inspector;
+
+namespace WebCore {
+
+InspectorCanvasAgent::InspectorCanvasAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent)
+    : InspectorAgentBase(ASCIILiteral(&quot;Canvas&quot;), instrumentingAgents)
+    , m_pageAgent(pageAgent)
+    , m_timer(*this, &amp;InspectorCanvasAgent::canvasDestroyedTimerFired)
+{
+    reset();
+}
+
+void InspectorCanvasAgent::didCreateFrontendAndBackend(Inspector::FrontendChannel* frontendChannel, Inspector::BackendDispatcher* backendDispatcher)
+{
+    m_frontendDispatcher = std::make_unique&lt;Inspector::CanvasFrontendDispatcher&gt;(frontendChannel);
+    m_backendDispatcher = Inspector::CanvasBackendDispatcher::create(backendDispatcher, this);
+}
+
+void InspectorCanvasAgent::willDestroyFrontendAndBackend(Inspector::DisconnectReason)
+{
+    m_frontendDispatcher = nullptr;
+    m_backendDispatcher.clear();
+}
+
+void InspectorCanvasAgent::frameNavigated(DocumentLoader* loader)
+{
+    if (loader-&gt;frame()-&gt;isMainFrame()) {
+        reset();
+        return;
+    }
+
+    Vector&lt;HTMLCanvasElement*&gt; canvasesForFrame;
+    for (const auto&amp; canvasElement : m_canvasEntries.keys()) {
+        if (canvasElement-&gt;document().frame() == loader-&gt;frame())
+            canvasesForFrame.append(canvasElement);
+    }
+
+    for (auto* canvasElement : canvasesForFrame) {
+        const auto&amp; canvasEntry = m_canvasEntries.get(canvasElement);
+        for (const auto&amp; programEntry : canvasEntry.programEntries.values()) {
+            removeShaderFromShaderMap(programEntry, programEntry.vertexShader);
+            removeShaderFromShaderMap(programEntry, programEntry.fragmentShader);
+        }
+
+        if (m_frontendDispatcher)
+            m_frontendDispatcher-&gt;canvasRemoved(canvasEntry.canvasId);
+    }
+}
+
+void InspectorCanvasAgent::didCreateCSSCanvas(HTMLCanvasElement&amp; canvasElement, const String&amp; name)
+{
+    ASSERT(!m_canvasToCSSCanvasId.contains(&amp;canvasElement));
+    ASSERT(!m_canvasEntries.contains(&amp;canvasElement));
+    if (m_canvasEntries.contains(&amp;canvasElement))
+        return;
+
+    m_canvasToCSSCanvasId.set(&amp;canvasElement, name);
+}
+
+void InspectorCanvasAgent::didCreateCanvasRenderingContext(HTMLCanvasElement&amp; canvasElement)
+{
+    ASSERT(!m_canvasEntries.contains(&amp;canvasElement));
+    if (m_canvasEntries.contains(&amp;canvasElement))
+        return;
+
+    CanvasEntry newCanvasEntry(m_nextCanvasId++, &amp;canvasElement);
+    if (m_canvasToCSSCanvasId.contains(&amp;canvasElement)) {
+        ASSERT(!canvasElement.parentElement());
+        newCanvasEntry.name = m_canvasToCSSCanvasId.get(&amp;canvasElement);
+        newCanvasEntry.cssCanvas = true;
+        m_canvasToCSSCanvasId.remove(&amp;canvasElement);
+    } else
+        newCanvasEntry.name = canvasElement.getAttribute(&quot;id&quot;);
+
+    m_canvasEntries.set(&amp;canvasElement, newCanvasEntry);
+    canvasElement.addObserver(*this);
+    if (m_frontendDispatcher)
+        m_frontendDispatcher-&gt;canvasAdded(buildObjectForCanvas(newCanvasEntry, canvasElement));
+}
+
+void InspectorCanvasAgent::didAttachShader(WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program, WebGLShader&amp; shader)
+{
+    ProgramEntry* programEntry = getProgramEntry(context, program);
+    ASSERT(programEntry);
+    if (!programEntry)
+        return;
+
+    ASSERT(!(programEntry-&gt;vertexShader == &amp;shader || programEntry-&gt;fragmentShader == &amp;shader));
+    if (shader.getType() == GraphicsContext3D::VERTEX_SHADER)
+        programEntry-&gt;vertexShader = &amp;shader;
+    else
+        programEntry-&gt;fragmentShader = &amp;shader;
+
+    auto addResult = m_shaderToProgramEntries.add(&amp;shader, HashSet&lt;const ProgramEntry*&gt;({programEntry}));
+    if (!addResult.isNewEntry)
+        addResult.iterator-&gt;value.add(programEntry);
+    ASSERT(m_shaderToProgramEntries.contains(&amp;shader));
+}
+
+void InspectorCanvasAgent::didDetachShader(WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program, WebGLShader&amp; shader)
+{
+    ProgramEntry* programEntry = getProgramEntry(context, program);
+    ASSERT(programEntry);
+    if (!programEntry)
+        return;
+
+    ASSERT(programEntry-&gt;vertexShader == &amp;shader || programEntry-&gt;fragmentShader == &amp;shader);
+    if (shader.getType() == GraphicsContext3D::VERTEX_SHADER) {
+        removeShaderFromShaderMap(*programEntry, programEntry-&gt;vertexShader);
+        programEntry-&gt;vertexShader = nullptr;
+    } else {
+        removeShaderFromShaderMap(*programEntry, programEntry-&gt;fragmentShader);
+        programEntry-&gt;fragmentShader = nullptr;
+    }
+}
+
+void InspectorCanvasAgent::didCreateProgram(WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program)
+{
+    CanvasEntry* canvasEntry = getCanvasEntry(context.canvas());
+    ASSERT(canvasEntry);
+    if (!canvasEntry)
+        return;
+
+    auto findResult = canvasEntry-&gt;programEntries.find(&amp;program);
+    ASSERT(findResult == canvasEntry-&gt;programEntries.end());
+    if (findResult != canvasEntry-&gt;programEntries.end())
+        return;
+
+    unsigned programId = canvasEntry-&gt;nextProgramId++;
+    canvasEntry-&gt;programEntries.set(&amp;program, ProgramEntry(programId, canvasEntry, &amp;program));
+    if (m_frontendDispatcher) {
+        auto compoundId = CanvasObjectId(canvasEntry-&gt;canvasId, programId);
+        m_frontendDispatcher-&gt;programCreated(compoundId.asProtocolValue&lt;Inspector::Protocol::Canvas::ProgramId&gt;());
+    }
+}
+
+void InspectorCanvasAgent::didDeleteProgram(WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program)
+{
+    ProgramEntry* programEntry = getProgramEntry(context, program);
+    if (!programEntry)
+        return;
+
+    if (programEntry-&gt;vertexShader)
+        removeShaderFromShaderMap(*programEntry, programEntry-&gt;vertexShader);
+    if (programEntry-&gt;fragmentShader)
+        removeShaderFromShaderMap(*programEntry, programEntry-&gt;fragmentShader);
+    programEntry-&gt;canvasEntry-&gt;programEntries.remove(&amp;program);
+    if (m_frontendDispatcher) {
+        auto compoundId = CanvasObjectId(programEntry-&gt;canvasEntry-&gt;canvasId, programEntry-&gt;programId);
+        m_frontendDispatcher-&gt;programDeleted(compoundId.asProtocolValue&lt;Inspector::Protocol::Canvas::ProgramId&gt;());
+    }
+}
+
+void InspectorCanvasAgent::getCanvases(ErrorString&amp;, RefPtr&lt;Inspector::Protocol::Array&lt;Inspector::Protocol::Canvas::Canvas&gt;&gt;&amp; result)
+{
+    result = Inspector::Protocol::Array&lt;Inspector::Protocol::Canvas::Canvas&gt;::create();
+    for (const auto&amp; pair : m_canvasEntries) {
+        HTMLCanvasElement&amp; canvasElement = *pair.key;
+        result-&gt;addItem(buildObjectForCanvas(pair.value, canvasElement));
+    }
+}
+
+void InspectorCanvasAgent::canvasDestroyed(HTMLCanvasElement&amp; canvasElement)
+{
+    ASSERT(!m_canvasToCSSCanvasId.contains(&amp;canvasElement));
+
+    const CanvasEntry* canvasEntry = getCanvasEntry(&amp;canvasElement);
+    ASSERT(canvasEntry);
+    if (!canvasEntry)
+        return;
+
+    m_canvasEntries.remove(&amp;canvasElement);
+
+    // WebCore::CanvasObserver::canvasDestroyed is called in response to the GC destroying the HTMLCanvasElement.
+    // Due to the single-process model used in WebKit1, the event must be dispatched from a timer to prevent
+    // the frontend from making JS allocations while the GC is still active.
+    m_lastRemovedCanvasId = canvasEntry-&gt;canvasId;
+    m_timer.startOneShot(0);
+}
+
+void InspectorCanvasAgent::canvasDestroyedTimerFired()
+{
+    if (m_frontendDispatcher)
+        m_frontendDispatcher-&gt;canvasRemoved(m_lastRemovedCanvasId);
+
+    m_lastRemovedCanvasId = 0;
+}
+
+void InspectorCanvasAgent::reset()
+{
+    m_nextCanvasId = 1;
+    for (auto* canvasElement : m_canvasEntries.keys())
+        canvasElement-&gt;removeObserver(*this);
+
+    m_canvasToCSSCanvasId.clear();
+    m_canvasEntries.clear();
+    m_shaderToProgramEntries.clear();
+}
+
+InspectorCanvasAgent::CanvasEntry* InspectorCanvasAgent::getCanvasEntry(HTMLCanvasElement* canvasElement)
+{
+    ASSERT(canvasElement);
+    if (!canvasElement)
+        return nullptr;
+
+    auto findResult = m_canvasEntries.find(canvasElement);
+    if (findResult != m_canvasEntries.end())
+        return &amp;findResult-&gt;value;
+    return nullptr;
+}
+
+InspectorCanvasAgent::CanvasEntry* InspectorCanvasAgent::getCanvasEntry(unsigned canvasId)
+{
+    for (auto&amp; canvasEntry : m_canvasEntries.values()) {
+        if (canvasEntry.canvasId == canvasId)
+            return &amp;canvasEntry;
+    }
+    return nullptr;
+}
+
+InspectorCanvasAgent::ProgramEntry* InspectorCanvasAgent::getProgramEntry(WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program)
+{
+    CanvasEntry* canvasEntry = getCanvasEntry(context.canvas());
+    if (!canvasEntry)
+        return nullptr;
+
+    auto findResult = canvasEntry-&gt;programEntries.find(&amp;program);
+    if (findResult == canvasEntry-&gt;programEntries.end())
+        return nullptr;
+
+    return &amp;findResult-&gt;value;
+}
+
+void InspectorCanvasAgent::removeShaderFromShaderMap(const ProgramEntry&amp; programEntry, WebGLShader* shader)
+{
+    ASSERT(shader);
+    if (!shader)
+        return;
+
+    auto findResult = m_shaderToProgramEntries.find(shader);
+    ASSERT(findResult != m_shaderToProgramEntries.end());
+    if (findResult == m_shaderToProgramEntries.end())
+        return;
+
+    auto&amp; programEntries = findResult-&gt;value;
+    programEntries.remove(&amp;programEntry);
+    if (programEntries.isEmpty())
+        m_shaderToProgramEntries.remove(shader);
+}
+
+Inspector::Protocol::Canvas::ContextType InspectorCanvasAgent::contextTypeJson(const CanvasRenderingContext* context)
+{
+    if (context-&gt;is2d())
+        return Inspector::Protocol::Canvas::ContextType::Canvas2D;
+
+    ASSERT(context-&gt;is3d());
+    return Inspector::Protocol::Canvas::ContextType::WebGL;
+}
+
+Ref&lt;Inspector::Protocol::Canvas::Canvas&gt; InspectorCanvasAgent::buildObjectForCanvas(const CanvasEntry&amp; canvasEntry, HTMLCanvasElement&amp; canvasElement)
+{
+    Frame* frame = canvasElement.document().frame();
+    CanvasRenderingContext* context = canvasElement.renderingContext();
+
+    auto programIds = Inspector::Protocol::Array&lt;Inspector::Protocol::Canvas::ProgramId&gt;::create();
+    for (auto&amp; pair : canvasEntry.programEntries) {
+        auto compoundId = CanvasObjectId(canvasEntry.canvasId, pair.value.programId);
+        programIds-&gt;addItem(compoundId.asProtocolValue&lt;Inspector::Protocol::Canvas::ProgramId&gt;());
+    }
+
+    auto canvas = Inspector::Protocol::Canvas::Canvas::create()
+        .setCanvasId(canvasEntry.canvasId)
+        .setFrameId(m_pageAgent-&gt;frameId(frame))
+        .setName(canvasEntry.name)
+        .setCssCanvas(canvasEntry.cssCanvas)
+        .setContextType(contextTypeJson(context))
+        .setProgramIds(WTF::move(programIds))
+        .release();
+
+    if (context-&gt;is3d()) {
+        auto attributes = static_cast&lt;WebGLRenderingContextBase*&gt;(context)-&gt;getContextAttributes();
+        canvas-&gt;setContextAttributes(Inspector::Protocol::Canvas::ContextAttributes::create()
+            .setAlpha(attributes-&gt;alpha())
+            .setDepth(attributes-&gt;depth())
+            .setStencil(attributes-&gt;stencil())
+            .setAntialias(attributes-&gt;antialias())
+            .setPremultipliedAlpha(attributes-&gt;premultipliedAlpha())
+            .setPreserveDrawingBuffer(attributes-&gt;preserveDrawingBuffer())
+            .release());
+    }
+
+    return canvas;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorCanvasAgenth"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/inspector/InspectorCanvasAgent.h (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorCanvasAgent.h                                (rev 0)
+++ trunk/Source/WebCore/inspector/InspectorCanvasAgent.h        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,176 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef InspectorCanvasAgent_h
+#define InspectorCanvasAgent_h
+
+#include &quot;HTMLCanvasElement.h&quot;
+#include &quot;InspectorWebAgentBase.h&quot;
+#include &quot;Timer.h&quot;
+#include &lt;inspector/InspectorBackendDispatchers.h&gt;
+#include &lt;inspector/InspectorFrontendDispatchers.h&gt;
+#include &lt;wtf/RefPtr.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+
+class DocumentLoader;
+class InspectorPageAgent;
+class WebGLProgram;
+class WebGLShader;
+class WebGLRenderingContextBase;
+
+typedef String ErrorString;
+
+class InspectorCanvasAgent final
+    : public InspectorAgentBase
+    , public CanvasObserver
+    , public Inspector::CanvasBackendDispatcherHandler {
+    WTF_MAKE_NONCOPYABLE(InspectorCanvasAgent);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    InspectorCanvasAgent(InstrumentingAgents*, InspectorPageAgent*);
+    virtual ~InspectorCanvasAgent() { }
+
+    virtual void didCreateFrontendAndBackend(Inspector::FrontendChannel*, Inspector::BackendDispatcher*) override;
+    virtual void willDestroyFrontendAndBackend(Inspector::DisconnectReason) override;
+
+    // InspectorInstrumentation API
+    void frameNavigated(DocumentLoader*);
+    void didCreateCSSCanvas(HTMLCanvasElement&amp;, const String&amp;);
+    void didCreateCanvasRenderingContext(HTMLCanvasElement&amp;);
+    void didAttachShader(WebGLRenderingContextBase&amp;, WebGLProgram&amp;, WebGLShader&amp;);
+    void didDetachShader(WebGLRenderingContextBase&amp;, WebGLProgram&amp;, WebGLShader&amp;);
+    void didCreateProgram(WebGLRenderingContextBase&amp;, WebGLProgram&amp;);
+    void didDeleteProgram(WebGLRenderingContextBase&amp;, WebGLProgram&amp;);
+
+    // Canvas API for InspectorFrontend
+    virtual void getCanvases(ErrorString&amp;, RefPtr&lt;Inspector::Protocol::Array&lt;Inspector::Protocol::Canvas::Canvas&gt;&gt;&amp;) override;
+
+    // CanvasObserver implementation
+    virtual void canvasChanged(HTMLCanvasElement&amp;, const FloatRect&amp;) override { }
+    virtual void canvasResized(HTMLCanvasElement&amp;) override { }
+    virtual void canvasDestroyed(HTMLCanvasElement&amp;) override;
+
+private:
+    class CanvasObjectId {
+    public:
+        CanvasObjectId() { }
+
+        explicit CanvasObjectId(const RefPtr&lt;Inspector::InspectorObject&gt; value)
+        {
+            if (!value-&gt;getInteger(ASCIILiteral(&quot;canvasId&quot;), m_canvasId))
+                return;
+            if (!value-&gt;getInteger(ASCIILiteral(&quot;objectId&quot;), m_objectId))
+                m_canvasId = 0;
+        }
+
+        CanvasObjectId(unsigned canvasId, unsigned programId)
+            : m_canvasId(canvasId)
+            , m_objectId(programId)
+        {
+        }
+
+        bool isEmpty() const { return !(m_canvasId &amp;&amp; m_objectId); }
+        unsigned canvasId() const { return m_canvasId; }
+        unsigned objectId() const { return m_objectId; }
+
+        // ID type is either Inspector::Protocol::Canvas::ProgramId or Inspector::Protocol::Canvas::TextureId.
+        template&lt;typename ID&gt;
+        RefPtr&lt;ID&gt; asProtocolValue() const
+        {
+            if (isEmpty())
+                return nullptr;
+
+            return ID::create()
+                .setCanvasId(m_canvasId)
+                .setObjectId(m_objectId).release();
+        }
+
+    private:
+        unsigned m_canvasId = {0};
+        unsigned m_objectId = {0};
+    };
+
+    struct CanvasEntry;
+
+    struct ProgramEntry {
+        unsigned programId = {0};
+        CanvasEntry* canvasEntry = {nullptr};
+        WebGLProgram* program = {nullptr};
+        WebGLShader* vertexShader = {nullptr};
+        WebGLShader* fragmentShader = {nullptr};
+
+        ProgramEntry() { }
+
+        ProgramEntry(unsigned id, CanvasEntry* canvasEntry, WebGLProgram* program)
+            : programId(id)
+            , canvasEntry(canvasEntry)
+            , program(program)
+        {
+        }
+    };
+
+    struct CanvasEntry {
+        unsigned canvasId = {0};
+        unsigned nextProgramId = {1};
+        bool cssCanvas = {false};
+        String name;
+        HTMLCanvasElement* element = {nullptr};
+        HashMap&lt;WebGLProgram*, ProgramEntry&gt; programEntries;
+
+        CanvasEntry() { }
+
+        CanvasEntry(unsigned id, HTMLCanvasElement* canvasElement)
+            : canvasId(id)
+            , element(canvasElement)
+        {
+        }
+    };
+
+    void canvasDestroyedTimerFired();
+    void reset();
+    CanvasEntry* getCanvasEntry(HTMLCanvasElement*);
+    CanvasEntry* getCanvasEntry(unsigned);
+    ProgramEntry* getProgramEntry(WebGLRenderingContextBase&amp;, WebGLProgram&amp;);
+    void removeShaderFromShaderMap(const ProgramEntry&amp;, WebGLShader*);
+    static Inspector::Protocol::Canvas::ContextType contextTypeJson(const CanvasRenderingContext*);
+    Ref&lt;Inspector::Protocol::Canvas::Canvas&gt; buildObjectForCanvas(const CanvasEntry&amp;, HTMLCanvasElement&amp;);
+
+    InspectorPageAgent* m_pageAgent;
+    std::unique_ptr&lt;Inspector::CanvasFrontendDispatcher&gt; m_frontendDispatcher;
+    RefPtr&lt;Inspector::CanvasBackendDispatcher&gt; m_backendDispatcher;
+
+    HashMap&lt;HTMLCanvasElement*, String&gt; m_canvasToCSSCanvasId;
+    HashMap&lt;HTMLCanvasElement*, CanvasEntry&gt; m_canvasEntries;
+    HashMap&lt;const WebGLShader*, HashSet&lt;const ProgramEntry*&gt;&gt; m_shaderToProgramEntries;
+    Timer m_timer;
+    unsigned m_nextCanvasId = {0};
+    unsigned m_lastRemovedCanvasId = {0};
+};
+
+} // namespace WebCore
+
+#endif // !defined(InspectorCanvasAgent_h)
</ins></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorController.cpp (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorController.cpp        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/inspector/InspectorController.cpp        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;GraphicsContext.h&quot;
</span><span class="cx"> #include &quot;InspectorApplicationCacheAgent.h&quot;
</span><span class="cx"> #include &quot;InspectorCSSAgent.h&quot;
</span><ins>+#include &quot;InspectorCanvasAgent.h&quot;
</ins><span class="cx"> #include &quot;InspectorClient.h&quot;
</span><span class="cx"> #include &quot;InspectorDOMAgent.h&quot;
</span><span class="cx"> #include &quot;InspectorDOMDebuggerAgent.h&quot;
</span><span class="lines">@@ -157,6 +158,10 @@
</span><span class="cx">     m_domDebuggerAgent = domDebuggerAgentPtr.get();
</span><span class="cx">     m_agents.append(WTF::move(domDebuggerAgentPtr));
</span><span class="cx"> 
</span><ins>+    auto canvasAgentPtr = std::make_unique&lt;InspectorCanvasAgent&gt;(m_instrumentingAgents.get(), m_pageAgent);
+    m_instrumentingAgents-&gt;setInspectorCanvasAgent(canvasAgentPtr.get());
+    m_agents.append(WTF::move(canvasAgentPtr));
+
</ins><span class="cx">     m_agents.append(std::make_unique&lt;InspectorApplicationCacheAgent&gt;(m_instrumentingAgents.get(), pageAgent));
</span><span class="cx">     m_agents.append(std::make_unique&lt;InspectorWorkerAgent&gt;(m_instrumentingAgents.get()));
</span><span class="cx">     m_agents.append(std::make_unique&lt;InspectorLayerTreeAgent&gt;(m_instrumentingAgents.get()));
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorInstrumentationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.cpp        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx"> #include &quot;InspectorApplicationCacheAgent.h&quot;
</span><span class="cx"> #include &quot;InspectorController.h&quot;
</span><span class="cx"> #include &quot;InspectorCSSAgent.h&quot;
</span><ins>+#include &quot;InspectorCanvasAgent.h&quot;
</ins><span class="cx"> #include &quot;InspectorDOMAgent.h&quot;
</span><span class="cx"> #include &quot;InspectorDOMDebuggerAgent.h&quot;
</span><span class="cx"> #include &quot;InspectorDOMStorageAgent.h&quot;
</span><span class="lines">@@ -62,6 +63,7 @@
</span><span class="cx"> #include &quot;StyleResolver.h&quot;
</span><span class="cx"> #include &quot;StyleRule.h&quot;
</span><span class="cx"> #include &quot;WebConsoleAgent.h&quot;
</span><ins>+#include &quot;WebGLRenderingContextBase.h&quot;
</ins><span class="cx"> #include &quot;WorkerGlobalScope.h&quot;
</span><span class="cx"> #include &quot;WorkerInspectorController.h&quot;
</span><span class="cx"> #include &quot;WorkerRuntimeAgent.h&quot;
</span><span class="lines">@@ -762,6 +764,9 @@
</span><span class="cx">             layerTreeAgent-&gt;reset();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents.inspectorCanvasAgent())
+        canvasAgent-&gt;frameNavigated(loader);
+
</ins><span class="cx">     if (InspectorDOMAgent* domAgent = instrumentingAgents.inspectorDOMAgent())
</span><span class="cx">         domAgent-&gt;didCommitLoad(loader-&gt;frame()-&gt;document());
</span><span class="cx"> 
</span><span class="lines">@@ -1028,6 +1033,44 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+void InspectorInstrumentation::didCreateCSSCanvasImpl(InstrumentingAgents* instrumentingAgents, HTMLCanvasElement&amp; canvasElement, const String&amp; name)
+{
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents-&gt;inspectorCanvasAgent())
+        canvasAgent-&gt;didCreateCSSCanvas(canvasElement, name);
+}
+
+void InspectorInstrumentation::didCreateCanvasRenderingContextImpl(InstrumentingAgents* instrumentingAgents, HTMLCanvasElement&amp; canvasElement)
+{
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents-&gt;inspectorCanvasAgent())
+        canvasAgent-&gt;didCreateCanvasRenderingContext(canvasElement);
+}
+
+#if ENABLE(WEBGL)
+void InspectorInstrumentation::didAttachShaderImpl(InstrumentingAgents* instrumentingAgents, WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program, WebGLShader&amp; shader)
+{
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents-&gt;inspectorCanvasAgent())
+        canvasAgent-&gt;didAttachShader(context, program, shader);
+}
+
+void InspectorInstrumentation::didDetachShaderImpl(InstrumentingAgents* instrumentingAgents, WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program, WebGLShader&amp; shader)
+{
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents-&gt;inspectorCanvasAgent())
+        canvasAgent-&gt;didDetachShader(context, program, shader);
+}
+
+void InspectorInstrumentation::didCreateProgramImpl(InstrumentingAgents* instrumentingAgents, WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program)
+{
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents-&gt;inspectorCanvasAgent())
+        canvasAgent-&gt;didCreateProgram(context, program);
+}
+
+void InspectorInstrumentation::didDeleteProgramImpl(InstrumentingAgents* instrumentingAgents, WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program)
+{
+    if (InspectorCanvasAgent* canvasAgent = instrumentingAgents-&gt;inspectorCanvasAgent())
+        canvasAgent-&gt;didDeleteProgram(context, program);
+}
+#endif
+
</ins><span class="cx"> #if ENABLE(WEB_REPLAY)
</span><span class="cx"> void InspectorInstrumentation::sessionCreatedImpl(InstrumentingAgents&amp; instrumentingAgents, RefPtr&lt;ReplaySession&gt;&amp;&amp; session)
</span><span class="cx"> {
</span><span class="lines">@@ -1221,6 +1264,16 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForRenderingContext(WebGLRenderingContextBase* context)
+{
+    if (!context)
+        return nullptr;
+    HTMLCanvasElement* canvasElement = context-&gt;canvas();
+    if (canvasElement)
+        return instrumentingAgentsForDocument(&amp;canvasElement-&gt;document());
+    return nullptr;
+}
+
</ins><span class="cx"> InstrumentingAgents* InspectorInstrumentation::instrumentingAgentsForPage(Page* page)
</span><span class="cx"> {
</span><span class="cx">     return page ? instrumentingAgentsForPage(*page) : nullptr;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorInstrumentationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorInstrumentation.h (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorInstrumentation.h        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/inspector/InspectorInstrumentation.h        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> #include &quot;Element.h&quot;
</span><span class="cx"> #include &quot;FormData.h&quot;
</span><span class="cx"> #include &quot;Frame.h&quot;
</span><ins>+#include &quot;HTMLCanvasElement.h&quot;
</ins><span class="cx"> #include &quot;HitTestResult.h&quot;
</span><span class="cx"> #include &quot;InspectorInstrumentationCookie.h&quot;
</span><span class="cx"> #include &quot;Page.h&quot;
</span><span class="lines">@@ -75,7 +76,6 @@
</span><span class="cx"> class DOMWrapperWorld;
</span><span class="cx"> class Database;
</span><span class="cx"> class Document;
</span><del>-class Element;
</del><span class="cx"> class DocumentLoader;
</span><span class="cx"> class DocumentStyleSheetCollection;
</span><span class="cx"> class GraphicsContext;
</span><span class="lines">@@ -93,13 +93,15 @@
</span><span class="cx"> class RenderObject;
</span><span class="cx"> class ResourceRequest;
</span><span class="cx"> class ResourceResponse;
</span><del>-class ScriptExecutionContext;
</del><span class="cx"> class SecurityOrigin;
</span><span class="cx"> class ShadowRoot;
</span><span class="cx"> class StorageArea;
</span><span class="cx"> class StyleResolver;
</span><span class="cx"> class StyleRule;
</span><span class="cx"> class ThreadableLoaderClient;
</span><ins>+class WebGLShader;
+class WebGLProgram;
+class WebGLRenderingContextBase;
</ins><span class="cx"> class WorkerGlobalScope;
</span><span class="cx"> class WorkerGlobalScopeProxy;
</span><span class="cx"> class XMLHttpRequest;
</span><span class="lines">@@ -263,9 +265,13 @@
</span><span class="cx">     static void didReceiveWebSocketFrameError(Document*, unsigned long identifier, const String&amp; errorMessage);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    static Deprecated::ScriptObject wrapCanvas2DRenderingContextForInstrumentation(Document*, const Deprecated::ScriptObject&amp;);
</del><ins>+    static void didCreateCSSCanvas(HTMLCanvasElement&amp;, const String&amp;);
+    static void didCreateCanvasRenderingContext(HTMLCanvasElement&amp;);
</ins><span class="cx"> #if ENABLE(WEBGL)
</span><del>-    static Deprecated::ScriptObject wrapWebGLRenderingContextForInstrumentation(Document*, const Deprecated::ScriptObject&amp;);
</del><ins>+    static void didAttachShader(WebGLRenderingContextBase&amp;, WebGLProgram&amp;, WebGLShader&amp;);
+    static void didDetachShader(WebGLRenderingContextBase&amp;, WebGLProgram&amp;, WebGLShader&amp;);
+    static void didCreateProgram(WebGLRenderingContextBase&amp;, WebGLProgram&amp;);
+    static void didDeleteProgram(WebGLRenderingContextBase&amp;, WebGLProgram&amp;);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     static void networkStateChanged(Page*);
</span><span class="lines">@@ -442,7 +448,16 @@
</span><span class="cx"> 
</span><span class="cx">     static void networkStateChangedImpl(InstrumentingAgents&amp;);
</span><span class="cx">     static void updateApplicationCacheStatusImpl(InstrumentingAgents&amp;, Frame*);
</span><ins>+    static void didCreateCSSCanvasImpl(InstrumentingAgents*, HTMLCanvasElement&amp;, const String&amp;);
+    static void didCreateCanvasRenderingContextImpl(InstrumentingAgents*, HTMLCanvasElement&amp;);
</ins><span class="cx"> 
</span><ins>+#if ENABLE(WEBGL)
+    static void didAttachShaderImpl(InstrumentingAgents*, WebGLRenderingContextBase&amp;, WebGLProgram&amp;, WebGLShader&amp;);
+    static void didDetachShaderImpl(InstrumentingAgents*, WebGLRenderingContextBase&amp;, WebGLProgram&amp;, WebGLShader&amp;);
+    static void didCreateProgramImpl(InstrumentingAgents*, WebGLRenderingContextBase&amp;, WebGLProgram&amp;);
+    static void didDeleteProgramImpl(InstrumentingAgents*, WebGLRenderingContextBase&amp;, WebGLProgram&amp;);
+#endif
+
</ins><span class="cx">     static void layerTreeDidChangeImpl(InstrumentingAgents&amp;);
</span><span class="cx">     static void renderLayerDestroyedImpl(InstrumentingAgents&amp;, const RenderLayer&amp;);
</span><span class="cx">     static void pseudoElementDestroyedImpl(InstrumentingAgents&amp;, PseudoElement&amp;);
</span><span class="lines">@@ -450,6 +465,7 @@
</span><span class="cx">     static InstrumentingAgents* instrumentingAgentsForPage(Page&amp;);
</span><span class="cx">     static InstrumentingAgents* instrumentingAgentsForFrame(Frame&amp;);
</span><span class="cx">     static InstrumentingAgents* instrumentingAgentsForFrame(Frame*);
</span><ins>+    static InstrumentingAgents* instrumentingAgentsForRenderingContext(WebGLRenderingContextBase*);
</ins><span class="cx">     static InstrumentingAgents* instrumentingAgentsForContext(ScriptExecutionContext*);
</span><span class="cx">     static InstrumentingAgents* instrumentingAgentsForDocument(Document&amp;);
</span><span class="cx">     static InstrumentingAgents* instrumentingAgentsForDocument(Document*);
</span><span class="lines">@@ -1155,6 +1171,75 @@
</span><span class="cx"> }
</span><span class="cx"> #endif // ENABLE(WEB_SOCKETS)
</span><span class="cx"> 
</span><ins>+inline void InspectorInstrumentation::didCreateCSSCanvas(HTMLCanvasElement&amp; canvasElement, const String&amp; name)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&amp;canvasElement.document()))
+        didCreateCSSCanvasImpl(instrumentingAgents, canvasElement, name);
+#else
+    UNUSED_PARAM(canvasElement);
+    UNUSED_PARAM(name);
+#endif
+}
+
+inline void InspectorInstrumentation::didCreateCanvasRenderingContext(HTMLCanvasElement&amp; canvasElement)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForDocument(&amp;canvasElement.document()))
+        didCreateCanvasRenderingContextImpl(instrumentingAgents, canvasElement);
+#else
+    UNUSED_PARAM(canvasElement);
+#endif
+}
+
+#if ENABLE(WEBGL)
+inline void InspectorInstrumentation::didAttachShader(WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program, WebGLShader&amp; shader)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForRenderingContext(&amp;context))
+        didAttachShaderImpl(instrumentingAgents, context, program, shader);
+#else
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(program);
+    UNUSED_PARAM(shader);
+#endif
+}
+
+inline void InspectorInstrumentation::didDetachShader(WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program, WebGLShader&amp; shader)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForRenderingContext(&amp;context))
+        didDetachShaderImpl(instrumentingAgents, context, program, shader);
+#else
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(program);
+    UNUSED_PARAM(shader);
+#endif
+}
+
+inline void InspectorInstrumentation::didCreateProgram(WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForRenderingContext(&amp;context))
+        didCreateProgramImpl(instrumentingAgents, context, program);
+#else
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(program);
+#endif
+}
+
+inline void InspectorInstrumentation::didDeleteProgram(WebGLRenderingContextBase&amp; context, WebGLProgram&amp; program)
+{
+#if ENABLE(INSPECTOR)
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForRenderingContext(&amp;context))
+        didDeleteProgramImpl(instrumentingAgents, context, program);
+#else
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(program);
+#endif
+}
+#endif
+
</ins><span class="cx"> #if ENABLE(WEB_REPLAY)
</span><span class="cx"> inline void InspectorInstrumentation::sessionCreated(Page&amp; page, RefPtr&lt;ReplaySession&gt;&amp;&amp; session)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInstrumentingAgentscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InstrumentingAgents.cpp (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InstrumentingAgents.cpp        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/inspector/InstrumentingAgents.cpp        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx">     : m_environment(environment)
</span><span class="cx">     , m_inspectorAgent(nullptr)
</span><span class="cx">     , m_inspectorPageAgent(nullptr)
</span><ins>+    , m_inspectorCanvasAgent(nullptr)
</ins><span class="cx">     , m_inspectorCSSAgent(nullptr)
</span><span class="cx">     , m_inspectorLayerTreeAgent(nullptr)
</span><span class="cx">     , m_webConsoleAgent(nullptr)
</span><span class="lines">@@ -72,6 +73,7 @@
</span><span class="cx"> {
</span><span class="cx">     m_inspectorAgent = nullptr;
</span><span class="cx">     m_inspectorPageAgent = nullptr;
</span><ins>+    m_inspectorCanvasAgent = nullptr;
</ins><span class="cx">     m_inspectorCSSAgent = nullptr;
</span><span class="cx">     m_inspectorLayerTreeAgent = nullptr;
</span><span class="cx">     m_webConsoleAgent = nullptr;
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInstrumentingAgentsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InstrumentingAgents.h (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InstrumentingAgents.h        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebCore/inspector/InstrumentingAgents.h        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class InspectorApplicationCacheAgent;
</span><ins>+class InspectorCanvasAgent;
</ins><span class="cx"> class InspectorCSSAgent;
</span><span class="cx"> class InspectorDOMAgent;
</span><span class="cx"> class InspectorDOMDebuggerAgent;
</span><span class="lines">@@ -83,6 +84,9 @@
</span><span class="cx">     InspectorPageAgent* inspectorPageAgent() const { return m_inspectorPageAgent; }
</span><span class="cx">     void setInspectorPageAgent(InspectorPageAgent* agent) { m_inspectorPageAgent = agent; }
</span><span class="cx"> 
</span><ins>+    InspectorCanvasAgent* inspectorCanvasAgent() const { return m_inspectorCanvasAgent; }
+    void setInspectorCanvasAgent(InspectorCanvasAgent* agent) { m_inspectorCanvasAgent = agent; }
+
</ins><span class="cx">     InspectorCSSAgent* inspectorCSSAgent() const { return m_inspectorCSSAgent; }
</span><span class="cx">     void setInspectorCSSAgent(InspectorCSSAgent* agent) { m_inspectorCSSAgent = agent; }
</span><span class="cx"> 
</span><span class="lines">@@ -143,6 +147,7 @@
</span><span class="cx"> 
</span><span class="cx">     Inspector::InspectorAgent* m_inspectorAgent;
</span><span class="cx">     InspectorPageAgent* m_inspectorPageAgent;
</span><ins>+    InspectorCanvasAgent* m_inspectorCanvasAgent;
</ins><span class="cx">     InspectorCSSAgent* m_inspectorCSSAgent;
</span><span class="cx">     InspectorLayerTreeAgent* m_inspectorLayerTreeAgent;
</span><span class="cx">     WebConsoleAgent* m_webConsoleAgent;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -1,3 +1,128 @@
</span><ins>+2015-03-31  Matt Baker  &lt;mattbaker@apple.com&gt;
+
+        Web Inspector: add 2D/WebGL canvas instrumentation infrastructure
+        https://bugs.webkit.org/show_bug.cgi?id=137278
+
+        Reviewed by Timothy Hatcher.
+
+        Added models, views, and controller classes for 2D and WebGL canvas inspection. Each canvas is shown in the
+        Resources navigation sidebar under its parent frame. Shader programs are displayed as child nodes of
+        their respective canvas. Canvases will get an associated content view and details sidebar in a later patch
+        (see https://bugs.webkit.org/show_bug.cgi?id=138941).
+
+        Shader programs will get an associated content view for editing shader source in a later patch (see
+        https://bugs.webkit.org/show_bug.cgi?id=138593). Individual shaders are not shown in the Resource navigation
+        sidebar, and at this time there are no plans to instrument shaders that aren't attached to a program.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Base/Main.js:
+        (WebInspector.loaded):
+        (WebInspector.sidebarPanelForRepresentedObject):
+        * UserInterface/Base/Test.js:
+        (WebInspector.loaded):
+        * UserInterface/Main.html:
+        * UserInterface/Test.html:
+        Updated for new canvas/shader program types.
+
+        * UserInterface/Controllers/CanvasManager.js: Added.
+        (WebInspector.CanvasManager):
+        (WebInspector.CanvasManager.prototype.canvasesForFrame):
+        (WebInspector.CanvasManager.prototype.canvasAdded.set this):
+        (WebInspector.CanvasManager.prototype.canvasAdded):
+        (WebInspector.CanvasManager.prototype.canvasRemoved):
+        (WebInspector.CanvasManager.programDeleted.get console):
+        (WebInspector.CanvasManager.prototype.programCreated.get console):
+        (WebInspector.CanvasManager.prototype.programCreated):
+        (WebInspector.CanvasManager.prototype._mainResourceDidChange):
+        Frontend controller for canvases and their shader programs.
+
+        * UserInterface/Images/Canvas.svg: Added.
+        * UserInterface/Images/DocumentGL.png: Added.
+        * UserInterface/Images/DocumentGL@2x.png: Added.
+        New art for canvas and shader program tree elements.
+
+        * UserInterface/Models/Canvas.js: Added.
+        (WebInspector.Canvas):
+        (WebInspector.Canvas.prototype.set fromPayload):
+        (WebInspector.Canvas.displayNameForContextType):
+        (WebInspector.Canvas.resetUniqueDisplayNameNumbers):
+        (WebInspector.Canvas.prototype.get id):
+        (WebInspector.Canvas.prototype.get parentFrame):
+        (WebInspector.Canvas.prototype.get name):
+        (WebInspector.Canvas.prototype.get cssCanvas):
+        (WebInspector.Canvas.prototype.get contextType):
+        (WebInspector.Canvas.prototype.get contextAttributes):
+        (WebInspector.Canvas.prototype.get programs):
+        (WebInspector.Canvas.prototype.get displayName):
+        (WebInspector.Canvas.programForId):
+        (WebInspector.Canvas.get programWasCreated.set this):
+        (WebInspector.Canvas.prototype.get programWasCreated):
+        (WebInspector.Canvas.prototype.programWasDeleted):
+        (WebInspector.Canvas.prototype.saveIdentityToCookie):
+        Model for DOM or CSS canvas (2D or WebGL).
+
+        * UserInterface/Models/ShaderProgram.js: Added.
+        (WebInspector.ShaderProgram):
+        (WebInspector.ShaderProgram.prototype.get id):
+        (WebInspector.ShaderProgram.prototype.get canvas):
+        (WebInspector.ShaderProgram.prototype.get displayName):
+        (WebInspector.ShaderProgram.prototype.saveIdentityToCookie):
+        (WebInspector.ShaderProgram.prototype.updateCanvas):
+        * UserInterface/Models/WebGLContextAttributes.js: Added.
+        (WebInspector.WebGLContextAttributes):
+        (WebInspector.WebGLContextAttributes.fromPayload):
+        (WebInspector.WebGLContextAttributes.prototype.get alpha):
+        (WebInspector.WebGLContextAttributes.prototype.get depth):
+        (WebInspector.WebGLContextAttributes.prototype.get stencil):
+        (WebInspector.WebGLContextAttributes.prototype.get antialias):
+        (WebInspector.WebGLContextAttributes.prototype.get premultipliedAlpha):
+        (WebInspector.WebGLContextAttributes.prototype.get preserveDrawingBuffer):
+        Model for WebGL canvas context attributes.
+
+        * UserInterface/Protocol/CanvasObserver.js: Added.
+        (WebInspector.CanvasObserver.prototype.canvasAdded):
+        (WebInspector.CanvasObserver.prototype.canvasRemoved):
+        (WebInspector.CanvasObserver.prototype.programCreated):
+        (WebInspector.CanvasObserver.prototype.programDeleted):
+        (WebInspector.CanvasObserver):
+        Model for WebGL canvas shader program.
+
+        * UserInterface/Views/CanvasTreeElement.js: Added.
+        (WebInspector.CanvasTreeElement.validateRepresentedObject):
+        (WebInspector.CanvasTreeElement.countChildren):
+        (WebInspector.CanvasTreeElement):
+        (WebInspector.CanvasTreeElement.prototype.onexpand):
+        (WebInspector.CanvasTreeElement.prototype.oncollapse):
+        (WebInspector.CanvasTreeElement.prototype.onpopulate):
+        (WebInspector.CanvasTreeElement.prototype._programWasCreated):
+        (WebInspector.CanvasTreeElement.prototype._programWasDeleted):
+        Folderized tree element for canvases and their child objects (shader programs).
+
+        * UserInterface/Views/FrameTreeElement.js:
+        (WebInspector.FrameTreeElement.prototype.onattach):
+        (WebInspector.FrameTreeElement.prototype.ondetach):
+        (WebInspector.FrameTreeElement.prototype.onpopulate):
+        (WebInspector.FrameTreeElement.prototype._canvasesAvailable):
+        (WebInspector.FrameTreeElement.prototype._canvasWasAdded):
+        (WebInspector.FrameTreeElement.prototype._canvasWasRemoved):
+        Updated to support canvas tree elements.
+
+        * UserInterface/Views/ResourceIcons.css:
+        (.canvas-icon .icon):
+        (.shader-program-icon .icon):
+        Styles for new canvas and shader program icons.
+
+        * UserInterface/Views/ResourceSidebarPanel.js:
+        (WebInspector.ResourceSidebarPanel.prototype._treeElementSelected):
+        Updated for new tree element types.
+
+        * UserInterface/Views/ShaderProgramTreeElement.js: Added.
+        (WebInspector.ShaderProgramTreeElement):
+        Tree element for shader programs. Shown as children of CanvasTreeElement.
+
+        * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj:
+        * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters:
+
</ins><span class="cx"> 2015-03-30  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Web Inspector: Regression: null shouldn't be expandable in object outline
</span></span></pre></div>
<a id="trunkSourceWebInspectorUILocalizationsenlprojlocalizedStringsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -36,6 +36,7 @@
</span><span class="cx"> localizedStrings[&quot;(uninitialized)&quot;] = &quot;(uninitialized)&quot;;
</span><span class="cx"> localizedStrings[&quot;, &quot;] = &quot;, &quot;;
</span><span class="cx"> localizedStrings[&quot;1 match&quot;] = &quot;1 match&quot;;
</span><ins>+localizedStrings[&quot;2D&quot;] = &quot;2D&quot;;
</ins><span class="cx"> localizedStrings[&quot;999+&quot;] = &quot;999+&quot;;
</span><span class="cx"> localizedStrings[&quot;Accessibility&quot;] = &quot;Accessibility&quot;;
</span><span class="cx"> localizedStrings[&quot;Action&quot;] = &quot;Action&quot;;
</span><span class="lines">@@ -79,10 +80,14 @@
</span><span class="cx"> localizedStrings[&quot;Box Model&quot;] = &quot;Box Model&quot;;
</span><span class="cx"> localizedStrings[&quot;Bubbling&quot;] = &quot;Bubbling&quot;;
</span><span class="cx"> localizedStrings[&quot;Busy&quot;] = &quot;Busy&quot;;
</span><ins>+localizedStrings[&quot;CSS canvas  %s &quot;] = &quot;CSS canvas  %s &quot;;
</ins><span class="cx"> localizedStrings[&quot;Cached&quot;] = &quot;Cached&quot;;
</span><span class="cx"> localizedStrings[&quot;Call Stack&quot;] = &quot;Call Stack&quot;;
</span><span class="cx"> localizedStrings[&quot;Calls&quot;] = &quot;Calls&quot;;
</span><span class="cx"> localizedStrings[&quot;Cancel Automatic Continue&quot;] = &quot;Cancel Automatic Continue&quot;;
</span><ins>+localizedStrings[&quot;Canvas #%s&quot;] = &quot;Canvas #%s&quot;;
+localizedStrings[&quot;Canvas %d&quot;] = &quot;Canvas %d&quot;;
+localizedStrings[&quot;Canvases&quot;] = &quot;Canvases&quot;;
</ins><span class="cx"> localizedStrings[&quot;Capturing&quot;] = &quot;Capturing&quot;;
</span><span class="cx"> localizedStrings[&quot;Catch Variables&quot;] = &quot;Catch Variables&quot;;
</span><span class="cx"> localizedStrings[&quot;Character Data&quot;] = &quot;Character Data&quot;;
</span><span class="lines">@@ -357,6 +362,8 @@
</span><span class="cx"> localizedStrings[&quot;Probe Sample Recorded&quot;] = &quot;Probe Sample Recorded&quot;;
</span><span class="cx"> localizedStrings[&quot;Probes&quot;] = &quot;Probes&quot;;
</span><span class="cx"> localizedStrings[&quot;Processing Instruction&quot;] = &quot;Processing Instruction&quot;;
</span><ins>+localizedStrings[&quot;Program %d&quot;] = &quot;Program %d&quot;;
+localizedStrings[&quot;Programs&quot;] = &quot;Programs&quot;;
</ins><span class="cx"> localizedStrings[&quot;Properties&quot;] = &quot;Properties&quot;;
</span><span class="cx"> localizedStrings[&quot;Prototype&quot;] = &quot;Prototype&quot;;
</span><span class="cx"> localizedStrings[&quot;Query Parameters&quot;] = &quot;Query Parameters&quot;;
</span><span class="lines">@@ -487,6 +494,7 @@
</span><span class="cx"> localizedStrings[&quot;Warning: &quot;] = &quot;Warning: &quot;;
</span><span class="cx"> localizedStrings[&quot;Warnings&quot;] = &quot;Warnings&quot;;
</span><span class="cx"> localizedStrings[&quot;Web Inspector&quot;] = &quot;Web Inspector&quot;;
</span><ins>+localizedStrings[&quot;WebGL&quot;] = &quot;WebGL&quot;;
</ins><span class="cx"> localizedStrings[&quot;Width&quot;] = &quot;Width&quot;;
</span><span class="cx"> localizedStrings[&quot;With Object Properties&quot;] = &quot;With Object Properties&quot;;
</span><span class="cx"> localizedStrings[&quot;Working Copy&quot;] = &quot;Working Copy&quot;;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceBaseMainjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Main.js (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Base/Main.js        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Main.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -78,6 +78,8 @@
</span><span class="cx">         InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeObserver);
</span><span class="cx">     if (InspectorBackend.registerReplayDispatcher)
</span><span class="cx">         InspectorBackend.registerReplayDispatcher(new WebInspector.ReplayObserver);
</span><ins>+    if (InspectorBackend.registerCanvasDispatcher)
+        InspectorBackend.registerCanvasDispatcher(new WebInspector.CanvasObserver);
</ins><span class="cx"> 
</span><span class="cx">     // Enable agents.
</span><span class="cx">     if (window.InspectorAgent)
</span><span class="lines">@@ -110,6 +112,7 @@
</span><span class="cx">     this.dashboardManager = new WebInspector.DashboardManager;
</span><span class="cx">     this.probeManager = new WebInspector.ProbeManager;
</span><span class="cx">     this.replayManager = new WebInspector.ReplayManager;
</span><ins>+    this.canvasManager = new WebInspector.CanvasManager;
</ins><span class="cx"> 
</span><span class="cx">     // Enable the Console Agent after creating the singleton managers.
</span><span class="cx">     if (window.ConsoleAgent)
</span><span class="lines">@@ -383,7 +386,8 @@
</span><span class="cx"> WebInspector.sidebarPanelForRepresentedObject = function(representedObject)
</span><span class="cx"> {
</span><span class="cx">     if (representedObject instanceof WebInspector.Frame || representedObject instanceof WebInspector.Resource ||
</span><del>-        representedObject instanceof WebInspector.Script || representedObject instanceof WebInspector.ContentFlow)
</del><ins>+        representedObject instanceof WebInspector.Script || representedObject instanceof WebInspector.ContentFlow ||
+        representedObject instanceof WebInspector.Canvas || representedObject instanceof WebInspector.ShaderProgram)
</ins><span class="cx">         return this.resourceSidebarPanel;
</span><span class="cx"> 
</span><span class="cx">     if (representedObject instanceof WebInspector.DOMStorageObject || representedObject instanceof WebInspector.CookieStorageObject ||
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceBaseTestjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Test.js (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Base/Test.js        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Test.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx">     InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeObserver);
</span><span class="cx">     if (InspectorBackend.registerReplayDispatcher)
</span><span class="cx">         InspectorBackend.registerReplayDispatcher(new WebInspector.ReplayObserver);
</span><ins>+    InspectorBackend.registerCanvasDispatcher(new WebInspector.CanvasObserver);
</ins><span class="cx"> 
</span><span class="cx">     // Instantiate controllers used by tests.
</span><span class="cx">     this.frameResourceManager = new WebInspector.FrameResourceManager;
</span><span class="lines">@@ -55,6 +56,7 @@
</span><span class="cx">     this.debuggerManager = new WebInspector.DebuggerManager;
</span><span class="cx">     this.probeManager = new WebInspector.ProbeManager;
</span><span class="cx">     this.replayManager = new WebInspector.ReplayManager;
</span><ins>+    this.canvasManager = new WebInspector.CanvasManager;
</ins><span class="cx"> 
</span><span class="cx">     // Global controllers.
</span><span class="cx">     this.quickConsole = {executionContextIdentifier: undefined};
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersCanvasManagerjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,162 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.CanvasManager = class CanvasManager extends WebInspector.Object
+{
+    constructor()
+    {
+        super();
+
+        WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
+
+        this._waitingForCanvasesPayload = false;
+        this._canvasIdMap = new Map;
+
+        this._initialize();
+    }
+
+    canvasesForFrame(frame)
+    {
+        if (this._waitingForCanvasesPayload)
+            return [];
+
+        var canvases = [];
+        for (var canvas of this._canvasIdMap.values()) {
+            if (canvas.parentFrame.id === frame.id)
+                canvases.push(canvas);
+        }
+        return canvases;
+    }
+
+    canvasAdded(canvasPayload)
+    {
+        // Called from WebInspector.CanvasObserver.
+        console.assert(!this._canvasIdMap.has(canvasPayload.canvasId));
+        var canvas = WebInspector.Canvas.fromPayload(canvasPayload);
+
+        this._canvasIdMap.set(canvas.id, canvas);
+        this.dispatchEventToListeners(WebInspector.CanvasManager.Event.CanvasWasAdded, {canvas: canvas});
+    }
+
+    canvasRemoved(canvasIdentifier)
+    {
+        // Called from WebInspector.CanvasObserver.
+
+        console.assert(this._canvasIdMap.has(canvasIdentifier));
+        if (!this._canvasIdMap.has(canvasIdentifier))
+            return;
+
+        var canvas = this._canvasIdMap.take(canvasIdentifier);
+        this.dispatchEventToListeners(WebInspector.CanvasManager.Event.CanvasWasRemoved, {canvas: canvas});
+    }
+
+    programCreated(programIdentifier)
+    {
+        // Called from WebInspector.CanvasObserver.
+
+        var canvas = this._canvasIdMap.get(programIdentifier.canvasId);
+        console.assert(canvas);
+        if (!canvas)
+            return;
+
+        canvas.programWasCreated(new WebInspector.ShaderProgram(programIdentifier, canvas));
+    }
+
+    programDeleted(programIdentifier)
+    {
+        // Called from WebInspector.CanvasObserver.
+
+        var canvas = this._canvasIdMap.get(programIdentifier.canvasId);
+        console.assert(canvas);
+        if (!canvas)
+            return;
+
+        canvas.programWasDeleted(programIdentifier);
+    }
+
+    // Private
+
+    _getCanvasesForFrameId(frameIdentifier)
+    {
+        var canvases = [];
+        for (var canvas of this._canvasIdMap.values()) {
+            if (canvas.parentFrame.id === frameIdentifier)
+                canvases.push(canvas);
+        }
+        return canvases;
+    }
+
+    _initialize()
+    {
+        if (!window.CanvasAgent)
+            return;
+
+        for (var canvas of this._canvasIdMap.values())
+            this.dispatchEventToListeners(WebInspector.CanvasManager.Event.CanvasWasRemoved, {canvas: canvas});
+
+        WebInspector.Canvas.resetUniqueDisplayNameNumbers();
+
+        this._canvasIdMap.clear();
+        this._waitingForCanvasesPayload = true;
+
+        CanvasAgent.getCanvases(this._processCanvasesPayload.bind(this));
+    }
+
+    _mainResourceDidChange(event)
+    {
+        console.assert(event.target instanceof WebInspector.Frame);
+
+        if (!event.target.isMainFrame())
+            return;
+
+        this._initialize();
+    }
+
+    _processCanvasesPayload(error, canvasArrayPayload)
+    {
+        console.assert(this._waitingForCanvasesPayload);
+        this._waitingForCanvasesPayload = false;
+
+        if (error) {
+            console.error(JSON.stringify(error));
+            return;
+        }
+
+        for (var canvasPayload of canvasArrayPayload) {
+            if (!this._canvasIdMap.has(canvasPayload.canvasId)) {
+                var canvas = WebInspector.Canvas.fromPayload(canvasPayload);
+                this._canvasIdMap.set(canvas.id, canvas);
+            }
+        }
+
+        this.dispatchEventToListeners(WebInspector.CanvasManager.Event.CanvasesAvailable);
+    }
+};
+
+WebInspector.CanvasManager.Event = {
+    CanvasesAvailable: &quot;canvas-manager-canvases-available&quot;,
+    CanvasWasAdded: &quot;canvas-manager-canvas-was-added&quot;,
+    CanvasWasRemoved: &quot;canvas-manager-canvas-was-removed&quot;
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceImagesCanvassvg"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Images/Canvas.svg (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Images/Canvas.svg                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Images/Canvas.svg        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+&lt;!-- Copyright © 2015 Apple Inc. All rights reserved. --&gt;
+&lt;svg viewBox=&quot;0 0 14 16&quot; version=&quot;1.1&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot;&gt;
+    &lt;path d=&quot;M 0.5 4.29857047 L 7.09714095 7.59714095 L 7.09714095 15.0189245 L 0.5 11.720354 L 0.5 4.29857047 Z&quot; stroke=&quot;white&quot; stroke-width=&quot;0.5&quot; stroke-linecap=&quot;square&quot; stroke-linejoin=&quot;round&quot; fill=&quot;rgb(92, 140, 229)&quot;/&gt;
+    &lt;path d=&quot;M 13.697 4.299 L 7.097 7.597 L 7.097 15.019 L 13.697 11.72 L 13.697 4.299 Z&quot; stroke=&quot;white&quot; stroke-width=&quot;0.5&quot; stroke-linecap=&quot;square&quot; stroke-linejoin=&quot;round&quot; fill=&quot;rgb(242, 97, 97)&quot;/&gt;
+    &lt;path d=&quot;M 0.5 4.29857047 L 7.09714095 1 L 13.6908901 4.29857047 L 7.09714095 7.59714095 L 0.5 4.29857047 Z&quot; stroke=&quot;white&quot; stroke-width=&quot;0.5&quot; stroke-linejoin=&quot;round&quot; fill=&quot;rgb(97, 242, 97)&quot;/&gt;
+&lt;/svg&gt;
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceImagesDocumentGLpng"></a>
<div class="binary"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Images/DocumentGL.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Property changes on: trunk/Source/WebInspectorUI/UserInterface/Images/DocumentGL.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="trunkSourceWebInspectorUIUserInterfaceImagesDocumentGL2xpng"></a>
<div class="binary"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Images/DocumentGL@2x.png</h4>
<pre class="diff"><span>
<span class="cx">(Binary files differ)
</span></span></pre></div>
<span class="cx">Property changes on: trunk/Source/WebInspectorUI/UserInterface/Images/DocumentGL@2x.png
</span><span class="cx">___________________________________________________________________
</span><a id="svnmimetype"></a>
<div class="addfile"><h4>Added: svn:mime-type</h4></div>
<a id="trunkSourceWebInspectorUIUserInterfaceMainhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -188,6 +188,7 @@
</span><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;Protocol/ApplicationCacheObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/CSSObserver.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Protocol/CanvasObserver.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Protocol/ConsoleObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/DOMObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/DOMStorageObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -227,6 +228,7 @@
</span><span class="cx">     &lt;script src=&quot;Models/CSSStyleDeclaration.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CSSStyleSheet.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CallFrame.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/Canvas.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Models/CollectionEntry.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CollectionEntryPreview.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/Color.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -281,6 +283,7 @@
</span><span class="cx">     &lt;script src=&quot;Models/ScriptSyntaxTree.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/ScriptTimelineRecord.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/Setting.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/ShaderProgram.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Models/SourceCodePosition.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/SourceCodeRevision.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/SourceCodeSearchMatchObject.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -294,6 +297,7 @@
</span><span class="cx">     &lt;script src=&quot;Models/TimelineRecording.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/TypeSet.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/UnitBezier.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/WebGLContextAttributes.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;Views/LegacyConsoleMessage.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/ContentView.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -324,6 +328,7 @@
</span><span class="cx">     &lt;script src=&quot;Views/ObjectTreeBaseTreeElement.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/FolderTreeElement.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/FolderizedTreeElement.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Views/ShaderProgramTreeElement.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Views/SourceCodeTreeElement.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/StorageTreeElement.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/TimelineRecordTreeElement.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -344,6 +349,7 @@
</span><span class="cx">     &lt;script src=&quot;Views/CSSStyleDeclarationTextEditor.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/CSSStyleDetailsSidebarPanel.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/CallFrameTreeElement.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Views/CanvasTreeElement.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Views/ClusterContentView.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/CodeMirrorAdditions.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Views/CodeMirrorFormatters.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -496,6 +502,7 @@
</span><span class="cx">     &lt;script src=&quot;Controllers/BasicBlockAnnotator.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/BranchManager.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/CSSStyleManager.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Controllers/CanvasManager.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Controllers/CodeMirrorColorEditingController.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/CodeMirrorCompletionController.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/CodeMirrorDragToAdjustNumberController.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsCanvasjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Models/Canvas.js (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/Canvas.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Canvas.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,196 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.Canvas = class Canvas extends WebInspector.Object
+{
+    constructor(id, parentFrame, name, cssCanvas, contextType, contextAttributes, programs)
+    {
+        super();
+
+        console.assert(id);
+        console.assert(parentFrame);
+        console.assert(contextType);
+        console.assert(this._contextType !== WebInspector.Canvas.ContextType.WebGL || contextAttributes);
+
+        this._id = id;
+        this._parentFrame = parentFrame;
+        this._name = name;
+        this._cssCanvas = cssCanvas;
+        this._contextType = contextType;
+        this._contextAttributes = contextAttributes;
+        this._programs = new Map;
+
+        if (programs) {
+            for (var program of programs) {
+                program.updateCanvas(this);
+                this._programs.set(program.id.objectId, program);
+            }
+        }
+    }
+
+    // Static
+
+    static fromPayload(payload)
+    {
+        var parentFrame = WebInspector.frameResourceManager.frameForIdentifier(payload.frameId);
+        var contextType = null;
+        switch (payload.contextType) {
+            case CanvasAgent.ContextType.Canvas2D:
+                contextType = WebInspector.Canvas.ContextType.Canvas2D;
+                break;
+            case CanvasAgent.ContextType.WebGL:
+                contextType = WebInspector.Canvas.ContextType.WebGL;
+                break;
+            default:
+                console.error(&quot;Invalid canvas context type&quot;, payload.contextType);
+        }
+
+        var programs = [];
+        for (var programId of payload.programIds)
+            programs.push(new WebInspector.ShaderProgram(programId));
+
+        var contextAttributes = null;
+        if (payload.contextAttributes) {
+            console.assert(contextType === WebInspector.Canvas.ContextType.WebGL);
+            contextAttributes = WebInspector.WebGLContextAttributes.fromPayload(payload.contextAttributes);
+        }
+
+        return new WebInspector.Canvas(payload.canvasId, parentFrame, payload.name, payload.cssCanvas, contextType, contextAttributes, programs);
+    }
+
+    static displayNameForContextType(contextType)
+    {
+        switch (contextType) {
+            case WebInspector.Canvas.ContextType.Canvas2D:
+                return WebInspector.UIString(&quot;2D&quot;);
+            case WebInspector.Canvas.ContextType.WebGL:
+                return WebInspector.UIString(&quot;WebGL&quot;);
+            default:
+                console.error(&quot;Invalid canvas context type&quot;, contextType);
+        }
+    }
+
+    static resetUniqueDisplayNameNumbers()
+    {
+        WebInspector.Canvas._nextUniqueDisplayNameNumber = 1;
+    }
+
+    // Public
+
+    get id()
+    {
+        return this._id;
+    }
+
+    get parentFrame()
+    {
+        return this._parentFrame;
+    }
+
+    get name()
+    {
+        return this._name;
+    }
+
+    get cssCanvas()
+    {
+        return this._cssCanvas;
+    }
+
+    get contextType()
+    {
+        return this._contextType;
+    }
+
+    get contextAttributes()
+    {
+        return this._contextAttributes;
+    }
+
+    get programs()
+    {
+        var programs = [];
+        for (var program of this._programs.values())
+            programs.push(program);
+        return programs;
+    }
+
+    get displayName()
+    {
+        if (this._cssCanvas)
+            return WebInspector.UIString(&quot;CSS canvas “%s”&quot;).format(this._name);
+
+        if (this._name)
+            return WebInspector.UIString(&quot;Canvas #%s&quot;).format(this._name);
+
+        if (!this._uniqueDisplayNameNumber)
+            this._uniqueDisplayNameNumber = this.constructor._nextUniqueDisplayNameNumber++;
+        return WebInspector.UIString(&quot;Canvas %d&quot;).format(this._uniqueDisplayNameNumber);
+    }
+
+    programForId(programIdentifier)
+    {
+        return this._programs.get(programIdentifier.objectId);
+    }
+
+    programWasCreated(program)
+    {
+        console.assert(!this._programs.has(program.id.objectId));
+        this._programs.set(program.id.objectId, program);
+
+        this.dispatchEventToListeners(WebInspector.Canvas.Event.ProgramWasCreated, {program: program});
+    }
+
+    programWasDeleted(programIdentifier)
+    {
+        var program = this._programs.take(programIdentifier.objectId);
+        console.assert(program);
+
+        this.dispatchEventToListeners(WebInspector.Canvas.Event.ProgramWasDeleted, {program: program});
+    }
+
+    saveIdentityToCookie(cookie)
+    {
+        cookie[WebInspector.Canvas.FrameURLCookieKey] = this.parentFrame.url.hash;
+        cookie[WebInspector.Canvas.CSSCanvasCookieKey] = this._cssCanvas;
+        cookie[WebInspector.Canvas.NameCookieKey] = this._name;
+    }
+};
+
+WebInspector.Canvas.Event = {
+    ProgramWasCreated: &quot;canvas-program-was-created&quot;,
+    ProgramWasDeleted: &quot;canvas-program-was-deleted&quot;,
+};
+
+WebInspector.Canvas.ContextType = {
+    Canvas2D: Symbol(&quot;canvas-context-type-canvas-2d&quot;),
+    WebGL: Symbol(&quot;canvas-context-type-webgl&quot;),
+};
+
+WebInspector.Canvas._nextUniqueDisplayNameNumber = 1;
+
+WebInspector.Canvas.FrameURLCookieKey = &quot;canvas-frame-url&quot;;
+WebInspector.Canvas.CSSCanvasCookieKey = &quot;canvas-css-canvas&quot;;
+WebInspector.Canvas.NameCookieKey = &quot;canvas-name&quot;;
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsShaderProgramjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Models/ShaderProgram.js (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/ShaderProgram.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ShaderProgram.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ShaderProgram = class ShaderProgram extends WebInspector.Object
+{
+    constructor(id, canvas)
+    {
+        super();
+
+        this._id = id;
+        this._canvas = canvas || null;
+    }
+
+    // Public
+
+    get id()
+    {
+        return this._id;
+    }
+
+    get canvas()
+    {
+        return this._canvas;
+    }
+
+    get displayName()
+    {
+        return WebInspector.UIString(&quot;Program %d&quot;).format(this._id.objectId);
+    }
+
+    saveIdentityToCookie(cookie)
+    {
+        cookie[WebInspector.ShaderProgram.FrameURLCookieKey] = this.canvas.parentFrame.url.hash;
+        cookie[WebInspector.ShaderProgram.CanvasNameKey] = this.canvas.name.hash;
+        cookie[WebInspector.ShaderProgram.IDCookieKey] = this._id;
+    }
+
+    updateCanvas(canvas)
+    {
+        // Called by canvas.
+
+        console.assert(!this._canvas);
+        this._canvas = canvas;
+    }
+};
+
+WebInspector.ShaderProgram.FrameURLCookieKey = &quot;shader-program-url&quot;;
+WebInspector.ShaderProgram.CanvasNameKey = &quot;shader-program-canvas-name&quot;;
+WebInspector.ShaderProgram.IDCookieKey = &quot;shader-program-id&quot;;
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsWebGLContextAttributesjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Models/WebGLContextAttributes.js (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/WebGLContextAttributes.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/WebGLContextAttributes.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.WebGLContextAttributes = class WebGLContextAttributes extends WebInspector.Object
+{
+    constructor(alpha, depth, stencil, antialias, premultipliedAlpha, preserveDrawingBuffer)
+    {
+        super();
+
+        this._alpha = alpha;
+        this._depth = depth;
+        this._stencil = stencil;
+        this._antialias = antialias;
+        this._premultipliedAlpha = premultipliedAlpha;
+        this._preserveDrawingBuffer = preserveDrawingBuffer;
+    }
+
+    // Static
+
+    static fromPayload(payload)
+    {
+        console.assert(payload);
+        return new WebInspector.WebGLContextAttributes(payload.alpha, payload.depth, payload.stencil, payload.antialias, payload.premultipliedAlpha, payload.preserveDrawingBuffer);
+    }
+
+    // Public
+
+    get alpha()
+    {
+        return this._alpha;
+    }
+
+    get depth()
+    {
+        return this._depth;
+    }
+
+    get stencil()
+    {
+        return this._stencil;
+    }
+
+    get antialias()
+    {
+        return this._antialias;
+    }
+
+    get premultipliedAlpha()
+    {
+        return this._premultipliedAlpha;
+    }
+
+    get preserveDrawingBuffer()
+    {
+        return this._preserveDrawingBuffer;
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolCanvasObserverjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/CanvasObserver.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.CanvasObserver = class CanvasObserver
+{
+    // Events defined by the &quot;Canvas&quot; domain.
+
+    canvasAdded(canvas)
+    {
+        WebInspector.canvasManager.canvasAdded(canvas);
+    }
+
+    canvasRemoved(canvasId)
+    {
+        WebInspector.canvasManager.canvasRemoved(canvasId);
+    }
+
+    programCreated(programId)
+    {
+        WebInspector.canvasManager.programCreated(programId);
+    }
+
+    programDeleted(programId)
+    {
+        WebInspector.canvasManager.programDeleted(programId);
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTesthtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Test.html        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;Protocol/InspectorObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/CSSObserver.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Protocol/CanvasObserver.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Protocol/DOMObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/DOMStorageObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Protocol/DebuggerObserver.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -75,6 +76,7 @@
</span><span class="cx">     &lt;script src=&quot;Models/CSSStyleDeclaration.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CSSStyleSheet.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/CallFrame.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/Canvas.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Models/CollectionEntry.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/Color.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/ContentFlow.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -115,6 +117,7 @@
</span><span class="cx">     &lt;script src=&quot;Models/ScriptSyntaxTree.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/ScriptTimelineRecord.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/Setting.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/ShaderProgram.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Models/SourceCodeLocation.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/SourceCodeRevision.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/SourceCodeTimeline.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -122,8 +125,10 @@
</span><span class="cx">     &lt;script src=&quot;Models/TextRange.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/TimelineMarker.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Models/TimelineRecording.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Models/WebGLContextAttributes.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;Controllers/CSSStyleManager.js&quot;&gt;&lt;/script&gt;
</span><ins>+    &lt;script src=&quot;Controllers/CanvasManager.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;script src=&quot;Controllers/DOMTreeManager.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/DebuggerManager.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Controllers/FrameResourceManager.js&quot;&gt;&lt;/script&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsCanvasTreeElementjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CanvasTreeElement.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.CanvasTreeElement = class CanvasTreeElement extends WebInspector.FolderizedTreeElement
+{
+    constructor(canvas)
+    {
+        super(&quot;canvas-icon&quot;, canvas.displayName, null, canvas, false);
+
+        console.assert(canvas instanceof WebInspector.Canvas);
+
+        this.small = true;
+        this.folderSettingsKey = canvas.parentFrame.url.hash + canvas.displayName.hash;
+
+        this._expandedSetting = new WebInspector.Setting(&quot;canvas-expanded-&quot; + this.folderSettingsKey, false);
+        if (this._expandedSetting.value)
+            this.expand();
+        else
+            this.collapse();
+
+        canvas.addEventListener(WebInspector.Canvas.Event.ProgramWasCreated, this._programWasCreated, this);
+        canvas.addEventListener(WebInspector.Canvas.Event.ProgramWasDeleted, this._programWasDeleted, this);
+
+        function validateRepresentedObject(representedObject) {
+            return representedObject instanceof WebInspector.ShaderProgram;
+        }
+
+        function countChildren() {
+            return canvas.programs.length;
+        }
+
+        this.registerFolderizeSettings(&quot;programs&quot;, WebInspector.UIString(&quot;Programs&quot;), validateRepresentedObject, countChildren.bind(this), WebInspector.ShaderProgramTreeElement);
+        this.updateParentStatus();
+    }
+
+    // Overrides from TreeElement (Protected).
+
+    onexpand()
+    {
+        this._expandedSetting.value = true;
+    }
+
+    oncollapse()
+    {
+        // Only store the setting if we have children, since setting hasChildren to false will cause a collapse,
+        // and we only care about user triggered collapses.
+        if (this.hasChildren)
+            this._expandedSetting.value = false;
+    }
+
+    onpopulate()
+    {
+        if (this.children.length &amp;&amp; !this.shouldRefreshChildren)
+            return;
+
+        this.shouldRefreshChildren = false;
+
+        this.removeChildren();
+
+        for (var program of this.representedObject.programs)
+            this.addChildForRepresentedObject(program);
+    }
+
+    // Private
+
+    _programWasCreated(event)
+    {
+        this.addRepresentedObjectToNewChildQueue(event.data.program);
+    }
+
+    _programWasDeleted(event)
+    {
+        this.removeChildForRepresentedObject(event.data.program);
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsFrameTreeElementjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/FrameTreeElement.js (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/FrameTreeElement.js        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/FrameTreeElement.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -63,6 +63,12 @@
</span><span class="cx">             WebInspector.ContentFlowTreeElement
</span><span class="cx">         );
</span><span class="cx"> 
</span><ins>+        this.registerFolderizeSettings(&quot;canvases&quot;, WebInspector.UIString(&quot;Canvases&quot;),
+            function(representedObject) { return representedObject instanceof WebInspector.Canvas; },
+            function() { return WebInspector.canvasManager.canvasesForFrame(this._frame).length; }.bind(this),
+            WebInspector.CanvasTreeElement
+        );
+
</ins><span class="cx">         function makeValidateCallback(resourceType) {
</span><span class="cx">             return function(representedObject) {
</span><span class="cx">                 return representedObject instanceof WebInspector.Resource &amp;&amp; representedObject.type === resourceType;
</span><span class="lines">@@ -136,6 +142,10 @@
</span><span class="cx">         // Immediate superclasses are skipped, since Frames handle their own SourceMapResources.
</span><span class="cx">         WebInspector.GeneralTreeElement.prototype.onattach.call(this);
</span><span class="cx"> 
</span><ins>+        WebInspector.canvasManager.addEventListener(WebInspector.CanvasManager.Event.CanvasesAvailable, this._canvasesAvailable, this);
+        WebInspector.canvasManager.addEventListener(WebInspector.CanvasManager.Event.CanvasWasAdded, this._canvasWasAdded, this);
+        WebInspector.canvasManager.addEventListener(WebInspector.CanvasManager.Event.CanvasWasRemoved, this._canvasWasRemoved, this);
+
</ins><span class="cx">         if (this._frame.isMainFrame()) {
</span><span class="cx">             WebInspector.notifications.addEventListener(WebInspector.Notification.PageArchiveStarted, this._pageArchiveStarted, this);
</span><span class="cx">             WebInspector.notifications.addEventListener(WebInspector.Notification.PageArchiveEnded, this._pageArchiveEnded, this);
</span><span class="lines">@@ -146,6 +156,10 @@
</span><span class="cx">     {
</span><span class="cx">         WebInspector.ResourceTreeElement.prototype.ondetach.call(this);
</span><span class="cx"> 
</span><ins>+        WebInspector.canvasManager.removeEventListener(WebInspector.CanvasManager.Event.CanvasesAvailable, this._canvasesAvailable, this);
+        WebInspector.canvasManager.removeEventListener(WebInspector.CanvasManager.Event.CanvasWasAdded, this._canvasWasAdded, this);
+        WebInspector.canvasManager.removeEventListener(WebInspector.CanvasManager.Event.CanvasWasRemoved, this._canvasWasRemoved, this);
+
</ins><span class="cx">         if (this._frame.isMainFrame()) {
</span><span class="cx">             WebInspector.notifications.removeEventListener(WebInspector.Notification.PageArchiveStarted, this._pageArchiveStarted, this);
</span><span class="cx">             WebInspector.notifications.removeEventListener(WebInspector.Notification.PageArchiveEnded, this._pageArchiveEnded, this);
</span><span class="lines">@@ -250,8 +264,11 @@
</span><span class="cx">         for (var flowKey in flowMap)
</span><span class="cx">             this.addChildForRepresentedObject(flowMap[flowKey]);
</span><span class="cx"> 
</span><ins>+        var canvases = WebInspector.canvasManager.canvasesForFrame(this._frame);
+        for (var canvas of canvases)
+            this.addChildForRepresentedObject(canvas);
</ins><span class="cx">     }
</span><del>-
</del><ins>+        
</ins><span class="cx">     onexpand()
</span><span class="cx">     {
</span><span class="cx">         this._expandedSetting.value = true;
</span><span class="lines">@@ -324,6 +341,28 @@
</span><span class="cx">         this.removeChildForRepresentedObject(event.data.flow);
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    _canvasesAvailable(event)
+    {
+        this.updateParentStatus();
+        this.removeChildren();
+
+        this.shouldRefreshChildren = true;
+    }
+
+    _canvasWasAdded(event)
+    {
+        var canvas = event.data.canvas;
+        if (canvas.parentFrame == this._frame)
+            this.addRepresentedObjectToNewChildQueue(canvas);
+    }
+
+    _canvasWasRemoved(event)
+    {
+        var canvas = event.data.canvas;
+        if (canvas.parentFrame == this._frame)
+            this.removeChildForRepresentedObject(canvas);
+    }
+
</ins><span class="cx">     _rootDOMNodeInvalidated()
</span><span class="cx">     {
</span><span class="cx">         if (this.expanded)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsResourceIconscss"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceIcons.css        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -51,6 +51,14 @@
</span><span class="cx">     content: -webkit-image-set(url(../Images/ClippingJS.png) 1x, url(../Images/ClippingJS@2x.png) 2x);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+.canvas-icon .icon {
+    content: url(../Images/Canvas.svg);
+}
+
+.shader-program-icon .icon {
+    content: -webkit-image-set(url(../Images/DocumentGL.png) 1x, url(../Images/DocumentGL@2x.png) 2x);
+}
+
</ins><span class="cx"> .source-map-resource.resource-icon .icon {
</span><span class="cx">     content: -webkit-image-set(url(../Images/ClippingGeneric.png) 1x, url(../Images/ClippingGeneric@2x.png) 2x);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsResourceSidebarPaneljs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSidebarPanel.js (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSidebarPanel.js        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSidebarPanel.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -774,6 +774,7 @@
</span><span class="cx">         if (treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.ScriptTreeElement ||
</span><span class="cx">             treeElement instanceof WebInspector.StorageTreeElement || treeElement instanceof WebInspector.DatabaseTableTreeElement ||
</span><span class="cx">             treeElement instanceof WebInspector.DatabaseTreeElement || treeElement instanceof WebInspector.ApplicationCacheFrameTreeElement ||
</span><ins>+            treeElement instanceof WebInspector.CanvasTreeElement || treeElement instanceof WebInspector.ShaderProgramTreeElement ||
</ins><span class="cx">             treeElement instanceof WebInspector.ContentFlowTreeElement || treeElement instanceof WebInspector.IndexedDatabaseObjectStoreTreeElement ||
</span><span class="cx">             treeElement instanceof WebInspector.IndexedDatabaseObjectStoreIndexTreeElement) {
</span><span class="cx">             WebInspector.contentBrowser.showContentViewForRepresentedObject(treeElement.representedObject);
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsShaderProgramTreeElementjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Views/ShaderProgramTreeElement.js (0 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/ShaderProgramTreeElement.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ShaderProgramTreeElement.js        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WebInspector.ShaderProgramTreeElement = class ShaderProgramTreeElement extends WebInspector.GeneralTreeElement
+{
+    constructor(program)
+    {
+        super(&quot;shader-program-icon&quot;, program.displayName, null, program, false);
+
+        console.assert(program instanceof WebInspector.ShaderProgram);
+
+        this.small = true;
+    }
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIWebInspectorUIvcxprojWebInspectorUIvcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -292,11 +292,14 @@
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\CallFrame.js&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\CallFrameIcons.css&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\CallFrameTreeElement.js&quot; /&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\Canvas.js&quot; /&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\CanvasDataGridNode.js&quot; /&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\CanvasManager.js&quot; /&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\CanvasObserver.js&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\CanvasProfileObject.js&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\CanvasProfileType.js&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\CanvasProfileView.js&quot; /&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\CanvasTreeElement.js&quot; /&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\ClusterContentView.css&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\ClusterContentView.js&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\CodeMirrorAdditions.js&quot; /&gt;
</span><span class="lines">@@ -473,6 +476,7 @@
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\BreakpointInactive.png&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\BreakpointInactiveButton.svg&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\Breakpoints.svg&quot; /&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\Images\Canvas.svg&quot; /&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\ClippingCSS%402x.png&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\ClippingCSS.png&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\ClippingGeneric%402x.png&quot; /&gt;
</span><span class="lines">@@ -631,6 +635,8 @@
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\Script.png&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\SessionStorage%402x.png&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\SessionStorage.png&quot; /&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\Images\ShaderProgram%402x.png&quot; /&gt;
+    &lt;None Include=&quot;..\UserInterface\Images\ShaderProgram.png&quot; /&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\ShadowDOM.svg&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\SortIndicatorDownArrow.svg&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\SortIndicatorUpArrow.svg&quot; /&gt;
</span><span class="lines">@@ -773,6 +779,8 @@
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Section.css&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Section.js&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Setting.js&quot; /&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\ShaderProgram.js&quot; /&gt;
+    &lt;None Include=&quot;..\UserInterface\ShaderProgramTreeElement.js&quot; /&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\Sidebar.css&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Sidebar.js&quot; /&gt;
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\SidebarPanel.css&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIWebInspectorUIvcxprojWebInspectorUIvcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters (182185 => 182186)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters        2015-03-31 17:17:07 UTC (rev 182185)
+++ trunk/Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters        2015-03-31 17:23:12 UTC (rev 182186)
</span><span class="lines">@@ -126,9 +126,15 @@
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\CallFrameTreeElement.js&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;UserInterface&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\Canvas.js&quot;&gt;
+      &lt;Filter&gt;UserInterface&lt;/Filter&gt;
+    &lt;/None&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\CanvasDataGridNode.js&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;UserInterface&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\CanvasManager.js&quot;&gt;
+      &lt;Filter&gt;UserInterface&lt;/Filter&gt;
+    &lt;/None&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\CanvasObserver.js&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;UserInterface&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><span class="lines">@@ -141,6 +147,9 @@
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\CanvasProfileView.js&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;UserInterface&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\CanvasTreeElement.js&quot;&gt;
+      &lt;Filter&gt;UserInterface&lt;/Filter&gt;
+    &lt;/None&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\ClusterContentView.css&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;UserInterface&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><span class="lines">@@ -891,6 +900,12 @@
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Setting.js&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;UserInterface&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\ShaderProgram.js&quot;&gt;
+      &lt;Filter&gt;UserInterface&lt;/Filter&gt;
+    &lt;/None&gt;
+    &lt;None Include=&quot;..\UserInterface\ShaderProgramTreeElement.js&quot;&gt;
+      &lt;Filter&gt;UserInterface&lt;/Filter&gt;
+    &lt;/None&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\Sidebar.css&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;UserInterface&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><span class="lines">@@ -1164,6 +1179,9 @@
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\Breakpoints.svg&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;Images&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\Images\Canvas.svg&quot;&gt;
+      &lt;Filter&gt;Images&lt;/Filter&gt;
+    &lt;/None&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\ClippingCSS.png&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;Images&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><span class="lines">@@ -1626,6 +1644,12 @@
</span><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\SessionStorage%402x.png&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;Images&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span><ins>+    &lt;None Include=&quot;..\UserInterface\Images\ShaderProgram%402x.png&quot;&gt;
+      &lt;Filter&gt;Images&lt;/Filter&gt;
+    &lt;/None&gt;
+    &lt;None Include=&quot;..\UserInterface\Images\ShaderProgram.png&quot;&gt;
+      &lt;Filter&gt;Images&lt;/Filter&gt;
+    &lt;/None&gt;
</ins><span class="cx">     &lt;None Include=&quot;..\UserInterface\Images\ShadowDOM.svg&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;Images&lt;/Filter&gt;
</span><span class="cx">     &lt;/None&gt;
</span></span></pre>
</div>
</div>

</body>
</html>