Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to enable/disable hardware acceleration (bug 1902012) #18238

Merged
merged 1 commit into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions extensions/chromium/preferences_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
"type": "boolean",
"default": false
},
"enableHWA": {
"description": "Whether to enable hardware acceleration.",
"type": "boolean",
"default": false
},
"enableML": {
"type": "boolean",
"default": false
Expand Down
2 changes: 1 addition & 1 deletion src/core/default_appearance.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ class FakeUnicodeFont {
this.fontFamily = fontFamily;

const canvas = new OffscreenCanvas(1, 1);
this.ctxMeasure = canvas.getContext("2d");
this.ctxMeasure = canvas.getContext("2d", { willReadFrequently: true });

if (!FakeUnicodeFont._fontNameId) {
FakeUnicodeFont._fontNameId = 1;
Expand Down
5 changes: 4 additions & 1 deletion src/display/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ const DefaultStandardFontDataFactory =
* when creating canvases. The default value is {new DOMCanvasFactory()}.
* @property {Object} [filterFactory] - A factory instance that will be used
* to create SVG filters when rendering some images on the main canvas.
* @property {boolean} [enableHWA] - Enables hardware acceleration for
* rendering. The default value is `false`.
*/

/**
Expand Down Expand Up @@ -297,6 +299,7 @@ function getDocument(src) {
const disableStream = src.disableStream === true;
const disableAutoFetch = src.disableAutoFetch === true;
const pdfBug = src.pdfBug === true;
const enableHWA = src.enableHWA === true;

// Parameters whose default values depend on other parameters.
const length = rangeTransport ? rangeTransport.length : src.length ?? NaN;
Expand All @@ -315,7 +318,7 @@ function getDocument(src) {
isValidFetchUrl(cMapUrl, document.baseURI) &&
isValidFetchUrl(standardFontDataUrl, document.baseURI));
const canvasFactory =
src.canvasFactory || new DefaultCanvasFactory({ ownerDocument });
src.canvasFactory || new DefaultCanvasFactory({ ownerDocument, enableHWA });
const filterFactory =
src.filterFactory || new DefaultFilterFactory({ docId, ownerDocument });

Expand Down
9 changes: 7 additions & 2 deletions src/display/base_factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,13 @@ class BaseFilterFactory {
}

class BaseCanvasFactory {
constructor() {
#enableHWA = false;

constructor({ enableHWA = false } = {}) {
if (this.constructor === BaseCanvasFactory) {
unreachable("Cannot initialize BaseCanvasFactory.");
}
this.#enableHWA = enableHWA;
}

create(width, height) {
Expand All @@ -59,7 +62,9 @@ class BaseCanvasFactory {
const canvas = this._createCanvas(width, height);
return {
canvas,
context: canvas.getContext("2d"),
context: canvas.getContext("2d", {
willReadFrequently: !this.#enableHWA,
}),
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/display/display_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,8 +477,8 @@ class DOMFilterFactory extends BaseFilterFactory {
}

class DOMCanvasFactory extends BaseCanvasFactory {
constructor({ ownerDocument = globalThis.document } = {}) {
super();
constructor({ ownerDocument = globalThis.document, enableHWA = false } = {}) {
super({ enableHWA });
this._document = ownerDocument;
}

Expand Down
2 changes: 1 addition & 1 deletion src/display/editor/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class ImageManager {
// behavior in Safari.
const svg = `data:image/svg+xml;charset=UTF-8,<svg viewBox="0 0 1 1" width="1" height="1" xmlns="http://www.w3.org/2000/svg"><rect width="1" height="1" style="fill:red;"/></svg>`;
const canvas = new OffscreenCanvas(1, 3);
const ctx = canvas.getContext("2d");
const ctx = canvas.getContext("2d", { willReadFrequently: true });
const image = new Image();
image.src = svg;
const promise = image.decode().then(() => {
Expand Down
5 changes: 4 additions & 1 deletion src/display/text_layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,10 @@ class TextLayer {
canvas.className = "hiddenCanvasElement";
canvas.lang = lang;
document.body.append(canvas);
canvasContext = canvas.getContext("2d", { alpha: false });
canvasContext = canvas.getContext("2d", {
alpha: false,
willReadFrequently: true,
});
this.#canvasContexts.set(lang, canvasContext);
}
return canvasContext;
Expand Down
3 changes: 3 additions & 0 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ const PDFViewerApplication = {
)
: null;

const enableHWA = AppOptions.get("enableHWA");
const pdfViewer = new PDFViewer({
container,
viewer,
Expand All @@ -465,6 +466,7 @@ const PDFViewerApplication = {
pageColors,
mlManager: this.mlManager,
abortSignal: this._globalAbortController.signal,
enableHWA,
});
this.pdfViewer = pdfViewer;

Expand All @@ -480,6 +482,7 @@ const PDFViewerApplication = {
linkService: pdfLinkService,
pageColors,
abortSignal: this._globalAbortController.signal,
enableHWA,
});
pdfRenderingQueue.setThumbnailViewer(this.pdfThumbnailViewer);
}
Expand Down
5 changes: 5 additions & 0 deletions web/app_options.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,11 @@ const defaultOptions = {
value: "",
kind: OptionKind.API,
},
enableHWA: {
/** @type {boolean} */
value: false,
kind: OptionKind.API + OptionKind.VIEWER + OptionKind.PREFERENCE,
},
enableXfa: {
/** @type {boolean} */
value: true,
Expand Down
10 changes: 9 additions & 1 deletion web/pdf_page_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ import { XfaLayerBuilder } from "./xfa_layer_builder.js";
* @property {IL10n} [l10n] - Localization service.
* @property {Object} [layerProperties] - The object that is used to lookup
* the necessary layer-properties.
* @property {boolean} [enableHWA] - Enables hardware acceleration for
* rendering. The default value is `false`.
*/

const DEFAULT_LAYER_PROPERTIES =
Expand Down Expand Up @@ -113,6 +115,8 @@ const LAYERS_ORDER = new Map([
class PDFPageView {
#annotationMode = AnnotationMode.ENABLE_FORMS;

#enableHWA = false;

#hasRestrictedScaling = false;

#layerProperties = null;
Expand Down Expand Up @@ -163,6 +167,7 @@ class PDFPageView {
this.maxCanvasPixels =
options.maxCanvasPixels ?? AppOptions.get("maxCanvasPixels");
this.pageColors = options.pageColors || null;
this.#enableHWA = options.enableHWA || false;

this.eventBus = options.eventBus;
this.renderingQueue = options.renderingQueue;
Expand Down Expand Up @@ -981,7 +986,10 @@ class PDFPageView {
canvasWrapper.append(canvas);
this.canvas = canvas;

const ctx = canvas.getContext("2d", { alpha: false });
const ctx = canvas.getContext("2d", {
alpha: false,
willReadFrequently: !this.#enableHWA,
});
const outputScale = (this.outputScale = new OutputScale());

if (
Expand Down
13 changes: 10 additions & 3 deletions web/pdf_thumbnail_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const THUMBNAIL_WIDTH = 98; // px
* @property {Object} [pageColors] - Overwrites background and foreground colors
* with user defined ones in order to improve readability in high contrast
* mode.
* @property {boolean} [enableHWA] - Enables hardware acceleration for
* rendering. The default value is `false`.
*/

class TempImageFactory {
Expand Down Expand Up @@ -92,6 +94,7 @@ class PDFThumbnailView {
linkService,
renderingQueue,
pageColors,
enableHWA,
}) {
this.id = id;
this.renderingId = "thumbnail" + id;
Expand All @@ -103,6 +106,7 @@ class PDFThumbnailView {
this.pdfPageRotate = defaultViewport.rotation;
this._optionalContentConfigPromise = optionalContentConfigPromise || null;
this.pageColors = pageColors || null;
this.enableHWA = enableHWA || false;

this.eventBus = eventBus;
this.linkService = linkService;
Expand Down Expand Up @@ -196,11 +200,14 @@ class PDFThumbnailView {
this.resume = null;
}

#getPageDrawContext(upscaleFactor = 1) {
#getPageDrawContext(upscaleFactor = 1, enableHWA = this.enableHWA) {
// Keep the no-thumbnail outline visible, i.e. `data-loaded === false`,
// until rendering/image conversion is complete, to avoid display issues.
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d", { alpha: false });
const ctx = canvas.getContext("2d", {
alpha: false,
willReadFrequently: !enableHWA,
});
const outputScale = new OutputScale();

canvas.width = (upscaleFactor * this.canvasWidth * outputScale.sx) | 0;
Expand Down Expand Up @@ -340,7 +347,7 @@ class PDFThumbnailView {
}

#reduceImage(img) {
const { ctx, canvas } = this.#getPageDrawContext();
const { ctx, canvas } = this.#getPageDrawContext(1, true);

if (img.width <= 2 * canvas.width) {
ctx.drawImage(
Expand Down
5 changes: 5 additions & 0 deletions web/pdf_thumbnail_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ const THUMBNAIL_SELECTED_CLASS = "selected";
* mode.
* @property {AbortSignal} [abortSignal] - The AbortSignal for the window
* events.
* @property {boolean} [enableHWA] - Enables hardware acceleration for
* rendering. The default value is `false`.
*/

/**
Expand All @@ -60,12 +62,14 @@ class PDFThumbnailViewer {
renderingQueue,
pageColors,
abortSignal,
enableHWA,
}) {
this.container = container;
this.eventBus = eventBus;
this.linkService = linkService;
this.renderingQueue = renderingQueue;
this.pageColors = pageColors || null;
this.enableHWA = enableHWA || false;

this.scroll = watchScroll(
this.container,
Expand Down Expand Up @@ -206,6 +210,7 @@ class PDFThumbnailViewer {
linkService: this.linkService,
renderingQueue: this.renderingQueue,
pageColors: this.pageColors,
enableHWA: this.enableHWA,
});
this._thumbnails.push(thumbnail);
}
Expand Down
6 changes: 6 additions & 0 deletions web/pdf_viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ function isValidAnnotationEditorMode(mode) {
* @property {Object} [pageColors] - Overwrites background and foreground colors
* with user defined ones in order to improve readability in high contrast
* mode.
* @property {boolean} [enableHWA] - Enables hardware acceleration for
* rendering. The default value is `false`.
*/

class PDFPageViewBuffer {
Expand Down Expand Up @@ -211,6 +213,8 @@ class PDFViewer {

#containerTopLeft = null;

#enableHWA = false;

#enableHighlightFloatingButton = false;

#enablePermissions = false;
Expand Down Expand Up @@ -296,6 +300,7 @@ class PDFViewer {
this.#enablePermissions = options.enablePermissions || false;
this.pageColors = options.pageColors || null;
this.#mlManager = options.mlManager || null;
this.#enableHWA = options.enableHWA || false;

this.defaultRenderingQueue = !options.renderingQueue;
if (
Expand Down Expand Up @@ -943,6 +948,7 @@ class PDFViewer {
pageColors,
l10n: this.l10n,
layerProperties: this._layerProperties,
enableHWA: this.#enableHWA,
});
this._pages.push(pageView);
}
Expand Down