Start of the benchmark recording framework.
This commit is contained in:
parent
cf00831a00
commit
bd6d89e1a8
33
src/core.js
33
src/core.js
@ -60,13 +60,8 @@ var Page = (function PageClosure() {
|
|||||||
function Page(xref, pageNumber, pageDict, ref) {
|
function Page(xref, pageNumber, pageDict, ref) {
|
||||||
this.pageNumber = pageNumber;
|
this.pageNumber = pageNumber;
|
||||||
this.pageDict = pageDict;
|
this.pageDict = pageDict;
|
||||||
this.stats = {
|
this.bench = new Bench();
|
||||||
create: Date.now(),
|
this.bench.enabled = !!globalScope.PDFJS.enableBench;
|
||||||
compile: 0.0,
|
|
||||||
fonts: 0.0,
|
|
||||||
images: 0.0,
|
|
||||||
render: 0.0
|
|
||||||
};
|
|
||||||
this.xref = xref;
|
this.xref = xref;
|
||||||
this.ref = ref;
|
this.ref = ref;
|
||||||
|
|
||||||
@ -187,6 +182,8 @@ var Page = (function PageClosure() {
|
|||||||
return this.IRQueue;
|
return this.IRQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.bench.time('Build IR Queue');
|
||||||
|
|
||||||
var xref = this.xref;
|
var xref = this.xref;
|
||||||
var content = xref.fetchIfRef(this.content);
|
var content = xref.fetchIfRef(this.content);
|
||||||
var resources = xref.fetchIfRef(this.resources);
|
var resources = xref.fetchIfRef(this.resources);
|
||||||
@ -201,11 +198,14 @@ var Page = (function PageClosure() {
|
|||||||
var pe = this.pe = new PartialEvaluator(
|
var pe = this.pe = new PartialEvaluator(
|
||||||
xref, handler, 'p' + this.pageNumber + '_');
|
xref, handler, 'p' + this.pageNumber + '_');
|
||||||
var IRQueue = {};
|
var IRQueue = {};
|
||||||
return (this.IRQueue = pe.getIRQueue(content, resources, IRQueue,
|
this.IRQueue = pe.getIRQueue(content, resources, IRQueue, dependency);
|
||||||
dependency));
|
|
||||||
|
this.bench.timeEnd('Build IR Queue');
|
||||||
|
return this.IRQueue;
|
||||||
},
|
},
|
||||||
|
|
||||||
ensureFonts: function pageEnsureFonts(fonts, callback) {
|
ensureFonts: function pageEnsureFonts(fonts, callback) {
|
||||||
|
this.bench.time('Font Loading');
|
||||||
// Convert the font names to the corresponding font obj.
|
// Convert the font names to the corresponding font obj.
|
||||||
for (var i = 0, ii = fonts.length; i < ii; i++) {
|
for (var i = 0, ii = fonts.length; i < ii; i++) {
|
||||||
fonts[i] = this.objs.objs[fonts[i]].data;
|
fonts[i] = this.objs.objs[fonts[i]].data;
|
||||||
@ -215,7 +215,7 @@ var Page = (function PageClosure() {
|
|||||||
var fontObjs = FontLoader.bind(
|
var fontObjs = FontLoader.bind(
|
||||||
fonts,
|
fonts,
|
||||||
function pageEnsureFontsFontObjs(fontObjs) {
|
function pageEnsureFontsFontObjs(fontObjs) {
|
||||||
this.stats.fonts = Date.now();
|
this.bench.timeEnd('Font Loading');
|
||||||
|
|
||||||
callback.call(this);
|
callback.call(this);
|
||||||
}.bind(this),
|
}.bind(this),
|
||||||
@ -224,6 +224,8 @@ var Page = (function PageClosure() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
display: function pageDisplay(gfx, callback) {
|
display: function pageDisplay(gfx, callback) {
|
||||||
|
var bench = this.bench;
|
||||||
|
bench.time('Rendering');
|
||||||
var xref = this.xref;
|
var xref = this.xref;
|
||||||
var resources = xref.fetchIfRef(this.resources);
|
var resources = xref.fetchIfRef(this.resources);
|
||||||
var mediaBox = xref.fetchIfRef(this.mediaBox);
|
var mediaBox = xref.fetchIfRef(this.mediaBox);
|
||||||
@ -244,8 +246,9 @@ var Page = (function PageClosure() {
|
|||||||
function next() {
|
function next() {
|
||||||
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next);
|
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next);
|
||||||
if (startIdx == length) {
|
if (startIdx == length) {
|
||||||
self.stats.render = Date.now();
|
|
||||||
gfx.endDrawing();
|
gfx.endDrawing();
|
||||||
|
bench.timeEnd('Rendering');
|
||||||
|
bench.timeEnd('Overall');
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -388,15 +391,14 @@ var Page = (function PageClosure() {
|
|||||||
return items;
|
return items;
|
||||||
},
|
},
|
||||||
startRendering: function pageStartRendering(ctx, callback, textLayer) {
|
startRendering: function pageStartRendering(ctx, callback, textLayer) {
|
||||||
this.startRenderingTime = Date.now();
|
var bench = this.bench;
|
||||||
|
bench.time('Overall');
|
||||||
// If there is no displayReadyPromise yet, then the IRQueue was never
|
// If there is no displayReadyPromise yet, then the IRQueue was never
|
||||||
// requested before. Make the request and create the promise.
|
// requested before. Make the request and create the promise.
|
||||||
if (!this.displayReadyPromise) {
|
if (!this.displayReadyPromise) {
|
||||||
this.pdf.startRendering(this);
|
this.pdf.startRendering(this);
|
||||||
this.displayReadyPromise = new Promise();
|
this.displayReadyPromise = new Promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Once the IRQueue and fonts are loaded, perform the actual rendering.
|
// Once the IRQueue and fonts are loaded, perform the actual rendering.
|
||||||
this.displayReadyPromise.then(
|
this.displayReadyPromise.then(
|
||||||
function pageDisplayReadyPromise() {
|
function pageDisplayReadyPromise() {
|
||||||
@ -677,7 +679,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
var pageNum = data.pageNum;
|
var pageNum = data.pageNum;
|
||||||
var page = this.pageCache[pageNum];
|
var page = this.pageCache[pageNum];
|
||||||
var depFonts = data.depFonts;
|
var depFonts = data.depFonts;
|
||||||
|
page.bench.timeEnd('Page Request');
|
||||||
page.startRenderingFromIRQueue(data.IRQueue, depFonts);
|
page.startRenderingFromIRQueue(data.IRQueue, depFonts);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
@ -786,6 +788,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
startRendering: function pdfDocStartRendering(page) {
|
startRendering: function pdfDocStartRendering(page) {
|
||||||
// The worker might not be ready to receive the page request yet.
|
// The worker might not be ready to receive the page request yet.
|
||||||
this.workerReadyPromise.then(function pdfDocStartRenderingThen() {
|
this.workerReadyPromise.then(function pdfDocStartRenderingThen() {
|
||||||
|
page.bench.time('Page Request');
|
||||||
this.messageHandler.send('page_request', page.pageNumber + 1);
|
this.messageHandler.send('page_request', page.pageNumber + 1);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
|
52
src/util.js
52
src/util.js
@ -338,3 +338,55 @@ var Promise = (function PromiseClosure() {
|
|||||||
return Promise;
|
return Promise;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
var Bench = (function BenchClosure() {
|
||||||
|
function rpad(str, pad, length) {
|
||||||
|
while (str.length < length)
|
||||||
|
str += pad;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
function Bench() {
|
||||||
|
this.started = {};
|
||||||
|
this.times = [];
|
||||||
|
this.enabled = true;
|
||||||
|
}
|
||||||
|
Bench.prototype = {
|
||||||
|
time: function benchTime(name) {
|
||||||
|
if (!this.enabled)
|
||||||
|
return;
|
||||||
|
if (name in this.started)
|
||||||
|
throw 'Timer is already running for ' + name;
|
||||||
|
this.started[name] = Date.now();
|
||||||
|
},
|
||||||
|
timeEnd: function benchTimeEnd(name) {
|
||||||
|
if (!this.enabled)
|
||||||
|
return;
|
||||||
|
if (!(name in this.started))
|
||||||
|
throw 'Timer has not been started for ' + name;
|
||||||
|
this.times.push({
|
||||||
|
'name': name,
|
||||||
|
'start': this.started[name],
|
||||||
|
'end': Date.now()
|
||||||
|
});
|
||||||
|
// Remove timer from started so it can be called again.
|
||||||
|
delete this.started[name];
|
||||||
|
},
|
||||||
|
toString: function benchToString() {
|
||||||
|
var times = this.times;
|
||||||
|
var out = '';
|
||||||
|
// Find the longest name for padding purposes.
|
||||||
|
var longest = 0;
|
||||||
|
for (var i = 0, ii = times.length; i < ii; ++i) {
|
||||||
|
var name = times[i]['name'];
|
||||||
|
if (name.length > longest)
|
||||||
|
longest = name.length;
|
||||||
|
}
|
||||||
|
for (var i = 0, ii = times.length; i < ii; ++i) {
|
||||||
|
var span = times[i];
|
||||||
|
var duration = span.end - span.start;
|
||||||
|
out += rpad(span['name'], ' ', longest) + ' ' + duration + 'ms\n';
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Bench;
|
||||||
|
})();
|
||||||
|
@ -67,6 +67,12 @@ body {
|
|||||||
|
|
||||||
span#info {
|
span#info {
|
||||||
display: none;
|
display: none;
|
||||||
|
position: fixed;
|
||||||
|
top: 32px;
|
||||||
|
right: 0px;
|
||||||
|
font-size: 10px;
|
||||||
|
white-space: pre;
|
||||||
|
font-family: courier;
|
||||||
}
|
}
|
||||||
|
|
||||||
@-moz-document regexp("http:.*debug=1.*") {
|
@-moz-document regexp("http:.*debug=1.*") {
|
||||||
|
@ -222,6 +222,7 @@ var PDFView = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pages[val - 1].updateStats();
|
||||||
currentPageNumber = val;
|
currentPageNumber = val;
|
||||||
var event = document.createEvent('UIEvents');
|
var event = document.createEvent('UIEvents');
|
||||||
event.initUIEvent('pagechange', false, false, window, 0);
|
event.initUIEvent('pagechange', false, false, window, 0);
|
||||||
@ -421,7 +422,7 @@ var PDFView = {
|
|||||||
for (var i = 1; i <= pagesCount; i++) {
|
for (var i = 1; i <= pagesCount; i++) {
|
||||||
var page = pdf.getPage(i);
|
var page = pdf.getPage(i);
|
||||||
var pageView = new PageView(container, page, i, page.width, page.height,
|
var pageView = new PageView(container, page, i, page.width, page.height,
|
||||||
page.stats, this.navigateTo.bind(this));
|
page.bench, this.navigateTo.bind(this));
|
||||||
var thumbnailView = new ThumbnailView(sidebar, page, i,
|
var thumbnailView = new ThumbnailView(sidebar, page, i,
|
||||||
page.width / page.height);
|
page.width / page.height);
|
||||||
bindOnAfterDraw(pageView, thumbnailView);
|
bindOnAfterDraw(pageView, thumbnailView);
|
||||||
@ -581,7 +582,7 @@ var PDFView = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
var PageView = function pageView(container, content, id, pageWidth, pageHeight,
|
var PageView = function pageView(container, content, id, pageWidth, pageHeight,
|
||||||
stats, navigateTo) {
|
bench, navigateTo) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.content = content;
|
this.content = content;
|
||||||
|
|
||||||
@ -800,11 +801,11 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
|
|||||||
ctx.restore();
|
ctx.restore();
|
||||||
ctx.translate(-this.x * scale, -this.y * scale);
|
ctx.translate(-this.x * scale, -this.y * scale);
|
||||||
|
|
||||||
stats.begin = Date.now();
|
|
||||||
this.content.startRendering(ctx,
|
this.content.startRendering(ctx,
|
||||||
(function pageViewDrawCallback(error) {
|
(function pageViewDrawCallback(error) {
|
||||||
if (error)
|
if (error)
|
||||||
PDFView.error('An error occurred while rendering the page.', error);
|
PDFView.error('An error occurred while rendering the page.', error);
|
||||||
|
this.stats = content.bench;
|
||||||
this.updateStats();
|
this.updateStats();
|
||||||
if (this.onAfterDraw)
|
if (this.onAfterDraw)
|
||||||
this.onAfterDraw();
|
this.onAfterDraw();
|
||||||
@ -819,10 +820,12 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.updateStats = function pageViewUpdateStats() {
|
this.updateStats = function pageViewUpdateStats() {
|
||||||
var t1 = stats.compile, t2 = stats.fonts, t3 = stats.render;
|
if (!PDFJS.enableBench || !this.stats || PDFView.page != this.id)
|
||||||
var str = 'Time to compile/fonts/render: ' +
|
return;
|
||||||
(t1 - stats.begin) + '/' + (t2 - t1) + '/' + (t3 - t2) + ' ms';
|
var stats = this.stats;
|
||||||
document.getElementById('info').innerHTML = str;
|
var statsHtml = 'Page ' + this.id + '\n';
|
||||||
|
statsHtml += stats.toString().replace(/\n/g, '<br>');
|
||||||
|
document.getElementById('info').innerHTML = statsHtml;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1016,6 +1019,11 @@ window.addEventListener('load', function webViewerLoad(evt) {
|
|||||||
if ('disableTextLayer' in params)
|
if ('disableTextLayer' in params)
|
||||||
PDFJS.disableTextLayer = (params['disableTextLayer'] === 'true');
|
PDFJS.disableTextLayer = (params['disableTextLayer'] === 'true');
|
||||||
|
|
||||||
|
if ('enableBench' in params)
|
||||||
|
PDFJS.enableBench = (params['enableBench'] === 'true');
|
||||||
|
if (PDFJS.enableBench)
|
||||||
|
document.getElementById('info').style.display = 'block';
|
||||||
|
|
||||||
var sidebarScrollView = document.getElementById('sidebarScrollView');
|
var sidebarScrollView = document.getElementById('sidebarScrollView');
|
||||||
sidebarScrollView.addEventListener('scroll', updateThumbViewArea, true);
|
sidebarScrollView.addEventListener('scroll', updateThumbViewArea, true);
|
||||||
}, true);
|
}, true);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user