Bug 1204429 - Part 1: Collect primitive counts information. r=vporof

This commit is contained in:
Daosheng Mu 2015-11-21 07:12:00 +01:00
parent 91399b403b
commit 06fa9f077c
3 changed files with 188 additions and 3 deletions

View File

@ -9,6 +9,7 @@ const promise = require("promise");
const protocol = require("devtools/server/protocol");
const {CallWatcherActor, CallWatcherFront} = require("devtools/server/actors/call-watcher");
const DevToolsUtils = require("devtools/shared/DevToolsUtils");
const {WebGLPrimitiveCounter} = require("devtools/server/primitive");
const {on, once, off, emit} = events;
const {method, custom, Arg, Option, RetVal} = protocol;
@ -113,11 +114,12 @@ var FrameSnapshotActor = protocol.ActorClass({
* @param object screenshot
* A single "snapshot-image" type instance.
*/
initialize: function(conn, { canvas, calls, screenshot }) {
initialize: function(conn, { canvas, calls, screenshot, primitive }) {
protocol.Actor.prototype.initialize.call(this, conn);
this._contentCanvas = canvas;
this._functionCalls = calls;
this._animationFrameEndScreenshot = screenshot;
this._primitive = primitive;
},
/**
@ -127,7 +129,13 @@ var FrameSnapshotActor = protocol.ActorClass({
return {
calls: this._functionCalls,
thumbnails: this._functionCalls.map(e => e._thumbnail).filter(e => !!e),
screenshot: this._animationFrameEndScreenshot
screenshot: this._animationFrameEndScreenshot,
primitive: {
tris: this._primitive.tris,
vertices: this._primitive.vertices,
points: this._primitive.points,
lines: this._primitive.lines
}
};
}, {
response: { overview: RetVal("snapshot-overview") }
@ -241,10 +249,12 @@ var CanvasActor = exports.CanvasActor = protocol.ActorClass({
initialize: function(conn, tabActor) {
protocol.Actor.prototype.initialize.call(this, conn);
this.tabActor = tabActor;
this._webGLPrimitiveCounter = new WebGLPrimitiveCounter(tabActor);
this._onContentFunctionCall = this._onContentFunctionCall.bind(this);
},
destroy: function(conn) {
protocol.Actor.prototype.destroy.call(this, conn);
this._webGLPrimitiveCounter.destroy();
this.finalize();
},
@ -317,6 +327,7 @@ var CanvasActor = exports.CanvasActor = protocol.ActorClass({
this._recordingContainsDrawCall = false;
this._callWatcher.eraseRecording();
this._callWatcher.initFrameStartTimestamp();
this._webGLPrimitiveCounter.resetCounts();
this._callWatcher.resumeRecording();
let deferred = this._currentAnimationFrameSnapshot = promise.defer();
@ -370,6 +381,7 @@ var CanvasActor = exports.CanvasActor = protocol.ActorClass({
}
if (CanvasFront.DRAW_CALLS.has(name) && this._animationStarted) {
this._handleDrawCall(functionCall);
this._webGLPrimitiveCounter.handleDrawPrimitive(functionCall);
return;
}
},
@ -415,6 +427,7 @@ var CanvasActor = exports.CanvasActor = protocol.ActorClass({
let height = this._lastContentCanvasHeight;
let flipped = !!this._lastThumbnailFlipped; // undefined -> false
let pixels = ContextUtils.getPixelStorage()["8bit"];
let primitiveResult = this._webGLPrimitiveCounter.getCounts();
let animationFrameEndScreenshot = {
index: index,
width: width,
@ -429,7 +442,13 @@ var CanvasActor = exports.CanvasActor = protocol.ActorClass({
let frameSnapshot = new FrameSnapshotActor(this.conn, {
canvas: this._lastDrawCallCanvas,
calls: functionCalls,
screenshot: animationFrameEndScreenshot
screenshot: animationFrameEndScreenshot,
primitive: {
tris: primitiveResult.tris,
vertices: primitiveResult.vertices,
points: primitiveResult.points,
lines: primitiveResult.lines
}
});
this._currentAnimationFrameSnapshot.resolve(frameSnapshot);

View File

@ -33,6 +33,7 @@ DevToolsModules(
'content-globals.js',
'content-server.jsm',
'main.js',
'primitive.js',
'protocol.js',
'worker.js'
)

View File

@ -0,0 +1,165 @@
/* 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";
const { on, once, off, emit } = require("sdk/event/core");
const { Class } = require("sdk/core/heritage");
const WebGLPrimitivesType = {
"POINTS": 0,
"LINES": 1,
"LINE_LOOP": 2,
"LINE_STRIP": 3,
"TRIANGLES": 4,
"TRIANGLE_STRIP": 5,
"TRIANGLE_FAN": 6
};
/**
* A utility for monitoring WebGL primitive draws. Takes a `tabActor`
* and monitors primitive draws over time.
*/
const WebGLDrawArrays = "drawArrays";
const WebGLDrawElements = "drawElements";
var WebGLPrimitiveCounter = exports.WebGLPrimitiveCounter = Class({
initialize: function(tabActor) {
this.tabActor = tabActor;
},
destroy: function() {
this.stopRecording();
},
/**
* Starts monitoring primitive draws, storing the primitives count per tick.
*/
resetCounts: function() {
this._tris = 0;
this._vertices = 0;
this._points = 0;
this._lines = 0;
this._startTime = this.tabActor.docShell.now();
},
/**
* Stops monitoring primitive draws, returning the recorded values.
*/
getCounts: function() {
var result = {
tris: this._tris,
vertices: this._vertices,
points: this._points,
lines: this._lines
};
this._tris = 0;
this._vertices = 0;
this._points = 0;
this._lines = 0;
return result;
},
/**
* Handles WebGL draw primitive functions to catch primitive info.
*/
handleDrawPrimitive: function(functionCall) {
let { name, args } = functionCall.details;
if (name === WebGLDrawArrays) {
this._processDrawArrays(args);
} else if (name === WebGLDrawElements) {
this._processDrawElements(args);
}
},
/**
* Processes WebGL drawArrays method to count primitve numbers
*/
_processDrawArrays: function(args) {
let mode = args[0];
let count = args[2];
switch ( mode ) {
case WebGLPrimitivesType.POINTS:
this._vertices += count;
this._points += count;
break;
case WebGLPrimitivesType.LINES:
this._vertices += count;
this._lines += (count / 2);
break;
case WebGLPrimitivesType.LINE_LOOP:
this._vertices += count;
this._lines += count;
break;
case WebGLPrimitivesType.LINE_STRIP:
this._vertices += count;
this._lines += (count - 1);
break;
case WebGLPrimitivesType.TRIANGLES:
this._tris += (count / 3);
this._vertices += count;
break;
case WebGLPrimitivesType.TRIANGLE_STRIP:
this._tris += (count - 2);
this._vertices += count;
break;
case WebGLPrimitivesType.TRIANGLE_FAN:
this._tris += (count - 2);
this._vertices += count;
break;
default:
console.error("_processDrawArrays doesn't define this type.");
break;
}
},
/**
* Processes WebGL drawElements method to count primitve numbers
*/
_processDrawElements: function(args) {
let mode = args[0];
let count = args[1];
switch ( mode ) {
case WebGLPrimitivesType.POINTS:
this._vertices += count;
this._points += count;
break;
case WebGLPrimitivesType.LINES:
this._vertices += count;
this._lines += (count / 2);
break;
case WebGLPrimitivesType.LINE_LOOP:
this._vertices += count;
this._lines += count;
break;
case WebGLPrimitivesType.LINE_STRIP:
this._vertices += count;
this._lines += (count - 1);
break;
case WebGLPrimitivesType.TRIANGLES:
let tris = count / 3;
let vertex = tris * 3;
if (tris > 1) {
vertex = tris * 2;
}
this._tris += tris;
this._vertices += vertex;
break;
case WebGLPrimitivesType.TRIANGLE_STRIP:
this._tris += (count - 2);
this._vertices += count;
break;
case WebGLPrimitivesType.TRIANGLE_FAN:
this._tris += (count - 2);
this._vertices += count;
default:
console.error("_processDrawElements doesn't define this type.");
break;
}
}
});