зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to b2g-inbound. a=merge
This commit is contained in:
Коммит
f71ecb2f9d
|
@ -18,6 +18,10 @@
|
|||
* a document view. When we hand an object off to an AT, we always want
|
||||
* to give it the represented view, in the latter case.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
inline id <mozAccessible>
|
||||
GetObjectOrRepresentedView(id <mozAccessible> aObject)
|
||||
{
|
||||
|
@ -25,7 +29,7 @@ GetObjectOrRepresentedView(id <mozAccessible> aObject)
|
|||
}
|
||||
|
||||
inline mozAccessible*
|
||||
GetNativeFromGeckoAccessible(mozilla::a11y::Accessible* aAccessible)
|
||||
GetNativeFromGeckoAccessible(Accessible* aAccessible)
|
||||
{
|
||||
mozAccessible* native = nil;
|
||||
aAccessible->GetNativeInterface((void**)&native);
|
||||
|
@ -33,11 +37,21 @@ GetNativeFromGeckoAccessible(mozilla::a11y::Accessible* aAccessible)
|
|||
}
|
||||
|
||||
inline mozAccessible*
|
||||
GetNativeFromProxy(mozilla::a11y::ProxyAccessible* aProxy)
|
||||
GetNativeFromProxy(const ProxyAccessible* aProxy)
|
||||
{
|
||||
return reinterpret_cast<mozAccessible*>(aProxy->GetWrapper());
|
||||
}
|
||||
|
||||
ProxyAccessible* GetProxyUnignoredParent(const ProxyAccessible* aProxy);
|
||||
|
||||
void GetProxyUnignoredChildren(const ProxyAccessible* aProxy,
|
||||
nsTArray<ProxyAccessible*>* aChildrenArray);
|
||||
|
||||
BOOL IsProxyIgnored(const ProxyAccessible* aProxy);
|
||||
|
||||
} // a11y
|
||||
} // mozilla
|
||||
|
||||
// This is OR'd with the Accessible owner to indicate the wrap-ee is a proxy.
|
||||
static const uintptr_t IS_PROXY = 1;
|
||||
|
||||
|
|
|
@ -76,6 +76,47 @@ GetClosestInterestingAccessible(id anObject)
|
|||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
ProxyAccessible*
|
||||
a11y::GetProxyUnignoredParent(const ProxyAccessible* aProxy)
|
||||
{
|
||||
ProxyAccessible* parent = aProxy->Parent();
|
||||
while (parent && IsProxyIgnored(aProxy))
|
||||
parent = parent->Parent();
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
void
|
||||
a11y::GetProxyUnignoredChildren(const ProxyAccessible* aProxy,
|
||||
nsTArray<ProxyAccessible*>* aChildrenArray)
|
||||
{
|
||||
if (aProxy->MustPruneChildren())
|
||||
return;
|
||||
|
||||
uint32_t childCount = aProxy->ChildrenCount();
|
||||
for (size_t childIdx = 0; childIdx < childCount; childIdx++) {
|
||||
ProxyAccessible* childProxy = aProxy->ChildAt(childIdx);
|
||||
|
||||
// If element is ignored, then add its children as substitutes.
|
||||
if (IsProxyIgnored(childProxy)) {
|
||||
GetProxyUnignoredChildren(aProxy, aChildrenArray);
|
||||
continue;
|
||||
}
|
||||
|
||||
aChildrenArray->AppendElement(childProxy);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
a11y::IsProxyIgnored(const ProxyAccessible* aProxy)
|
||||
{
|
||||
mozAccessible* nativeObject = GetNativeFromProxy(aProxy);
|
||||
if (!nativeObject)
|
||||
return true;
|
||||
|
||||
return [nativeObject accessibilityIsIgnored];
|
||||
}
|
||||
|
||||
// convert an array of Gecko accessibles to an NSArray of native accessibles
|
||||
static inline NSMutableArray*
|
||||
ConvertToNSArray(nsTArray<Accessible*>& aArray)
|
||||
|
@ -83,8 +124,8 @@ ConvertToNSArray(nsTArray<Accessible*>& aArray)
|
|||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
|
||||
// iterate through the list, and get each native accessible.
|
||||
uint32_t totalCount = aArray.Length();
|
||||
for (uint32_t i = 0; i < totalCount; i++) {
|
||||
size_t totalCount = aArray.Length();
|
||||
for (size_t i = 0; i < totalCount; i++) {
|
||||
Accessible* curAccessible = aArray.ElementAt(i);
|
||||
mozAccessible* curNative = GetNativeFromGeckoAccessible(curAccessible);
|
||||
if (curNative)
|
||||
|
@ -94,6 +135,24 @@ ConvertToNSArray(nsTArray<Accessible*>& aArray)
|
|||
return nativeArray;
|
||||
}
|
||||
|
||||
// convert an array of Gecko proxy accessibles to an NSArray of native accessibles
|
||||
static inline NSMutableArray*
|
||||
ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray)
|
||||
{
|
||||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
|
||||
// iterate through the list, and get each native accessible.
|
||||
size_t totalCount = aArray.Length();
|
||||
for (size_t i = 0; i < totalCount; i++) {
|
||||
ProxyAccessible* curAccessible = aArray.ElementAt(i);
|
||||
mozAccessible* curNative = GetNativeFromProxy(curAccessible);
|
||||
if (curNative)
|
||||
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
|
||||
}
|
||||
|
||||
return nativeArray;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation mozAccessible
|
||||
|
@ -612,21 +671,34 @@ ConvertToNSArray(nsTArray<Accessible*>& aArray)
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
Accessible* accessibleParent = accWrap->GetUnignoredParent();
|
||||
if (accessibleParent) {
|
||||
id nativeParent = GetNativeFromGeckoAccessible(accessibleParent);
|
||||
id nativeParent = nil;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
Accessible* accessibleParent = accWrap->GetUnignoredParent();
|
||||
if (accessibleParent)
|
||||
nativeParent = GetNativeFromGeckoAccessible(accessibleParent);
|
||||
if (nativeParent)
|
||||
return GetClosestInterestingAccessible(nativeParent);
|
||||
// GetUnignoredParent() returns null when there is no unignored accessible all the way up to
|
||||
// the root accessible. so we'll have to return whatever native accessible is above our root accessible
|
||||
// (which might be the owning NSWindow in the application, for example).
|
||||
//
|
||||
// get the native root accessible, and tell it to return its first parent unignored accessible.
|
||||
nativeParent = GetNativeFromGeckoAccessible(accWrap->RootAccessible());
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
// Go up the chain to find a parent that is not ignored.
|
||||
ProxyAccessible* accessibleParent = GetProxyUnignoredParent(proxy);
|
||||
if (accessibleParent)
|
||||
nativeParent = GetNativeFromProxy(accessibleParent);
|
||||
if (nativeParent)
|
||||
return GetClosestInterestingAccessible(nativeParent);
|
||||
|
||||
Accessible* outerDoc = proxy->OuterDocOfRemoteBrowser();
|
||||
nativeParent = outerDoc ?
|
||||
GetNativeFromGeckoAccessible(outerDoc->RootAccessible()) : nil;
|
||||
} else {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// GetUnignoredParent() returns null when there is no unignored accessible all the way up to
|
||||
// the root accessible. so we'll have to return whatever native accessible is above our root accessible
|
||||
// (which might be the owning NSWindow in the application, for example).
|
||||
//
|
||||
// get the native root accessible, and tell it to return its first parent unignored accessible.
|
||||
id nativeParent =
|
||||
GetNativeFromGeckoAccessible(accWrap->RootAccessible());
|
||||
NSAssert1 (nativeParent, @"!!! we can't find a parent for %@", self);
|
||||
|
||||
return GetClosestInterestingAccessible(nativeParent);
|
||||
|
@ -656,13 +728,19 @@ ConvertToNSArray(nsTArray<Accessible*>& aArray)
|
|||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
if (mChildren || !accWrap->AreChildrenCached())
|
||||
if (mChildren || (accWrap && !accWrap->AreChildrenCached()))
|
||||
return mChildren;
|
||||
|
||||
// get the array of children.
|
||||
nsAutoTArray<Accessible*, 10> childrenArray;
|
||||
accWrap->GetUnignoredChildren(&childrenArray);
|
||||
mChildren = ConvertToNSArray(childrenArray);
|
||||
if (accWrap) {
|
||||
nsAutoTArray<Accessible*, 10> childrenArray;
|
||||
accWrap->GetUnignoredChildren(&childrenArray);
|
||||
mChildren = ConvertToNSArray(childrenArray);
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
nsAutoTArray<ProxyAccessible*, 10> childrenArray;
|
||||
GetProxyUnignoredChildren(proxy, &childrenArray);
|
||||
mChildren = ConvertToNSArray(childrenArray);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_hakan
|
||||
// make sure we're not returning any ignored accessibles.
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "nsIGfxInfo.h"
|
||||
#include "nsIPersistentProperties2.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
@ -28,7 +29,7 @@ ApplicationAccessibleWrap::NativeAttributes()
|
|||
nsCOMPtr<nsIPersistentProperties> attributes =
|
||||
do_CreateInstance(NS_PERSISTENTPROPERTIES_CONTRACTID);
|
||||
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
if (gfxInfo) {
|
||||
bool isD2DEnabled = false;
|
||||
gfxInfo->GetD2DEnabled(&isD2DEnabled);
|
||||
|
|
|
@ -333,7 +333,6 @@ pref("media.video-queue.default-size", 3);
|
|||
|
||||
// optimize images' memory usage
|
||||
pref("image.downscale-during-decode.enabled", true);
|
||||
pref("image.decode-only-on-draw.enabled", false);
|
||||
pref("image.mem.allow_locking_in_content_processes", true);
|
||||
pref("image.decode.retry-on-alloc-failure", true);
|
||||
// Limit the surface cache to 1/8 of main memory or 128MB, whichever is smaller.
|
||||
|
|
|
@ -42,7 +42,7 @@ function test() {
|
|||
/** Test for Bug 615394 - Session Restore should notify when it is beginning and ending a restore **/
|
||||
waitForExplicitFinish();
|
||||
// Preemptively extend the timeout to prevent [orange]
|
||||
requestLongerTimeout(2);
|
||||
requestLongerTimeout(4);
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
no_tooltool=1
|
||||
no_sccache=1
|
||||
|
||||
ac_add_options --with-l10n-base=../../l10n
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
no_tooltool=1
|
||||
no_sccache=1
|
||||
|
||||
ac_add_options --with-l10n-base=../../l10n
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
ac_add_options --with-google-oauth-api-keyfile=/builds/google-oauth-api.key
|
||||
|
||||
. $topsrcdir/build/unix/mozconfig.tsan
|
||||
|
||||
# Need this to prevent name conflicts with the normal nightly build packages
|
||||
export MOZ_PKG_SPECIAL=tsan
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common.override"
|
|
@ -0,0 +1,12 @@
|
|||
[
|
||||
{
|
||||
"clang_version": "r241773"
|
||||
},
|
||||
{
|
||||
"size": 89690541,
|
||||
"digest": "470d258d9785a120fcba65eee90daa632a42affa0f97f57d70fc8285bd76bcc27d4d0d70b6c37577ab271a04c843b6269425391a8d6df1967718dba26dd3a73d",
|
||||
"algorithm": "sha512",
|
||||
"filename": "clang.tar.bz2",
|
||||
"unpack": true
|
||||
}
|
||||
]
|
|
@ -185,7 +185,6 @@ let DebuggerController = {
|
|||
if (this._target.isTabActor) {
|
||||
this.Workers.disconnect();
|
||||
}
|
||||
this.Tracer.disconnect();
|
||||
this.disconnect();
|
||||
|
||||
this._shutdown = true;
|
||||
|
@ -204,7 +203,7 @@ let DebuggerController = {
|
|||
}
|
||||
|
||||
let target = this._target;
|
||||
let { client, form: { chromeDebugger, traceActor, actor } } = target;
|
||||
let { client, form: { chromeDebugger, actor } } = target;
|
||||
target.on("close", this._onTabDetached);
|
||||
target.on("navigate", this._onTabNavigated);
|
||||
target.on("will-navigate", this._onTabNavigated);
|
||||
|
@ -218,10 +217,6 @@ let DebuggerController = {
|
|||
yield this._startChromeDebugging(chromeDebugger);
|
||||
} else {
|
||||
yield this._startDebuggingTab();
|
||||
|
||||
if (Prefs.tracerEnabled && traceActor) {
|
||||
yield this._startTracingTab(traceActor);
|
||||
}
|
||||
}
|
||||
|
||||
this._hideUnsupportedFeatures();
|
||||
|
@ -390,31 +385,6 @@ let DebuggerController = {
|
|||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets up an execution tracing session.
|
||||
*
|
||||
* @param object aTraceActor
|
||||
* The remote protocol grip of the trace actor.
|
||||
* @return object
|
||||
* A promise resolved once the client attaches to the tracer.
|
||||
*/
|
||||
_startTracingTab: function(aTraceActor) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
this.client.attachTracer(aTraceActor, (response, traceClient) => {
|
||||
if (!traceClient) {
|
||||
deferred.reject(new Error("Failed to attach to tracing actor."));
|
||||
return;
|
||||
}
|
||||
this.traceClient = traceClient;
|
||||
this.Tracer.connect();
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Detach and reattach to the thread actor with useSourceMaps true, blow
|
||||
* away old sources and get them again.
|
||||
|
@ -1301,7 +1271,6 @@ SourceScripts.prototype = {
|
|||
// both in the editor and the breakpoints pane.
|
||||
DebuggerController.Breakpoints.updatePaneBreakpoints();
|
||||
DebuggerController.Breakpoints.updateEditorBreakpoints();
|
||||
DebuggerController.HitCounts.updateEditorHitCounts();
|
||||
|
||||
// Make sure the events listeners are up to date.
|
||||
if (DebuggerView.instrumentsPaneTab == "events-tab") {
|
||||
|
@ -1354,7 +1323,6 @@ SourceScripts.prototype = {
|
|||
// both in the editor and the breakpoints pane.
|
||||
DebuggerController.Breakpoints.updatePaneBreakpoints();
|
||||
DebuggerController.Breakpoints.updateEditorBreakpoints();
|
||||
DebuggerController.HitCounts.updateEditorHitCounts();
|
||||
|
||||
// Signal that sources have been added.
|
||||
window.emit(EVENTS.SOURCES_ADDED);
|
||||
|
@ -1566,237 +1534,6 @@ SourceScripts.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Tracer update the UI according to the messages exchanged with the tracer
|
||||
* actor.
|
||||
*/
|
||||
function Tracer() {
|
||||
this._trace = null;
|
||||
this._idCounter = 0;
|
||||
this.onTraces = this.onTraces.bind(this);
|
||||
}
|
||||
|
||||
Tracer.prototype = {
|
||||
get client() {
|
||||
return DebuggerController.client;
|
||||
},
|
||||
|
||||
get traceClient() {
|
||||
return DebuggerController.traceClient;
|
||||
},
|
||||
|
||||
get tracing() {
|
||||
return !!this._trace;
|
||||
},
|
||||
|
||||
/**
|
||||
* Hooks up the debugger controller with the tracer client.
|
||||
*/
|
||||
connect: function() {
|
||||
this._stack = [];
|
||||
this.client.addListener("traces", this.onTraces);
|
||||
},
|
||||
|
||||
/**
|
||||
* Disconnects the debugger controller from the tracer client. Any further
|
||||
* communcation with the tracer actor will not have any effect on the UI.
|
||||
*/
|
||||
disconnect: function() {
|
||||
this._stack = null;
|
||||
this.client.removeListener("traces", this.onTraces);
|
||||
},
|
||||
|
||||
/**
|
||||
* Instructs the tracer actor to start tracing.
|
||||
*/
|
||||
startTracing: function(aCallback = () => {}) {
|
||||
if (this.tracing) {
|
||||
return;
|
||||
}
|
||||
|
||||
DebuggerView.Tracer.selectTab();
|
||||
|
||||
let id = this._trace = "dbg.trace" + Math.random();
|
||||
let fields = [
|
||||
"name",
|
||||
"location",
|
||||
"hitCount",
|
||||
"parameterNames",
|
||||
"depth",
|
||||
"arguments",
|
||||
"return",
|
||||
"throw",
|
||||
"yield"
|
||||
];
|
||||
|
||||
this.traceClient.startTrace(fields, id, aResponse => {
|
||||
const { error } = aResponse;
|
||||
if (error) {
|
||||
DevToolsUtils.reportException("Tracer.prototype.startTracing", error);
|
||||
this._trace = null;
|
||||
}
|
||||
|
||||
aCallback(aResponse);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Instructs the tracer actor to stop tracing.
|
||||
*/
|
||||
stopTracing: function(aCallback = () => {}) {
|
||||
if (!this.tracing) {
|
||||
return;
|
||||
}
|
||||
this.traceClient.stopTrace(this._trace, aResponse => {
|
||||
const { error } = aResponse;
|
||||
if (error) {
|
||||
DevToolsUtils.reportException("Tracer.prototype.stopTracing", error);
|
||||
}
|
||||
|
||||
this._trace = null;
|
||||
DebuggerController.HitCounts.clear();
|
||||
aCallback(aResponse);
|
||||
});
|
||||
},
|
||||
|
||||
onTraces: function (aEvent, { traces }) {
|
||||
const tracesLength = traces.length;
|
||||
let tracesToShow;
|
||||
|
||||
// Update hit counts.
|
||||
for (let t of traces) {
|
||||
if (t.type == "enteredFrame") {
|
||||
DebuggerController.HitCounts.set(t.location, t.hitCount);
|
||||
}
|
||||
}
|
||||
DebuggerController.HitCounts.updateEditorHitCounts();
|
||||
|
||||
// Limit number of traces to be shown in the log.
|
||||
if (tracesLength > TracerView.MAX_TRACES) {
|
||||
tracesToShow = traces.slice(tracesLength - TracerView.MAX_TRACES, tracesLength);
|
||||
this._stack.splice(0, this._stack.length);
|
||||
DebuggerView.Tracer.empty();
|
||||
} else {
|
||||
tracesToShow = traces;
|
||||
}
|
||||
|
||||
// Show traces in the log.
|
||||
for (let t of tracesToShow) {
|
||||
if (t.type == "enteredFrame") {
|
||||
this._onCall(t);
|
||||
} else {
|
||||
this._onReturn(t);
|
||||
}
|
||||
}
|
||||
DebuggerView.Tracer.commit();
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback for handling a new call frame.
|
||||
*/
|
||||
_onCall: function({ name, location, blackBoxed, parameterNames, depth, arguments: args }) {
|
||||
const item = {
|
||||
name: name,
|
||||
location: location,
|
||||
id: this._idCounter++,
|
||||
blackBoxed
|
||||
};
|
||||
|
||||
this._stack.push(item);
|
||||
DebuggerView.Tracer.addTrace({
|
||||
type: "call",
|
||||
name: name,
|
||||
location: location,
|
||||
depth: depth,
|
||||
parameterNames: parameterNames,
|
||||
arguments: args,
|
||||
frameId: item.id,
|
||||
blackBoxed
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback for handling an exited frame.
|
||||
*/
|
||||
_onReturn: function(aPacket) {
|
||||
if (!this._stack.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { name, id, location, blackBoxed } = this._stack.pop();
|
||||
DebuggerView.Tracer.addTrace({
|
||||
type: aPacket.why,
|
||||
name: name,
|
||||
location: location,
|
||||
depth: aPacket.depth,
|
||||
frameId: id,
|
||||
returnVal: aPacket.return || aPacket.throw || aPacket.yield,
|
||||
blackBoxed
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Create an object which has the same interface as a normal object client,
|
||||
* but since we already have all the information for an object that we will
|
||||
* ever get (the server doesn't create actors when tracing, just firehoses
|
||||
* data and forgets about it) just return the data immdiately.
|
||||
*
|
||||
* @param Object aObject
|
||||
* The tracer object "grip" (more like a limited snapshot).
|
||||
* @returns Object
|
||||
* The synchronous client object.
|
||||
*/
|
||||
syncGripClient: function(aObject) {
|
||||
return {
|
||||
get isFrozen() { return aObject.frozen; },
|
||||
get isSealed() { return aObject.sealed; },
|
||||
get isExtensible() { return aObject.extensible; },
|
||||
|
||||
get ownProperties() { return aObject.ownProperties; },
|
||||
get prototype() { return null; },
|
||||
|
||||
getParameterNames: callback => callback(aObject),
|
||||
getPrototypeAndProperties: callback => callback(aObject),
|
||||
getPrototype: callback => callback(aObject),
|
||||
|
||||
getOwnPropertyNames: (callback) => {
|
||||
callback({
|
||||
ownPropertyNames: aObject.ownProperties
|
||||
? Object.keys(aObject.ownProperties)
|
||||
: []
|
||||
});
|
||||
},
|
||||
|
||||
getProperty: (property, callback) => {
|
||||
callback({
|
||||
descriptor: aObject.ownProperties
|
||||
? aObject.ownProperties[property]
|
||||
: null
|
||||
});
|
||||
},
|
||||
|
||||
getDisplayString: callback => callback("[object " + aObject.class + "]"),
|
||||
|
||||
getScope: callback => callback({
|
||||
error: "scopeNotAvailable",
|
||||
message: "Cannot get scopes for traced objects"
|
||||
})
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Wraps object snapshots received from the tracer server so that we can
|
||||
* differentiate them from long living object grips from the debugger server
|
||||
* in the variables view.
|
||||
*
|
||||
* @param Object aObject
|
||||
* The object snapshot from the tracer actor.
|
||||
*/
|
||||
WrappedObject: function(aObject) {
|
||||
this.object = aObject;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles breaking on event listeners in the currently debugged target.
|
||||
*/
|
||||
|
@ -2167,10 +1904,10 @@ Breakpoints.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
// Preserve information about the breakpoint's line text, to display it
|
||||
// in the sources pane without requiring fetching the source (for example,
|
||||
// after the target navigated). Note that this will get out of sync
|
||||
// if the source text contents change.
|
||||
// Preserve information about the breakpoint's line text, to display it in
|
||||
// the sources pane without requiring fetching the source (for example,
|
||||
// after the target navigated). Note that this will get out of sync if the
|
||||
// source text contents change.
|
||||
let line = aBreakpointClient.location.line - 1;
|
||||
aBreakpointClient.text = DebuggerView.editor.getText(line).trim();
|
||||
|
||||
|
@ -2427,87 +2164,6 @@ Object.defineProperty(Breakpoints.prototype, "_addedOrDisabled", {
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Handles Tracer's hit counts.
|
||||
*/
|
||||
function HitCounts() {
|
||||
/**
|
||||
* Storage of hit counts for every location
|
||||
* hitCount = _locations[url][line][column]
|
||||
*/
|
||||
this._hitCounts = Object.create(null);
|
||||
}
|
||||
|
||||
HitCounts.prototype = {
|
||||
set: function({url, line, column}, aHitCount) {
|
||||
if (url) {
|
||||
if (!this._hitCounts[url]) {
|
||||
this._hitCounts[url] = Object.create(null);
|
||||
}
|
||||
if (!this._hitCounts[url][line]) {
|
||||
this._hitCounts[url][line] = Object.create(null);
|
||||
}
|
||||
this._hitCounts[url][line][column] = aHitCount;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update all the hit counts in the editor view. This is invoked when the
|
||||
* selected script is changed, or when new sources are received via the
|
||||
* _onNewSource and _onSourcesAdded event listeners.
|
||||
*/
|
||||
updateEditorHitCounts: function() {
|
||||
// First, remove all hit counters.
|
||||
DebuggerView.editor.removeAllMarkers("hit-counts");
|
||||
|
||||
// Then, add new hit counts, just for the current source.
|
||||
for (let url in this._hitCounts) {
|
||||
for (let line in this._hitCounts[url]) {
|
||||
for (let column in this._hitCounts[url][line]) {
|
||||
this._updateEditorHitCount({url, line, column});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Update a hit counter on a certain line.
|
||||
*/
|
||||
_updateEditorHitCount: function({url, line, column}) {
|
||||
// Editor must be initialized.
|
||||
if (!DebuggerView.editor) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to do anything if the counter's source is not being shown in the
|
||||
// editor.
|
||||
if (url &&
|
||||
DebuggerView.Sources.selectedItem.attachment.source.url != url) {
|
||||
return;
|
||||
}
|
||||
|
||||
// There might be more counters on the same line. We need to combine them
|
||||
// into one.
|
||||
let content = Object.keys(this._hitCounts[url][line])
|
||||
.sort() // Sort by key (column).
|
||||
.map(a => this._hitCounts[url][line][a]) // Extract values.
|
||||
.map(a => a + "\u00D7") // Format hit count (e.g. 146×).
|
||||
.join("|");
|
||||
|
||||
// CodeMirror's lines are indexed from 0, while traces start from 1
|
||||
DebuggerView.editor.addContentMarker(line - 1, "hit-counts", "hit-count",
|
||||
content);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove all hit couters and clear the storage
|
||||
*/
|
||||
clear: function() {
|
||||
DebuggerView.editor.removeAllMarkers("hit-counts");
|
||||
this._hitCounts = Object.create(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Localization convenience methods.
|
||||
*/
|
||||
|
@ -2528,7 +2184,6 @@ let Prefs = new ViewHelpers.Prefs("devtools", {
|
|||
sourceMapsEnabled: ["Bool", "debugger.source-maps-enabled"],
|
||||
prettyPrintEnabled: ["Bool", "debugger.pretty-print-enabled"],
|
||||
autoPrettyPrint: ["Bool", "debugger.auto-pretty-print"],
|
||||
tracerEnabled: ["Bool", "debugger.tracer"],
|
||||
workersEnabled: ["Bool", "debugger.workers"],
|
||||
editorTabSize: ["Int", "editor.tabsize"],
|
||||
autoBlackBox: ["Bool", "debugger.auto-black-box"]
|
||||
|
@ -2550,8 +2205,6 @@ DebuggerController.StackFrames = new StackFrames();
|
|||
DebuggerController.SourceScripts = new SourceScripts();
|
||||
DebuggerController.Breakpoints = new Breakpoints();
|
||||
DebuggerController.Breakpoints.DOM = new EventListeners();
|
||||
DebuggerController.Tracer = new Tracer();
|
||||
DebuggerController.HitCounts = new HitCounts();
|
||||
|
||||
/**
|
||||
* Export some properties to the global scope for easier access.
|
||||
|
|
|
@ -58,7 +58,6 @@ let DebuggerView = {
|
|||
this.Workers.initialize();
|
||||
this.Sources.initialize();
|
||||
this.VariableBubble.initialize();
|
||||
this.Tracer.initialize();
|
||||
this.WatchExpressions.initialize();
|
||||
this.EventListeners.initialize();
|
||||
this.GlobalSearch.initialize();
|
||||
|
@ -91,7 +90,6 @@ let DebuggerView = {
|
|||
this.StackFramesClassicList.destroy();
|
||||
this.Sources.destroy();
|
||||
this.VariableBubble.destroy();
|
||||
this.Tracer.destroy();
|
||||
this.WatchExpressions.destroy();
|
||||
this.EventListeners.destroy();
|
||||
this.GlobalSearch.destroy();
|
||||
|
@ -174,9 +172,7 @@ let DebuggerView = {
|
|||
VariablesViewController.attach(this.Variables, {
|
||||
getEnvironmentClient: aObject => gThreadClient.environment(aObject),
|
||||
getObjectClient: aObject => {
|
||||
return aObject instanceof DebuggerController.Tracer.WrappedObject
|
||||
? DebuggerController.Tracer.syncGripClient(aObject.object)
|
||||
: gThreadClient.pauseGrip(aObject)
|
||||
return gThreadClient.pauseGrip(aObject)
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -219,9 +215,6 @@ let DebuggerView = {
|
|||
}
|
||||
|
||||
let gutters = ["breakpoints"];
|
||||
if (Services.prefs.getBoolPref("devtools.debugger.tracer")) {
|
||||
gutters.unshift("hit-counts");
|
||||
}
|
||||
|
||||
this.editor = new Editor({
|
||||
mode: Editor.modes.text,
|
||||
|
@ -414,7 +407,6 @@ let DebuggerView = {
|
|||
// source.
|
||||
DebuggerView.Sources.selectedValue = aSource.actor;
|
||||
DebuggerController.Breakpoints.updateEditorBreakpoints();
|
||||
DebuggerController.HitCounts.updateEditorHitCounts();
|
||||
|
||||
histogram.add(Date.now() - startTime);
|
||||
|
||||
|
@ -673,7 +665,6 @@ let DebuggerView = {
|
|||
GlobalSearch: null,
|
||||
StackFrames: null,
|
||||
Sources: null,
|
||||
Tracer: null,
|
||||
Variables: null,
|
||||
VariableBubble: null,
|
||||
WatchExpressions: null,
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
<script type="text/javascript" src="debugger/workers-view.js"/>
|
||||
<script type="text/javascript" src="debugger/sources-view.js"/>
|
||||
<script type="text/javascript" src="debugger/variable-bubble-view.js"/>
|
||||
<script type="text/javascript" src="debugger/tracer-view.js"/>
|
||||
<script type="text/javascript" src="debugger/watch-expressions-view.js"/>
|
||||
<script type="text/javascript" src="debugger/event-listeners-view.js"/>
|
||||
<script type="text/javascript" src="debugger/global-search-view.js"/>
|
||||
|
@ -280,13 +279,6 @@
|
|||
class="devtools-toolbarbutton"
|
||||
tabindex="0"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<toolbarbutton id="trace"
|
||||
class="devtools-toolbarbutton"
|
||||
command="toggleTracing"
|
||||
tabindex="0"
|
||||
hidden="true"/>
|
||||
</hbox>
|
||||
<vbox id="stackframes" flex="1"/>
|
||||
<textbox id="searchbox"
|
||||
class="devtools-searchinput" type="search"/>
|
||||
|
@ -324,7 +316,6 @@
|
|||
<tabs>
|
||||
<tab id="sources-tab" label="&debuggerUI.tabs.sources;"/>
|
||||
<tab id="callstack-tab" label="&debuggerUI.tabs.callstack;"/>
|
||||
<tab id="tracer-tab" label="&debuggerUI.tabs.traces;" hidden="true"/>
|
||||
</tabs>
|
||||
<tabpanels flex="1">
|
||||
<tabpanel id="sources-tabpanel">
|
||||
|
@ -355,26 +346,6 @@
|
|||
<tabpanel id="callstack-tabpanel">
|
||||
<vbox id="callstack-list" flex="1"/>
|
||||
</tabpanel>
|
||||
<tabpanel id="tracer-tabpanel">
|
||||
<vbox id="tracer-traces" flex="1"/>
|
||||
<hbox class="trace-item-template" hidden="true">
|
||||
<hbox class="trace-item" align="center" flex="1" crop="end">
|
||||
<label class="trace-type plain"/>
|
||||
<label class="trace-name plain" crop="end"/>
|
||||
</hbox>
|
||||
</hbox>
|
||||
<toolbar id="tracer-toolbar" class="devtools-toolbar">
|
||||
<toolbarbutton id="clear-tracer"
|
||||
label="&debuggerUI.clearButton;"
|
||||
tooltiptext="&debuggerUI.clearButton.tooltip;"
|
||||
command="clearTraces"
|
||||
class="devtools-toolbarbutton"/>
|
||||
<textbox id="tracer-search"
|
||||
class="devtools-searchinput"
|
||||
flex="1"
|
||||
type="search"/>
|
||||
</toolbar>
|
||||
</tabpanel>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
</vbox>
|
||||
|
|
|
@ -33,7 +33,6 @@ support-files =
|
|||
code_script-switching-01.js
|
||||
code_script-switching-02.js
|
||||
code_test-editor-mode
|
||||
code_tracing-01.js
|
||||
code_ugly.js
|
||||
code_ugly-2.js
|
||||
code_ugly-3.js
|
||||
|
@ -91,7 +90,6 @@ support-files =
|
|||
doc_promise.html
|
||||
doc_random-javascript.html
|
||||
doc_recursion-stack.html
|
||||
doc_same-line-functions.html
|
||||
doc_scope-variable.html
|
||||
doc_scope-variable-2.html
|
||||
doc_scope-variable-3.html
|
||||
|
@ -103,7 +101,6 @@ support-files =
|
|||
doc_split-console-paused-reload.html
|
||||
doc_step-out.html
|
||||
doc_terminate-on-tab-close.html
|
||||
doc_tracing-01.html
|
||||
doc_watch-expressions.html
|
||||
doc_watch-expression-button.html
|
||||
doc_with-frame.html
|
||||
|
@ -247,10 +244,6 @@ skip-if = e10s && debug
|
|||
skip-if = e10s # TODO
|
||||
[browser_dbg_hide-toolbar-buttons.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_hit-counts-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_hit-counts-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_host-layout.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_iframes.js]
|
||||
|
@ -353,7 +346,7 @@ skip-if = e10s && debug
|
|||
[browser_dbg_promises-allocation-stack.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_promises-chrome-allocation-stack.js]
|
||||
skip-if = (e10s && debug) || os == "linux" # Bug 1177730
|
||||
skip-if = (e10s && debug) || os == "linux" || os == "win" # Bug 1177730
|
||||
[browser_dbg_reload-preferred-script-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_reload-preferred-script-02.js]
|
||||
|
@ -453,22 +446,6 @@ skip-if = e10s # TODO
|
|||
skip-if = e10s # TODO
|
||||
[browser_dbg_terminate-on-tab-close.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-06.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-07.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tracing-08.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-02.js]
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Evaluating two functions on the same line and checking for correct hit count
|
||||
* for both of them in CodeMirror's gutter.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_same-line-functions.html";
|
||||
const CODE_URL = "code_same-line-functions.js";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor;
|
||||
|
||||
function test() {
|
||||
Task.async(function* () {
|
||||
yield pushPrefs(["devtools.debugger.tracer", true]);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
|
||||
Task.async(function* () {
|
||||
yield waitForSourceShown(gPanel, CODE_URL);
|
||||
yield startTracing(gPanel);
|
||||
|
||||
clickButton();
|
||||
|
||||
yield waitForClientEvents(aPanel, "traces");
|
||||
|
||||
testHitCounts();
|
||||
|
||||
yield stopTracing(gPanel);
|
||||
yield popPrefs();
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
})();
|
||||
});
|
||||
})().catch(e => {
|
||||
ok(false, "Got an error: " + e.message + "\n" + e.stack);
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function testHitCounts() {
|
||||
let marker = gEditor.getMarker(0, 'hit-counts');
|
||||
|
||||
is(marker.innerHTML, "1\u00D7|1\u00D7",
|
||||
"Both functions should be hit only once.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
});
|
|
@ -1,66 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* When tracing is stopped all hit counters should be cleared.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_same-line-functions.html";
|
||||
const CODE_URL = "code_same-line-functions.js";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gEditor;
|
||||
|
||||
function test() {
|
||||
Task.async(function* () {
|
||||
yield pushPrefs(["devtools.debugger.tracer", true]);
|
||||
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
|
||||
Task.async(function* () {
|
||||
yield waitForSourceShown(gPanel, CODE_URL);
|
||||
yield startTracing(gPanel);
|
||||
|
||||
clickButton();
|
||||
|
||||
yield waitForClientEvents(aPanel, "traces");
|
||||
|
||||
testHitCountsBeforeStopping();
|
||||
|
||||
yield stopTracing(gPanel);
|
||||
|
||||
testHitCountsAfterStopping();
|
||||
|
||||
yield popPrefs();
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
})();
|
||||
});
|
||||
})().catch(e => {
|
||||
ok(false, "Got an error: " + e.message + "\n" + e.stack);
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function testHitCountsBeforeStopping() {
|
||||
let marker = gEditor.getMarker(0, 'hit-counts');
|
||||
ok(marker, "A counter should exists.");
|
||||
}
|
||||
|
||||
function testHitCountsAfterStopping() {
|
||||
let marker = gEditor.getMarker(0, 'hit-counts');
|
||||
is(marker, undefined, "A counter should be cleared.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
});
|
|
@ -1,105 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that we get the expected frame enter/exit logs in the tracer view.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => startTracing(gPanel))
|
||||
.then(clickButton)
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(testTraceLogs)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function testTraceLogs() {
|
||||
const onclickLogs = filterTraces(gPanel,
|
||||
t => t.querySelector(".trace-name[value=onclick]"));
|
||||
is(onclickLogs.length, 2, "Should have two logs from 'onclick'");
|
||||
ok(onclickLogs[0].querySelector(".trace-call"),
|
||||
"The first 'onclick' log should be a call.");
|
||||
ok(onclickLogs[1].querySelector(".trace-return"),
|
||||
"The second 'onclick' log should be a return.");
|
||||
for (let t of onclickLogs) {
|
||||
ok(t.querySelector(".trace-item").getAttribute("tooltiptext")
|
||||
.includes("doc_tracing-01.html"));
|
||||
}
|
||||
|
||||
const nonOnclickLogs = filterTraces(gPanel,
|
||||
t => !t.querySelector(".trace-name[value=onclick]"));
|
||||
for (let t of nonOnclickLogs) {
|
||||
ok(t.querySelector(".trace-item").getAttribute("tooltiptext")
|
||||
.includes("code_tracing-01.js"));
|
||||
}
|
||||
|
||||
const mainLogs = filterTraces(gPanel,
|
||||
t => t.querySelector(".trace-name[value=main]"));
|
||||
is(mainLogs.length, 2, "Should have an enter and an exit for 'main'");
|
||||
ok(mainLogs[0].querySelector(".trace-call"),
|
||||
"The first 'main' log should be a call.");
|
||||
ok(mainLogs[1].querySelector(".trace-return"),
|
||||
"The second 'main' log should be a return.");
|
||||
|
||||
const factorialLogs = filterTraces(gPanel,
|
||||
t => t.querySelector(".trace-name[value=factorial]"));
|
||||
is(factorialLogs.length, 10, "Should have 5 enter, and 5 exit frames for 'factorial'");
|
||||
ok(factorialLogs.slice(0, 5).every(t => t.querySelector(".trace-call")),
|
||||
"The first five 'factorial' logs should be calls.");
|
||||
ok(factorialLogs.slice(5).every(t => t.querySelector(".trace-return")),
|
||||
"The second five 'factorial' logs should be returns.")
|
||||
|
||||
// Test that the depth affects padding so that calls are indented properly.
|
||||
let lastDepth = -Infinity;
|
||||
for (let t of factorialLogs.slice(0, 5)) {
|
||||
let depth = parseInt(t.querySelector(".trace-item").style.MozPaddingStart, 10);
|
||||
ok(depth > lastDepth, "The depth should be increasing");
|
||||
lastDepth = depth;
|
||||
}
|
||||
lastDepth = Infinity;
|
||||
for (let t of factorialLogs.slice(5)) {
|
||||
let depth = parseInt(t.querySelector(".trace-item").style.MozPaddingStart, 10);
|
||||
ok(depth < lastDepth, "The depth should be decreasing");
|
||||
lastDepth = depth;
|
||||
}
|
||||
|
||||
const throwerLogs = filterTraces(gPanel,
|
||||
t => t.querySelector(".trace-name[value=thrower]"));
|
||||
is(throwerLogs.length, 2, "Should have an enter and an exit for 'thrower'");
|
||||
ok(throwerLogs[0].querySelector(".trace-call"),
|
||||
"The first 'thrower' log should be a call.");
|
||||
ok(throwerLogs[1].querySelector(".trace-throw",
|
||||
"The second 'thrower' log should be a throw."));
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
|
@ -1,74 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that we highlight matching calls and returns on hover.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => startTracing(gPanel))
|
||||
.then(clickButton)
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(highlightCall)
|
||||
.then(testReturnHighlighted)
|
||||
.then(unhighlightCall)
|
||||
.then(testNoneHighlighted)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function highlightCall() {
|
||||
const callTrace = filterTraces(gPanel, t => t.querySelector(".trace-name[value=main]"))[0];
|
||||
EventUtils.sendMouseEvent({ type: "mouseover" },
|
||||
callTrace,
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testReturnHighlighted() {
|
||||
const returnTrace = filterTraces(gPanel, t => t.querySelector(".trace-name[value=main]"))[1];
|
||||
ok(Array.indexOf(returnTrace.querySelector(".trace-item").classList, "selected-matching") >= 0,
|
||||
"The corresponding return log should be highlighted.");
|
||||
}
|
||||
|
||||
function unhighlightCall() {
|
||||
const callTrace = filterTraces(gPanel, t => t.querySelector(".trace-name[value=main]"))[0];
|
||||
EventUtils.sendMouseEvent({ type: "mouseout" },
|
||||
callTrace,
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function testNoneHighlighted() {
|
||||
const highlightedTraces = filterTraces(gPanel, t => t.querySelector(".selected-matching"));
|
||||
is(highlightedTraces.length, 0, "Shouldn't have any highlighted traces");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
|
@ -1,70 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
SimpleTest.requestCompleteLog();
|
||||
|
||||
/**
|
||||
* Test that we can jump to function definitions by clicking on logs.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger, gSources;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => startTracing(gPanel))
|
||||
.then(() => clickButton())
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(() => {
|
||||
// Switch away from the JS file so we can make sure that clicking on a
|
||||
// log will switch us back to the correct JS file.
|
||||
gSources.selectedValue = getSourceActor(gSources, TAB_URL);
|
||||
return ensureSourceIs(aPanel, getSourceActor(gSources, TAB_URL), true);
|
||||
})
|
||||
.then(() => {
|
||||
const finished = waitForSourceShown(gPanel, "code_tracing-01.js");
|
||||
clickTraceLog();
|
||||
return finished;
|
||||
})
|
||||
.then(testCorrectLine)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function clickTraceLog() {
|
||||
filterTraces(gPanel, t => t.querySelector(".trace-name[value=main]"))[0].click();
|
||||
}
|
||||
|
||||
function testCorrectLine() {
|
||||
is(gDebugger.DebuggerView.editor.getCursor().line, 18,
|
||||
"The editor should have the function definition site's line selected.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gSources = null;
|
||||
});
|
|
@ -1,80 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that when we click on logs, we get the parameters/return value in the variables view.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => startTracing(gPanel))
|
||||
.then(clickButton)
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(clickTraceCall)
|
||||
.then(testParams)
|
||||
.then(clickTraceReturn)
|
||||
.then(testReturn)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
DevToolsUtils.reportException("browser_dbg_tracing-04.js", aError);
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function clickTraceCall() {
|
||||
filterTraces(gPanel, t => t.querySelector(".trace-name[value=factorial]"))[0]
|
||||
.click();
|
||||
}
|
||||
|
||||
function testParams() {
|
||||
const name = gDebugger.document.querySelector(".variables-view-variable .name");
|
||||
ok(name, "Should have a variable name");
|
||||
is(name.getAttribute("value"), "n", "The variable name should be n");
|
||||
|
||||
const value = gDebugger.document.querySelector(".variables-view-variable .value.token-number");
|
||||
ok(value, "Should have a variable value");
|
||||
is(value.getAttribute("value"), "5", "The variable value should be 5");
|
||||
}
|
||||
|
||||
function clickTraceReturn() {
|
||||
filterTraces(gPanel, t => t.querySelector(".trace-name[value=factorial]"))
|
||||
.pop().click();
|
||||
}
|
||||
|
||||
function testReturn() {
|
||||
const name = gDebugger.document.querySelector(".variables-view-variable .name");
|
||||
ok(name, "Should have a variable name");
|
||||
is(name.getAttribute("value"), "<return>", "The variable name should be <return>");
|
||||
|
||||
const value = gDebugger.document.querySelector(".variables-view-variable .value.token-number");
|
||||
ok(value, "Should have a variable value");
|
||||
is(value.getAttribute("value"), "120", "The variable value should be 120");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
|
@ -1,81 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that text describing the tracing state is correctly displayed.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gTracer, gL10N;
|
||||
|
||||
function test() {
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, () => {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gTracer = gDebugger.DebuggerView.Tracer;
|
||||
gL10N = gDebugger.L10N;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(testTracingNotStartedText)
|
||||
.then(() => gTracer._onStartTracing())
|
||||
.then(testFunctionCallsUnavailableText)
|
||||
.then(clickButton)
|
||||
.then(() => waitForClientEvents(aPanel, "traces"))
|
||||
.then(testNoEmptyText)
|
||||
.then(() => gTracer._onClear())
|
||||
.then(testFunctionCallsUnavailableText)
|
||||
.then(() => gTracer._onStopTracing())
|
||||
.then(testTracingNotStartedText)
|
||||
.then(() => gTracer._onClear())
|
||||
.then(testTracingNotStartedText)
|
||||
.then(() => {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
})
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
DevToolsUtils.reportException("browser_dbg_tracing-05.js", aError);
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testTracingNotStartedText() {
|
||||
let label = gDebugger.document.querySelector("#tracer-tabpanel .fast-list-widget-empty-text");
|
||||
ok(label,
|
||||
"A label is displayed in the tracer tabpanel.");
|
||||
is(label.getAttribute("value"), gL10N.getStr("tracingNotStartedText"),
|
||||
"The correct {{tracingNotStartedText}} is displayed in the tracer tabpanel.");
|
||||
}
|
||||
|
||||
function testFunctionCallsUnavailableText() {
|
||||
let label = gDebugger.document.querySelector("#tracer-tabpanel .fast-list-widget-empty-text");
|
||||
ok(label,
|
||||
"A label is displayed in the tracer tabpanel.");
|
||||
is(label.getAttribute("value"), gL10N.getStr("noFunctionCallsText"),
|
||||
"The correct {{noFunctionCallsText}} is displayed in the tracer tabpanel.");
|
||||
}
|
||||
|
||||
function testNoEmptyText() {
|
||||
let label = gDebugger.document.querySelector("#tracer-tabpanel .fast-list-widget-empty-text");
|
||||
ok(!label,
|
||||
"No label should be displayed in the tracer tabpanel.");
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gTracer = null;
|
||||
gL10N = null;
|
||||
});
|
|
@ -1,37 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that the tracer doesn't connect to the backend when tracing is disabled.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
const TRACER_PREF = "devtools.debugger.tracer";
|
||||
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gOriginalPref = Services.prefs.getBoolPref(TRACER_PREF);
|
||||
Services.prefs.setBoolPref(TRACER_PREF, false);
|
||||
|
||||
function test() {
|
||||
initDebugger(TAB_URL).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
waitForSourceShown(gPanel, "code_tracing-01.js")
|
||||
.then(() => {
|
||||
ok(!gDebugger.DebuggerController.traceClient, "Should not have a trace client");
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
})
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
Services.prefs.setBoolPref(TRACER_PREF, gOriginalPref);
|
||||
});
|
|
@ -1,83 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Execute code both before and after blackboxing and test that we get
|
||||
* appropriately styled traces.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_tracing-01.html";
|
||||
|
||||
let gTab, gPanel;
|
||||
|
||||
function test() {
|
||||
Task.async(function*() {
|
||||
yield pushPref();
|
||||
|
||||
[gTab,, gPanel] = yield initDebugger(TAB_URL);
|
||||
|
||||
yield startTracing(gPanel);
|
||||
yield clickButton();
|
||||
yield waitForClientEvents(gPanel, "traces");
|
||||
|
||||
/**
|
||||
* Test that there are some traces which are not blackboxed.
|
||||
*/
|
||||
const firstBbButton = getBlackBoxButton(gPanel);
|
||||
ok(!firstBbButton.checked, "Should not be black boxed by default");
|
||||
|
||||
const blackBoxedTraces =
|
||||
gPanel.panelWin.document.querySelectorAll(".trace-item.black-boxed");
|
||||
ok(blackBoxedTraces.length === 0, "There should no blackboxed traces.");
|
||||
|
||||
const notBlackBoxedTraces =
|
||||
gPanel.panelWin.document.querySelectorAll(".trace-item:not(.black-boxed)");
|
||||
ok(notBlackBoxedTraces.length > 0,
|
||||
"There should be some traces which are not blackboxed.");
|
||||
|
||||
yield toggleBlackBoxing(gPanel);
|
||||
yield clickButton();
|
||||
yield waitForClientEvents(gPanel, "traces");
|
||||
|
||||
/**
|
||||
* Test that there are some traces which are blackboxed.
|
||||
*/
|
||||
const secondBbButton = getBlackBoxButton(gPanel);
|
||||
ok(secondBbButton.checked, "The checkbox should no longer be checked.");
|
||||
const traces =
|
||||
gPanel.panelWin.document.querySelectorAll(".trace-item.black-boxed");
|
||||
ok(traces.length > 0, "There should be some blackboxed traces.");
|
||||
|
||||
yield stopTracing(gPanel);
|
||||
yield popPref();
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
|
||||
finish();
|
||||
})().catch(e => {
|
||||
ok(false, "Got an error: " + e.message + "\n" + e.stack);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
function clickButton() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
}
|
||||
|
||||
function pushPref() {
|
||||
let deferred = promise.defer();
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]},
|
||||
deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function popPref() {
|
||||
let deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
});
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that tracing about:config doesn't produce errors.
|
||||
*/
|
||||
|
||||
const TAB_URL = "about:config";
|
||||
|
||||
let gPanel, gDoneChecks;
|
||||
|
||||
function test() {
|
||||
gDoneChecks = promise.defer();
|
||||
const tracerPref = promise.defer();
|
||||
const configPref = promise.defer();
|
||||
SpecialPowers.pushPrefEnv({'set': [["devtools.debugger.tracer", true]]}, tracerPref.resolve);
|
||||
SpecialPowers.pushPrefEnv({'set': [["general.warnOnAboutConfig", false]]}, configPref.resolve);
|
||||
promise.all([tracerPref.promise, configPref.promise]).then(() => {
|
||||
initDebugger(TAB_URL).then(([,, aPanel]) => {
|
||||
gPanel = aPanel;
|
||||
gPanel.panelWin.gClient.addOneTimeListener("traces", testTraceLogs);
|
||||
}).then(() => startTracing(gPanel))
|
||||
.then(generateTrace)
|
||||
.then(() => waitForClientEvents(gPanel, "traces"))
|
||||
.then(() => gDoneChecks.promise)
|
||||
.then(() => stopTracing(gPanel))
|
||||
.then(resetPreferences)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testTraceLogs(name, packet) {
|
||||
info("Traces: " + packet.traces.length);
|
||||
ok(packet.traces.length > 0, "Got some traces.");
|
||||
ok(packet.traces.every(t => t.type != "enteredFrame" || !!t.location),
|
||||
"All enteredFrame traces contain location.");
|
||||
gDoneChecks.resolve();
|
||||
}
|
||||
|
||||
function generateTrace(name, packet) {
|
||||
// Interact with the page to cause JS execution.
|
||||
let search = content.document.getElementById("textbox");
|
||||
info("Interacting with the page.");
|
||||
search.value = "devtools";
|
||||
}
|
||||
|
||||
function resetPreferences() {
|
||||
const deferred = promise.defer();
|
||||
SpecialPowers.popPrefEnv(() => SpecialPowers.popPrefEnv(deferred.resolve));
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gPanel = null;
|
||||
gDoneChecks = null;
|
||||
});
|
|
@ -1,29 +0,0 @@
|
|||
function factorial(n) {
|
||||
if (n <= 1) {
|
||||
return 1;
|
||||
} else {
|
||||
return n * factorial(n - 1);
|
||||
}
|
||||
}
|
||||
|
||||
function* yielder(n) {
|
||||
while (n-- >= 0) {
|
||||
yield { value: n, squared: n * n };
|
||||
}
|
||||
}
|
||||
|
||||
function thrower() {
|
||||
throw new Error("Curse your sudden but inevitable betrayal!");
|
||||
}
|
||||
|
||||
function main() {
|
||||
factorial(5);
|
||||
|
||||
// XXX bug 923729: Can't test yielding yet.
|
||||
// for (let x of yielder(5)) {}
|
||||
|
||||
try {
|
||||
thrower();
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
<!doctype html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Debugger Tracer test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src="code_same-line-functions.js"></script>
|
||||
<button onclick="first()">Click me!</button>
|
||||
</body>
|
||||
</html>
|
|
@ -1,20 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>Debugger Tracer test page</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script src="code_tracing-01.js"></script>
|
||||
<button onclick="main()">Click me!</button>
|
||||
|
||||
<script type="text/javascript">
|
||||
// Have an inline script to make sure the HTML file is listed
|
||||
// in the sources. We want to switch between them.
|
||||
function foo() {
|
||||
return 5;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -888,39 +888,6 @@ function reopenVarPopup(...aArgs) {
|
|||
return hideVarPopup.apply(this, aArgs).then(() => openVarPopup.apply(this, aArgs));
|
||||
}
|
||||
|
||||
// Tracing helpers
|
||||
|
||||
function startTracing(aPanel) {
|
||||
const deferred = promise.defer();
|
||||
aPanel.panelWin.DebuggerController.Tracer.startTracing(aResponse => {
|
||||
if (aResponse.error) {
|
||||
deferred.reject(aResponse);
|
||||
} else {
|
||||
deferred.resolve(aResponse);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function stopTracing(aPanel) {
|
||||
const deferred = promise.defer();
|
||||
aPanel.panelWin.DebuggerController.Tracer.stopTracing(aResponse => {
|
||||
if (aResponse.error) {
|
||||
deferred.reject(aResponse);
|
||||
} else {
|
||||
deferred.resolve(aResponse);
|
||||
}
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function filterTraces(aPanel, f) {
|
||||
const traces = aPanel.panelWin.document
|
||||
.getElementById("tracer-traces")
|
||||
.querySelector("scrollbox")
|
||||
.children;
|
||||
return Array.filter(traces, f);
|
||||
}
|
||||
function attachAddonActorForUrl(aClient, aUrl) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
|
|
|
@ -1,416 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Functions handling the traces UI.
|
||||
*/
|
||||
function TracerView(DebuggerController, DebuggerView) {
|
||||
this._selectedItem = null;
|
||||
this._matchingItems = null;
|
||||
this.widget = null;
|
||||
|
||||
this.Tracer = DebuggerController.Tracer;
|
||||
this.DebuggerView = DebuggerView;
|
||||
|
||||
this._highlightItem = this._highlightItem.bind(this);
|
||||
this._isNotSelectedItem = this._isNotSelectedItem.bind(this);
|
||||
|
||||
this._unhighlightMatchingItems =
|
||||
DevToolsUtils.makeInfallible(this._unhighlightMatchingItems.bind(this));
|
||||
this._onToggleTracing =
|
||||
DevToolsUtils.makeInfallible(this._onToggleTracing.bind(this));
|
||||
this._onStartTracing =
|
||||
DevToolsUtils.makeInfallible(this._onStartTracing.bind(this));
|
||||
this._onClear =
|
||||
DevToolsUtils.makeInfallible(this._onClear.bind(this));
|
||||
this._onSelect =
|
||||
DevToolsUtils.makeInfallible(this._onSelect.bind(this));
|
||||
this._onMouseOver =
|
||||
DevToolsUtils.makeInfallible(this._onMouseOver.bind(this));
|
||||
this._onSearch =
|
||||
DevToolsUtils.makeInfallible(this._onSearch.bind(this));
|
||||
}
|
||||
|
||||
TracerView.MAX_TRACES = 200;
|
||||
|
||||
TracerView.prototype = Heritage.extend(WidgetMethods, {
|
||||
/**
|
||||
* Initialization function, called when the debugger is started.
|
||||
*/
|
||||
initialize: function() {
|
||||
dumpn("Initializing the TracerView");
|
||||
|
||||
this._traceButton = document.getElementById("trace");
|
||||
this._tracerTab = document.getElementById("tracer-tab");
|
||||
|
||||
// Remove tracer related elements from the dom and tear everything down if
|
||||
// the tracer isn't enabled.
|
||||
if (!Prefs.tracerEnabled) {
|
||||
this._traceButton.remove();
|
||||
this._traceButton = null;
|
||||
this._tracerTab.remove();
|
||||
this._tracerTab = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.widget = new FastListWidget(document.getElementById("tracer-traces"));
|
||||
this._traceButton.removeAttribute("hidden");
|
||||
this._tracerTab.removeAttribute("hidden");
|
||||
|
||||
this._search = document.getElementById("tracer-search");
|
||||
this._template = document.getElementsByClassName("trace-item-template")[0];
|
||||
this._templateItem = this._template.getElementsByClassName("trace-item")[0];
|
||||
this._templateTypeIcon = this._template.getElementsByClassName("trace-type")[0];
|
||||
this._templateNameNode = this._template.getElementsByClassName("trace-name")[0];
|
||||
|
||||
this.widget.addEventListener("select", this._onSelect, false);
|
||||
this.widget.addEventListener("mouseover", this._onMouseOver, false);
|
||||
this.widget.addEventListener("mouseout", this._unhighlightMatchingItems, false);
|
||||
this._search.addEventListener("input", this._onSearch, false);
|
||||
|
||||
this._startTooltip = L10N.getStr("startTracingTooltip");
|
||||
this._stopTooltip = L10N.getStr("stopTracingTooltip");
|
||||
this._tracingNotStartedString = L10N.getStr("tracingNotStartedText");
|
||||
this._noFunctionCallsString = L10N.getStr("noFunctionCallsText");
|
||||
|
||||
this._traceButton.setAttribute("tooltiptext", this._startTooltip);
|
||||
this.emptyText = this._tracingNotStartedString;
|
||||
|
||||
this._addCommands();
|
||||
},
|
||||
|
||||
/**
|
||||
* Destruction function, called when the debugger is closed.
|
||||
*/
|
||||
destroy: function() {
|
||||
dumpn("Destroying the TracerView");
|
||||
|
||||
if (!this.widget) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.widget.removeEventListener("select", this._onSelect, false);
|
||||
this.widget.removeEventListener("mouseover", this._onMouseOver, false);
|
||||
this.widget.removeEventListener("mouseout", this._unhighlightMatchingItems, false);
|
||||
this._search.removeEventListener("input", this._onSearch, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Add commands that XUL can fire.
|
||||
*/
|
||||
_addCommands: function() {
|
||||
XULUtils.addCommands(document.getElementById('debuggerCommands'), {
|
||||
toggleTracing: () => this._onToggleTracing(),
|
||||
startTracing: () => this._onStartTracing(),
|
||||
clearTraces: () => this._onClear()
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked by the "toggleTracing" command to switch the tracer state.
|
||||
*/
|
||||
_onToggleTracing: function() {
|
||||
if (this.Tracer.tracing) {
|
||||
this._onStopTracing();
|
||||
} else {
|
||||
this._onStartTracing();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked either by the "startTracing" command or by
|
||||
* _onToggleTracing to start execution tracing in the backend.
|
||||
*
|
||||
* @return object
|
||||
* A promise resolved once the tracing has successfully started.
|
||||
*/
|
||||
_onStartTracing: function() {
|
||||
this._traceButton.setAttribute("checked", true);
|
||||
this._traceButton.setAttribute("tooltiptext", this._stopTooltip);
|
||||
|
||||
this.empty();
|
||||
this.emptyText = this._noFunctionCallsString;
|
||||
|
||||
let deferred = promise.defer();
|
||||
this.Tracer.startTracing(deferred.resolve);
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked by _onToggleTracing to stop execution tracing in the
|
||||
* backend.
|
||||
*
|
||||
* @return object
|
||||
* A promise resolved once the tracing has successfully stopped.
|
||||
*/
|
||||
_onStopTracing: function() {
|
||||
this._traceButton.removeAttribute("checked");
|
||||
this._traceButton.setAttribute("tooltiptext", this._startTooltip);
|
||||
|
||||
this.emptyText = this._tracingNotStartedString;
|
||||
|
||||
let deferred = promise.defer();
|
||||
this.Tracer.stopTracing(deferred.resolve);
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Function invoked by the "clearTraces" command to empty the traces pane.
|
||||
*/
|
||||
_onClear: function() {
|
||||
this.empty();
|
||||
},
|
||||
|
||||
/**
|
||||
* Populate the given parent scope with the variable with the provided name
|
||||
* and value.
|
||||
*
|
||||
* @param String aName
|
||||
* The name of the variable.
|
||||
* @param Object aParent
|
||||
* The parent scope.
|
||||
* @param Object aValue
|
||||
* The value of the variable.
|
||||
*/
|
||||
_populateVariable: function(aName, aParent, aValue) {
|
||||
let item = aParent.addItem(aName, { value: aValue });
|
||||
|
||||
if (aValue) {
|
||||
let wrappedValue = new this.Tracer.WrappedObject(aValue);
|
||||
this.DebuggerView.Variables.controller.populate(item, wrappedValue);
|
||||
item.expand();
|
||||
item.twisty = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for the widget's "select" event. Displays parameters, exception, or
|
||||
* return value depending on whether the selected trace is a call, throw, or
|
||||
* return respectively.
|
||||
*
|
||||
* @param Object traceItem
|
||||
* The selected trace item.
|
||||
*/
|
||||
_onSelect: function _onSelect({ detail: traceItem }) {
|
||||
if (!traceItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = traceItem.attachment.trace;
|
||||
const { location: { url, line } } = data;
|
||||
this.DebuggerView.setEditorLocation(
|
||||
this.DebuggerView.Sources.getActorForLocation({ url }),
|
||||
line,
|
||||
{ noDebug: true }
|
||||
);
|
||||
|
||||
this.DebuggerView.Variables.empty();
|
||||
const scope = this.DebuggerView.Variables.addScope();
|
||||
|
||||
if (data.type == "call") {
|
||||
const params = DevToolsUtils.zip(data.parameterNames, data.arguments);
|
||||
for (let [name, val] of params) {
|
||||
if (val === undefined) {
|
||||
scope.addItem(name, { value: "<value not available>" });
|
||||
} else {
|
||||
this._populateVariable(name, scope, val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const varName = "<" + (data.type == "throw" ? "exception" : data.type) + ">";
|
||||
this._populateVariable(varName, scope, data.returnVal);
|
||||
}
|
||||
|
||||
scope.expand();
|
||||
this.DebuggerView.showInstrumentsPane();
|
||||
},
|
||||
|
||||
/**
|
||||
* Add the hover frame enter/exit highlighting to a given item.
|
||||
*/
|
||||
_highlightItem: function(aItem) {
|
||||
if (!aItem || !aItem.target) {
|
||||
return;
|
||||
}
|
||||
const trace = aItem.target.querySelector(".trace-item");
|
||||
trace.classList.add("selected-matching");
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the hover frame enter/exit highlighting to a given item.
|
||||
*/
|
||||
_unhighlightItem: function(aItem) {
|
||||
if (!aItem || !aItem.target) {
|
||||
return;
|
||||
}
|
||||
const match = aItem.target.querySelector(".selected-matching");
|
||||
if (match) {
|
||||
match.classList.remove("selected-matching");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove the frame enter/exit pair highlighting we do when hovering.
|
||||
*/
|
||||
_unhighlightMatchingItems: function() {
|
||||
if (this._matchingItems) {
|
||||
this._matchingItems.forEach(this._unhighlightItem);
|
||||
this._matchingItems = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the given item is not the selected item.
|
||||
*/
|
||||
_isNotSelectedItem: function(aItem) {
|
||||
return aItem !== this.selectedItem;
|
||||
},
|
||||
|
||||
/**
|
||||
* Highlight the frame enter/exit pair of items for the given item.
|
||||
*/
|
||||
_highlightMatchingItems: function(aItem) {
|
||||
const frameId = aItem.attachment.trace.frameId;
|
||||
const predicate = e => e.attachment.trace.frameId == frameId;
|
||||
|
||||
this._unhighlightMatchingItems();
|
||||
this._matchingItems = this.items.filter(predicate);
|
||||
this._matchingItems
|
||||
.filter(this._isNotSelectedItem)
|
||||
.forEach(this._highlightItem);
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener for the mouseover event.
|
||||
*/
|
||||
_onMouseOver: function({ target }) {
|
||||
const traceItem = this.getItemForElement(target);
|
||||
if (traceItem) {
|
||||
this._highlightMatchingItems(traceItem);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Listener for typing in the search box.
|
||||
*/
|
||||
_onSearch: function() {
|
||||
const query = this._search.value.trim().toLowerCase();
|
||||
const predicate = name => name.toLowerCase().includes(query);
|
||||
this.filterContents(item => predicate(item.attachment.trace.name));
|
||||
},
|
||||
|
||||
/**
|
||||
* Select the traces tab in the sidebar.
|
||||
*/
|
||||
selectTab: function() {
|
||||
const tabs = this._tracerTab.parentElement;
|
||||
tabs.selectedIndex = Array.indexOf(tabs.children, this._tracerTab);
|
||||
},
|
||||
|
||||
/**
|
||||
* Commit all staged items to the widget. Overridden so that we can call
|
||||
* |FastListWidget.prototype.flush|.
|
||||
*/
|
||||
commit: function() {
|
||||
WidgetMethods.commit.call(this);
|
||||
// TODO: Accessing non-standard widget properties. Figure out what's the
|
||||
// best way to expose such things. Bug 895514.
|
||||
this.widget.flush();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds the trace record provided as an argument to the view.
|
||||
*
|
||||
* @param object aTrace
|
||||
* The trace record coming from the tracer actor.
|
||||
*/
|
||||
addTrace: function(aTrace) {
|
||||
// Create the element node for the trace item.
|
||||
let view = this._createView(aTrace);
|
||||
|
||||
// Append a source item to this container.
|
||||
this.push([view], {
|
||||
staged: true,
|
||||
attachment: {
|
||||
trace: aTrace
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Customization function for creating an item's UI.
|
||||
*
|
||||
* @return nsIDOMNode
|
||||
* The network request view.
|
||||
*/
|
||||
_createView: function(aTrace) {
|
||||
let { type, name, location, blackBoxed, depth, frameId } = aTrace;
|
||||
let { parameterNames, returnVal, arguments: args } = aTrace;
|
||||
let fragment = document.createDocumentFragment();
|
||||
|
||||
this._templateItem.classList.toggle("black-boxed", blackBoxed);
|
||||
this._templateItem.setAttribute("tooltiptext", SourceUtils.trimUrl(location.url));
|
||||
this._templateItem.style.MozPaddingStart = depth + "em";
|
||||
|
||||
const TYPES = ["call", "yield", "return", "throw"];
|
||||
for (let t of TYPES) {
|
||||
this._templateTypeIcon.classList.toggle("trace-" + t, t == type);
|
||||
}
|
||||
this._templateTypeIcon.setAttribute("value", {
|
||||
call: "\u2192",
|
||||
yield: "Y",
|
||||
return: "\u2190",
|
||||
throw: "E",
|
||||
terminated: "TERMINATED"
|
||||
}[type]);
|
||||
|
||||
this._templateNameNode.setAttribute("value", name);
|
||||
|
||||
// All extra syntax and parameter nodes added.
|
||||
const addedNodes = [];
|
||||
|
||||
if (parameterNames) {
|
||||
const syntax = (p) => {
|
||||
const el = document.createElement("label");
|
||||
el.setAttribute("value", p);
|
||||
el.classList.add("trace-syntax");
|
||||
el.classList.add("plain");
|
||||
addedNodes.push(el);
|
||||
return el;
|
||||
};
|
||||
|
||||
this._templateItem.appendChild(syntax("("));
|
||||
|
||||
for (let i = 0, n = parameterNames.length; i < n; i++) {
|
||||
let param = document.createElement("label");
|
||||
param.setAttribute("value", parameterNames[i]);
|
||||
param.classList.add("trace-param");
|
||||
param.classList.add("plain");
|
||||
addedNodes.push(param);
|
||||
this._templateItem.appendChild(param);
|
||||
|
||||
if (i + 1 !== n) {
|
||||
this._templateItem.appendChild(syntax(", "));
|
||||
}
|
||||
}
|
||||
|
||||
this._templateItem.appendChild(syntax(")"));
|
||||
}
|
||||
|
||||
// Flatten the DOM by removing one redundant box (the template container).
|
||||
for (let node of this._template.childNodes) {
|
||||
fragment.appendChild(node.cloneNode(true));
|
||||
}
|
||||
|
||||
// Remove any added nodes from the template.
|
||||
for (let node of addedNodes) {
|
||||
this._templateItem.removeChild(node);
|
||||
}
|
||||
|
||||
return fragment;
|
||||
}
|
||||
});
|
||||
|
||||
DebuggerView.Tracer = new TracerView(DebuggerController, DebuggerView);
|
|
@ -71,7 +71,6 @@ browser.jar:
|
|||
content/browser/devtools/debugger/workers-view.js (debugger/views/workers-view.js)
|
||||
content/browser/devtools/debugger/sources-view.js (debugger/views/sources-view.js)
|
||||
content/browser/devtools/debugger/variable-bubble-view.js (debugger/views/variable-bubble-view.js)
|
||||
content/browser/devtools/debugger/tracer-view.js (debugger/views/tracer-view.js)
|
||||
content/browser/devtools/debugger/watch-expressions-view.js (debugger/views/watch-expressions-view.js)
|
||||
content/browser/devtools/debugger/event-listeners-view.js (debugger/views/event-listeners-view.js)
|
||||
content/browser/devtools/debugger/global-search-view.js (debugger/views/global-search-view.js)
|
||||
|
|
|
@ -38,6 +38,9 @@ const gNSURLStore = new Map();
|
|||
// The cache used to store inflated frames.
|
||||
const gInflatedFrameStore = new WeakMap();
|
||||
|
||||
// The cache used to store frame data from `getInfo`.
|
||||
const gFrameData = new WeakMap();
|
||||
|
||||
/**
|
||||
* Parses the raw location of this function call to retrieve the actual
|
||||
* function name, source url, host name, line and column.
|
||||
|
@ -449,6 +452,69 @@ function isNumeric(c) {
|
|||
return c >= CHAR_CODE_0 && c <= CHAR_CODE_9;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the relative costs of this frame compared to a root,
|
||||
* and generates allocations information if specified. Uses caching
|
||||
* if possible.
|
||||
*
|
||||
* @param {ThreadNode|FrameNode} node
|
||||
* The node we are calculating.
|
||||
* @param {ThreadNode} options.root
|
||||
* The root thread node to calculate relative costs.
|
||||
* Generates [self|total] [duration|percentage] values.
|
||||
* @param {boolean} options.allocations
|
||||
* Generates `totalAllocations` and `selfAllocations`.
|
||||
*
|
||||
* @return {object}
|
||||
*/
|
||||
function getFrameInfo (node, options) {
|
||||
let data = gFrameData.get(node);
|
||||
|
||||
if (!data) {
|
||||
if (node.nodeType === "Thread") {
|
||||
data = Object.create(null);
|
||||
data.functionName = global.L10N.getStr("table.root");
|
||||
} else {
|
||||
data = parseLocation(node.location, node.line, node.column);
|
||||
data.hasOptimizations = node.hasOptimizations();
|
||||
data.isContent = node.isContent;
|
||||
data.isMetaCategory = node.isMetaCategory;
|
||||
}
|
||||
data.samples = node.youngestFrameSamples;
|
||||
data.categoryData = global.CATEGORY_MAPPINGS[node.category] || {};
|
||||
data.nodeType = node.nodeType;
|
||||
|
||||
// Frame name (function location or some meta information)
|
||||
data.name = data.isMetaCategory ? data.categoryData.label : data.functionName || "";
|
||||
data.tooltiptext = data.isMetaCategory ? data.categoryData.label : node.location || "";
|
||||
|
||||
gFrameData.set(node, data);
|
||||
}
|
||||
|
||||
// If a root specified, calculate the relative costs in the context of
|
||||
// this call tree. The cached store may already have this, but generate
|
||||
// if it does not.
|
||||
if (options && options.root && !data.COSTS_CALCULATED) {
|
||||
let totalSamples = options.root.samples;
|
||||
let totalDuration = options.root.duration;
|
||||
|
||||
data.selfDuration = node.youngestFrameSamples / totalSamples * totalDuration;
|
||||
data.selfPercentage = node.youngestFrameSamples / totalSamples * 100;
|
||||
data.totalDuration = node.samples / totalSamples * totalDuration;
|
||||
data.totalPercentage = node.samples / totalSamples * 100;
|
||||
data.COSTS_CALCULATED = true;
|
||||
}
|
||||
|
||||
if (options && options.allocations && !data.ALLOCATIONS_CALCULATED) {
|
||||
data.totalAllocations = node.allocations + node.calls.reduce((acc, node) => acc + node.allocations, 0);
|
||||
data.selfAllocations = node.allocations;
|
||||
data.ALLOCATIONS_CALCULATED = true;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
exports.getFrameInfo = getFrameInfo;
|
||||
exports.computeIsContentAndCategory = computeIsContentAndCategory;
|
||||
exports.parseLocation = parseLocation;
|
||||
exports.getInflatedFrameCache = getInflatedFrameCache;
|
||||
|
|
|
@ -5,10 +5,6 @@
|
|||
|
||||
const { Cc, Ci, Cu, Cr } = require("chrome");
|
||||
|
||||
loader.lazyRequireGetter(this, "L10N",
|
||||
"devtools/performance/global", true);
|
||||
loader.lazyRequireGetter(this, "CATEGORY_MAPPINGS",
|
||||
"devtools/performance/global", true);
|
||||
loader.lazyRequireGetter(this, "JITOptimizations",
|
||||
"devtools/performance/jit", true);
|
||||
loader.lazyRequireGetter(this, "FrameUtils",
|
||||
|
@ -39,6 +35,7 @@ function ThreadNode(thread, options = {}) {
|
|||
this.youngestFrameSamples = 0;
|
||||
this.calls = [];
|
||||
this.duration = options.endTime - options.startTime;
|
||||
this.nodeType = "Thread";
|
||||
|
||||
let { samples, stackTable, frameTable, stringTable, allocationsTable } = thread;
|
||||
|
||||
|
@ -307,14 +304,12 @@ ThreadNode.prototype = {
|
|||
|
||||
/**
|
||||
* Gets additional details about this node.
|
||||
* @see FrameNode.prototype.getInfo for more information.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
getInfo: function() {
|
||||
return {
|
||||
nodeType: "Thread",
|
||||
functionName: L10N.getStr("table.root"),
|
||||
categoryData: {}
|
||||
};
|
||||
getInfo: function(options) {
|
||||
return FrameUtils.getFrameInfo(this, options);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -378,6 +373,7 @@ function FrameNode(frameKey, { location, line, category, allocations, isContent
|
|||
this._stringTable = null;
|
||||
this.isMetaCategory = !!isMetaCategory;
|
||||
this.category = category;
|
||||
this.nodeType = "Frame";
|
||||
}
|
||||
|
||||
FrameNode.prototype = {
|
||||
|
@ -443,30 +439,21 @@ FrameNode.prototype = {
|
|||
|
||||
/**
|
||||
* Returns the parsed location and additional data describing
|
||||
* this frame. Uses cached data if possible.
|
||||
* this frame. Uses cached data if possible. Takes the following
|
||||
* options:
|
||||
*
|
||||
* @param {ThreadNode} options.root
|
||||
* The root thread node to calculate relative costs.
|
||||
* Generates [self|total] [duration|percentage] values.
|
||||
* @param {boolean} options.allocations
|
||||
* Generates `totalAllocations` and `selfAllocations`.
|
||||
*
|
||||
* @return object
|
||||
* The computed { name, file, url, line } properties for this
|
||||
* function call.
|
||||
* function call, as well as additional params if options specified.
|
||||
*/
|
||||
getInfo: function() {
|
||||
return this._data || this._computeInfo();
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses the raw location of this function call to retrieve the actual
|
||||
* function name and source url.
|
||||
*/
|
||||
_computeInfo: function() {
|
||||
let categoryData = CATEGORY_MAPPINGS[this.category] || {};
|
||||
let parsedData = FrameUtils.parseLocation(this.location, this.line, this.column);
|
||||
parsedData.nodeType = "Frame";
|
||||
parsedData.categoryData = categoryData;
|
||||
parsedData.isContent = this.isContent;
|
||||
parsedData.isMetaCategory = this.isMetaCategory;
|
||||
parsedData.hasOptimizations = this.hasOptimizations();
|
||||
|
||||
return this._data = parsedData;
|
||||
getInfo: function(options) {
|
||||
return FrameUtils.getFrameInfo(this, options);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -133,39 +133,38 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
|||
* @return nsIDOMNode
|
||||
*/
|
||||
_displaySelf: function(document, arrowNode) {
|
||||
let displayedData = this.getDisplayedData();
|
||||
let frameInfo = this.frame.getInfo();
|
||||
let frameInfo = this.getDisplayedData();
|
||||
|
||||
if (this.visibleCells.duration) {
|
||||
var durationCell = this._createTimeCell(document, displayedData.totalDuration);
|
||||
var durationCell = this._createTimeCell(document, frameInfo.totalDuration);
|
||||
}
|
||||
if (this.visibleCells.selfDuration) {
|
||||
var selfDurationCell = this._createTimeCell(document, displayedData.selfDuration, true);
|
||||
var selfDurationCell = this._createTimeCell(document, frameInfo.selfDuration, true);
|
||||
}
|
||||
if (this.visibleCells.percentage) {
|
||||
var percentageCell = this._createExecutionCell(document, displayedData.totalPercentage);
|
||||
var percentageCell = this._createExecutionCell(document, frameInfo.totalPercentage);
|
||||
}
|
||||
if (this.visibleCells.selfPercentage) {
|
||||
var selfPercentageCell = this._createExecutionCell(document, displayedData.selfPercentage, true);
|
||||
var selfPercentageCell = this._createExecutionCell(document, frameInfo.selfPercentage, true);
|
||||
}
|
||||
if (this.visibleCells.allocations) {
|
||||
var allocationsCell = this._createAllocationsCell(document, displayedData.totalAllocations);
|
||||
var allocationsCell = this._createAllocationsCell(document, frameInfo.totalAllocations);
|
||||
}
|
||||
if (this.visibleCells.selfAllocations) {
|
||||
var selfAllocationsCell = this._createAllocationsCell(document, displayedData.selfAllocations, true);
|
||||
var selfAllocationsCell = this._createAllocationsCell(document, frameInfo.selfAllocations, true);
|
||||
}
|
||||
if (this.visibleCells.samples) {
|
||||
var samplesCell = this._createSamplesCell(document, displayedData.samples);
|
||||
var samplesCell = this._createSamplesCell(document, frameInfo.samples);
|
||||
}
|
||||
if (this.visibleCells.function) {
|
||||
var functionCell = this._createFunctionCell(document, arrowNode, displayedData.name, frameInfo, this.level);
|
||||
var functionCell = this._createFunctionCell(document, arrowNode, frameInfo.name, frameInfo, this.level);
|
||||
}
|
||||
|
||||
let targetNode = document.createElement("hbox");
|
||||
targetNode.className = "call-tree-item";
|
||||
targetNode.setAttribute("origin", frameInfo.isContent ? "content" : "chrome");
|
||||
targetNode.setAttribute("category", frameInfo.categoryData.abbrev || "");
|
||||
targetNode.setAttribute("tooltiptext", displayedData.tooltiptext);
|
||||
targetNode.setAttribute("tooltiptext", frameInfo.tooltiptext);
|
||||
|
||||
if (this.hidden) {
|
||||
targetNode.style.display = "none";
|
||||
|
@ -355,8 +354,10 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
|||
return this._cachedDisplayedData;
|
||||
}
|
||||
|
||||
let data = this._cachedDisplayedData = Object.create(null);
|
||||
let frameInfo = this.frame.getInfo();
|
||||
return this._cachedDisplayedData = this.frame.getInfo({
|
||||
root: this.root.frame,
|
||||
allocations: (this.visibleCells.allocations || this.visibleCells.selfAllocations)
|
||||
});
|
||||
|
||||
/**
|
||||
* When inverting call tree, the costs and times are dependent on position
|
||||
|
@ -373,52 +374,6 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
|||
* Every instance of a `CallView` represents a row in the call tree. The same
|
||||
* container node is used for all rows.
|
||||
*/
|
||||
|
||||
// Leaf nodes in an inverted tree don't have to do anything special.
|
||||
let isLeaf = this._level === 0;
|
||||
let totalSamples = this.root.frame.samples;
|
||||
let totalDuration = this.root.frame.duration;
|
||||
|
||||
// Self duration, cost
|
||||
if (this.visibleCells.selfDuration) {
|
||||
data.selfDuration = this.frame.youngestFrameSamples / totalSamples * totalDuration;
|
||||
}
|
||||
if (this.visibleCells.selfPercentage) {
|
||||
data.selfPercentage = this.frame.youngestFrameSamples / totalSamples * 100;
|
||||
}
|
||||
|
||||
// Total duration, cost
|
||||
if (this.visibleCells.duration) {
|
||||
data.totalDuration = this.frame.samples / totalSamples * totalDuration;
|
||||
}
|
||||
if (this.visibleCells.percentage) {
|
||||
data.totalPercentage = this.frame.samples / totalSamples * 100;
|
||||
}
|
||||
|
||||
// Raw samples.
|
||||
if (this.visibleCells.samples) {
|
||||
data.samples = this.frame.youngestFrameSamples;
|
||||
}
|
||||
|
||||
// Self/total allocations count.
|
||||
if (this.visibleCells.allocations) {
|
||||
let childrenAllocations = this.frame.calls.reduce((acc, node) => acc + node.allocations, 0);
|
||||
data.totalAllocations = this.frame.allocations + childrenAllocations;
|
||||
}
|
||||
if (this.visibleCells.selfAllocations) {
|
||||
data.selfAllocations = this.frame.allocations;
|
||||
}
|
||||
|
||||
// Frame name (function location or some meta information).
|
||||
data.name = frameInfo.isMetaCategory
|
||||
? frameInfo.categoryData.label
|
||||
: frameInfo.functionName || "";
|
||||
|
||||
data.tooltiptext = frameInfo.isMetaCategory
|
||||
? frameInfo.categoryData.label
|
||||
: this.frame.location || "";
|
||||
|
||||
return this._cachedDisplayedData;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the tree model calculates correct costs/percentages for
|
||||
* frame nodes. The model-only version of browser_profiler-tree-view-10.js
|
||||
*/
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function () {
|
||||
let { ThreadNode } = devtools.require("devtools/performance/tree-model");
|
||||
let thread = new ThreadNode(gThread, { invertTree: true, startTime: 0, endTime: 50 });
|
||||
|
||||
/**
|
||||
* Samples
|
||||
*
|
||||
* A->C
|
||||
* A->B
|
||||
* A->B->C x4
|
||||
* A->B->D x4
|
||||
*
|
||||
* Expected Tree
|
||||
* +--total--+--self--+--tree-------------+
|
||||
* | 50% | 50% | C
|
||||
* | 40% | 0 | -> B
|
||||
* | 30% | 0 | -> A
|
||||
* | 10% | 0 | -> A
|
||||
*
|
||||
* | 40% | 40% | D
|
||||
* | 40% | 0 | -> B
|
||||
* | 40% | 0 | -> A
|
||||
*
|
||||
* | 10% | 10% | B
|
||||
* | 10% | 0 | -> A
|
||||
*/
|
||||
|
||||
[ // total, self, name
|
||||
[ 50, 50, "C", [
|
||||
[ 40, 0, "B", [
|
||||
[ 30, 0, "A"]
|
||||
]],
|
||||
[ 10, 0, "A"]
|
||||
]],
|
||||
[ 40, 40, "D", [
|
||||
[ 40, 0, "B", [
|
||||
[ 40, 0, "A"],
|
||||
]]
|
||||
]],
|
||||
[ 10, 10, "B", [
|
||||
[ 10, 0, "A"],
|
||||
]]
|
||||
].forEach(compareFrameInfo(thread));
|
||||
});
|
||||
|
||||
function compareFrameInfo (root, parent) {
|
||||
parent = parent || root;
|
||||
return function (def) {
|
||||
let [total, self, name, children] = def;
|
||||
let node = getFrameNodePath(parent, name);
|
||||
let data = node.getInfo({ root });
|
||||
equal(total, data.totalPercentage, `${name} has correct total percentage: ${data.totalPercentage}`);
|
||||
equal(self, data.selfPercentage, `${name} has correct self percentage: ${data.selfPercentage}`);
|
||||
if (children) {
|
||||
children.forEach(compareFrameInfo(root, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let gThread = synthesizeProfileForTest([{
|
||||
time: 5,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "C" }
|
||||
]
|
||||
}, {
|
||||
time: 10,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "D" }
|
||||
]
|
||||
}, {
|
||||
time: 15,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "C" },
|
||||
]
|
||||
}, {
|
||||
time: 20,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
]
|
||||
}, {
|
||||
time: 25,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "C" }
|
||||
]
|
||||
}, {
|
||||
time: 30,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "C" }
|
||||
]
|
||||
}, {
|
||||
time: 35,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "D" }
|
||||
]
|
||||
}, {
|
||||
time: 40,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "D" }
|
||||
]
|
||||
}, {
|
||||
time: 45,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "B" },
|
||||
{ location: "C" }
|
||||
]
|
||||
}, {
|
||||
time: 50,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "D" }
|
||||
]
|
||||
}]);
|
|
@ -0,0 +1,85 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the costs for recursive frames does not overcount the collapsed
|
||||
* samples.
|
||||
*/
|
||||
|
||||
function run_test() {
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
add_task(function () {
|
||||
let { ThreadNode } = devtools.require("devtools/performance/tree-model");
|
||||
let thread = new ThreadNode(gThread, { startTime: 0, endTime: 50, flattenRecursion: true });
|
||||
|
||||
/**
|
||||
* Samples
|
||||
*
|
||||
* A->B->C
|
||||
* A->B->B->B->C
|
||||
* A->B
|
||||
* A->B->B->B
|
||||
*/
|
||||
|
||||
[ // total, self, name
|
||||
[ 100, 0, "(root)", [
|
||||
[ 100, 0, "A", [
|
||||
[ 100, 50, "B", [
|
||||
[ 50, 50, "C"]
|
||||
]]
|
||||
]],
|
||||
]],
|
||||
].forEach(compareFrameInfo(thread));
|
||||
});
|
||||
|
||||
function compareFrameInfo (root, parent) {
|
||||
parent = parent || root;
|
||||
return function (def) {
|
||||
let [total, self, name, children] = def;
|
||||
let node = getFrameNodePath(parent, name);
|
||||
let data = node.getInfo({ root });
|
||||
equal(total, data.totalPercentage, `${name} has correct total percentage: ${data.totalPercentage}`);
|
||||
equal(self, data.selfPercentage, `${name} has correct self percentage: ${data.selfPercentage}`);
|
||||
if (children) {
|
||||
children.forEach(compareFrameInfo(root, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let gThread = synthesizeProfileForTest([{
|
||||
time: 5,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "B" },
|
||||
{ location: "B" },
|
||||
{ location: "C" }
|
||||
]
|
||||
}, {
|
||||
time: 10,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "C" }
|
||||
]
|
||||
}, {
|
||||
time: 15,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
{ location: "B" },
|
||||
{ location: "B" },
|
||||
]
|
||||
}, {
|
||||
time: 20,
|
||||
frames: [
|
||||
{ location: "(root)" },
|
||||
{ location: "A" },
|
||||
{ location: "B" },
|
||||
]
|
||||
}]);
|
|
@ -22,6 +22,8 @@ skip-if = toolkit == 'android' || toolkit == 'gonk'
|
|||
[test_tree-model-07.js]
|
||||
[test_tree-model-08.js]
|
||||
[test_tree-model-09.js]
|
||||
[test_tree-model-10.js]
|
||||
[test_tree-model-11.js]
|
||||
[test_waterfall-utils-collapse-01.js]
|
||||
[test_waterfall-utils-collapse-02.js]
|
||||
[test_waterfall-utils-collapse-03.js]
|
||||
|
|
|
@ -182,7 +182,7 @@ function test() {
|
|||
},
|
||||
{
|
||||
name: "background",
|
||||
value: "radial-gradient(circle closest-side at center, orange 0%, red 100%)",
|
||||
value: "-moz-radial-gradient(center 45deg, circle closest-side, orange 0%, red 100%)",
|
||||
test: fragment => {
|
||||
is(countAll(fragment), 4);
|
||||
let allSwatches = fragment.querySelectorAll("." + COLOR_CLASS);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"llvm_revision": "241773",
|
||||
"llvm_repo": "http://llvm.org/svn/llvm-project/llvm/branches/release_36",
|
||||
"clang_repo": "http://llvm.org/svn/llvm-project/cfe/branches/release_36",
|
||||
"compiler_repo": "http://llvm.org/svn/llvm-project/compiler-rt/branches/release_36",
|
||||
"patches": {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
MOZ_AUTOMATION_L10N_CHECK=0
|
||||
|
||||
. "$topsrcdir/build/mozconfig.common"
|
||||
|
||||
# Use Clang as specified in manifest
|
||||
export CC="$topsrcdir/clang/bin/clang"
|
||||
export CXX="$topsrcdir/clang/bin/clang++"
|
||||
export LLVM_SYMBOLIZER="$topsrcdir/clang/bin/llvm-symbolizer"
|
||||
|
||||
# Mandatory flag for TSan
|
||||
export CFLAGS="-fsanitize=thread"
|
||||
export CXXFLAGS="-fsanitize=thread"
|
||||
export LDFLAGS="-fsanitize=thread"
|
||||
|
||||
# Enable TSan specific code and build workarounds
|
||||
ac_add_options --enable-thread-sanitizer
|
||||
|
||||
# The ThreadSanitizer is not compatible with sanboxing
|
||||
# (see bug 1182565)
|
||||
ac_add_options --disable-sandbox
|
||||
|
||||
# These are required by TSan
|
||||
ac_add_options --disable-jemalloc
|
||||
ac_add_options --disable-crashreporter
|
||||
ac_add_options --disable-elf-hack
|
||||
ac_add_options --enable-pie
|
||||
|
||||
# Keep symbols to symbolize TSan traces
|
||||
ac_add_options --disable-install-strip
|
||||
# -gline-tables-only results in significantly smaller binaries.
|
||||
ac_add_options --enable-debug-symbols="-gline-tables-only"
|
||||
|
||||
# Avoid dependency on libstdc++ 4.7
|
||||
ac_add_options --enable-stdcxx-compat
|
|
@ -145,12 +145,6 @@ OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
|
|||
return PopulateFromSuffix(Substring(origin, pos));
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::CookieJar(nsACString& aStr)
|
||||
{
|
||||
mozilla::GetJarPrefix(mAppId, mInBrowser, aStr);
|
||||
}
|
||||
|
||||
BasePrincipal::BasePrincipal()
|
||||
{}
|
||||
|
||||
|
@ -259,7 +253,7 @@ BasePrincipal::GetJarPrefix(nsACString& aJarPrefix)
|
|||
{
|
||||
MOZ_ASSERT(AppId() != nsIScriptSecurityManager::UNKNOWN_APP_ID);
|
||||
|
||||
mOriginAttributes.CookieJar(aJarPrefix);
|
||||
mozilla::GetJarPrefix(mOriginAttributes.mAppId, mOriginAttributes.mInBrowser, aJarPrefix);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -279,13 +273,6 @@ BasePrincipal::GetOriginSuffix(nsACString& aOriginAttributes)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetCookieJar(nsACString& aCookieJar)
|
||||
{
|
||||
mOriginAttributes.CookieJar(aCookieJar);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BasePrincipal::GetAppStatus(uint16_t* aAppStatus)
|
||||
{
|
||||
|
|
|
@ -48,14 +48,45 @@ public:
|
|||
void CreateSuffix(nsACString& aStr) const;
|
||||
bool PopulateFromSuffix(const nsACString& aStr);
|
||||
|
||||
void CookieJar(nsACString& aStr);
|
||||
|
||||
// Populates the attributes from a string like
|
||||
// |uri!key1=value1&key2=value2| and returns the uri without the suffix.
|
||||
bool PopulateFromOrigin(const nsACString& aOrigin,
|
||||
nsACString& aOriginNoSuffix);
|
||||
};
|
||||
|
||||
class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary
|
||||
{
|
||||
public:
|
||||
// To convert a JSON string to an OriginAttributesPattern, do the following:
|
||||
//
|
||||
// OriginAttributesPattern pattern;
|
||||
// if (!pattern.Init(aJSONString)) {
|
||||
// ... // handle failure.
|
||||
// }
|
||||
OriginAttributesPattern() {}
|
||||
|
||||
explicit OriginAttributesPattern(const OriginAttributesPatternDictionary& aOther)
|
||||
: OriginAttributesPatternDictionary(aOther) {}
|
||||
|
||||
// Performs a match of |aAttrs| against this pattern.
|
||||
bool Matches(const OriginAttributes& aAttrs) const
|
||||
{
|
||||
if (mAppId.WasPassed() && mAppId.Value() != aAttrs.mAppId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mInBrowser.WasPassed() && mInBrowser.Value() != aAttrs.mInBrowser) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mAddonId.WasPassed() && mAddonId.Value() != aAttrs.mAddonId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Base class from which all nsIPrincipal implementations inherit. Use this for
|
||||
* default implementations and other commonalities between principal
|
||||
|
@ -84,7 +115,6 @@ public:
|
|||
NS_IMETHOD GetJarPrefix(nsACString& aJarPrefix) final;
|
||||
NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) final;
|
||||
NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final;
|
||||
NS_IMETHOD GetCookieJar(nsACString& aCookieJar) final;
|
||||
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus) final;
|
||||
NS_IMETHOD GetAppId(uint32_t* aAppStatus) final;
|
||||
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement) final;
|
||||
|
|
|
@ -20,7 +20,7 @@ interface nsIContentSecurityPolicy;
|
|||
[ptr] native JSPrincipals(JSPrincipals);
|
||||
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
|
||||
|
||||
[scriptable, builtinclass, uuid(49c2faf0-b6de-4640-8d0f-e0217baa8627)]
|
||||
[scriptable, builtinclass, uuid(7a9aa074-7565-4567-af2f-9e3704c7af9e)]
|
||||
interface nsIPrincipal : nsISerializable
|
||||
{
|
||||
/**
|
||||
|
@ -204,30 +204,6 @@ interface nsIPrincipal : nsISerializable
|
|||
*/
|
||||
readonly attribute AUTF8String originSuffix;
|
||||
|
||||
/**
|
||||
* Opaque string token representing the "cookie jar" associated with this
|
||||
* principal. Cookie jars are intended to be a tag associated with persistent
|
||||
* data (like cookies, localStorage data, etc) such that all data associated
|
||||
* with a given cookie jar can be quickly located and (for example) deleted.
|
||||
* Code from many origins may share a given cookie jar, so callers still need
|
||||
* to consult .origin (or equivalent) to compartmentalize data - the cookie
|
||||
* jar should _only_ be used as a tag in the manner described above.
|
||||
*
|
||||
* If two principals are in different cookie jars, they must be cross-origin.
|
||||
* As such, the information making up the cookie jar token must be contained
|
||||
* in the originAttributes (i.e. cookieJar must be a function of / derivable
|
||||
* from originAttributes). Long term, the intention is for the cookie jar
|
||||
* identifier to simply be an origin attribute. But we don't have that
|
||||
* attribute yet, and we also need to concatenate the appId and inBrowser
|
||||
* attributes until those go away.
|
||||
*
|
||||
* This getter is designed to hide these details from consumers so that they
|
||||
* don't need to be updated when we swap out the implementation. For that
|
||||
* reason, callers should treat the string as opaque and not rely on the
|
||||
* current format.
|
||||
*/
|
||||
readonly attribute ACString cookieJar;
|
||||
|
||||
/**
|
||||
* The base domain of the codebase URI to which this principal pertains
|
||||
* (generally the document URI), handling null principals and
|
||||
|
|
|
@ -20,9 +20,6 @@ function checkCrossOrigin(a, b) {
|
|||
do_check_false(a.subsumesConsideringDomain(b));
|
||||
do_check_false(b.subsumes(a));
|
||||
do_check_false(b.subsumesConsideringDomain(a));
|
||||
do_check_eq(a.cookieJar === b.cookieJar,
|
||||
a.originAttributes.appId == b.originAttributes.appId &&
|
||||
a.originAttributes.inBrowser == b.originAttributes.inBrowser);
|
||||
}
|
||||
|
||||
function checkOriginAttributes(prin, attrs, suffix) {
|
||||
|
|
|
@ -4851,22 +4851,16 @@ this.DOMApplicationRegistry = {
|
|||
browserOnly: browserOnly,
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.mozIApplicationClearPrivateDataParams])
|
||||
};
|
||||
this._clearCookieJarData(appId, browserOnly);
|
||||
this._clearOriginData(appId, browserOnly);
|
||||
this._notifyCategoryAndObservers(subject, "webapps-clear-data", null, msg);
|
||||
},
|
||||
|
||||
_clearCookieJarData: function(appId, browserOnly) {
|
||||
let browserCookieJar =
|
||||
ChromeUtils.originAttributesToCookieJar({appId: appId,
|
||||
inBrowser: true});
|
||||
this._notifyCategoryAndObservers(null, "clear-cookiejar-data", browserCookieJar);
|
||||
|
||||
if (!browserOnly) {
|
||||
let appCookieJar =
|
||||
ChromeUtils.originAttributesToCookieJar({appId: appId,
|
||||
inBrowser: false});
|
||||
this._notifyCategoryAndObservers(null, "clear-cookiejar-data", appCookieJar);
|
||||
_clearOriginData: function(appId, browserOnly) {
|
||||
let attributes = {appId: appId};
|
||||
if (browserOnly) {
|
||||
attributes.inBrowser = true;
|
||||
}
|
||||
this._notifyCategoryAndObservers(null, "clear-origin-data", JSON.stringify(attributes));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -52,20 +52,17 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1168300
|
|||
yield undefined;
|
||||
let app = request.result;
|
||||
|
||||
let _topic = "clear-cookiejar-data";
|
||||
let _topic = "clear-origin-data";
|
||||
let observer = new Observer(_topic);
|
||||
observer.onobserve = function(subject, topic, data, count) {
|
||||
ok(topic == _topic, "unknown topic " + topic);
|
||||
|
||||
let cookieJar = data;
|
||||
ok(cookieJar, "params.cookieJar should have value for an app.");
|
||||
let props = Object.getOwnPropertyNames(JSON.parse(data));
|
||||
is(props.length, 1, "pattern should have one property");
|
||||
is(props[0], 'appId', "pattern property should be appId");
|
||||
|
||||
// should receive 2 notifications when an app is uninstalled.
|
||||
if (count == 2) {
|
||||
ok(true);
|
||||
observer.shutdown();
|
||||
continueTest();
|
||||
}
|
||||
observer.shutdown();
|
||||
continueTest();
|
||||
};
|
||||
|
||||
request = navigator.mozApps.mgmt.uninstall(app);
|
||||
|
@ -79,7 +76,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1168300
|
|||
continueTest();
|
||||
};
|
||||
|
||||
// we now wait for "clear-cookiejar-data" notifications and onuninstall
|
||||
// we now wait for "clear-origin-data" notifications and onuninstall
|
||||
// callback.
|
||||
yield undefined;
|
||||
yield undefined;
|
||||
|
|
|
@ -185,7 +185,7 @@ AudioChannelService::Shutdown()
|
|||
if (obs) {
|
||||
obs->RemoveObserver(gAudioChannelService, "ipc:content-shutdown");
|
||||
obs->RemoveObserver(gAudioChannelService, "xpcom-shutdown");
|
||||
obs->RemoveObserver(gAudioChannelService, "inner-window-destroyed");
|
||||
obs->RemoveObserver(gAudioChannelService, "outer-window-destroyed");
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// To monitor the volume settings based on audio channel.
|
||||
obs->RemoveObserver(gAudioChannelService, "mozsettings-changed");
|
||||
|
@ -218,7 +218,7 @@ AudioChannelService::AudioChannelService()
|
|||
if (obs) {
|
||||
obs->AddObserver(this, "ipc:content-shutdown", false);
|
||||
obs->AddObserver(this, "xpcom-shutdown", false);
|
||||
obs->AddObserver(this, "inner-window-destroyed", false);
|
||||
obs->AddObserver(this, "outer-window-destroyed", false);
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// To monitor the volume settings based on audio channel.
|
||||
obs->AddObserver(this, "mozsettings-changed", false);
|
||||
|
@ -508,12 +508,12 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
}
|
||||
#endif
|
||||
|
||||
else if (!strcmp(aTopic, "inner-window-destroyed")) {
|
||||
else if (!strcmp(aTopic, "outer-window-destroyed")) {
|
||||
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
|
||||
NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
|
||||
|
||||
uint64_t innerID;
|
||||
nsresult rv = wrapper->GetData(&innerID);
|
||||
uint64_t outerID;
|
||||
nsresult rv = wrapper->GetData(&outerID);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -524,7 +524,7 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
iter(mWindows);
|
||||
while (iter.HasMore()) {
|
||||
nsAutoPtr<AudioChannelWindow>& next = iter.GetNext();
|
||||
if (next->mWindowID == innerID) {
|
||||
if (next->mWindowID == outerID) {
|
||||
uint32_t pos = mWindows.IndexOf(next);
|
||||
winData = next.forget();
|
||||
mWindows.RemoveElementAt(pos);
|
||||
|
|
|
@ -10,15 +10,6 @@
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/* static */ void
|
||||
ChromeUtils::OriginAttributesToCookieJar(GlobalObject& aGlobal,
|
||||
const OriginAttributesDictionary& aAttrs,
|
||||
nsCString& aCookieJar)
|
||||
{
|
||||
OriginAttributes attrs(aAttrs);
|
||||
attrs.CookieJar(aCookieJar);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ChromeUtils::OriginAttributesToSuffix(dom::GlobalObject& aGlobal,
|
||||
const dom::OriginAttributesDictionary& aAttrs,
|
||||
|
@ -29,5 +20,15 @@ ChromeUtils::OriginAttributesToSuffix(dom::GlobalObject& aGlobal,
|
|||
attrs.CreateSuffix(aSuffix);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
ChromeUtils::OriginAttributesMatchPattern(dom::GlobalObject& aGlobal,
|
||||
const dom::OriginAttributesDictionary& aAttrs,
|
||||
const dom::OriginAttributesPatternDictionary& aPattern)
|
||||
{
|
||||
OriginAttributes attrs(aAttrs);
|
||||
OriginAttributesPattern pattern(aPattern);
|
||||
return pattern.Matches(attrs);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -40,15 +40,15 @@ public:
|
|||
class ChromeUtils : public ThreadSafeChromeUtils
|
||||
{
|
||||
public:
|
||||
static void
|
||||
OriginAttributesToCookieJar(dom::GlobalObject& aGlobal,
|
||||
const dom::OriginAttributesDictionary& aAttrs,
|
||||
nsCString& aCookieJar);
|
||||
|
||||
static void
|
||||
OriginAttributesToSuffix(dom::GlobalObject& aGlobal,
|
||||
const dom::OriginAttributesDictionary& aAttrs,
|
||||
nsCString& aSuffix);
|
||||
|
||||
static bool
|
||||
OriginAttributesMatchPattern(dom::GlobalObject& aGlobal,
|
||||
const dom::OriginAttributesDictionary& aAttrs,
|
||||
const dom::OriginAttributesPatternDictionary& aPattern);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -800,7 +800,10 @@ nsFrameMessageManager::DispatchAsyncMessageInternal(JSContext* aCx,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(mCallback, NS_ERROR_NOT_INITIALIZED);
|
||||
if (!mCallback) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!mCallback->DoSendAsyncMessage(aCx, aMessage, aData, aCpows, aPrincipal)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -2113,10 +2113,6 @@ GK_ATOM(x_sinh, "x-sinh")
|
|||
GK_ATOM(x_telu, "x-telu")
|
||||
GK_ATOM(x_tibt, "x-tibt")
|
||||
|
||||
// used in gfxGDIFontList.h
|
||||
GK_ATOM(ko_xxx, "ko-xxx")
|
||||
GK_ATOM(x_symbol, "x-symbol")
|
||||
|
||||
// additional languages that have special case transformations
|
||||
GK_ATOM(az, "az")
|
||||
GK_ATOM(ba, "ba")
|
||||
|
|
|
@ -1129,7 +1129,9 @@ nsRange::SetStart(nsIDOMNode* aParent, int32_t aOffset)
|
|||
nsRange::SetStart(nsINode* aParent, int32_t aOffset)
|
||||
{
|
||||
nsINode* newRoot = IsValidBoundary(aParent);
|
||||
NS_ENSURE_TRUE(newRoot, NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
|
||||
if (!newRoot) {
|
||||
return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (aOffset < 0 || uint32_t(aOffset) > aParent->Length()) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
@ -1228,7 +1230,9 @@ nsRange::SetEnd(nsIDOMNode* aParent, int32_t aOffset)
|
|||
nsRange::SetEnd(nsINode* aParent, int32_t aOffset)
|
||||
{
|
||||
nsINode* newRoot = IsValidBoundary(aParent);
|
||||
NS_ENSURE_TRUE(newRoot, NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
|
||||
if (!newRoot) {
|
||||
return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
|
||||
}
|
||||
|
||||
if (aOffset < 0 || uint32_t(aOffset) > aParent->Length()) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include "qsObjectHelper.h"
|
||||
#include "xpcpublic.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "pldhash.h" // For PLDHashOperator
|
||||
|
||||
#include "nsWrapperCacheInlines.h"
|
||||
|
||||
|
@ -2146,17 +2145,13 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
// XXXbz It's not clear whether it's better to add a pldhash dependency here
|
||||
// (for PLDHashOperator) or add a BindingUtils.h dependency (for
|
||||
// SequenceTracer) to MozMap.h...
|
||||
template<typename T>
|
||||
static PLDHashOperator
|
||||
static void
|
||||
TraceMozMapValue(T* aValue, void* aClosure)
|
||||
{
|
||||
JSTracer* trc = static_cast<JSTracer*>(aClosure);
|
||||
// Act like it's a one-element sequence to leverage all that infrastructure.
|
||||
SequenceTracer<T>::TraceSequence(trc, aValue, aValue + 1);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -89,17 +89,19 @@ public:
|
|||
}
|
||||
|
||||
void GetKeys(nsTArray<nsString>& aKeys) const {
|
||||
// Sadly, EnumerateEntries is not a const method
|
||||
const_cast<SelfType*>(this)->EnumerateEntries(KeyEnumerator, &aKeys);
|
||||
for (auto iter = this->ConstIter(); !iter.Done(); iter.Next()) {
|
||||
aKeys.AppendElement(iter.Get()->GetKey());
|
||||
}
|
||||
}
|
||||
|
||||
// XXXbz we expose this generic enumerator for tracing. Otherwise we'd end up
|
||||
// with a dependency on BindingUtils.h here for the SequenceTracer bits.
|
||||
typedef PLDHashOperator (* Enumerator)(DataType* aValue, void* aClosure);
|
||||
typedef void (* Enumerator)(DataType* aValue, void* aClosure);
|
||||
void EnumerateValues(Enumerator aEnumerator, void *aClosure)
|
||||
{
|
||||
ValueEnumClosure args = { aEnumerator, aClosure };
|
||||
this->EnumerateEntries(ValueEnumerator, &args);
|
||||
for (auto iter = this->Iter(); !iter.Done(); iter.Next()) {
|
||||
aEnumerator(&iter.Get()->mData, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_WARN_UNUSED_RESULT
|
||||
|
@ -111,27 +113,6 @@ public:
|
|||
}
|
||||
return &ent->mData;
|
||||
}
|
||||
|
||||
private:
|
||||
static PLDHashOperator
|
||||
KeyEnumerator(EntryType* aEntry, void* aClosure)
|
||||
{
|
||||
nsTArray<nsString>& keys = *static_cast<nsTArray<nsString>*>(aClosure);
|
||||
keys.AppendElement(aEntry->GetKey());
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
struct ValueEnumClosure {
|
||||
Enumerator mEnumerator;
|
||||
void* mClosure;
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
ValueEnumerator(EntryType* aEntry, void* aClosure)
|
||||
{
|
||||
ValueEnumClosure* enumClosure = static_cast<ValueEnumClosure*>(aClosure);
|
||||
return enumClosure->mEnumerator(&aEntry->mData, enumClosure->mClosure);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
#include "nsDeviceContext.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "Units.h"
|
||||
#include "CanvasUtils.h"
|
||||
|
||||
#undef free // apparently defined by some windows header, clashing with a free()
|
||||
// method in SkTypes.h
|
||||
|
@ -2580,7 +2581,6 @@ CanvasRenderingContext2D::BeginPath()
|
|||
void
|
||||
CanvasRenderingContext2D::Fill(const CanvasWindingRule& winding)
|
||||
{
|
||||
EnsureTarget();
|
||||
EnsureUserSpacePath(winding);
|
||||
|
||||
if (!mPath) {
|
||||
|
@ -2626,7 +2626,6 @@ void CanvasRenderingContext2D::Fill(const CanvasPath& path, const CanvasWindingR
|
|||
void
|
||||
CanvasRenderingContext2D::Stroke()
|
||||
{
|
||||
EnsureTarget();
|
||||
EnsureUserSpacePath();
|
||||
|
||||
if (!mPath) {
|
||||
|
@ -2762,8 +2761,6 @@ bool CanvasRenderingContext2D::DrawCustomFocusRing(mozilla::dom::Element& aEleme
|
|||
void
|
||||
CanvasRenderingContext2D::Clip(const CanvasWindingRule& winding)
|
||||
{
|
||||
EnsureTarget();
|
||||
|
||||
EnsureUserSpacePath(winding);
|
||||
|
||||
if (!mPath) {
|
||||
|
@ -2905,6 +2902,8 @@ CanvasRenderingContext2D::Rect(double x, double y, double w, double h)
|
|||
void
|
||||
CanvasRenderingContext2D::EnsureWritablePath()
|
||||
{
|
||||
EnsureTarget();
|
||||
|
||||
if (mDSPathBuilder) {
|
||||
return;
|
||||
}
|
||||
|
@ -2923,7 +2922,6 @@ CanvasRenderingContext2D::EnsureWritablePath()
|
|||
return;
|
||||
}
|
||||
|
||||
EnsureTarget();
|
||||
if (!mPath) {
|
||||
NS_ASSERTION(!mPathTransformWillUpdate, "mPathTransformWillUpdate should be false, if all paths are null");
|
||||
mPathBuilder = mTarget->CreatePathBuilder(fillRule);
|
||||
|
@ -2944,8 +2942,9 @@ CanvasRenderingContext2D::EnsureUserSpacePath(const CanvasWindingRule& winding)
|
|||
if(winding == CanvasWindingRule::Evenodd)
|
||||
fillRule = FillRule::FILL_EVEN_ODD;
|
||||
|
||||
EnsureTarget();
|
||||
|
||||
if (!mPath && !mPathBuilder && !mDSPathBuilder) {
|
||||
EnsureTarget();
|
||||
mPathBuilder = mTarget->CreatePathBuilder(fillRule);
|
||||
}
|
||||
|
||||
|
@ -3212,6 +3211,7 @@ CanvasRenderingContext2D::AddHitRegion(const HitRegionOptions& options, ErrorRes
|
|||
{
|
||||
RefPtr<gfx::Path> path;
|
||||
if (options.mPath) {
|
||||
EnsureTarget();
|
||||
path = options.mPath->GetPath(CanvasWindingRule::Nonzero, mTarget);
|
||||
}
|
||||
|
||||
|
@ -5278,12 +5278,12 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w
|
|||
//uint8_t *src = aArray->Data();
|
||||
uint8_t *dst = imgsurf->Data();
|
||||
uint8_t* srcLine = aArray->Data() + copyY * (w * 4) + copyX * 4;
|
||||
#if 0
|
||||
#if 0
|
||||
printf("PutImageData_explicit: dirty x=%d y=%d w=%d h=%d copy x=%d y=%d w=%d h=%d ext x=%d y=%d w=%d h=%d\n",
|
||||
dirtyRect.x, dirtyRect.y, copyWidth, copyHeight,
|
||||
copyX, copyY, copyWidth, copyHeight,
|
||||
x, y, w, h);
|
||||
#endif
|
||||
#endif
|
||||
for (uint32_t j = 0; j < copyHeight; j++) {
|
||||
uint8_t *src = srcLine;
|
||||
for (uint32_t i = 0; i < copyWidth; i++) {
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "nsColor.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/dom/HTMLVideoElement.h"
|
||||
#include "CanvasUtils.h"
|
||||
#include "gfxTextRun.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/CanvasGradient.h"
|
||||
|
|
|
@ -28,9 +28,9 @@ WebGL1Context::~WebGL1Context()
|
|||
}
|
||||
|
||||
JSObject*
|
||||
WebGL1Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
|
||||
WebGL1Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
|
||||
{
|
||||
return dom::WebGLRenderingContextBinding::Wrap(cx, this, aGivenProto);
|
||||
return dom::WebGLRenderingContextBinding::Wrap(cx, this, givenProto);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
}
|
||||
|
||||
// nsWrapperCache
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
private:
|
||||
virtual bool ValidateAttribPointerType(bool integerMode, GLenum type, GLsizei* alignment, const char* info) override;
|
||||
|
|
|
@ -4,11 +4,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGL1Context.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Buffer objects
|
||||
|
@ -50,3 +47,5 @@ WebGL1Context::ValidateBufferUsageEnum(GLenum usage, const char* info)
|
|||
ErrorInvalidEnumInfo(info, usage);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -43,9 +43,9 @@ WebGL2Context::Create()
|
|||
}
|
||||
|
||||
JSObject*
|
||||
WebGL2Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
|
||||
WebGL2Context::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
|
||||
{
|
||||
return dom::WebGL2RenderingContextBinding::Wrap(cx, this, aGivenProto);
|
||||
return dom::WebGL2RenderingContextBinding::Wrap(cx, this, givenProto);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
// -------------------------------------------------------------------------
|
||||
// IMPLEMENT nsWrapperCache
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Buffer objects - WebGL2ContextBuffers.cpp
|
||||
|
@ -58,9 +58,9 @@ public:
|
|||
void FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
|
||||
void GetInternalformatParameter(JSContext*, GLenum target, GLenum internalformat, GLenum pname, JS::MutableHandleValue retval);
|
||||
void InvalidateFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments,
|
||||
ErrorResult& aRv);
|
||||
ErrorResult& rv);
|
||||
void InvalidateSubFramebuffer (GLenum target, const dom::Sequence<GLenum>& attachments, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height, ErrorResult& aRv);
|
||||
GLsizei width, GLsizei height, ErrorResult& rv);
|
||||
void ReadBuffer(GLenum mode);
|
||||
void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat,
|
||||
GLsizei width, GLsizei height);
|
||||
|
@ -75,12 +75,12 @@ public:
|
|||
void TexImage3D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum format, GLenum type,
|
||||
const Nullable<dom::ArrayBufferView> &pixels,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void TexSubImage3D(GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLenum type, const Nullable<dom::ArrayBufferView>& pixels,
|
||||
GLenum format, GLenum type, const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void TexSubImage3D(GLenum target, GLint level,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#include "GLContext.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLTransformFeedback.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
bool
|
||||
WebGL2Context::ValidateBufferTarget(GLenum target, const char* info)
|
||||
|
@ -224,3 +224,5 @@ WebGL2Context::GetBufferSubData(GLenum target, GLintptr offset,
|
|||
BindTransformFeedback(LOCAL_GL_TRANSFORM_FEEDBACK, currentTF);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -4,10 +4,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGL2Context.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Writing to the drawing buffer
|
||||
|
@ -17,3 +15,5 @@ WebGL2Context::DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei
|
|||
{
|
||||
MOZ_CRASH("Not Implemented.");
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -6,10 +6,11 @@
|
|||
#include "WebGL2Context.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "GLScreenBuffer.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
// Returns one of FLOAT, INT, UNSIGNED_INT.
|
||||
// Fixed-points (normalized ints) are considered FLOAT.
|
||||
|
@ -374,7 +375,7 @@ TranslateDefaultAttachments(const dom::Sequence<GLenum>& in, dom::Sequence<GLenu
|
|||
void
|
||||
WebGL2Context::InvalidateFramebuffer(GLenum target,
|
||||
const dom::Sequence<GLenum>& attachments,
|
||||
ErrorResult& aRv)
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
@ -420,7 +421,7 @@ WebGL2Context::InvalidateFramebuffer(GLenum target,
|
|||
if (!fb && !isDefaultFB) {
|
||||
dom::Sequence<GLenum> tmpAttachments;
|
||||
if (!TranslateDefaultAttachments(attachments, &tmpAttachments)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -433,7 +434,7 @@ WebGL2Context::InvalidateFramebuffer(GLenum target,
|
|||
void
|
||||
WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
ErrorResult& aRv)
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
@ -479,7 +480,7 @@ WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenu
|
|||
if (!fb && !isDefaultFB) {
|
||||
dom::Sequence<GLenum> tmpAttachments;
|
||||
if (!TranslateDefaultAttachments(attachments, &tmpAttachments)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -536,3 +537,5 @@ WebGL2Context::RenderbufferStorageMultisample(GLenum target, GLsizei samples,
|
|||
RenderbufferStorage_base("renderbufferStorageMultisample", target, samples,
|
||||
internalFormat, width, height);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
#include "WebGL2Context.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
bool WebGL2Context::ValidateClearBuffer(const char* info, GLenum buffer, GLint drawbuffer, size_t elemCount)
|
||||
{
|
||||
|
@ -140,3 +139,5 @@ WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLi
|
|||
MakeContextCurrent();
|
||||
gl->fClearBufferfi(buffer, drawbuffer, depth, stencil);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
#include "WebGLSampler.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
already_AddRefed<WebGLSampler>
|
||||
WebGL2Context::CreateSampler()
|
||||
|
@ -225,3 +224,5 @@ WebGL2Context::GetSamplerParameter(JSContext*, WebGLSampler* sampler, GLenum pna
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -5,7 +5,14 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGL2Context.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLSampler.h"
|
||||
#include "WebGLTransformFeedback.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
#include "GLContext.h"
|
||||
#include "WebGLSync.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Sync objects
|
||||
|
@ -131,3 +130,5 @@ WebGL2Context::GetSyncParameter(JSContext*, WebGLSync* sync, GLenum pname, JS::M
|
|||
|
||||
ErrorInvalidEnum("getSyncParameter: Invalid pname 0x%04x", pname);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "WebGL2Context.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
#include "GLContext.h"
|
||||
#include "WebGLTexture.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
bool
|
||||
WebGL2Context::ValidateSizedInternalFormat(GLenum internalformat, const char* info)
|
||||
|
@ -205,7 +205,7 @@ void
|
|||
WebGL2Context::TexImage3D(GLenum target, GLint level, GLenum internalformat,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLint border, GLenum format, GLenum type,
|
||||
const Nullable<dom::ArrayBufferView> &pixels,
|
||||
const dom::Nullable<dom::ArrayBufferView> &pixels,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
|
@ -219,7 +219,7 @@ WebGL2Context::TexImage3D(GLenum target, GLint level, GLenum internalformat,
|
|||
dataLength = 0;
|
||||
jsArrayType = js::Scalar::MaxTypedArrayViewType;
|
||||
} else {
|
||||
const ArrayBufferView& view = pixels.Value();
|
||||
const dom::ArrayBufferView& view = pixels.Value();
|
||||
view.ComputeLengthAndData();
|
||||
|
||||
data = view.Data();
|
||||
|
@ -318,7 +318,8 @@ void
|
|||
WebGL2Context::TexSubImage3D(GLenum rawTarget, GLint level,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
GLsizei width, GLsizei height, GLsizei depth,
|
||||
GLenum format, GLenum type, const Nullable<dom::ArrayBufferView>& pixels,
|
||||
GLenum format, GLenum type,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
|
@ -327,7 +328,7 @@ WebGL2Context::TexSubImage3D(GLenum rawTarget, GLint level,
|
|||
if (pixels.IsNull())
|
||||
return ErrorInvalidValue("texSubImage3D: pixels must not be null!");
|
||||
|
||||
const ArrayBufferView& view = pixels.Value();
|
||||
const dom::ArrayBufferView& view = pixels.Value();
|
||||
view.ComputeLengthAndData();
|
||||
|
||||
const WebGLTexImageFunc func = WebGLTexImageFunc::TexSubImage;
|
||||
|
@ -489,3 +490,5 @@ WebGL2Context::GetTexParameterInternal(const TexTarget& target, GLenum pname)
|
|||
|
||||
return WebGLContext::GetTexParameterInternal(target, pname);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
#include "WebGLTransformFeedback.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
namespace mozilla {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Transform Feedback
|
||||
|
@ -216,3 +215,5 @@ WebGL2Context::GetTransformFeedbackVarying(WebGLProgram* program, GLuint index)
|
|||
|
||||
return program->GetTransformFeedbackVarying(index);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -4,12 +4,15 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGL2Context.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
|
||||
#include "nsRefPtr.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLProgram.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -543,7 +546,7 @@ WebGL2Context::GetUniformBlockIndex(WebGLProgram* program,
|
|||
void
|
||||
WebGL2Context::GetActiveUniformBlockParameter(JSContext* cx, WebGLProgram* program,
|
||||
GLuint uniformBlockIndex, GLenum pname,
|
||||
Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
|
||||
dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
retval.SetNull();
|
||||
|
|
|
@ -91,9 +91,9 @@ WebGLActiveInfo::WebGLActiveInfo(WebGLContext* webgl, GLint elemCount, GLenum el
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
JSObject*
|
||||
WebGLActiveInfo::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
|
||||
WebGLActiveInfo::WrapObject(JSContext* js, JS::Handle<JSObject*> givenProto)
|
||||
{
|
||||
return dom::WebGLActiveInfoBinding::Wrap(js, this, aGivenProto);
|
||||
return dom::WebGLActiveInfoBinding::Wrap(js, this, givenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLActiveInfo)
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#define WEBGL_ACTIVE_INFO_H_
|
||||
|
||||
#include "GLDefs.h"
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsCycleCollectionParticipant.h" // NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS
|
||||
#include "nsISupportsImpl.h" // NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING
|
||||
|
@ -25,7 +24,7 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLActiveInfo)
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLActiveInfo)
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
WebGLContext* GetParentObject() const {
|
||||
return mWebGL;
|
||||
|
|
|
@ -104,9 +104,9 @@ WebGLBuffer::IsElementArrayUsedWithMultipleTypes() const
|
|||
}
|
||||
|
||||
JSObject*
|
||||
WebGLBuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
|
||||
WebGLBuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
|
||||
{
|
||||
return dom::WebGLBufferBinding::Wrap(cx, this, aGivenProto);
|
||||
return dom::WebGLBufferBinding::Wrap(cx, this, givenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLBuffer)
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -58,7 +58,7 @@ public:
|
|||
return Context();
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
const GLenum mGLName;
|
||||
|
||||
|
|
|
@ -5,8 +5,9 @@
|
|||
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#include <queue>
|
||||
|
||||
#include "AccessCheck.h"
|
||||
#include "CanvasUtils.h"
|
||||
#include "gfxContext.h"
|
||||
#include "gfxCrashReporterUtils.h"
|
||||
#include "gfxPattern.h"
|
||||
|
@ -16,13 +17,13 @@
|
|||
#include "GLContext.h"
|
||||
#include "GLContextProvider.h"
|
||||
#include "GLReadTexImageHelper.h"
|
||||
#include "GLScreenBuffer.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "ImageEncoder.h"
|
||||
#include "Layers.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/HTMLVideoElement.h"
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "mozilla/EnumeratedArrayCycleCollection.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/ProcessPriorityManager.h"
|
||||
|
@ -33,18 +34,25 @@
|
|||
#include "nsError.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsIConsoleService.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIGfxInfo.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsSVGEffects.h"
|
||||
#include "prenv.h"
|
||||
#include <queue>
|
||||
#include "ScopedGLHelpers.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#endif
|
||||
|
||||
// Local
|
||||
#include "CanvasUtils.h"
|
||||
#include "WebGL1Context.h"
|
||||
#include "WebGLActiveInfo.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContextLossHandler.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
|
@ -52,17 +60,20 @@
|
|||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLMemoryTracker.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLProgram.h"
|
||||
#include "WebGLQuery.h"
|
||||
#include "WebGLSampler.h"
|
||||
#include "WebGLShader.h"
|
||||
#include "WebGLTransformFeedback.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#endif
|
||||
// Generated
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gl;
|
||||
|
@ -729,7 +740,7 @@ CreateOffscreen(GLContext* gl, const WebGLContextOptions& options,
|
|||
bool
|
||||
WebGLContext::CreateOffscreenGL(bool forceEnabled)
|
||||
{
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
|
||||
layers::ISurfaceAllocator* surfAllocator = nullptr;
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
@ -903,12 +914,12 @@ WebGLContext::SetDimensions(int32_t signedWidth, int32_t signedHeight)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
|
||||
nsCOMPtr<nsIGfxInfo> gfxInfo = services::GetGfxInfo();
|
||||
bool failIfMajorPerformanceCaveat =
|
||||
!gfxPrefs::WebGLDisableFailIfMajorPerformanceCaveat() &&
|
||||
!HasAcceleratedLayers(gfxInfo);
|
||||
if (failIfMajorPerformanceCaveat) {
|
||||
Nullable<dom::WebGLContextAttributes> contextAttributes;
|
||||
dom::Nullable<dom::WebGLContextAttributes> contextAttributes;
|
||||
this->GetContextAttributes(contextAttributes);
|
||||
if (contextAttributes.Value().mFailIfMajorPerformanceCaveat) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -1182,8 +1193,6 @@ WebGLContext::UpdateLastUseIndex()
|
|||
|
||||
static uint8_t gWebGLLayerUserData;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLContextUserData : public LayerUserData
|
||||
{
|
||||
public:
|
||||
|
@ -1222,8 +1231,6 @@ private:
|
|||
nsRefPtr<HTMLCanvasElement> mCanvas;
|
||||
};
|
||||
|
||||
} // end namespace mozilla
|
||||
|
||||
already_AddRefed<layers::CanvasLayer>
|
||||
WebGLContext::GetCanvasLayer(nsDisplayListBuilder* builder,
|
||||
CanvasLayer* oldLayer,
|
||||
|
@ -1283,7 +1290,7 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* builder,
|
|||
}
|
||||
|
||||
void
|
||||
WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributes>& retval)
|
||||
WebGLContext::GetContextAttributes(dom::Nullable<dom::WebGLContextAttributes>& retval)
|
||||
{
|
||||
retval.SetNull();
|
||||
if (IsContextLost())
|
||||
|
@ -1902,7 +1909,69 @@ WebGLContext::TexImageFromVideoElement(const TexImageTarget texImageTarget,
|
|||
return ok;
|
||||
}
|
||||
|
||||
size_t mozilla::RoundUpToMultipleOf(size_t value, size_t multiple)
|
||||
void
|
||||
WebGLContext::TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xoffset,
|
||||
GLint yoffset, GLenum format, GLenum type,
|
||||
dom::Element* elt, ErrorResult* const out_rv)
|
||||
{
|
||||
// TODO: Consolidate all the parameter validation
|
||||
// checks. Instead of spreading out the cheks in multple
|
||||
// places, consolidate into one spot.
|
||||
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateTexImageTarget(rawTexImageTarget,
|
||||
WebGLTexImageFunc::TexSubImage,
|
||||
WebGLTexDimensions::Tex2D))
|
||||
{
|
||||
ErrorInvalidEnumInfo("texSubImage2D: target", rawTexImageTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
const TexImageTarget texImageTarget(rawTexImageTarget);
|
||||
|
||||
if (level < 0)
|
||||
return ErrorInvalidValue("texSubImage2D: level is negative");
|
||||
|
||||
const int32_t maxLevel = MaxTextureLevelForTexImageTarget(texImageTarget);
|
||||
if (level > maxLevel) {
|
||||
ErrorInvalidValue("texSubImage2D: level %d is too large, max is %d",
|
||||
level, maxLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
|
||||
if (!tex)
|
||||
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
|
||||
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
const TexInternalFormat internalFormat = imageInfo.EffectiveInternalFormat();
|
||||
|
||||
// Trying to handle the video by GPU directly first
|
||||
if (TexImageFromVideoElement(texImageTarget, level,
|
||||
internalFormat.get(), format, type, *elt))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> data;
|
||||
WebGLTexelFormat srcFormat;
|
||||
nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(*elt);
|
||||
*out_rv = SurfaceFromElementResultToImageSurface(res, data, &srcFormat);
|
||||
if (out_rv->Failed() || !data)
|
||||
return;
|
||||
|
||||
gfx::IntSize size = data->GetSize();
|
||||
uint32_t byteLength = data->Stride() * size.height;
|
||||
TexSubImage2D_base(texImageTarget.get(), level, xoffset, yoffset, size.width,
|
||||
size.height, data->Stride(), format, type, data->GetData(),
|
||||
byteLength, js::Scalar::MaxTypedArrayViewType, srcFormat,
|
||||
mPixelStorePremultiplyAlpha);
|
||||
}
|
||||
|
||||
size_t
|
||||
RoundUpToMultipleOf(size_t value, size_t multiple)
|
||||
{
|
||||
size_t overshoot = value + multiple - 1;
|
||||
return overshoot - (overshoot % multiple);
|
||||
|
@ -1977,3 +2046,5 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLContext)
|
|||
// ToSupports() method.
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMWebGLRenderingContext)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -6,45 +6,40 @@
|
|||
#ifndef WEBGLCONTEXT_H_
|
||||
#define WEBGLCONTEXT_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
|
||||
#include "GLDefs.h"
|
||||
#include "WebGLActiveInfo.h"
|
||||
#include "WebGLContextUnchecked.h"
|
||||
#include "WebGLFormats.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLShaderValidator.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "nsCycleCollectionNoteChild.h"
|
||||
|
||||
#include "nsIDOMWebGLRenderingContext.h"
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#include "GLContextProvider.h"
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include "ForceDiscreteGPUHelperCGL.h"
|
||||
#endif
|
||||
|
||||
#include "mozilla/dom/TypedArray.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
// Local
|
||||
#include "WebGLContextUnchecked.h"
|
||||
#include "WebGLFormats.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
|
||||
// Generated
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMWebGLRenderingContext.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
|
||||
class nsIDocShell;
|
||||
|
||||
|
@ -108,6 +103,7 @@ class SourceSurface;
|
|||
|
||||
namespace webgl {
|
||||
struct LinkedProgramInfo;
|
||||
class ShaderValidator;
|
||||
} // namespace webgl
|
||||
|
||||
WebGLTexelFormat GetWebGLTexelFormat(TexInternalFormat format);
|
||||
|
@ -201,6 +197,10 @@ class WebGLContext
|
|||
public:
|
||||
WebGLContext();
|
||||
|
||||
protected:
|
||||
virtual ~WebGLContext();
|
||||
|
||||
public:
|
||||
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLContext)
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
@ -208,7 +208,7 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(WebGLContext,
|
||||
nsIDOMWebGLRenderingContext)
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override = 0;
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override = 0;
|
||||
|
||||
NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT
|
||||
|
||||
|
@ -542,7 +542,7 @@ public:
|
|||
void PolygonOffset(GLfloat factor, GLfloat units);
|
||||
void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const Nullable<dom::ArrayBufferView>& pixels,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void RenderbufferStorage(GLenum target, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height);
|
||||
|
@ -563,7 +563,7 @@ public:
|
|||
GLenum dppass);
|
||||
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLsizei width, GLsizei height, GLint border, GLenum format,
|
||||
GLenum type, const Nullable<dom::ArrayBufferView>& pixels,
|
||||
GLenum type, const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void TexImage2D(GLenum texImageTarget, GLint level, GLenum internalFormat,
|
||||
GLenum format, GLenum type, dom::ImageData* pixels,
|
||||
|
@ -640,73 +640,25 @@ public:
|
|||
void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xoffset,
|
||||
GLint yoffset, GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const Nullable<dom::ArrayBufferView>& pixels,
|
||||
const dom::Nullable<dom::ArrayBufferView>& pixels,
|
||||
ErrorResult& rv);
|
||||
void TexSubImage2D(GLenum texImageTarget, GLint level, GLint xoffset,
|
||||
GLint yoffset, GLenum format, GLenum type,
|
||||
dom::ImageData* pixels, ErrorResult& rv);
|
||||
|
||||
void TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xoffset,
|
||||
GLint yoffset, GLenum format, GLenum type,
|
||||
dom::Element* elt, ErrorResult* const out_rv);
|
||||
|
||||
// Allow whatever element types the bindings are willing to pass
|
||||
// us in TexSubImage2D
|
||||
template<class ElementType>
|
||||
void TexSubImage2D(GLenum rawTexImageTarget, GLint level, GLint xoffset,
|
||||
GLint yoffset, GLenum format, GLenum type,
|
||||
ElementType& elt, ErrorResult& rv)
|
||||
ElementType& elt, ErrorResult& out_rv)
|
||||
{
|
||||
// TODO: Consolidate all the parameter validation
|
||||
// checks. Instead of spreading out the cheks in multple
|
||||
// places, consolidate into one spot.
|
||||
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateTexImageTarget(rawTexImageTarget,
|
||||
WebGLTexImageFunc::TexSubImage,
|
||||
WebGLTexDimensions::Tex2D))
|
||||
{
|
||||
ErrorInvalidEnumInfo("texSubImage2D: target", rawTexImageTarget);
|
||||
return;
|
||||
}
|
||||
|
||||
const TexImageTarget texImageTarget(rawTexImageTarget);
|
||||
|
||||
if (level < 0)
|
||||
return ErrorInvalidValue("texSubImage2D: level is negative");
|
||||
|
||||
const int32_t maxLevel = MaxTextureLevelForTexImageTarget(texImageTarget);
|
||||
if (level > maxLevel) {
|
||||
ErrorInvalidValue("texSubImage2D: level %d is too large, max is %d",
|
||||
level, maxLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
WebGLTexture* tex = ActiveBoundTextureForTexImageTarget(texImageTarget);
|
||||
if (!tex)
|
||||
return ErrorInvalidOperation("texSubImage2D: no texture bound on active texture unit");
|
||||
|
||||
const WebGLTexture::ImageInfo& imageInfo = tex->ImageInfoAt(texImageTarget, level);
|
||||
const TexInternalFormat internalFormat = imageInfo.EffectiveInternalFormat();
|
||||
|
||||
// Trying to handle the video by GPU directly first
|
||||
if (TexImageFromVideoElement(texImageTarget, level,
|
||||
internalFormat.get(), format, type, elt))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<gfx::DataSourceSurface> data;
|
||||
WebGLTexelFormat srcFormat;
|
||||
nsLayoutUtils::SurfaceFromElementResult res = SurfaceFromElement(elt);
|
||||
rv = SurfaceFromElementResultToImageSurface(res, data, &srcFormat);
|
||||
if (rv.Failed() || !data)
|
||||
return;
|
||||
|
||||
gfx::IntSize size = data->GetSize();
|
||||
uint32_t byteLength = data->Stride() * size.height;
|
||||
return TexSubImage2D_base(texImageTarget.get(), level, xoffset, yoffset,
|
||||
size.width, size.height, data->Stride(),
|
||||
format, type, data->GetData(), byteLength,
|
||||
js::Scalar::MaxTypedArrayViewType, srcFormat,
|
||||
mPixelStorePremultiplyAlpha);
|
||||
TexSubImage2D(rawTexImageTarget, level, xoffset, yoffset, format, type, &elt,
|
||||
&out_rv);
|
||||
}
|
||||
|
||||
void Uniform1i(WebGLUniformLocation* loc, GLint x);
|
||||
|
@ -917,7 +869,7 @@ public:
|
|||
void BufferData(GLenum target, WebGLsizeiptr size, GLenum usage);
|
||||
void BufferData(GLenum target, const dom::ArrayBufferView& data,
|
||||
GLenum usage);
|
||||
void BufferData(GLenum target, const Nullable<dom::ArrayBuffer>& maybeData,
|
||||
void BufferData(GLenum target, const dom::Nullable<dom::ArrayBuffer>& maybeData,
|
||||
GLenum usage);
|
||||
|
||||
private:
|
||||
|
@ -928,7 +880,7 @@ public:
|
|||
void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const dom::ArrayBufferView& data);
|
||||
void BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
|
||||
const Nullable<dom::ArrayBuffer>& maybeData);
|
||||
const dom::Nullable<dom::ArrayBuffer>& maybeData);
|
||||
already_AddRefed<WebGLBuffer> CreateBuffer();
|
||||
void DeleteBuffer(WebGLBuffer* buf);
|
||||
bool IsBuffer(WebGLBuffer* buf);
|
||||
|
@ -1087,8 +1039,6 @@ private:
|
|||
// -----------------------------------------------------------------------------
|
||||
// PROTECTED
|
||||
protected:
|
||||
virtual ~WebGLContext();
|
||||
|
||||
void SetFakeBlackStatus(WebGLContextFakeBlackStatus x) {
|
||||
mFakeBlackStatus = x;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
#include "WebGLVertexArray.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::gl;
|
||||
namespace mozilla {
|
||||
|
||||
// For a Tegra workaround.
|
||||
static const int MAX_DRAW_CALLS_SINCE_FLUSH = 100;
|
||||
|
@ -748,7 +746,7 @@ WebGLContext::UnbindFakeBlackTextures()
|
|||
gl->fActiveTexture(LOCAL_GL_TEXTURE0 + mActiveTexture);
|
||||
}
|
||||
|
||||
WebGLContext::FakeBlackTexture::FakeBlackTexture(GLContext* gl, TexTarget target, GLenum format)
|
||||
WebGLContext::FakeBlackTexture::FakeBlackTexture(gl::GLContext* gl, TexTarget target, GLenum format)
|
||||
: mGL(gl)
|
||||
, mGLName(0)
|
||||
{
|
||||
|
@ -788,3 +786,5 @@ WebGLContext::FakeBlackTexture::~FakeBlackTexture()
|
|||
mGL->fDeleteTextures(1, &mGLName);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -393,7 +393,7 @@ WebGLContext::EnableExtension(WebGLExtensionID ext)
|
|||
|
||||
void
|
||||
WebGLContext::GetSupportedExtensions(JSContext* cx,
|
||||
Nullable< nsTArray<nsString> >& retval)
|
||||
dom::Nullable< nsTArray<nsString> >& retval)
|
||||
{
|
||||
retval.SetNull();
|
||||
if (IsContextLost())
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "WebGLFramebuffer.h"
|
||||
#include "GLContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
WebGLContext::Clear(GLbitfield mask)
|
||||
|
@ -250,6 +250,4 @@ WebGLContext::StencilMaskSeparate(GLenum face, GLuint mask)
|
|||
gl->fStencilMaskSeparate(face, mask);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLContext.h"
|
||||
|
||||
#include "WebGLActiveInfo.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
|
@ -17,9 +19,10 @@
|
|||
#include "WebGLExtensions.h"
|
||||
#include "WebGLVertexArray.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "../../xpcom/base/nsRefPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#include "gfxContext.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
@ -49,7 +52,8 @@
|
|||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/Endian.h"
|
||||
|
||||
using namespace mozilla;
|
||||
namespace mozilla {
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::gl;
|
||||
|
@ -1023,7 +1027,7 @@ WebGLContext::GetActiveUniform(WebGLProgram* prog, GLuint index)
|
|||
|
||||
void
|
||||
WebGLContext::GetAttachedShaders(WebGLProgram* prog,
|
||||
Nullable<nsTArray<nsRefPtr<WebGLShader>>>& retval)
|
||||
dom::Nullable<nsTArray<nsRefPtr<WebGLShader>>>& retval)
|
||||
{
|
||||
retval.SetNull();
|
||||
if (IsContextLost())
|
||||
|
@ -1140,7 +1144,7 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
|
|||
|
||||
MakeContextCurrent();
|
||||
|
||||
const WebGLFramebuffer::AttachPoint& fba = fb->GetAttachPoint(attachment);
|
||||
const WebGLFBAttachPoint& fba = fb->GetAttachPoint(attachment);
|
||||
|
||||
if (fba.Renderbuffer()) {
|
||||
switch (pname) {
|
||||
|
@ -1972,7 +1976,7 @@ IsFormatAndTypeUnpackable(GLenum format, GLenum type)
|
|||
void
|
||||
WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
|
||||
GLsizei height, GLenum format,
|
||||
GLenum type, const Nullable<ArrayBufferView> &pixels,
|
||||
GLenum type, const dom::Nullable<ArrayBufferView>& pixels,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
|
@ -2087,9 +2091,9 @@ WebGLContext::ReadPixels(GLint x, GLint y, GLsizei width,
|
|||
return;
|
||||
|
||||
MOZ_ASSERT(srcFormat != LOCAL_GL_NONE);
|
||||
TexType type = TypeFromInternalFormat(srcFormat);
|
||||
isSourceTypeFloat = (type == LOCAL_GL_FLOAT ||
|
||||
type == LOCAL_GL_HALF_FLOAT);
|
||||
TexType texType = TypeFromInternalFormat(srcFormat);
|
||||
isSourceTypeFloat = (texType == LOCAL_GL_FLOAT ||
|
||||
texType == LOCAL_GL_HALF_FLOAT);
|
||||
} else {
|
||||
ClearBackbufferIfNeeded();
|
||||
|
||||
|
@ -3407,7 +3411,8 @@ void
|
|||
WebGLContext::TexImage2D(GLenum rawTarget, GLint level,
|
||||
GLenum internalformat, GLsizei width,
|
||||
GLsizei height, GLint border, GLenum format,
|
||||
GLenum type, const Nullable<ArrayBufferView> &pixels, ErrorResult& rv)
|
||||
GLenum type, const dom::Nullable<ArrayBufferView>& pixels,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
@ -3608,7 +3613,7 @@ WebGLContext::TexSubImage2D(GLenum rawTarget, GLint level,
|
|||
GLint xoffset, GLint yoffset,
|
||||
GLsizei width, GLsizei height,
|
||||
GLenum format, GLenum type,
|
||||
const Nullable<ArrayBufferView> &pixels,
|
||||
const dom::Nullable<ArrayBufferView>& pixels,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (IsContextLost())
|
||||
|
@ -3684,7 +3689,7 @@ WebGLContext::RestoreContext()
|
|||
}
|
||||
|
||||
WebGLTexelFormat
|
||||
mozilla::GetWebGLTexelFormat(TexInternalFormat effectiveInternalFormat)
|
||||
GetWebGLTexelFormat(TexInternalFormat effectiveInternalFormat)
|
||||
{
|
||||
switch (effectiveInternalFormat.get()) {
|
||||
case LOCAL_GL_RGBA8: return WebGLTexelFormat::RGBA8;
|
||||
|
@ -3768,3 +3773,5 @@ WebGLContext::SampleCoverage(GLclampf value, WebGLboolean invert) {
|
|||
MakeContextCurrent();
|
||||
gl->fSampleCoverage(value, invert);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLMemoryTracker.h"
|
||||
|
||||
using namespace mozilla;
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS(WebGLObserver, nsIObserver)
|
||||
|
||||
|
@ -151,3 +152,5 @@ WebGLMemoryTracker::GetShaderSize()
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
#include "GLContext.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace dom;
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
WebGLContext::Disable(GLenum cap)
|
||||
|
@ -353,7 +352,8 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
|||
return JS::Int32Value(0);
|
||||
case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS: {
|
||||
uint32_t length = mCompressedTextureFormats.Length();
|
||||
JSObject* obj = Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements());
|
||||
JSObject* obj = dom::Uint32Array::Create(cx, this, length,
|
||||
mCompressedTextureFormats.Elements());
|
||||
if (!obj) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -419,7 +419,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
|||
case LOCAL_GL_ALIASED_LINE_WIDTH_RANGE: {
|
||||
GLfloat fv[2] = { 0 };
|
||||
gl->fGetFloatv(pname, fv);
|
||||
JSObject* obj = Float32Array::Create(cx, this, 2, fv);
|
||||
JSObject* obj = dom::Float32Array::Create(cx, this, 2, fv);
|
||||
if (!obj) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -431,7 +431,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
|||
case LOCAL_GL_BLEND_COLOR: {
|
||||
GLfloat fv[4] = { 0 };
|
||||
gl->fGetFloatv(pname, fv);
|
||||
JSObject* obj = Float32Array::Create(cx, this, 4, fv);
|
||||
JSObject* obj = dom::Float32Array::Create(cx, this, 4, fv);
|
||||
if (!obj) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -442,7 +442,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
|||
case LOCAL_GL_MAX_VIEWPORT_DIMS: {
|
||||
GLint iv[2] = { 0 };
|
||||
gl->fGetIntegerv(pname, iv);
|
||||
JSObject* obj = Int32Array::Create(cx, this, 2, iv);
|
||||
JSObject* obj = dom::Int32Array::Create(cx, this, 2, iv);
|
||||
if (!obj) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -454,7 +454,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
|||
case LOCAL_GL_VIEWPORT: {
|
||||
GLint iv[4] = { 0 };
|
||||
gl->fGetIntegerv(pname, iv);
|
||||
JSObject* obj = Int32Array::Create(cx, this, 4, iv);
|
||||
JSObject* obj = dom::Int32Array::Create(cx, this, 4, iv);
|
||||
if (!obj) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -468,7 +468,7 @@ WebGLContext::GetParameter(JSContext* cx, GLenum pname, ErrorResult& rv)
|
|||
bool vals[4] = { bool(gl_bv[0]), bool(gl_bv[1]),
|
||||
bool(gl_bv[2]), bool(gl_bv[3]) };
|
||||
JS::Rooted<JS::Value> arr(cx);
|
||||
if (!ToJSValue(cx, vals, &arr)) {
|
||||
if (!dom::ToJSValue(cx, vals, &arr)) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return arr;
|
||||
|
@ -593,3 +593,5 @@ WebGLContext::GetStateTrackingSlot(GLenum cap)
|
|||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -27,8 +27,6 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace gl;
|
||||
|
||||
bool
|
||||
IsGLDepthFormat(TexInternalFormat internalformat)
|
||||
{
|
||||
|
@ -496,7 +494,7 @@ WebGLContext::GenerateWarning(const char* fmt, va_list ap)
|
|||
return;
|
||||
}
|
||||
|
||||
AutoJSAPI api;
|
||||
dom::AutoJSAPI api;
|
||||
if (!api.Init(mCanvasElement->OwnerDoc()->GetScopeObject())) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -7,10 +7,12 @@
|
|||
#define WEBGL_CONTEXT_UTILS_H_
|
||||
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
|
||||
#include "WebGLStrongTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
bool IsGLDepthFormat(TexInternalFormat webGLFormat);
|
||||
|
|
|
@ -14,11 +14,13 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "WebGLActiveInfo.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLProgram.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLSampler.h"
|
||||
#include "WebGLShader.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLUniformLocation.h"
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
#include "WebGLVertexArray.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace dom;
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
WebGLContext::VertexAttrib1f(GLuint index, GLfloat x0)
|
||||
|
@ -306,7 +305,7 @@ WebGLContext::GetVertexAttrib(JSContext* cx, GLuint index, GLenum pname,
|
|||
vec[2] = mVertexAttrib0Vector[2];
|
||||
vec[3] = mVertexAttrib0Vector[3];
|
||||
}
|
||||
JSObject* obj = Float32Array::Create(cx, this, 4, vec);
|
||||
JSObject* obj = dom::Float32Array::Create(cx, this, 4, vec);
|
||||
if (!obj) {
|
||||
rv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
@ -410,3 +409,5 @@ WebGLContext::VertexAttribDivisor(GLuint index, GLuint divisor)
|
|||
|
||||
gl->fVertexAttribDivisor(index, divisor);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLExtensions.h"
|
||||
|
||||
using namespace mozilla;
|
||||
namespace mozilla {
|
||||
|
||||
WebGLExtensionBase::WebGLExtensionBase(WebGLContext* context)
|
||||
: WebGLContextBoundObject(context)
|
||||
|
@ -28,3 +27,5 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLExtensionBase)
|
|||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLExtensionBase, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLExtensionBase, Release)
|
||||
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -6,14 +6,20 @@
|
|||
#ifndef WEBGL_EXTENSIONS_H_
|
||||
#define WEBGL_EXTENSIONS_H_
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/AlreadyAddRefed.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
template<typename T>
|
||||
class Sequence;
|
||||
} // namespace dom
|
||||
|
||||
class WebGLContext;
|
||||
class WebGLShader;
|
||||
class WebGLQuery;
|
||||
|
@ -43,12 +49,12 @@ protected:
|
|||
};
|
||||
|
||||
#define DECL_WEBGL_EXTENSION_GOOP \
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
#define IMPL_WEBGL_EXTENSION_GOOP(WebGLExtensionType, WebGLBindingType)\
|
||||
JSObject* \
|
||||
WebGLExtensionType::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) { \
|
||||
return dom::WebGLBindingType##Binding::Wrap(cx, this, aGivenProto); \
|
||||
WebGLExtensionType::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) { \
|
||||
return dom::WebGLBindingType##Binding::Wrap(cx, this, givenProto); \
|
||||
}
|
||||
|
||||
class WebGLExtensionCompressedTextureATC
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "WebGLFormats.h"
|
||||
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
|
|
@ -15,21 +15,21 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
WebGLFramebuffer::AttachPoint::AttachPoint(WebGLFramebuffer* fb,
|
||||
FBAttachment attachmentPoint)
|
||||
WebGLFBAttachPoint::WebGLFBAttachPoint(WebGLFramebuffer* fb,
|
||||
FBAttachment attachmentPoint)
|
||||
: mFB(fb)
|
||||
, mAttachmentPoint(attachmentPoint)
|
||||
, mTexImageTarget(LOCAL_GL_NONE)
|
||||
{ }
|
||||
|
||||
WebGLFramebuffer::AttachPoint::~AttachPoint()
|
||||
WebGLFBAttachPoint::~WebGLFBAttachPoint()
|
||||
{
|
||||
MOZ_ASSERT(!mRenderbufferPtr);
|
||||
MOZ_ASSERT(!mTexturePtr);
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::AttachPoint::IsDeleteRequested() const
|
||||
WebGLFBAttachPoint::IsDeleteRequested() const
|
||||
{
|
||||
return Texture() ? Texture()->IsDeleteRequested()
|
||||
: Renderbuffer() ? Renderbuffer()->IsDeleteRequested()
|
||||
|
@ -37,14 +37,14 @@ WebGLFramebuffer::AttachPoint::IsDeleteRequested() const
|
|||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::AttachPoint::IsDefined() const
|
||||
WebGLFBAttachPoint::IsDefined() const
|
||||
{
|
||||
return Renderbuffer() ||
|
||||
(Texture() && Texture()->HasImageInfoAt(ImageTarget(), 0));
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::AttachPoint::HasAlpha() const
|
||||
WebGLFBAttachPoint::HasAlpha() const
|
||||
{
|
||||
MOZ_ASSERT(HasImage());
|
||||
|
||||
|
@ -62,7 +62,7 @@ WebGLFramebuffer::AttachPoint::HasAlpha() const
|
|||
}
|
||||
|
||||
GLenum
|
||||
WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::AttachPoint& attachment) const
|
||||
WebGLFramebuffer::GetFormatForAttachment(const WebGLFBAttachPoint& attachment) const
|
||||
{
|
||||
MOZ_ASSERT(attachment.IsDefined());
|
||||
MOZ_ASSERT(attachment.Texture() || attachment.Renderbuffer());
|
||||
|
@ -83,7 +83,7 @@ WebGLFramebuffer::GetFormatForAttachment(const WebGLFramebuffer::AttachPoint& at
|
|||
}
|
||||
|
||||
TexInternalFormat
|
||||
WebGLFramebuffer::AttachPoint::EffectiveInternalFormat() const
|
||||
WebGLFBAttachPoint::EffectiveInternalFormat() const
|
||||
{
|
||||
const WebGLTexture* tex = Texture();
|
||||
if (tex && tex->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
|
||||
|
@ -99,7 +99,7 @@ WebGLFramebuffer::AttachPoint::EffectiveInternalFormat() const
|
|||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::AttachPoint::IsReadableFloat() const
|
||||
WebGLFBAttachPoint::IsReadableFloat() const
|
||||
{
|
||||
TexInternalFormat internalformat = EffectiveInternalFormat();
|
||||
MOZ_ASSERT(internalformat != LOCAL_GL_NONE);
|
||||
|
@ -110,7 +110,7 @@ WebGLFramebuffer::AttachPoint::IsReadableFloat() const
|
|||
}
|
||||
|
||||
static void
|
||||
UnmarkAttachment(WebGLFramebuffer::AttachPoint& attachment)
|
||||
UnmarkAttachment(WebGLFBAttachPoint& attachment)
|
||||
{
|
||||
WebGLFramebufferAttachable* maybe = attachment.Texture();
|
||||
if (!maybe)
|
||||
|
@ -121,7 +121,7 @@ UnmarkAttachment(WebGLFramebuffer::AttachPoint& attachment)
|
|||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::AttachPoint::SetTexImage(WebGLTexture* tex, TexImageTarget target,
|
||||
WebGLFBAttachPoint::SetTexImage(WebGLTexture* tex, TexImageTarget target,
|
||||
GLint level)
|
||||
{
|
||||
mFB->InvalidateFramebufferStatus();
|
||||
|
@ -138,7 +138,7 @@ WebGLFramebuffer::AttachPoint::SetTexImage(WebGLTexture* tex, TexImageTarget tar
|
|||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::AttachPoint::SetRenderbuffer(WebGLRenderbuffer* rb)
|
||||
WebGLFBAttachPoint::SetRenderbuffer(WebGLRenderbuffer* rb)
|
||||
{
|
||||
mFB->InvalidateFramebufferStatus();
|
||||
|
||||
|
@ -152,7 +152,7 @@ WebGLFramebuffer::AttachPoint::SetRenderbuffer(WebGLRenderbuffer* rb)
|
|||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::AttachPoint::HasUninitializedImageData() const
|
||||
WebGLFBAttachPoint::HasUninitializedImageData() const
|
||||
{
|
||||
if (!HasImage())
|
||||
return false;
|
||||
|
@ -171,7 +171,7 @@ WebGLFramebuffer::AttachPoint::HasUninitializedImageData() const
|
|||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::AttachPoint::SetImageDataStatus(WebGLImageDataStatus newStatus)
|
||||
WebGLFBAttachPoint::SetImageDataStatus(WebGLImageDataStatus newStatus)
|
||||
{
|
||||
if (!HasImage())
|
||||
return;
|
||||
|
@ -191,7 +191,7 @@ WebGLFramebuffer::AttachPoint::SetImageDataStatus(WebGLImageDataStatus newStatus
|
|||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::AttachPoint::HasImage() const
|
||||
WebGLFBAttachPoint::HasImage() const
|
||||
{
|
||||
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel))
|
||||
return true;
|
||||
|
@ -203,7 +203,7 @@ WebGLFramebuffer::AttachPoint::HasImage() const
|
|||
}
|
||||
|
||||
const WebGLRectangleObject&
|
||||
WebGLFramebuffer::AttachPoint::RectangleObject() const
|
||||
WebGLFBAttachPoint::RectangleObject() const
|
||||
{
|
||||
MOZ_ASSERT(HasImage(),
|
||||
"Make sure it has an image before requesting the rectangle.");
|
||||
|
@ -285,7 +285,7 @@ WebGLContext::IsFormatValidForFB(GLenum sizedFormat) const
|
|||
}
|
||||
|
||||
bool
|
||||
WebGLFramebuffer::AttachPoint::IsComplete() const
|
||||
WebGLFBAttachPoint::IsComplete() const
|
||||
{
|
||||
if (!HasImage())
|
||||
return false;
|
||||
|
@ -353,7 +353,7 @@ WebGLFramebuffer::AttachPoint::IsComplete() const
|
|||
}
|
||||
|
||||
void
|
||||
WebGLFramebuffer::AttachPoint::FinalizeAttachment(gl::GLContext* gl,
|
||||
WebGLFBAttachPoint::FinalizeAttachment(gl::GLContext* gl,
|
||||
FBAttachment attachmentLoc) const
|
||||
{
|
||||
if (!HasImage()) {
|
||||
|
@ -454,7 +454,7 @@ WebGLFramebuffer::FramebufferRenderbuffer(FBAttachment attachPointEnum,
|
|||
return;
|
||||
|
||||
// `attachPoint` is validated by ValidateFramebufferAttachment().
|
||||
AttachPoint& attachPoint = GetAttachPoint(attachPointEnum);
|
||||
WebGLFBAttachPoint& attachPoint = GetAttachPoint(attachPointEnum);
|
||||
attachPoint.SetRenderbuffer(rb);
|
||||
|
||||
InvalidateFramebufferStatus();
|
||||
|
@ -481,13 +481,13 @@ WebGLFramebuffer::FramebufferTexture2D(FBAttachment attachPointEnum,
|
|||
}
|
||||
}
|
||||
|
||||
AttachPoint& attachPoint = GetAttachPoint(attachPointEnum);
|
||||
WebGLFBAttachPoint& attachPoint = GetAttachPoint(attachPointEnum);
|
||||
attachPoint.SetTexImage(tex, texImageTarget, level);
|
||||
|
||||
InvalidateFramebufferStatus();
|
||||
}
|
||||
|
||||
WebGLFramebuffer::AttachPoint&
|
||||
WebGLFBAttachPoint&
|
||||
WebGLFramebuffer::GetAttachPoint(FBAttachment attachPoint)
|
||||
{
|
||||
switch (attachPoint.get()) {
|
||||
|
@ -581,7 +581,7 @@ WebGLFramebuffer::HasDefinedAttachments() const
|
|||
}
|
||||
|
||||
static bool
|
||||
IsIncomplete(const WebGLFramebuffer::AttachPoint& cur)
|
||||
IsIncomplete(const WebGLFBAttachPoint& cur)
|
||||
{
|
||||
return cur.IsDefined() && !cur.IsComplete();
|
||||
}
|
||||
|
@ -631,7 +631,7 @@ WebGLFramebuffer::GetAnyRectObject() const
|
|||
}
|
||||
|
||||
static bool
|
||||
RectsMatch(const WebGLFramebuffer::AttachPoint& attachment,
|
||||
RectsMatch(const WebGLFBAttachPoint& attachment,
|
||||
const WebGLRectangleObject& rect)
|
||||
{
|
||||
return attachment.RectangleObject().HasSameDimensionsAs(rect);
|
||||
|
@ -839,7 +839,7 @@ void WebGLFramebuffer::EnsureColorAttachPoints(size_t colorAttachmentId)
|
|||
|
||||
while (ColorAttachmentCount() < WebGLContext::kMaxColorAttachments) {
|
||||
GLenum nextAttachPoint = LOCAL_GL_COLOR_ATTACHMENT0 + ColorAttachmentCount();
|
||||
mMoreColorAttachments.AppendElement(AttachPoint(this, nextAttachPoint));
|
||||
mMoreColorAttachments.AppendElement(WebGLFBAttachPoint(this, nextAttachPoint));
|
||||
}
|
||||
|
||||
MOZ_ASSERT(ColorAttachmentCount() == WebGLContext::kMaxColorAttachments);
|
||||
|
@ -941,20 +941,20 @@ WebGLFramebuffer::ValidateForRead(const char* info, TexInternalFormat* const out
|
|||
// Goop.
|
||||
|
||||
JSObject*
|
||||
WebGLFramebuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
|
||||
WebGLFramebuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
|
||||
{
|
||||
return dom::WebGLFramebufferBinding::Wrap(cx, this, aGivenProto);
|
||||
return dom::WebGLFramebufferBinding::Wrap(cx, this, givenProto);
|
||||
}
|
||||
|
||||
inline void
|
||||
ImplCycleCollectionUnlink(mozilla::WebGLFramebuffer::AttachPoint& field)
|
||||
ImplCycleCollectionUnlink(mozilla::WebGLFBAttachPoint& field)
|
||||
{
|
||||
field.Unlink();
|
||||
}
|
||||
|
||||
inline void
|
||||
ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& callback,
|
||||
mozilla::WebGLFramebuffer::AttachPoint& field,
|
||||
mozilla::WebGLFBAttachPoint& field,
|
||||
const char* name,
|
||||
uint32_t flags = 0)
|
||||
{
|
||||
|
|
|
@ -7,12 +7,17 @@
|
|||
#define WEBGL_FRAMEBUFFER_H_
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLTexture.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLFramebuffer;
|
||||
class WebGLRenderbuffer;
|
||||
class WebGLTexture;
|
||||
|
||||
|
@ -20,6 +25,72 @@ namespace gl {
|
|||
class GLContext;
|
||||
} // namespace gl
|
||||
|
||||
class WebGLFBAttachPoint
|
||||
{
|
||||
public:
|
||||
WebGLFramebuffer* const mFB;
|
||||
private:
|
||||
WebGLRefPtr<WebGLTexture> mTexturePtr;
|
||||
WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
|
||||
FBAttachment mAttachmentPoint;
|
||||
TexImageTarget mTexImageTarget;
|
||||
GLint mTexImageLevel;
|
||||
|
||||
public:
|
||||
WebGLFBAttachPoint(WebGLFramebuffer* fb, FBAttachment attachmentPoint);
|
||||
~WebGLFBAttachPoint();
|
||||
|
||||
void Unlink() {
|
||||
mRenderbufferPtr = nullptr;
|
||||
mTexturePtr = nullptr;
|
||||
}
|
||||
|
||||
bool IsDefined() const;
|
||||
bool IsDeleteRequested() const;
|
||||
|
||||
TexInternalFormat EffectiveInternalFormat() const;
|
||||
|
||||
bool HasAlpha() const;
|
||||
bool IsReadableFloat() const;
|
||||
|
||||
void Clear() {
|
||||
SetRenderbuffer(nullptr);
|
||||
}
|
||||
|
||||
void SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint level);
|
||||
void SetRenderbuffer(WebGLRenderbuffer* rb);
|
||||
|
||||
const WebGLTexture* Texture() const {
|
||||
return mTexturePtr;
|
||||
}
|
||||
WebGLTexture* Texture() {
|
||||
return mTexturePtr;
|
||||
}
|
||||
const WebGLRenderbuffer* Renderbuffer() const {
|
||||
return mRenderbufferPtr;
|
||||
}
|
||||
WebGLRenderbuffer* Renderbuffer() {
|
||||
return mRenderbufferPtr;
|
||||
}
|
||||
TexImageTarget ImageTarget() const {
|
||||
return mTexImageTarget;
|
||||
}
|
||||
GLint MipLevel() const {
|
||||
return mTexImageLevel;
|
||||
}
|
||||
|
||||
bool HasUninitializedImageData() const;
|
||||
void SetImageDataStatus(WebGLImageDataStatus x);
|
||||
|
||||
const WebGLRectangleObject& RectangleObject() const;
|
||||
|
||||
bool HasImage() const;
|
||||
bool IsComplete() const;
|
||||
|
||||
void FinalizeAttachment(gl::GLContext* gl,
|
||||
FBAttachment attachmentLoc) const;
|
||||
};
|
||||
|
||||
class WebGLFramebuffer final
|
||||
: public nsWrapperCache
|
||||
, public WebGLRefCountedObject<WebGLFramebuffer>
|
||||
|
@ -32,72 +103,6 @@ class WebGLFramebuffer final
|
|||
public:
|
||||
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(WebGLFramebuffer)
|
||||
|
||||
class AttachPoint
|
||||
{
|
||||
public:
|
||||
WebGLFramebuffer* const mFB;
|
||||
private:
|
||||
WebGLRefPtr<WebGLTexture> mTexturePtr;
|
||||
WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
|
||||
FBAttachment mAttachmentPoint;
|
||||
TexImageTarget mTexImageTarget;
|
||||
GLint mTexImageLevel;
|
||||
|
||||
public:
|
||||
AttachPoint(WebGLFramebuffer* fb, FBAttachment attachmentPoint);
|
||||
~AttachPoint();
|
||||
|
||||
void Unlink() {
|
||||
mRenderbufferPtr = nullptr;
|
||||
mTexturePtr = nullptr;
|
||||
}
|
||||
|
||||
bool IsDefined() const;
|
||||
bool IsDeleteRequested() const;
|
||||
|
||||
TexInternalFormat EffectiveInternalFormat() const;
|
||||
|
||||
bool HasAlpha() const;
|
||||
bool IsReadableFloat() const;
|
||||
|
||||
void Clear() {
|
||||
SetRenderbuffer(nullptr);
|
||||
}
|
||||
|
||||
void SetTexImage(WebGLTexture* tex, TexImageTarget target, GLint level);
|
||||
void SetRenderbuffer(WebGLRenderbuffer* rb);
|
||||
|
||||
const WebGLTexture* Texture() const {
|
||||
return mTexturePtr;
|
||||
}
|
||||
WebGLTexture* Texture() {
|
||||
return mTexturePtr;
|
||||
}
|
||||
const WebGLRenderbuffer* Renderbuffer() const {
|
||||
return mRenderbufferPtr;
|
||||
}
|
||||
WebGLRenderbuffer* Renderbuffer() {
|
||||
return mRenderbufferPtr;
|
||||
}
|
||||
TexImageTarget ImageTarget() const {
|
||||
return mTexImageTarget;
|
||||
}
|
||||
GLint MipLevel() const {
|
||||
return mTexImageLevel;
|
||||
}
|
||||
|
||||
bool HasUninitializedImageData() const;
|
||||
void SetImageDataStatus(WebGLImageDataStatus x);
|
||||
|
||||
const WebGLRectangleObject& RectangleObject() const;
|
||||
|
||||
bool HasImage() const;
|
||||
bool IsComplete() const;
|
||||
|
||||
void FinalizeAttachment(gl::GLContext* gl,
|
||||
FBAttachment attachmentLoc) const;
|
||||
};
|
||||
|
||||
const GLuint mGLName;
|
||||
|
||||
private:
|
||||
|
@ -106,11 +111,11 @@ private:
|
|||
GLenum mReadBufferMode;
|
||||
|
||||
// No need to chase pointers for the oft-used color0.
|
||||
AttachPoint mColorAttachment0;
|
||||
AttachPoint mDepthAttachment;
|
||||
AttachPoint mStencilAttachment;
|
||||
AttachPoint mDepthStencilAttachment;
|
||||
nsTArray<AttachPoint> mMoreColorAttachments;
|
||||
WebGLFBAttachPoint mColorAttachment0;
|
||||
WebGLFBAttachPoint mDepthAttachment;
|
||||
WebGLFBAttachPoint mStencilAttachment;
|
||||
WebGLFBAttachPoint mDepthStencilAttachment;
|
||||
nsTArray<WebGLFBAttachPoint> mMoreColorAttachments;
|
||||
|
||||
#ifdef ANDROID
|
||||
// Bug 1140459: Some drivers (including our test slaves!) don't
|
||||
|
@ -148,7 +153,7 @@ public:
|
|||
FBStatus CheckFramebufferStatus() const;
|
||||
|
||||
GLenum
|
||||
GetFormatForAttachment(const WebGLFramebuffer::AttachPoint& attachment) const;
|
||||
GetFormatForAttachment(const WebGLFBAttachPoint& attachment) const;
|
||||
|
||||
bool HasDepthStencilConflict() const {
|
||||
return int(mDepthAttachment.IsDefined()) +
|
||||
|
@ -159,25 +164,25 @@ public:
|
|||
size_t ColorAttachmentCount() const {
|
||||
return 1 + mMoreColorAttachments.Length();
|
||||
}
|
||||
const AttachPoint& ColorAttachment(size_t colorAttachmentId) const {
|
||||
const WebGLFBAttachPoint& ColorAttachment(size_t colorAttachmentId) const {
|
||||
MOZ_ASSERT(colorAttachmentId < ColorAttachmentCount());
|
||||
return colorAttachmentId ? mMoreColorAttachments[colorAttachmentId - 1]
|
||||
: mColorAttachment0;
|
||||
}
|
||||
|
||||
const AttachPoint& DepthAttachment() const {
|
||||
const WebGLFBAttachPoint& DepthAttachment() const {
|
||||
return mDepthAttachment;
|
||||
}
|
||||
|
||||
const AttachPoint& StencilAttachment() const {
|
||||
const WebGLFBAttachPoint& StencilAttachment() const {
|
||||
return mStencilAttachment;
|
||||
}
|
||||
|
||||
const AttachPoint& DepthStencilAttachment() const {
|
||||
const WebGLFBAttachPoint& DepthStencilAttachment() const {
|
||||
return mDepthStencilAttachment;
|
||||
}
|
||||
|
||||
AttachPoint& GetAttachPoint(FBAttachment attachPointEnum);
|
||||
WebGLFBAttachPoint& GetAttachPoint(FBAttachment attachPointEnum);
|
||||
|
||||
void DetachTexture(const WebGLTexture* tex);
|
||||
|
||||
|
@ -191,7 +196,7 @@ public:
|
|||
|
||||
void FinalizeAttachments() const;
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLFramebuffer)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLFramebuffer)
|
||||
|
|
|
@ -5,15 +5,12 @@
|
|||
|
||||
#include "WebGLFramebufferAttachable.h"
|
||||
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLTexture.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
WebGLFramebufferAttachable::MarkAttachment(const WebGLFramebuffer::AttachPoint& attachment)
|
||||
WebGLFramebufferAttachable::MarkAttachment(const WebGLFBAttachPoint& attachment)
|
||||
{
|
||||
if (mAttachmentPoints.Contains(&attachment))
|
||||
return; // Already attached. Ignore.
|
||||
|
@ -22,7 +19,7 @@ WebGLFramebufferAttachable::MarkAttachment(const WebGLFramebuffer::AttachPoint&
|
|||
}
|
||||
|
||||
void
|
||||
WebGLFramebufferAttachable::UnmarkAttachment(const WebGLFramebuffer::AttachPoint& attachment)
|
||||
WebGLFramebufferAttachable::UnmarkAttachment(const WebGLFBAttachPoint& attachment)
|
||||
{
|
||||
const size_t i = mAttachmentPoints.IndexOf(&attachment);
|
||||
if (i == mAttachmentPoints.NoIndex) {
|
||||
|
|
|
@ -6,22 +6,19 @@
|
|||
#ifndef WEBGL_FRAMEBUFFER_ATTACHABLE_H_
|
||||
#define WEBGL_FRAMEBUFFER_ATTACHABLE_H_
|
||||
|
||||
#include "GLDefs.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
class WebGLFBAttachPoint;
|
||||
|
||||
class WebGLFramebufferAttachable
|
||||
{
|
||||
nsTArray<const WebGLFramebuffer::AttachPoint*> mAttachmentPoints;
|
||||
nsTArray<const WebGLFBAttachPoint*> mAttachmentPoints;
|
||||
|
||||
public:
|
||||
// Track FBO/Attachment combinations
|
||||
void MarkAttachment(const WebGLFramebuffer::AttachPoint& attachment);
|
||||
void UnmarkAttachment(const WebGLFramebuffer::AttachPoint& attachment);
|
||||
void MarkAttachment(const WebGLFBAttachPoint& attachment);
|
||||
void UnmarkAttachment(const WebGLFBAttachPoint& attachment);
|
||||
void InvalidateStatusOfAttachedFBs() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLMemoryTracker.h"
|
||||
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
#include "WebGLProgram.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLShader.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLUniformLocation.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_ISUPPORTS(WebGLObserver, nsIObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* handleReport,
|
||||
nsISupports* data, bool)
|
||||
{
|
||||
#define REPORT(_path, _kind, _units, _amount, _desc) \
|
||||
do { \
|
||||
nsresult rv; \
|
||||
rv = handleReport->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \
|
||||
_kind, _units, _amount, \
|
||||
NS_LITERAL_CSTRING(_desc), data); \
|
||||
NS_ENSURE_SUCCESS(rv, rv); \
|
||||
} while (0)
|
||||
|
||||
REPORT("webgl-texture-memory",
|
||||
KIND_OTHER, UNITS_BYTES, GetTextureMemoryUsed(),
|
||||
"Memory used by WebGL textures.The OpenGL"
|
||||
" implementation is free to store these textures in either video"
|
||||
" memory or main memory. This measurement is only a lower bound,"
|
||||
" actual memory usage may be higher for example if the storage"
|
||||
" is strided.");
|
||||
|
||||
REPORT("webgl-texture-count",
|
||||
KIND_OTHER, UNITS_COUNT, GetTextureCount(),
|
||||
"Number of WebGL textures.");
|
||||
|
||||
REPORT("webgl-buffer-memory",
|
||||
KIND_OTHER, UNITS_BYTES, GetBufferMemoryUsed(),
|
||||
"Memory used by WebGL buffers. The OpenGL"
|
||||
" implementation is free to store these buffers in either video"
|
||||
" memory or main memory. This measurement is only a lower bound,"
|
||||
" actual memory usage may be higher for example if the storage"
|
||||
" is strided.");
|
||||
|
||||
REPORT("explicit/webgl/buffer-cache-memory",
|
||||
KIND_HEAP, UNITS_BYTES, GetBufferCacheMemoryUsed(),
|
||||
"Memory used by WebGL buffer caches. The WebGL"
|
||||
" implementation caches the contents of element array buffers"
|
||||
" only.This adds up with the webgl-buffer-memory value, but"
|
||||
" contrary to it, this one represents bytes on the heap,"
|
||||
" not managed by OpenGL.");
|
||||
|
||||
REPORT("webgl-buffer-count",
|
||||
KIND_OTHER, UNITS_COUNT, GetBufferCount(),
|
||||
"Number of WebGL buffers.");
|
||||
|
||||
REPORT("webgl-renderbuffer-memory",
|
||||
KIND_OTHER, UNITS_BYTES, GetRenderbufferMemoryUsed(),
|
||||
"Memory used by WebGL renderbuffers. The OpenGL"
|
||||
" implementation is free to store these renderbuffers in either"
|
||||
" video memory or main memory. This measurement is only a lower"
|
||||
" bound, actual memory usage may be higher for example if the"
|
||||
" storage is strided.");
|
||||
|
||||
REPORT("webgl-renderbuffer-count",
|
||||
KIND_OTHER, UNITS_COUNT, GetRenderbufferCount(),
|
||||
"Number of WebGL renderbuffers.");
|
||||
|
||||
REPORT("explicit/webgl/shader",
|
||||
KIND_HEAP, UNITS_BYTES, GetShaderSize(),
|
||||
"Combined size of WebGL shader ASCII sources and translation"
|
||||
" logs cached on the heap.");
|
||||
|
||||
REPORT("webgl-shader-count",
|
||||
KIND_OTHER, UNITS_COUNT, GetShaderCount(),
|
||||
"Number of WebGL shaders.");
|
||||
|
||||
REPORT("webgl-context-count",
|
||||
KIND_OTHER, UNITS_COUNT, GetContextCount(),
|
||||
"Number of WebGL contexts.");
|
||||
|
||||
#undef REPORT
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(WebGLMemoryTracker, nsIMemoryReporter)
|
||||
|
||||
StaticRefPtr<WebGLMemoryTracker> WebGLMemoryTracker::sUniqueInstance;
|
||||
|
||||
WebGLMemoryTracker*
|
||||
WebGLMemoryTracker::UniqueInstance()
|
||||
{
|
||||
if (!sUniqueInstance) {
|
||||
sUniqueInstance = new WebGLMemoryTracker;
|
||||
sUniqueInstance->InitMemoryReporter();
|
||||
}
|
||||
return sUniqueInstance;
|
||||
}
|
||||
|
||||
WebGLMemoryTracker::WebGLMemoryTracker()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
WebGLMemoryTracker::InitMemoryReporter()
|
||||
{
|
||||
RegisterWeakMemoryReporter(this);
|
||||
}
|
||||
|
||||
WebGLMemoryTracker::~WebGLMemoryTracker()
|
||||
{
|
||||
UnregisterWeakMemoryReporter(this);
|
||||
}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLBufferMallocSizeOf)
|
||||
|
||||
int64_t
|
||||
WebGLMemoryTracker::GetBufferCacheMemoryUsed()
|
||||
{
|
||||
const ContextsArrayType& contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
|
||||
buffer;
|
||||
buffer = buffer->getNext())
|
||||
{
|
||||
if (buffer->Content() == WebGLBuffer::Kind::ElementArray) {
|
||||
result += buffer->SizeOfIncludingThis(WebGLBufferMallocSizeOf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLShaderMallocSizeOf)
|
||||
|
||||
int64_t
|
||||
WebGLMemoryTracker::GetShaderSize()
|
||||
{
|
||||
const ContextsArrayType& contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLShader* shader = contexts[i]->mShaders.getFirst();
|
||||
shader;
|
||||
shader = shader->getNext())
|
||||
{
|
||||
result += shader->SizeOfIncludingThis(WebGLShaderMallocSizeOf);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/ int64_t
|
||||
WebGLMemoryTracker::GetTextureMemoryUsed()
|
||||
{
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLTexture* texture = contexts[i]->mTextures.getFirst();
|
||||
texture;
|
||||
texture = texture->getNext())
|
||||
{
|
||||
result += texture->MemoryUsage();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/ int64_t
|
||||
WebGLMemoryTracker::GetTextureCount()
|
||||
{
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLTexture* texture = contexts[i]->mTextures.getFirst();
|
||||
texture;
|
||||
texture = texture->getNext())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/ int64_t
|
||||
WebGLMemoryTracker::GetBufferMemoryUsed()
|
||||
{
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
|
||||
buffer;
|
||||
buffer = buffer->getNext())
|
||||
{
|
||||
result += buffer->ByteLength();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/ int64_t
|
||||
WebGLMemoryTracker::GetBufferCount()
|
||||
{
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
|
||||
buffer;
|
||||
buffer = buffer->getNext())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/ int64_t
|
||||
WebGLMemoryTracker::GetRenderbufferMemoryUsed()
|
||||
{
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLRenderbuffer* rb = contexts[i]->mRenderbuffers.getFirst();
|
||||
rb;
|
||||
rb = rb->getNext())
|
||||
{
|
||||
result += rb->MemoryUsage();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/ int64_t
|
||||
WebGLMemoryTracker::GetRenderbufferCount()
|
||||
{
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLRenderbuffer* rb = contexts[i]->mRenderbuffers.getFirst();
|
||||
rb;
|
||||
rb = rb->getNext())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*static*/ int64_t
|
||||
WebGLMemoryTracker::GetShaderCount()
|
||||
{
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLShader* shader = contexts[i]->mShaders.getFirst();
|
||||
shader;
|
||||
shader = shader->getNext())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -8,17 +8,11 @@
|
|||
|
||||
#include "mozilla/StaticPtr.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "WebGLBuffer.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLVertexAttribData.h"
|
||||
#include "WebGLProgram.h"
|
||||
#include "WebGLRenderbuffer.h"
|
||||
#include "WebGLShader.h"
|
||||
#include "WebGLTexture.h"
|
||||
#include "WebGLUniformLocation.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class WebGLContext;
|
||||
|
||||
class WebGLMemoryTracker : public nsIMemoryReporter
|
||||
{
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
@ -58,107 +52,23 @@ class WebGLMemoryTracker : public nsIMemoryReporter
|
|||
private:
|
||||
virtual ~WebGLMemoryTracker();
|
||||
|
||||
static int64_t GetTextureMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLTexture* texture = contexts[i]->mTextures.getFirst();
|
||||
texture;
|
||||
texture = texture->getNext())
|
||||
{
|
||||
result += texture->MemoryUsage();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static int64_t GetTextureMemoryUsed();
|
||||
|
||||
static int64_t GetTextureCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLTexture* texture = contexts[i]->mTextures.getFirst();
|
||||
texture;
|
||||
texture = texture->getNext())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static int64_t GetTextureCount();
|
||||
|
||||
static int64_t GetBufferMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
|
||||
buffer;
|
||||
buffer = buffer->getNext())
|
||||
{
|
||||
result += buffer->ByteLength();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static int64_t GetBufferMemoryUsed();
|
||||
|
||||
static int64_t GetBufferCacheMemoryUsed();
|
||||
|
||||
static int64_t GetBufferCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
|
||||
buffer;
|
||||
buffer = buffer->getNext())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static int64_t GetBufferCount();
|
||||
|
||||
static int64_t GetRenderbufferMemoryUsed() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLRenderbuffer* rb = contexts[i]->mRenderbuffers.getFirst();
|
||||
rb;
|
||||
rb = rb->getNext())
|
||||
{
|
||||
result += rb->MemoryUsage();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static int64_t GetRenderbufferMemoryUsed();
|
||||
|
||||
static int64_t GetRenderbufferCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLRenderbuffer* rb = contexts[i]->mRenderbuffers.getFirst();
|
||||
rb;
|
||||
rb = rb->getNext())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static int64_t GetRenderbufferCount();
|
||||
|
||||
static int64_t GetShaderSize();
|
||||
|
||||
static int64_t GetShaderCount() {
|
||||
const ContextsArrayType & contexts = Contexts();
|
||||
int64_t result = 0;
|
||||
for(size_t i = 0; i < contexts.Length(); ++i) {
|
||||
for (const WebGLShader* shader = contexts[i]->mShaders.getFirst();
|
||||
shader;
|
||||
shader = shader->getNext())
|
||||
{
|
||||
result++;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
static int64_t GetShaderCount();
|
||||
|
||||
static int64_t GetContextCount() {
|
||||
return Contexts().Length();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#define WEBGLOBJECTMODEL_H_
|
||||
|
||||
#include "nsCycleCollectionNoteChild.h"
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
#include "WebGLProgram.h"
|
||||
|
||||
#include "GLContext.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
|
||||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "nsRefPtr.h"
|
||||
#include "WebGLActiveInfo.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLShader.h"
|
||||
#include "WebGLUniformLocation.h"
|
||||
|
@ -67,12 +71,12 @@ ParseName(const nsCString& name, nsCString* const out_baseName,
|
|||
static void
|
||||
AddActiveInfo(WebGLContext* webgl, GLint elemCount, GLenum elemType, bool isArray,
|
||||
const nsACString& baseUserName, const nsACString& baseMappedName,
|
||||
std::vector<nsRefPtr<WebGLActiveInfo>>* activeInfoList,
|
||||
std::vector<RefPtr<WebGLActiveInfo>>* activeInfoList,
|
||||
std::map<nsCString, const WebGLActiveInfo*>* infoLocMap)
|
||||
{
|
||||
nsRefPtr<WebGLActiveInfo> info = new WebGLActiveInfo(webgl, elemCount, elemType,
|
||||
isArray, baseUserName,
|
||||
baseMappedName);
|
||||
RefPtr<WebGLActiveInfo> info = new WebGLActiveInfo(webgl, elemCount, elemType,
|
||||
isArray, baseUserName,
|
||||
baseMappedName);
|
||||
activeInfoList->push_back(info);
|
||||
|
||||
infoLocMap->insert(std::make_pair(info->mBaseUserName, info.get()));
|
||||
|
@ -202,10 +206,10 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
|
|||
// By GLES 3, GetUniformLocation("foo[0]") should return -1 if `foo` is
|
||||
// not an array. Our current linux Try slaves return the location of `foo`
|
||||
// anyways, though.
|
||||
std::string mappedName = baseMappedName.BeginReading();
|
||||
mappedName += "[0]";
|
||||
std::string mappedNameStr = baseMappedName.BeginReading();
|
||||
mappedNameStr += "[0]";
|
||||
|
||||
GLint loc = gl->fGetUniformLocation(prog->mGLName, mappedName.c_str());
|
||||
GLint loc = gl->fGetUniformLocation(prog->mGLName, mappedNameStr.c_str());
|
||||
if (loc != -1)
|
||||
isArray = true;
|
||||
}
|
||||
|
@ -246,14 +250,17 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
|
|||
MOZ_CRASH("Failed to parse `mappedName` received from driver.");
|
||||
|
||||
nsAutoCString baseUserName;
|
||||
if (!prog->FindUniformBlockByMappedName(baseMappedName, &baseUserName, &isArray)) {
|
||||
if (!prog->FindUniformBlockByMappedName(baseMappedName, &baseUserName,
|
||||
&isArray))
|
||||
{
|
||||
baseUserName = baseMappedName;
|
||||
|
||||
if (needsCheckForArrays && !isArray) {
|
||||
std::string mappedName = baseMappedName.BeginReading();
|
||||
mappedName += "[0]";
|
||||
std::string mappedNameStr = baseMappedName.BeginReading();
|
||||
mappedNameStr += "[0]";
|
||||
|
||||
GLuint loc = gl->fGetUniformBlockIndex(prog->mGLName, mappedName.c_str());
|
||||
GLuint loc = gl->fGetUniformBlockIndex(prog->mGLName,
|
||||
mappedNameStr.c_str());
|
||||
if (loc != LOCAL_GL_INVALID_INDEX)
|
||||
isArray = true;
|
||||
}
|
||||
|
@ -277,8 +284,8 @@ QueryProgramInfo(WebGLProgram* prog, gl::GLContext* gl)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
webgl::LinkedProgramInfo::LinkedProgramInfo(WebGLProgram* aProg)
|
||||
: prog(aProg)
|
||||
webgl::LinkedProgramInfo::LinkedProgramInfo(WebGLProgram* prog)
|
||||
: prog(prog)
|
||||
, fragDataMap(nullptr)
|
||||
{ }
|
||||
|
||||
|
@ -300,6 +307,11 @@ WebGLProgram::WebGLProgram(WebGLContext* webgl)
|
|||
mContext->mPrograms.insertBack(this);
|
||||
}
|
||||
|
||||
WebGLProgram::~WebGLProgram()
|
||||
{
|
||||
DeleteOnce();
|
||||
}
|
||||
|
||||
void
|
||||
WebGLProgram::Delete()
|
||||
{
|
||||
|
@ -425,7 +437,7 @@ WebGLProgram::GetActiveAttrib(GLuint index) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<WebGLActiveInfo> ret = activeList[index];
|
||||
RefPtr<WebGLActiveInfo> ret = activeList[index];
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
|
@ -446,7 +458,7 @@ WebGLProgram::GetActiveUniform(GLuint index) const
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<WebGLActiveInfo> ret = activeList[index];
|
||||
RefPtr<WebGLActiveInfo> ret = activeList[index];
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
|
@ -627,7 +639,7 @@ WebGLProgram::GetActiveUniformBlockName(GLuint uniformBlockIndex, nsAString& ret
|
|||
|
||||
void
|
||||
WebGLProgram::GetActiveUniformBlockParam(GLuint uniformBlockIndex, GLenum pname,
|
||||
Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval) const
|
||||
dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval) const
|
||||
{
|
||||
retval.SetNull();
|
||||
if (!IsLinked()) {
|
||||
|
@ -663,7 +675,7 @@ WebGLProgram::GetActiveUniformBlockParam(GLuint uniformBlockIndex, GLenum pname,
|
|||
|
||||
void
|
||||
WebGLProgram::GetActiveUniformBlockActiveUniforms(JSContext* cx, GLuint uniformBlockIndex,
|
||||
Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
|
||||
dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
|
||||
ErrorResult& rv) const
|
||||
{
|
||||
if (!IsLinked()) {
|
||||
|
@ -1013,7 +1025,7 @@ WebGLProgram::GetTransformFeedbackVarying(GLuint index)
|
|||
LinkInfo()->FindAttrib(varyingUserName, (const WebGLActiveInfo**) &info);
|
||||
MOZ_ASSERT(info);
|
||||
|
||||
nsRefPtr<WebGLActiveInfo> ret(info);
|
||||
RefPtr<WebGLActiveInfo> ret(info);
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
|
@ -1034,9 +1046,9 @@ WebGLProgram::FindUniformBlockByMappedName(const nsACString& mappedName,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
JSObject*
|
||||
WebGLProgram::WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto)
|
||||
WebGLProgram::WrapObject(JSContext* js, JS::Handle<JSObject*> givenProto)
|
||||
{
|
||||
return dom::WebGLProgramBinding::Wrap(js, this, aGivenProto);
|
||||
return dom::WebGLProgramBinding::Wrap(js, this, givenProto);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebGLProgram, mVertShader, mFragShader)
|
||||
|
|
|
@ -7,22 +7,33 @@
|
|||
#define WEBGL_PROGRAM_H_
|
||||
|
||||
#include <map>
|
||||
#include "mozilla/CheckedInt.h"
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
|
||||
#include "nsString.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLShader.h"
|
||||
|
||||
|
||||
template<class> class nsRefPtr;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class ErrorResult;
|
||||
class WebGLActiveInfo;
|
||||
class WebGLProgram;
|
||||
class WebGLShader;
|
||||
class WebGLUniformLocation;
|
||||
|
||||
namespace dom {
|
||||
template<typename> struct Nullable;
|
||||
class OwningUnsignedLongOrUint32ArrayOrBoolean;
|
||||
template<typename> class Sequence;
|
||||
} // namespace dom
|
||||
|
||||
namespace webgl {
|
||||
|
||||
struct UniformBlockInfo final
|
||||
|
@ -48,8 +59,8 @@ struct LinkedProgramInfo final
|
|||
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(LinkedProgramInfo)
|
||||
|
||||
WebGLProgram* const prog;
|
||||
std::vector<nsRefPtr<WebGLActiveInfo>> activeAttribs;
|
||||
std::vector<nsRefPtr<WebGLActiveInfo>> activeUniforms;
|
||||
std::vector<RefPtr<WebGLActiveInfo>> activeAttribs;
|
||||
std::vector<RefPtr<WebGLActiveInfo>> activeUniforms;
|
||||
|
||||
// Needed for Get{Attrib,Uniform}Location. The keys for these are non-mapped
|
||||
// user-facing `GLActiveInfo::name`s, without any final "[0]".
|
||||
|
@ -62,7 +73,7 @@ struct LinkedProgramInfo final
|
|||
// Needed for draw call validation.
|
||||
std::set<GLuint> activeAttribLocs;
|
||||
|
||||
explicit LinkedProgramInfo(WebGLProgram* aProg);
|
||||
explicit LinkedProgramInfo(WebGLProgram* prog);
|
||||
|
||||
bool FindAttrib(const nsCString& baseUserName,
|
||||
const WebGLActiveInfo** const out_activeInfo) const
|
||||
|
@ -119,10 +130,6 @@ struct LinkedProgramInfo final
|
|||
|
||||
} // namespace webgl
|
||||
|
||||
class WebGLShader;
|
||||
|
||||
typedef nsDataHashtable<nsCStringHashKey, nsCString> CStringMap;
|
||||
|
||||
class WebGLProgram final
|
||||
: public nsWrapperCache
|
||||
, public WebGLRefCountedObject<WebGLProgram>
|
||||
|
@ -151,9 +158,9 @@ public:
|
|||
GLuint GetUniformBlockIndex(const nsAString& name) const;
|
||||
void GetActiveUniformBlockName(GLuint uniformBlockIndex, nsAString& name) const;
|
||||
void GetActiveUniformBlockParam(GLuint uniformBlockIndex, GLenum pname,
|
||||
Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval) const;
|
||||
dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval) const;
|
||||
void GetActiveUniformBlockActiveUniforms(JSContext* cx, GLuint uniformBlockIndex,
|
||||
Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
|
||||
dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
|
||||
ErrorResult& rv) const;
|
||||
already_AddRefed<WebGLUniformLocation> GetUniformLocation(const nsAString& name) const;
|
||||
void UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) const;
|
||||
|
@ -187,12 +194,10 @@ public:
|
|||
return Context();
|
||||
}
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
private:
|
||||
~WebGLProgram() {
|
||||
DeleteOnce();
|
||||
}
|
||||
~WebGLProgram();
|
||||
|
||||
bool LinkAndUpdate();
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
namespace mozilla {
|
||||
|
||||
JSObject*
|
||||
WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
|
||||
WebGLQuery::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
|
||||
{
|
||||
return dom::WebGLQueryBinding::Wrap(cx, this, aGivenProto);
|
||||
return dom::WebGLQueryBinding::Wrap(cx, this, givenProto);
|
||||
}
|
||||
|
||||
WebGLQuery::WebGLQuery(WebGLContext* webgl)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "nsWrapperCache.h"
|
||||
|
||||
#include "WebGLObjectModel.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -36,7 +37,7 @@ public:
|
|||
}
|
||||
|
||||
// NS
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto) override;
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(WebGLQuery)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(WebGLQuery)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mozilla/dom/WebGLRenderingContextBinding.h"
|
||||
#include "ScopedGLHelpers.h"
|
||||
#include "WebGLContext.h"
|
||||
#include "WebGLStrongTypes.h"
|
||||
#include "WebGLTexture.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -41,9 +42,9 @@ NeedsDepthStencilEmu(gl::GLContext* gl, GLenum internalFormat)
|
|||
}
|
||||
|
||||
JSObject*
|
||||
WebGLRenderbuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto)
|
||||
WebGLRenderbuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
|
||||
{
|
||||
return dom::WebGLRenderbufferBinding::Wrap(cx, this, aGivenProto);
|
||||
return dom::WebGLRenderbufferBinding::Wrap(cx, this, givenProto);
|
||||
}
|
||||
|
||||
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl)
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче