[api-minor] Remove the WebGL implementation

Reasons for the removal include:
 - This functionality was always somewhat experimental and has never been enabled by default, partly because of worries about rendering bugs caused by e.g. bad/outdated graphics drivers.

 - After the initial implementation, in PR 4286 (back in 2014), no additional functionality has been added to the WebGL implementation.

 - The vast majority of all documents do not benefit from WebGL rendering, since only a couple of *specific* features are supported (e.g. some Soft Masks and Patterns).

 - There is, and has always been, *zero* test-coverage for the WebGL implementation.

 - Overall performance, in the PDF.js library, has improved since the experimental WebGL implementation was added.

Rather than shipping unused *and* untested code, it seems reasonable to simply remove the WebGL implementation for now; thanks to version control it's always possible to bring back the code should the need ever arise.
This commit is contained in:
Jonas Jenwald 2021-05-09 15:54:26 +02:00
parent 99eac86478
commit 2ba4b65ca8
9 changed files with 28 additions and 608 deletions

View File

@ -52,12 +52,6 @@
],
"default": 0
},
"enableWebGL": {
"title": "Enable WebGL",
"description": "Whether to enable WebGL.",
"type": "boolean",
"default": false
},
"pdfBugEnabled": {
"title": "Enable debugging tools",
"description": "Whether to enable debugging tools.",

View File

@ -57,7 +57,6 @@ import { MessageHandler } from "../shared/message_handler.js";
import { Metadata } from "./metadata.js";
import { OptionalContentConfig } from "./optional_content_config.js";
import { PDFDataTransportStream } from "./transport_stream.js";
import { WebGLContext } from "./webgl.js";
const DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536
const RENDERING_CANCELLED_TIMEOUT = 100; // ms
@ -1092,8 +1091,6 @@ class PDFDocumentProxy {
* the `PDFPageProxy.getViewport` method.
* @property {string} [intent] - Rendering intent, can be 'display' or 'print'.
* The default value is 'display'.
* @property {boolean} [enableWebGL] - Enables WebGL accelerated rendering for
* some operations. The default value is `false`.
* @property {boolean} [renderInteractiveForms] - Whether or not interactive
* form elements are rendered in the display layer. If so, we do not render
* them on the canvas as well. The default value is `false`.
@ -1272,7 +1269,6 @@ class PDFPageProxy {
canvasContext,
viewport,
intent = "display",
enableWebGL = false,
renderInteractiveForms = false,
transform = null,
imageLayer = null,
@ -1319,9 +1315,6 @@ class PDFPageProxy {
const canvasFactoryInstance =
canvasFactory ||
new DefaultCanvasFactory({ ownerDocument: this._ownerDocument });
const webGLContext = new WebGLContext({
enable: enableWebGL,
});
const annotationStorage = includeAnnotationStorage
? this._transport.annotationStorage.serializable
: null;
@ -1388,7 +1381,6 @@ class PDFPageProxy {
operatorList: intentState.operatorList,
pageIndex: this._pageIndex,
canvasFactory: canvasFactoryInstance,
webGLContext,
useRequestAnimationFrame: renderingIntent !== "print",
pdfBug: this._pdfBug,
});
@ -3022,7 +3014,6 @@ const InternalRenderTask = (function InternalRenderTaskClosure() {
operatorList,
pageIndex,
canvasFactory,
webGLContext,
useRequestAnimationFrame = false,
pdfBug = false,
}) {
@ -3034,7 +3025,6 @@ const InternalRenderTask = (function InternalRenderTaskClosure() {
this.operatorList = operatorList;
this._pageIndex = pageIndex;
this.canvasFactory = canvasFactory;
this.webGLContext = webGLContext;
this._pdfBug = pdfBug;
this.running = false;
@ -3093,7 +3083,6 @@ const InternalRenderTask = (function InternalRenderTaskClosure() {
this.commonObjs,
this.objs,
this.canvasFactory,
this.webGLContext,
imageLayer,
optionalContentConfig
);

View File

@ -808,7 +808,7 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
}
}
function composeSMask(ctx, smask, layerCtx, webGLContext) {
function composeSMask(ctx, smask, layerCtx) {
const mask = smask.canvas;
const maskCtx = smask.context;
@ -821,27 +821,13 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
smask.offsetY
);
const backdrop = smask.backdrop || null;
if (!smask.transferMap && webGLContext.isEnabled) {
const composed = webGLContext.composeSMask({
layer: layerCtx.canvas,
mask,
properties: {
subtype: smask.subtype,
backdrop,
},
});
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.drawImage(composed, smask.offsetX, smask.offsetY);
return;
}
genericComposeSMask(
maskCtx,
layerCtx,
mask.width,
mask.height,
smask.subtype,
backdrop,
smask.backdrop,
smask.transferMap
);
ctx.drawImage(mask, 0, 0);
@ -859,7 +845,6 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
commonObjs,
objs,
canvasFactory,
webGLContext,
imageLayer,
optionalContentConfig
) {
@ -873,7 +858,6 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.commonObjs = commonObjs;
this.objs = objs;
this.canvasFactory = canvasFactory;
this.webGLContext = webGLContext;
this.imageLayer = imageLayer;
this.groupStack = [];
this.processingType3 = null;
@ -1042,7 +1026,6 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
}
this.cachedCanvases.clear();
this.webGLContext.clear();
if (this.imageLayer) {
this.imageLayer.endLayout();
@ -1192,12 +1175,7 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.groupLevel--;
this.ctx = this.groupStack.pop();
composeSMask(
this.ctx,
this.current.activeSMask,
groupCtx,
this.webGLContext
);
composeSMask(this.ctx, this.current.activeSMask, groupCtx);
this.ctx.restore();
this.ctx.save(); // save is needed since SMask will be resumed.
copyCtxState(groupCtx, this.ctx);
@ -1235,12 +1213,7 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
this.groupLevel--;
this.ctx = this.groupStack.pop();
composeSMask(
this.ctx,
this.current.activeSMask,
groupCtx,
this.webGLContext
);
composeSMask(this.ctx, this.current.activeSMask, groupCtx);
this.ctx.restore();
copyCtxState(groupCtx, this.ctx);
// Transform was changed in the SMask canvas, reflecting this change on
@ -2004,8 +1977,7 @@ const CanvasGraphics = (function CanvasGraphicsClosure() {
ctx,
this.commonObjs,
this.objs,
this.canvasFactory,
this.webGLContext
this.canvasFactory
);
},
};

View File

@ -233,8 +233,7 @@ const createMeshCanvas = (function createMeshCanvasClosure() {
colors,
figures,
backgroundColor,
cachedCanvases,
webGLContext
cachedCanvases
) {
// we will increase scale on some weird factor to let antialiasing take
// care of "rough" edges
@ -273,49 +272,29 @@ const createMeshCanvas = (function createMeshCanvasClosure() {
const paddedWidth = width + BORDER_SIZE * 2;
const paddedHeight = height + BORDER_SIZE * 2;
let canvas, tmpCanvas, i, ii;
if (webGLContext.isEnabled) {
canvas = webGLContext.drawFigures({
width,
height,
backgroundColor,
figures,
context,
});
// https://bugzilla.mozilla.org/show_bug.cgi?id=972126
tmpCanvas = cachedCanvases.getCanvas(
"mesh",
paddedWidth,
paddedHeight,
false
);
tmpCanvas.context.drawImage(canvas, BORDER_SIZE, BORDER_SIZE);
canvas = tmpCanvas.canvas;
} else {
tmpCanvas = cachedCanvases.getCanvas(
"mesh",
paddedWidth,
paddedHeight,
false
);
const tmpCtx = tmpCanvas.context;
const tmpCanvas = cachedCanvases.getCanvas(
"mesh",
paddedWidth,
paddedHeight,
false
);
const tmpCtx = tmpCanvas.context;
const data = tmpCtx.createImageData(width, height);
if (backgroundColor) {
const bytes = data.data;
for (i = 0, ii = bytes.length; i < ii; i += 4) {
bytes[i] = backgroundColor[0];
bytes[i + 1] = backgroundColor[1];
bytes[i + 2] = backgroundColor[2];
bytes[i + 3] = 255;
}
const data = tmpCtx.createImageData(width, height);
if (backgroundColor) {
const bytes = data.data;
for (let i = 0, ii = bytes.length; i < ii; i += 4) {
bytes[i] = backgroundColor[0];
bytes[i + 1] = backgroundColor[1];
bytes[i + 2] = backgroundColor[2];
bytes[i + 3] = 255;
}
for (i = 0; i < figures.length; i++) {
drawFigure(data, figures[i], context);
}
tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE);
canvas = tmpCanvas.canvas;
}
for (let i = 0, ii = figures.length; i < ii; i++) {
drawFigure(data, figures[i], context);
}
tmpCtx.putImageData(data, BORDER_SIZE, BORDER_SIZE);
const canvas = tmpCanvas.canvas;
return {
canvas,
@ -362,8 +341,7 @@ ShadingIRs.Mesh = {
colors,
figures,
shadingFill ? null : background,
owner.cachedCanvases,
owner.webGLContext
owner.cachedCanvases
);
if (!shadingFill) {

View File

@ -1,495 +0,0 @@
/* Copyright 2014 Mozilla Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable no-multi-str */
import { shadow } from "../shared/util.js";
class WebGLContext {
constructor({ enable = false }) {
this._enabled = enable === true;
}
get isEnabled() {
let enabled = this._enabled;
if (enabled) {
enabled = WebGLUtils.tryInitGL();
}
return shadow(this, "isEnabled", enabled);
}
composeSMask({ layer, mask, properties }) {
return WebGLUtils.composeSMask(layer, mask, properties);
}
drawFigures({ width, height, backgroundColor, figures, context }) {
return WebGLUtils.drawFigures(
width,
height,
backgroundColor,
figures,
context
);
}
clear() {
WebGLUtils.cleanup();
}
}
const WebGLUtils = (function WebGLUtilsClosure() {
function loadShader(gl, code, shaderType) {
const shader = gl.createShader(shaderType);
gl.shaderSource(shader, code);
gl.compileShader(shader);
const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!compiled) {
const errorMsg = gl.getShaderInfoLog(shader);
throw new Error("Error during shader compilation: " + errorMsg);
}
return shader;
}
function createVertexShader(gl, code) {
return loadShader(gl, code, gl.VERTEX_SHADER);
}
function createFragmentShader(gl, code) {
return loadShader(gl, code, gl.FRAGMENT_SHADER);
}
function createProgram(gl, shaders) {
const program = gl.createProgram();
for (let i = 0, ii = shaders.length; i < ii; ++i) {
gl.attachShader(program, shaders[i]);
}
gl.linkProgram(program);
const linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
const errorMsg = gl.getProgramInfoLog(program);
throw new Error("Error during program linking: " + errorMsg);
}
return program;
}
function createTexture(gl, image, textureId) {
gl.activeTexture(textureId);
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// Set the parameters so we can render any size image.
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
// Upload the image into the texture.
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
return texture;
}
let currentGL, currentCanvas;
function generateGL() {
if (currentGL) {
return;
}
// The temporary canvas is used in the WebGL context.
currentCanvas = document.createElement("canvas");
currentGL = currentCanvas.getContext("webgl", {
premultipliedalpha: false,
});
}
const smaskVertexShaderCode =
"\
attribute vec2 a_position; \
attribute vec2 a_texCoord; \
\
uniform vec2 u_resolution; \
\
varying vec2 v_texCoord; \
\
void main() { \
vec2 clipSpace = (a_position / u_resolution) * 2.0 - 1.0; \
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); \
\
v_texCoord = a_texCoord; \
} ";
const smaskFragmentShaderCode =
"\
precision mediump float; \
\
uniform vec4 u_backdrop; \
uniform int u_subtype; \
uniform sampler2D u_image; \
uniform sampler2D u_mask; \
\
varying vec2 v_texCoord; \
\
void main() { \
vec4 imageColor = texture2D(u_image, v_texCoord); \
vec4 maskColor = texture2D(u_mask, v_texCoord); \
if (u_backdrop.a > 0.0) { \
maskColor.rgb = maskColor.rgb * maskColor.a + \
u_backdrop.rgb * (1.0 - maskColor.a); \
} \
float lum; \
if (u_subtype == 0) { \
lum = maskColor.a; \
} else { \
lum = maskColor.r * 0.3 + maskColor.g * 0.59 + \
maskColor.b * 0.11; \
} \
imageColor.a *= lum; \
imageColor.rgb *= imageColor.a; \
gl_FragColor = imageColor; \
} ";
let smaskCache = null;
function initSmaskGL() {
generateGL();
const canvas = currentCanvas;
currentCanvas = null;
const gl = currentGL;
currentGL = null;
// setup a GLSL program
const vertexShader = createVertexShader(gl, smaskVertexShaderCode);
const fragmentShader = createFragmentShader(gl, smaskFragmentShaderCode);
const program = createProgram(gl, [vertexShader, fragmentShader]);
gl.useProgram(program);
const cache = {};
cache.gl = gl;
cache.canvas = canvas;
cache.resolutionLocation = gl.getUniformLocation(program, "u_resolution");
cache.positionLocation = gl.getAttribLocation(program, "a_position");
cache.backdropLocation = gl.getUniformLocation(program, "u_backdrop");
cache.subtypeLocation = gl.getUniformLocation(program, "u_subtype");
const texCoordLocation = gl.getAttribLocation(program, "a_texCoord");
const texLayerLocation = gl.getUniformLocation(program, "u_image");
const texMaskLocation = gl.getUniformLocation(program, "u_mask");
// provide texture coordinates for the rectangle.
const texCoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
// prettier-ignore
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 1.0,
1.0, 0.0,
1.0, 1.0]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(texCoordLocation);
gl.vertexAttribPointer(texCoordLocation, 2, gl.FLOAT, false, 0, 0);
gl.uniform1i(texLayerLocation, 0);
gl.uniform1i(texMaskLocation, 1);
smaskCache = cache;
}
function composeSMask(layer, mask, properties) {
const width = layer.width,
height = layer.height;
if (!smaskCache) {
initSmaskGL();
}
const cache = smaskCache,
canvas = cache.canvas,
gl = cache.gl;
canvas.width = width;
canvas.height = height;
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.uniform2f(cache.resolutionLocation, width, height);
if (properties.backdrop) {
gl.uniform4f(
cache.resolutionLocation,
properties.backdrop[0],
properties.backdrop[1],
properties.backdrop[2],
1
);
} else {
gl.uniform4f(cache.resolutionLocation, 0, 0, 0, 0);
}
gl.uniform1i(
cache.subtypeLocation,
properties.subtype === "Luminosity" ? 1 : 0
);
// Create a textures
const texture = createTexture(gl, layer, gl.TEXTURE0);
const maskTexture = createTexture(gl, mask, gl.TEXTURE1);
// Create a buffer and put a single clipspace rectangle in
// it (2 triangles)
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// prettier-ignore
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
0, 0,
width, 0,
0, height,
0, height,
width, 0,
width, height]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(cache.positionLocation);
gl.vertexAttribPointer(cache.positionLocation, 2, gl.FLOAT, false, 0, 0);
// draw
gl.clearColor(0, 0, 0, 0);
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.flush();
gl.deleteTexture(texture);
gl.deleteTexture(maskTexture);
gl.deleteBuffer(buffer);
return canvas;
}
const figuresVertexShaderCode =
"\
attribute vec2 a_position; \
attribute vec3 a_color; \
\
uniform vec2 u_resolution; \
uniform vec2 u_scale; \
uniform vec2 u_offset; \
\
varying vec4 v_color; \
\
void main() { \
vec2 position = (a_position + u_offset) * u_scale; \
vec2 clipSpace = (position / u_resolution) * 2.0 - 1.0; \
gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1); \
\
v_color = vec4(a_color / 255.0, 1.0); \
} ";
const figuresFragmentShaderCode =
"\
precision mediump float; \
\
varying vec4 v_color; \
\
void main() { \
gl_FragColor = v_color; \
} ";
let figuresCache = null;
function initFiguresGL() {
generateGL();
const canvas = currentCanvas;
currentCanvas = null;
const gl = currentGL;
currentGL = null;
// setup a GLSL program
const vertexShader = createVertexShader(gl, figuresVertexShaderCode);
const fragmentShader = createFragmentShader(gl, figuresFragmentShaderCode);
const program = createProgram(gl, [vertexShader, fragmentShader]);
gl.useProgram(program);
const cache = {};
cache.gl = gl;
cache.canvas = canvas;
cache.resolutionLocation = gl.getUniformLocation(program, "u_resolution");
cache.scaleLocation = gl.getUniformLocation(program, "u_scale");
cache.offsetLocation = gl.getUniformLocation(program, "u_offset");
cache.positionLocation = gl.getAttribLocation(program, "a_position");
cache.colorLocation = gl.getAttribLocation(program, "a_color");
figuresCache = cache;
}
function drawFigures(width, height, backgroundColor, figures, context) {
if (!figuresCache) {
initFiguresGL();
}
const cache = figuresCache,
canvas = cache.canvas,
gl = cache.gl;
canvas.width = width;
canvas.height = height;
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.uniform2f(cache.resolutionLocation, width, height);
// count triangle points
let count = 0;
for (let i = 0, ii = figures.length; i < ii; i++) {
switch (figures[i].type) {
case "lattice":
const rows =
(figures[i].coords.length / figures[i].verticesPerRow) | 0;
count += (rows - 1) * (figures[i].verticesPerRow - 1) * 6;
break;
case "triangles":
count += figures[i].coords.length;
break;
}
}
// transfer data
const coords = new Float32Array(count * 2);
const colors = new Uint8Array(count * 3);
const coordsMap = context.coords,
colorsMap = context.colors;
let pIndex = 0,
cIndex = 0;
for (let i = 0, ii = figures.length; i < ii; i++) {
const figure = figures[i],
ps = figure.coords,
cs = figure.colors;
switch (figure.type) {
case "lattice":
const cols = figure.verticesPerRow;
const rows = (ps.length / cols) | 0;
for (let row = 1; row < rows; row++) {
let offset = row * cols + 1;
for (let col = 1; col < cols; col++, offset++) {
coords[pIndex] = coordsMap[ps[offset - cols - 1]];
coords[pIndex + 1] = coordsMap[ps[offset - cols - 1] + 1];
coords[pIndex + 2] = coordsMap[ps[offset - cols]];
coords[pIndex + 3] = coordsMap[ps[offset - cols] + 1];
coords[pIndex + 4] = coordsMap[ps[offset - 1]];
coords[pIndex + 5] = coordsMap[ps[offset - 1] + 1];
colors[cIndex] = colorsMap[cs[offset - cols - 1]];
colors[cIndex + 1] = colorsMap[cs[offset - cols - 1] + 1];
colors[cIndex + 2] = colorsMap[cs[offset - cols - 1] + 2];
colors[cIndex + 3] = colorsMap[cs[offset - cols]];
colors[cIndex + 4] = colorsMap[cs[offset - cols] + 1];
colors[cIndex + 5] = colorsMap[cs[offset - cols] + 2];
colors[cIndex + 6] = colorsMap[cs[offset - 1]];
colors[cIndex + 7] = colorsMap[cs[offset - 1] + 1];
colors[cIndex + 8] = colorsMap[cs[offset - 1] + 2];
coords[pIndex + 6] = coords[pIndex + 2];
coords[pIndex + 7] = coords[pIndex + 3];
coords[pIndex + 8] = coords[pIndex + 4];
coords[pIndex + 9] = coords[pIndex + 5];
coords[pIndex + 10] = coordsMap[ps[offset]];
coords[pIndex + 11] = coordsMap[ps[offset] + 1];
colors[cIndex + 9] = colors[cIndex + 3];
colors[cIndex + 10] = colors[cIndex + 4];
colors[cIndex + 11] = colors[cIndex + 5];
colors[cIndex + 12] = colors[cIndex + 6];
colors[cIndex + 13] = colors[cIndex + 7];
colors[cIndex + 14] = colors[cIndex + 8];
colors[cIndex + 15] = colorsMap[cs[offset]];
colors[cIndex + 16] = colorsMap[cs[offset] + 1];
colors[cIndex + 17] = colorsMap[cs[offset] + 2];
pIndex += 12;
cIndex += 18;
}
}
break;
case "triangles":
for (let j = 0, jj = ps.length; j < jj; j++) {
coords[pIndex] = coordsMap[ps[j]];
coords[pIndex + 1] = coordsMap[ps[j] + 1];
colors[cIndex] = colorsMap[cs[j]];
colors[cIndex + 1] = colorsMap[cs[j] + 1];
colors[cIndex + 2] = colorsMap[cs[j] + 2];
pIndex += 2;
cIndex += 3;
}
break;
}
}
// draw
if (backgroundColor) {
gl.clearColor(
backgroundColor[0] / 255,
backgroundColor[1] / 255,
backgroundColor[2] / 255,
1.0
);
} else {
gl.clearColor(0, 0, 0, 0);
}
gl.clear(gl.COLOR_BUFFER_BIT);
const coordsBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, coordsBuffer);
gl.bufferData(gl.ARRAY_BUFFER, coords, gl.STATIC_DRAW);
gl.enableVertexAttribArray(cache.positionLocation);
gl.vertexAttribPointer(cache.positionLocation, 2, gl.FLOAT, false, 0, 0);
const colorsBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorsBuffer);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
gl.enableVertexAttribArray(cache.colorLocation);
gl.vertexAttribPointer(
cache.colorLocation,
3,
gl.UNSIGNED_BYTE,
false,
0,
0
);
gl.uniform2f(cache.scaleLocation, context.scaleX, context.scaleY);
gl.uniform2f(cache.offsetLocation, context.offsetX, context.offsetY);
gl.drawArrays(gl.TRIANGLES, 0, count);
gl.flush();
gl.deleteBuffer(coordsBuffer);
gl.deleteBuffer(colorsBuffer);
return canvas;
}
return {
tryInitGL() {
try {
generateGL();
return !!currentGL;
} catch (ex) {}
return false;
},
composeSMask,
drawFigures,
cleanup() {
if (smaskCache?.canvas) {
smaskCache.canvas.width = 0;
smaskCache.canvas.height = 0;
}
if (figuresCache?.canvas) {
figuresCache.canvas.width = 0;
figuresCache.canvas.height = 0;
}
smaskCache = null;
figuresCache = null;
},
};
})();
export { WebGLContext };

View File

@ -354,9 +354,6 @@ const PDFViewerApplication = {
if ("disablehistory" in hashParams) {
AppOptions.set("disableHistory", hashParams.disablehistory === "true");
}
if ("webgl" in hashParams) {
AppOptions.set("enableWebGL", hashParams.webgl === "true");
}
if ("verbosity" in hashParams) {
AppOptions.set("verbosity", hashParams.verbosity | 0);
}
@ -511,7 +508,6 @@ const PDFViewerApplication = {
findController,
scriptingManager: pdfScriptingManager,
renderer: AppOptions.get("renderer"),
enableWebGL: AppOptions.get("enableWebGL"),
l10n: this.l10n,
textLayerMode: AppOptions.get("textLayerMode"),
imageResourcesPath: AppOptions.get("imageResourcesPath"),
@ -1520,8 +1516,7 @@ const PDFViewerApplication = {
console.log(
`PDF ${pdfDocument.fingerprint} [${info.PDFFormatVersion} ` +
`${(info.Producer || "-").trim()} / ${(info.Creator || "-").trim()}] ` +
`(PDF.js: ${version || "-"}` +
`${this.pdfViewer.enableWebGL ? " [WebGL]" : ""})`
`(PDF.js: ${version || "-"})`
);
let pdfTitle = info?.Title;

View File

@ -70,11 +70,6 @@ const defaultOptions = {
value: true,
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
},
enableWebGL: {
/** @type {boolean} */
value: false,
kind: OptionKind.VIEWER + OptionKind.PREFERENCE,
},
externalLinkRel: {
/** @type {string} */
value: "noopener noreferrer nofollow",

View File

@ -73,8 +73,6 @@ const DEFAULT_CACHE_SIZE = 10;
* @property {boolean} [enablePrintAutoRotate] - Enables automatic rotation of
* landscape pages upon printing. The default is `false`.
* @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'.
* @property {boolean} [enableWebGL] - Enables WebGL accelerated rendering for
* some operations. The default value is `false`.
* @property {boolean} [useOnlyCssZoom] - Enables CSS only zooming. The default
* value is `false`.
* @property {number} [maxCanvasPixels] - The maximum supported canvas size in
@ -194,7 +192,6 @@ class BaseViewer {
this.renderInteractiveForms = options.renderInteractiveForms !== false;
this.enablePrintAutoRotate = options.enablePrintAutoRotate || false;
this.renderer = options.renderer || RendererType.CANVAS;
this.enableWebGL = options.enableWebGL || false;
this.useOnlyCssZoom = options.useOnlyCssZoom || false;
this.maxCanvasPixels = options.maxCanvasPixels;
this.l10n = options.l10n || NullL10n;
@ -550,7 +547,6 @@ class BaseViewer {
imageResourcesPath: this.imageResourcesPath,
renderInteractiveForms: this.renderInteractiveForms,
renderer: this.renderer,
enableWebGL: this.enableWebGL,
useOnlyCssZoom: this.useOnlyCssZoom,
maxCanvasPixels: this.maxCanvasPixels,
l10n: this.l10n,

View File

@ -55,8 +55,6 @@ import { viewerCompatibilityParams } from "./viewer_compatibility.js";
* @property {boolean} renderInteractiveForms - Turns on rendering of
* interactive form elements. The default value is `true`.
* @property {string} renderer - 'canvas' or 'svg'. The default is 'canvas'.
* @property {boolean} [enableWebGL] - Enables WebGL accelerated rendering for
* some operations. The default value is `false`.
* @property {boolean} [useOnlyCssZoom] - Enables CSS only zooming. The default
* value is `false`.
* @property {number} [maxCanvasPixels] - The maximum supported canvas size in
@ -105,7 +103,6 @@ class PDFPageView {
this.xfaLayerFactory = options.xfaLayerFactory;
this.structTreeLayerFactory = options.structTreeLayerFactory;
this.renderer = options.renderer || RendererType.CANVAS;
this.enableWebGL = options.enableWebGL || false;
this.l10n = options.l10n || NullL10n;
this.paintTask = null;
@ -728,7 +725,6 @@ class PDFPageView {
canvasContext: ctx,
transform,
viewport: this.viewport,
enableWebGL: this.enableWebGL,
renderInteractiveForms: this.renderInteractiveForms,
optionalContentConfigPromise: this._optionalContentConfigPromise,
};