Skip to content

Commit

Permalink
Merge pull request #12583 from Snuffleupagus/nonBlendModesSet
Browse files Browse the repository at this point in the history
Add global caching, for /Resources without blend modes, and use it to reduce repeated fetching/parsing in `PartialEvaluator.hasBlendModes`
  • Loading branch information
timvandermeij authored Nov 5, 2020
2 parents 646f895 + 082cd8f commit 99ac2d1
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 5 deletions.
8 changes: 7 additions & 1 deletion src/core/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class Page {
fontCache,
builtInCMapCache,
globalImageCache,
nonBlendModesSet,
}) {
this.pdfManager = pdfManager;
this.pageIndex = pageIndex;
Expand All @@ -85,6 +86,7 @@ class Page {
this.fontCache = fontCache;
this.builtInCMapCache = builtInCMapCache;
this.globalImageCache = globalImageCache;
this.nonBlendModesSet = nonBlendModesSet;
this.evaluatorOptions = pdfManager.evaluatorOptions;
this.resourcesPromise = null;

Expand Down Expand Up @@ -312,7 +314,10 @@ class Page {
const opList = new OperatorList(intent, sink);

handler.send("StartRenderPage", {
transparency: partialEvaluator.hasBlendModes(this.resources),
transparency: partialEvaluator.hasBlendModes(
this.resources,
this.nonBlendModesSet
),
pageIndex: this.pageIndex,
intent,
});
Expand Down Expand Up @@ -917,6 +922,7 @@ class PDFDocument {
fontCache: catalog.fontCache,
builtInCMapCache: catalog.builtInCMapCache,
globalImageCache: catalog.globalImageCache,
nonBlendModesSet: catalog.nonBlendModesSet,
});
}));
}
Expand Down
14 changes: 12 additions & 2 deletions src/core/evaluator.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,15 @@ class PartialEvaluator {
return newEvaluator;
}

hasBlendModes(resources) {
hasBlendModes(resources, nonBlendModesSet) {
if (!(resources instanceof Dict)) {
return false;
}
if (resources.objId && nonBlendModesSet.has(resources.objId)) {
return false;
}

const processed = new RefSet();
const processed = new RefSet(nonBlendModesSet);
if (resources.objId) {
processed.put(resources.objId);
}
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions src/core/obj.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class Catalog {
this.builtInCMapCache = new Map();
this.globalImageCache = new GlobalImageCache();
this.pageKidsCountCache = new RefSetCache();
this.nonBlendModesSet = new RefSet();
}

get version() {
Expand Down Expand Up @@ -937,6 +938,7 @@ class Catalog {
clearPrimitiveCaches();
this.globalImageCache.clear(/* onlyData = */ manuallyTriggered);
this.pageKidsCountCache.clear();
this.nonBlendModesSet.clear();

const promises = [];
this.fontCache.forEach(function (promise) {
Expand Down
22 changes: 20 additions & 2 deletions src/core/primitives.js
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,16 @@ var Ref = (function RefClosure() {
// The reference is identified by number and generation.
// This structure stores only one instance of the reference.
class RefSet {
constructor() {
this._set = new Set();
constructor(parent = null) {
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) {
Expand All @@ -292,6 +300,16 @@ class RefSet {
remove(ref) {
this._set.delete(ref.toString());
}

forEach(callback) {
for (const ref of this._set.values()) {
callback(ref);
}
}

clear() {
this._set.clear();
}
}

class RefSetCache {
Expand Down

0 comments on commit 99ac2d1

Please sign in to comment.