Merge pull request #12583 from Snuffleupagus/nonBlendModesSet
Add global caching, for /Resources without blend modes, and use it to reduce repeated fetching/parsing in `PartialEvaluator.hasBlendModes`
This commit is contained in:
commit
99ac2d1036
@ -76,6 +76,7 @@ class Page {
|
|||||||
fontCache,
|
fontCache,
|
||||||
builtInCMapCache,
|
builtInCMapCache,
|
||||||
globalImageCache,
|
globalImageCache,
|
||||||
|
nonBlendModesSet,
|
||||||
}) {
|
}) {
|
||||||
this.pdfManager = pdfManager;
|
this.pdfManager = pdfManager;
|
||||||
this.pageIndex = pageIndex;
|
this.pageIndex = pageIndex;
|
||||||
@ -85,6 +86,7 @@ class Page {
|
|||||||
this.fontCache = fontCache;
|
this.fontCache = fontCache;
|
||||||
this.builtInCMapCache = builtInCMapCache;
|
this.builtInCMapCache = builtInCMapCache;
|
||||||
this.globalImageCache = globalImageCache;
|
this.globalImageCache = globalImageCache;
|
||||||
|
this.nonBlendModesSet = nonBlendModesSet;
|
||||||
this.evaluatorOptions = pdfManager.evaluatorOptions;
|
this.evaluatorOptions = pdfManager.evaluatorOptions;
|
||||||
this.resourcesPromise = null;
|
this.resourcesPromise = null;
|
||||||
|
|
||||||
@ -312,7 +314,10 @@ class Page {
|
|||||||
const opList = new OperatorList(intent, sink);
|
const opList = new OperatorList(intent, sink);
|
||||||
|
|
||||||
handler.send("StartRenderPage", {
|
handler.send("StartRenderPage", {
|
||||||
transparency: partialEvaluator.hasBlendModes(this.resources),
|
transparency: partialEvaluator.hasBlendModes(
|
||||||
|
this.resources,
|
||||||
|
this.nonBlendModesSet
|
||||||
|
),
|
||||||
pageIndex: this.pageIndex,
|
pageIndex: this.pageIndex,
|
||||||
intent,
|
intent,
|
||||||
});
|
});
|
||||||
@ -917,6 +922,7 @@ class PDFDocument {
|
|||||||
fontCache: catalog.fontCache,
|
fontCache: catalog.fontCache,
|
||||||
builtInCMapCache: catalog.builtInCMapCache,
|
builtInCMapCache: catalog.builtInCMapCache,
|
||||||
globalImageCache: catalog.globalImageCache,
|
globalImageCache: catalog.globalImageCache,
|
||||||
|
nonBlendModesSet: catalog.nonBlendModesSet,
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -239,12 +239,15 @@ class PartialEvaluator {
|
|||||||
return newEvaluator;
|
return newEvaluator;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasBlendModes(resources) {
|
hasBlendModes(resources, nonBlendModesSet) {
|
||||||
if (!(resources instanceof Dict)) {
|
if (!(resources instanceof Dict)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (resources.objId && nonBlendModesSet.has(resources.objId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const processed = new RefSet();
|
const processed = new RefSet(nonBlendModesSet);
|
||||||
if (resources.objId) {
|
if (resources.objId) {
|
||||||
processed.put(resources.objId);
|
processed.put(resources.objId);
|
||||||
}
|
}
|
||||||
@ -344,6 +347,13 @@ class PartialEvaluator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When no blend modes exist, there's no need re-fetch/re-parse any of the
|
||||||
|
// processed `Ref`s again for subsequent pages. This helps reduce redundant
|
||||||
|
// `XRef.fetch` calls for some documents (e.g. issue6961.pdf).
|
||||||
|
processed.forEach(ref => {
|
||||||
|
nonBlendModesSet.put(ref);
|
||||||
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ class Catalog {
|
|||||||
this.builtInCMapCache = new Map();
|
this.builtInCMapCache = new Map();
|
||||||
this.globalImageCache = new GlobalImageCache();
|
this.globalImageCache = new GlobalImageCache();
|
||||||
this.pageKidsCountCache = new RefSetCache();
|
this.pageKidsCountCache = new RefSetCache();
|
||||||
|
this.nonBlendModesSet = new RefSet();
|
||||||
}
|
}
|
||||||
|
|
||||||
get version() {
|
get version() {
|
||||||
@ -937,6 +938,7 @@ class Catalog {
|
|||||||
clearPrimitiveCaches();
|
clearPrimitiveCaches();
|
||||||
this.globalImageCache.clear(/* onlyData = */ manuallyTriggered);
|
this.globalImageCache.clear(/* onlyData = */ manuallyTriggered);
|
||||||
this.pageKidsCountCache.clear();
|
this.pageKidsCountCache.clear();
|
||||||
|
this.nonBlendModesSet.clear();
|
||||||
|
|
||||||
const promises = [];
|
const promises = [];
|
||||||
this.fontCache.forEach(function (promise) {
|
this.fontCache.forEach(function (promise) {
|
||||||
|
@ -277,8 +277,16 @@ var Ref = (function RefClosure() {
|
|||||||
// The reference is identified by number and generation.
|
// The reference is identified by number and generation.
|
||||||
// This structure stores only one instance of the reference.
|
// This structure stores only one instance of the reference.
|
||||||
class RefSet {
|
class RefSet {
|
||||||
constructor() {
|
constructor(parent = null) {
|
||||||
this._set = new Set();
|
if (
|
||||||
|
(typeof PDFJSDev === "undefined" ||
|
||||||
|
PDFJSDev.test("!PRODUCTION || TESTING")) &&
|
||||||
|
parent &&
|
||||||
|
!(parent instanceof RefSet)
|
||||||
|
) {
|
||||||
|
unreachable('RefSet: Invalid "parent" value.');
|
||||||
|
}
|
||||||
|
this._set = new Set(parent && parent._set);
|
||||||
}
|
}
|
||||||
|
|
||||||
has(ref) {
|
has(ref) {
|
||||||
@ -292,6 +300,16 @@ class RefSet {
|
|||||||
remove(ref) {
|
remove(ref) {
|
||||||
this._set.delete(ref.toString());
|
this._set.delete(ref.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forEach(callback) {
|
||||||
|
for (const ref of this._set.values()) {
|
||||||
|
callback(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this._set.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RefSetCache {
|
class RefSetCache {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user