Merge pull request #1551 from yurydelendik/issue-1549

Fix the operator list deallocation
This commit is contained in:
Brendan Dahl 2012-04-17 09:02:47 -07:00
commit 9b0224b5cf
5 changed files with 49 additions and 14 deletions

View File

@ -133,6 +133,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
this.stats = new StatTimer(); this.stats = new StatTimer();
this.stats.enabled = !!globalScope.PDFJS.enableStats; this.stats.enabled = !!globalScope.PDFJS.enableStats;
this.objs = transport.objs; this.objs = transport.objs;
this.renderInProgress = false;
} }
PDFPageProxy.prototype = { PDFPageProxy.prototype = {
/** /**
@ -198,6 +199,8 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
* rendering. * rendering.
*/ */
render: function(params) { render: function(params) {
this.renderInProgress = true;
var promise = new Promise(); var promise = new Promise();
var stats = this.stats; var stats = this.stats;
stats.time('Overall'); stats.time('Overall');
@ -205,6 +208,7 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
// 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.displayReadyPromise = new Promise(); this.displayReadyPromise = new Promise();
this.destroyed = false;
this.stats.time('Page Request'); this.stats.time('Page Request');
this.transport.messageHandler.send('RenderPageRequest', { this.transport.messageHandler.send('RenderPageRequest', {
@ -212,7 +216,14 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
}); });
} }
var self = this;
function complete(error) { function complete(error) {
self.renderInProgress = false;
if (self.destroyed) {
delete self.operatorList;
delete self.displayReadyPromise;
}
if (error) if (error)
promise.reject(error); promise.reject(error);
else else
@ -222,6 +233,11 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
// Once the operatorList and fonts are loaded, do the actual rendering. // Once the operatorList and fonts are loaded, do the actual rendering.
this.displayReadyPromise.then( this.displayReadyPromise.then(
function pageDisplayReadyPromise() { function pageDisplayReadyPromise() {
if (self.destroyed) {
complete();
return;
}
var gfx = new CanvasGraphics(params.canvasContext, var gfx = new CanvasGraphics(params.canvasContext,
this.objs, params.textLayer); this.objs, params.textLayer);
try { try {
@ -305,7 +321,6 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
gfx.executeOperatorList(operatorList, startIdx, next, stepper); gfx.executeOperatorList(operatorList, startIdx, next, stepper);
if (startIdx == length) { if (startIdx == length) {
gfx.endDrawing(); gfx.endDrawing();
delete this.operatorList;
stats.timeEnd('Rendering'); stats.timeEnd('Rendering');
stats.timeEnd('Overall'); stats.timeEnd('Overall');
if (callback) callback(); if (callback) callback();
@ -333,6 +348,17 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
}; };
promise.resolve(operationList); promise.resolve(operationList);
return promise; return promise;
},
/**
* Destroys resources allocated by the page.
*/
destroy: function() {
this.destroyed = true;
if (!this.renderInProgress) {
delete this.operatorList;
delete this.displayReadyPromise;
}
} }
}; };
return PDFPageProxy; return PDFPageProxy;
@ -463,6 +489,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
messageHandler.on('obj', function transportObj(data) { messageHandler.on('obj', function transportObj(data) {
var id = data[0]; var id = data[0];
var type = data[1]; var type = data[1];
if (this.objs.hasData(id))
return;
switch (type) { switch (type) {
case 'JpegStream': case 'JpegStream':

View File

@ -132,20 +132,18 @@ var Page = (function PageClosure() {
}, },
getOperatorList: function Page_getOperatorList(handler, dependency) { getOperatorList: function Page_getOperatorList(handler, dependency) {
if (this.operatorList) {
// content was compiled
return this.operatorList;
}
var xref = this.xref; var xref = this.xref;
var content = this.content; var content = this.content;
var resources = this.resources; var resources = this.resources;
if (isArray(content)) { if (isArray(content)) {
// fetching items // fetching items
var streams = [];
var i, n = content.length; var i, n = content.length;
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
content[i] = xref.fetchIfRef(content[i]); streams.push(xref.fetchIfRef(content[i]));
content = new StreamsSequenceStream(content); content = new StreamsSequenceStream(streams);
} else if (isStream(content)) {
content.reset();
} else if (!content) { } else if (!content) {
// replacing non-existent page content with empty one // replacing non-existent page content with empty one
content = new Stream(new Uint8Array(0)); content = new Stream(new Uint8Array(0));
@ -154,8 +152,7 @@ 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 + '_');
this.operatorList = pe.getOperatorList(content, resources, dependency); return pe.getOperatorList(content, resources, dependency);
return this.operatorList;
}, },
getLinks: function Page_getLinks() { getLinks: function Page_getLinks() {

View File

@ -153,13 +153,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
font = xref.fetchIfRef(font) || fontRes.get(fontName); font = xref.fetchIfRef(font) || fontRes.get(fontName);
assertWellFormed(isDict(font)); assertWellFormed(isDict(font));
++self.objIdCounter;
if (!font.translated) { if (!font.translated) {
font.translated = self.translateFont(font, xref, resources, font.translated = self.translateFont(font, xref, resources,
dependency); dependency);
if (font.translated) { if (font.translated) {
// keep track of each font we translated so the caller can // keep track of each font we translated so the caller can
// load them asynchronously before calling display on a page // load them asynchronously before calling display on a page
loadedName = 'font_' + uniquePrefix + (++self.objIdCounter); loadedName = 'font_' + uniquePrefix + self.objIdCounter;
font.translated.properties.loadedName = loadedName; font.translated.properties.loadedName = loadedName;
font.loadedName = loadedName; font.loadedName = loadedName;

View File

@ -194,11 +194,15 @@ function nextPage(task, loadError) {
textLayer: textLayerBuilder, textLayer: textLayerBuilder,
viewport: viewport viewport: viewport
}; };
var completeRender = (function(error) {
page.destroy();
snapshotCurrentPage(task, error);
});
page.render(renderContext).then(function() { page.render(renderContext).then(function() {
snapshotCurrentPage(task, false); completeRender(false);
}, },
function(error) { function(error) {
snapshotCurrentPage(task, 'render : ' + error); completeRender('render : ' + error);
}); });
}, },
function(error) { function(error) {

View File

@ -32,7 +32,7 @@ var Cache = function cacheCache(size) {
data.splice(i); data.splice(i);
data.push(view); data.push(view);
if (data.length > size) if (data.length > size)
data.shift().update(); data.shift().destroy();
}; };
}; };
@ -743,6 +743,11 @@ var PageView = function pageView(container, pdfPage, id, scale,
container.appendChild(anchor); container.appendChild(anchor);
container.appendChild(div); container.appendChild(div);
this.destroy = function pageViewDestroy() {
this.update();
this.pdfPage.destroy();
};
this.update = function pageViewUpdate(scale) { this.update = function pageViewUpdate(scale) {
this.scale = scale || this.scale; this.scale = scale || this.scale;
var viewport = this.pdfPage.getViewport(this.scale); var viewport = this.pdfPage.getViewport(this.scale);