Send JpegStreams to the main thread ASAP. No need for ImagesLoader anymore
This commit is contained in:
parent
32ae879219
commit
ac11f30ae9
61
pdf.js
61
pdf.js
@ -943,44 +943,6 @@ var JpegStream = (function() {
|
|||||||
return constructor;
|
return constructor;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// Simple object to track the loading images
|
|
||||||
// Initialy for every that is in loading call imageLoading()
|
|
||||||
// and, when images onload is fired, call imageLoaded()
|
|
||||||
// When all images are loaded, the onLoad event is fired.
|
|
||||||
var ImagesLoader = (function() {
|
|
||||||
function constructor() {
|
|
||||||
this.loading = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor.prototype = {
|
|
||||||
imageLoading: function() {
|
|
||||||
++this.loading;
|
|
||||||
},
|
|
||||||
|
|
||||||
imageLoaded: function() {
|
|
||||||
if (--this.loading == 0 && this.onLoad) {
|
|
||||||
this.onLoad();
|
|
||||||
delete this.onLoad;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
bind: function(jpegStream) {
|
|
||||||
if (jpegStream.loaded)
|
|
||||||
return;
|
|
||||||
this.imageLoading();
|
|
||||||
jpegStream.onLoad = this.imageLoaded.bind(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
notifyOnLoad: function(callback) {
|
|
||||||
if (this.loading == 0)
|
|
||||||
callback();
|
|
||||||
this.onLoad = callback;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return constructor;
|
|
||||||
})();
|
|
||||||
|
|
||||||
var DecryptStream = (function() {
|
var DecryptStream = (function() {
|
||||||
function constructor(str, decrypt) {
|
function constructor(str, decrypt) {
|
||||||
this.str = str;
|
this.str = str;
|
||||||
@ -3377,7 +3339,7 @@ var Page = (function() {
|
|||||||
return shadow(this, 'rotate', rotate);
|
return shadow(this, 'rotate', rotate);
|
||||||
},
|
},
|
||||||
|
|
||||||
startRenderingFromIRQueue: function(gfx, IRQueue, fonts, images, continuation) {
|
startRenderingFromIRQueue: function(gfx, IRQueue, fonts, continuation) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.IRQueue = IRQueue;
|
this.IRQueue = IRQueue;
|
||||||
|
|
||||||
@ -3396,14 +3358,11 @@ var Page = (function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.ensureFonts(fonts, function() {
|
this.ensureFonts(fonts, function() {
|
||||||
images.notifyOnLoad(function() {
|
|
||||||
self.stats.images = Date.now();
|
|
||||||
displayContinuation();
|
displayContinuation();
|
||||||
});
|
});
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getIRQueue: function(fonts, images) {
|
getIRQueue: function(handler, fonts) {
|
||||||
if (this.IRQueue) {
|
if (this.IRQueue) {
|
||||||
// content was compiled
|
// content was compiled
|
||||||
return this.IRQueue;
|
return this.IRQueue;
|
||||||
@ -3422,7 +3381,7 @@ var Page = (function() {
|
|||||||
|
|
||||||
var pe = this.pe = new PartialEvaluator();
|
var pe = this.pe = new PartialEvaluator();
|
||||||
var IRQueue = {};
|
var IRQueue = {};
|
||||||
return this.IRQueue = pe.getIRQueue(content, xref, resources, IRQueue, fonts, images, "p" + this.pageNumber + "_");
|
return this.IRQueue = pe.getIRQueue(content, xref, resources, IRQueue, handler, fonts, "p" + this.pageNumber + "_");
|
||||||
},
|
},
|
||||||
|
|
||||||
ensureFonts: function(fonts, callback) {
|
ensureFonts: function(fonts, callback) {
|
||||||
@ -3460,10 +3419,13 @@ var Page = (function() {
|
|||||||
var IRQueue = this.IRQueue;
|
var IRQueue = this.IRQueue;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
var startTime = Date.now();
|
||||||
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();
|
self.stats.render = Date.now();
|
||||||
|
console.log("page=%d - executeIRQueue: time=%dms",
|
||||||
|
self.pageNumber + 1, self.stats.render - startTime);
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4199,7 +4161,7 @@ var PartialEvaluator = (function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
constructor.prototype = {
|
constructor.prototype = {
|
||||||
getIRQueue: function(stream, xref, resources, queue, fonts, images, uniquePrefix) {
|
getIRQueue: function(stream, xref, resources, queue, handler, fonts, uniquePrefix) {
|
||||||
function buildPaintImageXObject(image, inline) {
|
function buildPaintImageXObject(image, inline) {
|
||||||
var dict = image.dict;
|
var dict = image.dict;
|
||||||
var w = dict.get('Width', 'W');
|
var w = dict.get('Width', 'W');
|
||||||
@ -4207,10 +4169,7 @@ var PartialEvaluator = (function() {
|
|||||||
|
|
||||||
if (image instanceof JpegStream) {
|
if (image instanceof JpegStream) {
|
||||||
var objId = ++objIdCounter;
|
var objId = ++objIdCounter;
|
||||||
images.push({
|
handler.send("obj", [objId, "JpegStream", image.getIR()]);
|
||||||
id: objId,
|
|
||||||
IR: image.getIR()
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add the dependency on the image object.
|
// Add the dependency on the image object.
|
||||||
fnArray.push("dependency");
|
fnArray.push("dependency");
|
||||||
@ -4306,7 +4265,7 @@ var PartialEvaluator = (function() {
|
|||||||
// TODO: Add dependency here.
|
// TODO: Add dependency here.
|
||||||
// Create an IR of the pattern code.
|
// Create an IR of the pattern code.
|
||||||
var codeIR = this.getIRQueue(pattern, xref,
|
var codeIR = this.getIRQueue(pattern, xref,
|
||||||
dict.get('Resources'), {}, fonts, images, uniquePrefix);
|
dict.get('Resources'), {}, handler, fonts, uniquePrefix);
|
||||||
|
|
||||||
args = TilingPattern.getIR(codeIR, dict, args);
|
args = TilingPattern.getIR(codeIR, dict, args);
|
||||||
}
|
}
|
||||||
@ -4344,7 +4303,7 @@ var PartialEvaluator = (function() {
|
|||||||
|
|
||||||
// This adds the IRQueue of the xObj to the current queue.
|
// This adds the IRQueue of the xObj to the current queue.
|
||||||
this.getIRQueue(xobj, xref, xobj.dict.get('Resources'), queue,
|
this.getIRQueue(xobj, xref, xobj.dict.get('Resources'), queue,
|
||||||
fonts, images, uniquePrefix);
|
handler, fonts, uniquePrefix);
|
||||||
|
|
||||||
|
|
||||||
fn = "paintFormXObjectEnd";
|
fn = "paintFormXObjectEnd";
|
||||||
|
38
worker.js
38
worker.js
@ -30,16 +30,24 @@ var WorkerPage = (function() {
|
|||||||
// TODO: Place the worker magic HERE.
|
// TODO: Place the worker magic HERE.
|
||||||
// this.page.startRendering(ctx, callback, errback);
|
// this.page.startRendering(ctx, callback, errback);
|
||||||
|
|
||||||
|
this.startRenderingTime = Date.now();
|
||||||
this.workerPDF.startRendering(this)
|
this.workerPDF.startRendering(this)
|
||||||
},
|
},
|
||||||
|
|
||||||
startRenderingFromIRQueue: function(IRQueue, fonts, images) {
|
startRenderingFromIRQueue: function(IRQueue, fonts) {
|
||||||
var gfx = new CanvasGraphics(this.ctx);
|
var gfx = new CanvasGraphics(this.ctx);
|
||||||
|
|
||||||
// TODO: Add proper handling for images loaded by the worker.
|
var startTime = Date.now();
|
||||||
var images = new ImagesLoader();
|
var callback = function(err) {
|
||||||
|
var pageNum = this.page.pageNumber + 1;
|
||||||
|
console.log("page=%d - rendering time: time=%dms",
|
||||||
|
pageNum, Date.now() - startTime);
|
||||||
|
console.log("page=%d - total time: time=%dms",
|
||||||
|
pageNum, Date.now() - this.startRenderingTime);
|
||||||
|
|
||||||
this.page.startRenderingFromIRQueue(gfx, IRQueue, fonts, images, this.callback);
|
this.callback(err);
|
||||||
|
}.bind(this);
|
||||||
|
this.page.startRenderingFromIRQueue(gfx, IRQueue, fonts, callback);
|
||||||
},
|
},
|
||||||
|
|
||||||
getLinks: function() {
|
getLinks: function() {
|
||||||
@ -153,15 +161,21 @@ var WorkerPDFDoc = (function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var images = data.images;
|
page.startRenderingFromIRQueue(data.IRQueue, data.fonts);
|
||||||
for (var i = 0; i < images.length; i++) {
|
}, this);
|
||||||
var image = images[i];
|
|
||||||
var stream = new JpegStreamIR(image.id, image.IR);
|
|
||||||
}
|
|
||||||
|
|
||||||
var timeStart = new Date();
|
handler.on("obj", function(data) {
|
||||||
page.startRenderingFromIRQueue(data.IRQueue, data.fonts, data.images);
|
var objId = data[0];
|
||||||
console.log("RenderingTime", (new Date()) - timeStart);
|
var objType = data[1];
|
||||||
|
|
||||||
|
switch (objType) {
|
||||||
|
case "JpegStream":
|
||||||
|
var IR = data[2];
|
||||||
|
new JpegStreamIR(objId, IR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw "Got unkown object type " + objType;
|
||||||
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
if (!useWorker) {
|
if (!useWorker) {
|
||||||
|
@ -20,11 +20,12 @@ var WorkerHandler = {
|
|||||||
// but stops at one point and sends the result back to the main thread.
|
// but stops at one point and sends the result back to the main thread.
|
||||||
var gfx = new CanvasGraphics(null);
|
var gfx = new CanvasGraphics(null);
|
||||||
var fonts = [];
|
var fonts = [];
|
||||||
var images = [];
|
|
||||||
|
|
||||||
|
var start = Date.now();
|
||||||
// Pre compile the pdf page and fetch the fonts/images.
|
// Pre compile the pdf page and fetch the fonts/images.
|
||||||
var IRQueue = page.getIRQueue(fonts, images);
|
var IRQueue = page.getIRQueue(handler, fonts);
|
||||||
|
|
||||||
|
console.log("page=%d - getIRQueue: time=%dms, len=%d", pageNum, Date.now() - start, IRQueue.fnArray.length);
|
||||||
// Extract the minimum of font data that is required to build all required
|
// Extract the minimum of font data that is required to build all required
|
||||||
// font stuff on the main thread.
|
// font stuff on the main thread.
|
||||||
var fontsMin = [];
|
var fontsMin = [];
|
||||||
@ -59,7 +60,6 @@ var WorkerHandler = {
|
|||||||
handler.send("page", {
|
handler.send("page", {
|
||||||
pageNum: pageNum,
|
pageNum: pageNum,
|
||||||
fonts: fontsMin,
|
fonts: fontsMin,
|
||||||
images: images,
|
|
||||||
IRQueue: IRQueue,
|
IRQueue: IRQueue,
|
||||||
});
|
});
|
||||||
}, this);
|
}, this);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user