Skip to content
Permalink
Browse files
Web Inspector: [Canvas] use timeline's didBeginFrame for marking fram…
…e end calls

https://bugs.webkit.org/show_bug.cgi?id=110130

Reviewed by Pavel Feldman.

In Web Inspector canvas profiler use timeline's didBeginFrame for marking frame end calls instead of an ad-hoc timeout-based solution.

* inspector/InjectedScriptCanvasModule.cpp:
(WebCore::InjectedScriptCanvasModule::markFrameEnd):
(WebCore):
* inspector/InjectedScriptCanvasModule.h:
(InjectedScriptCanvasModule):
* inspector/InjectedScriptCanvasModuleSource.js:
(.):
* inspector/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::hasUninstrumentedCanvases):
(WebCore::InspectorCanvasAgent::notifyRenderingContextWasWrapped):
(WebCore::InspectorCanvasAgent::findFramesWithUninstrumentedCanvases):
(WebCore::InspectorCanvasAgent::frameNavigated):
(WebCore::InspectorCanvasAgent::didBeginFrame):
(WebCore):
* inspector/InspectorCanvasAgent.h:
(InspectorCanvasAgent):
* inspector/InspectorController.cpp:
(WebCore::InspectorController::didBeginFrame):

Canonical link: https://commits.webkit.org/128515@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@143328 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Andrey Adaykin committed Feb 19, 2013
1 parent 35a7707 commit 4b98362b1dc702c491998510335aa3a1b63e6a8c
Showing 7 changed files with 81 additions and 55 deletions.
@@ -1,3 +1,31 @@
2013-02-19 Andrey Adaikin <aandrey@chromium.org>

Web Inspector: [Canvas] use timeline's didBeginFrame for marking frame end calls
https://bugs.webkit.org/show_bug.cgi?id=110130

Reviewed by Pavel Feldman.

In Web Inspector canvas profiler use timeline's didBeginFrame for marking frame end calls instead of an ad-hoc timeout-based solution.

* inspector/InjectedScriptCanvasModule.cpp:
(WebCore::InjectedScriptCanvasModule::markFrameEnd):
(WebCore):
* inspector/InjectedScriptCanvasModule.h:
(InjectedScriptCanvasModule):
* inspector/InjectedScriptCanvasModuleSource.js:
(.):
* inspector/InspectorCanvasAgent.cpp:
(WebCore::InspectorCanvasAgent::hasUninstrumentedCanvases):
(WebCore::InspectorCanvasAgent::notifyRenderingContextWasWrapped):
(WebCore::InspectorCanvasAgent::findFramesWithUninstrumentedCanvases):
(WebCore::InspectorCanvasAgent::frameNavigated):
(WebCore::InspectorCanvasAgent::didBeginFrame):
(WebCore):
* inspector/InspectorCanvasAgent.h:
(InspectorCanvasAgent):
* inspector/InspectorController.cpp:
(WebCore::InspectorController::didBeginFrame):

2013-02-19 Vsevolod Vlasov <vsevik@chromium.org>

Web Inspector: Decouple various file system project implementation parts for better testability and cover with tests.
@@ -91,6 +91,14 @@ ScriptObject InjectedScriptCanvasModule::callWrapContextFunction(const String& f
return ScriptObject(context.scriptState(), resultValue);
}

void InjectedScriptCanvasModule::markFrameEnd()
{
ScriptFunctionCall function(injectedScriptObject(), "markFrameEnd");
RefPtr<InspectorValue> resultValue;
makeCall(function, &resultValue);
ASSERT(resultValue);
}

void InjectedScriptCanvasModule::captureFrame(ErrorString* errorString, TraceLogId* traceLogId)
{
callStartCapturingFunction("captureFrame", errorString, traceLogId);
@@ -54,6 +54,7 @@ class InjectedScriptCanvasModule : public InjectedScriptModule {
#if ENABLE(WEBGL)
ScriptObject wrapWebGLContext(const ScriptObject&);
#endif
void markFrameEnd();

void captureFrame(ErrorString*, TypeBuilder::Canvas::TraceLogId*);
void startCapturing(ErrorString*, TypeBuilder::Canvas::TraceLogId*);
@@ -2864,45 +2864,6 @@ TraceLogPlayer.prototype = {
}
}

/**
* @constructor
* @param {function()} callback
*/
function ZeroTimeoutCallback(callback)
{
this._callback = callback;
this._scheduled = false;
}

ZeroTimeoutCallback.prototype = {
schedule: function()
{
if (this._scheduled)
return;
this._scheduled = true;
var callback = this._onCallback.bind(this);
// We need a fastest async callback, whatever fires first.
// Usually a postMessage should be faster than a setTimeout(0).
var channel = new MessageChannel();
channel.port1.onmessage = callback;
channel.port2.postMessage("");
inspectedWindow.setTimeout(callback, 0);
},

cancel: function()
{
this._scheduled = false;
},

_onCallback: function()
{
if (!this._scheduled)
return;
this._scheduled = false;
this._callback();
}
}

/**
* @constructor
*/
@@ -2911,7 +2872,6 @@ function ResourceTrackingManager()
this._capturing = false;
this._stopCapturingOnFrameEnd = false;
this._lastTraceLog = null;
this._frameEndScheduler = new ZeroTimeoutCallback(this.markFrameEnd.bind(this));
}

ResourceTrackingManager.prototype = {
@@ -2956,7 +2916,6 @@ ResourceTrackingManager.prototype = {
return;
this._capturing = false;
this._stopCapturingOnFrameEnd = false;
this._frameEndScheduler.cancel();
if (this._lastTraceLog)
this._lastTraceLog.addFrameEndMark();
},
@@ -3002,15 +2961,14 @@ ResourceTrackingManager.prototype = {
if (!this._capturing)
return;
this._lastTraceLog.addCall(call);
this._frameEndScheduler.schedule();
},

markFrameEnd: function()
{
if (!this._lastTraceLog)
return;
this._lastTraceLog.addFrameEndMark();
if (this._stopCapturingOnFrameEnd)
if (this._stopCapturingOnFrameEnd && this._lastTraceLog.size())
this.stopCapturing(this._lastTraceLog);
}
}
@@ -3069,6 +3027,11 @@ InjectedCanvasModule.prototype = {
return this._callStartCapturingFunction(this._manager.startCapturing);
},

markFrameEnd: function()
{
this._manager.markFrameEnd();
},

/**
* @param {function(this:ResourceTrackingManager)} func
* @return {CanvasAgent.TraceLogId}
@@ -127,7 +127,13 @@ void InspectorCanvasAgent::hasUninstrumentedCanvases(ErrorString* errorString, b
{
if (!checkIsEnabled(errorString))
return;
*result = !m_framesWithUninstrumentedCanvases.isEmpty();
for (FramesWithUninstrumentedCanvases::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it) {
if (it->value) {
*result = true;
return;
}
}
*result = false;
}

void InspectorCanvasAgent::captureFrame(ErrorString* errorString, const FrameId* frameId, TraceLogId* traceLogId)
@@ -211,6 +217,8 @@ ScriptObject InspectorCanvasAgent::notifyRenderingContextWasWrapped(const Script
ScriptState* scriptState = wrappedContext.scriptState();
DOMWindow* domWindow = scriptState ? domWindowFromScriptState(scriptState) : 0;
Frame* frame = domWindow ? domWindow->frame() : 0;
if (frame && !m_framesWithUninstrumentedCanvases.contains(frame))
m_framesWithUninstrumentedCanvases.set(frame, false);
String frameId = m_pageAgent->frameId(frame);
if (!frameId.isEmpty())
m_frontend->contextCreated(frameId);
@@ -257,7 +265,7 @@ void InspectorCanvasAgent::findFramesWithUninstrumentedCanvases()
{
class NodeVisitor : public WrappedNodeVisitor {
public:
NodeVisitor(Page* page, HashSet<Frame*>& result)
NodeVisitor(Page* page, FramesWithUninstrumentedCanvases& result)
: m_page(page)
, m_framesWithUninstrumentedCanvases(result)
{
@@ -274,19 +282,19 @@ void InspectorCanvasAgent::findFramesWithUninstrumentedCanvases()

HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(node);
if (canvas->renderingContext())
m_framesWithUninstrumentedCanvases.add(frame);
m_framesWithUninstrumentedCanvases.set(frame, true);
}

private:
Page* m_page;
HashSet<Frame*>& m_framesWithUninstrumentedCanvases;
FramesWithUninstrumentedCanvases& m_framesWithUninstrumentedCanvases;
} nodeVisitor(m_pageAgent->page(), m_framesWithUninstrumentedCanvases);

m_framesWithUninstrumentedCanvases.clear();
ScriptProfiler::visitNodeWrappers(&nodeVisitor);

for (HashSet<Frame*>::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it) {
String frameId = m_pageAgent->frameId(*it);
for (FramesWithUninstrumentedCanvases::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it) {
String frameId = m_pageAgent->frameId(it->key);
if (!frameId.isEmpty())
m_frontend->contextCreated(frameId);
}
@@ -305,11 +313,13 @@ void InspectorCanvasAgent::frameNavigated(Frame* frame)
if (!m_enabled)
return;
if (frame == m_pageAgent->mainFrame()) {
m_framesWithUninstrumentedCanvases.clear();
for (FramesWithUninstrumentedCanvases::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it)
m_framesWithUninstrumentedCanvases.set(it->key, false);
m_frontend->traceLogsRemoved(0, 0);
} else {
while (frame) {
m_framesWithUninstrumentedCanvases.remove(frame);
if (m_framesWithUninstrumentedCanvases.contains(frame))
m_framesWithUninstrumentedCanvases.set(frame, false);
if (m_pageAgent->hasIdForFrame(frame)) {
String frameId = m_pageAgent->frameId(frame);
m_frontend->traceLogsRemoved(&frameId, 0);
@@ -325,6 +335,18 @@ void InspectorCanvasAgent::frameDetached(Frame* frame)
m_framesWithUninstrumentedCanvases.remove(frame);
}

void InspectorCanvasAgent::didBeginFrame()
{
if (!m_enabled)
return;
ErrorString error;
for (FramesWithUninstrumentedCanvases::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it) {
InjectedScriptCanvasModule module = injectedScriptCanvasModule(&error, mainWorldScriptState(it->key));
if (!module.hasNoValue())
module.markFrameEnd();
}
}

} // namespace WebCore

#endif // ENABLE(INSPECTOR)
@@ -37,7 +37,7 @@
#include "InspectorFrontend.h"
#include "InspectorTypeBuilder.h"
#include "ScriptState.h"
#include <wtf/HashSet.h>
#include <wtf/HashMap.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/PassRefPtr.h>
#include <wtf/text/WTFString.h>
@@ -66,11 +66,11 @@ class InspectorCanvasAgent : public InspectorBaseAgent<InspectorCanvasAgent>, pu
virtual void clearFrontend();
virtual void restore();

// Called from InspectorInstrumentation
void frameNavigated(Frame*);
void frameDetached(Frame*);
void didBeginFrame();

// Called from InspectorCanvasInstrumentation
// Called from InspectorCanvasInstrumentation.
ScriptObject wrapCanvas2DRenderingContextForInstrumentation(const ScriptObject&);
#if ENABLE(WEBGL)
ScriptObject wrapWebGLRenderingContextForInstrumentation(const ScriptObject&);
@@ -104,7 +104,9 @@ class InspectorCanvasAgent : public InspectorBaseAgent<InspectorCanvasAgent>, pu
InjectedScriptManager* m_injectedScriptManager;
InspectorFrontend::Canvas* m_frontend;
bool m_enabled;
HashSet<Frame*> m_framesWithUninstrumentedCanvases;
// Contains all frames with canvases, value is true only for frames that have an uninstrumented canvas.
typedef HashMap<Frame*, bool> FramesWithUninstrumentedCanvases;
FramesWithUninstrumentedCanvases m_framesWithUninstrumentedCanvases;
};

} // namespace WebCore
@@ -450,6 +450,8 @@ void InspectorController::didBeginFrame()
{
if (InspectorTimelineAgent* timelineAgent = m_instrumentingAgents->inspectorTimelineAgent())
timelineAgent->didBeginFrame();
if (InspectorCanvasAgent* canvasAgent = m_instrumentingAgents->inspectorCanvasAgent())
canvasAgent->didBeginFrame();
}

void InspectorController::didCancelFrame()

0 comments on commit 4b98362

Please sign in to comment.