Merge pull request #9095 from Snuffleupagus/WebGLFactory

Split the existing `WebGLUtils` in two classes, a private `WebGLUtils` and a public `WebGLContext`, and utilize the latter in the API to allow various code to access the methods of `WebGLUtils`
This commit is contained in:
Jonas Jenwald 2017-11-24 23:25:06 +01:00 committed by GitHub
commit 343f331b8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 43 deletions

View File

@ -30,6 +30,7 @@ import { CanvasGraphics } from './canvas';
import globalScope from '../shared/global_scope'; import globalScope from '../shared/global_scope';
import { Metadata } from './metadata'; import { Metadata } from './metadata';
import { PDFDataTransportStream } from './transport_stream'; import { PDFDataTransportStream } from './transport_stream';
import { WebGLContext } from './webgl';
var DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536 var DEFAULT_RANGE_CHUNK_SIZE = 65536; // 2^16 = 65536
@ -820,6 +821,11 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
var renderingIntent = (params.intent === 'print' ? 'print' : 'display'); var renderingIntent = (params.intent === 'print' ? 'print' : 'display');
var canvasFactory = params.canvasFactory || new DOMCanvasFactory(); var canvasFactory = params.canvasFactory || new DOMCanvasFactory();
let webGLContext = new WebGLContext({
// TODO: When moving this parameter from `PDFJS` to {RenderParameters},
// change its name to `enableWebGL` instead.
enable: !getDefaultSetting('disableWebGL'),
});
if (!this.intentStates[renderingIntent]) { if (!this.intentStates[renderingIntent]) {
this.intentStates[renderingIntent] = Object.create(null); this.intentStates[renderingIntent] = Object.create(null);
@ -870,7 +876,8 @@ var PDFPageProxy = (function PDFPageProxyClosure() {
this.commonObjs, this.commonObjs,
intentState.operatorList, intentState.operatorList,
this.pageNumber, this.pageNumber,
canvasFactory); canvasFactory,
webGLContext);
internalRenderTask.useRequestAnimationFrame = renderingIntent !== 'print'; internalRenderTask.useRequestAnimationFrame = renderingIntent !== 'print';
if (!intentState.renderTasks) { if (!intentState.renderTasks) {
intentState.renderTasks = []; intentState.renderTasks = [];
@ -2174,7 +2181,7 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
let canvasInRendering = new WeakMap(); let canvasInRendering = new WeakMap();
function InternalRenderTask(callback, params, objs, commonObjs, operatorList, function InternalRenderTask(callback, params, objs, commonObjs, operatorList,
pageNumber, canvasFactory) { pageNumber, canvasFactory, webGLContext) {
this.callback = callback; this.callback = callback;
this.params = params; this.params = params;
this.objs = objs; this.objs = objs;
@ -2183,6 +2190,8 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
this.operatorList = operatorList; this.operatorList = operatorList;
this.pageNumber = pageNumber; this.pageNumber = pageNumber;
this.canvasFactory = canvasFactory; this.canvasFactory = canvasFactory;
this.webGLContext = webGLContext;
this.running = false; this.running = false;
this.graphicsReadyCallback = null; this.graphicsReadyCallback = null;
this.graphicsReady = false; this.graphicsReady = false;
@ -2225,7 +2234,7 @@ var InternalRenderTask = (function InternalRenderTaskClosure() {
var params = this.params; var params = this.params;
this.gfx = new CanvasGraphics(params.canvasContext, this.commonObjs, this.gfx = new CanvasGraphics(params.canvasContext, this.commonObjs,
this.objs, this.canvasFactory, this.objs, this.canvasFactory,
params.imageLayer); this.webGLContext, params.imageLayer);
this.gfx.beginDrawing({ this.gfx.beginDrawing({
transform: params.transform, transform: params.transform,

View File

@ -18,7 +18,6 @@ import {
OPS, shadow, TextRenderingMode, Util, warn OPS, shadow, TextRenderingMode, Util, warn
} from '../shared/util'; } from '../shared/util';
import { getShadingPatternFromIR, TilingPattern } from './pattern_helper'; import { getShadingPatternFromIR, TilingPattern } from './pattern_helper';
import { WebGLUtils } from './webgl';
// <canvas> contexts store most of the state we need natively. // <canvas> contexts store most of the state we need natively.
// However, PDF needs a bit more state, which we store here. // However, PDF needs a bit more state, which we store here.
@ -407,7 +406,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
var EXECUTION_STEPS = 10; var EXECUTION_STEPS = 10;
function CanvasGraphics(canvasCtx, commonObjs, objs, canvasFactory, function CanvasGraphics(canvasCtx, commonObjs, objs, canvasFactory,
imageLayer) { webGLContext, imageLayer) {
this.ctx = canvasCtx; this.ctx = canvasCtx;
this.current = new CanvasExtraState(); this.current = new CanvasExtraState();
this.stateStack = []; this.stateStack = [];
@ -418,6 +417,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
this.commonObjs = commonObjs; this.commonObjs = commonObjs;
this.objs = objs; this.objs = objs;
this.canvasFactory = canvasFactory; this.canvasFactory = canvasFactory;
this.webGLContext = webGLContext;
this.imageLayer = imageLayer; this.imageLayer = imageLayer;
this.groupStack = []; this.groupStack = [];
this.processingType3 = null; this.processingType3 = null;
@ -693,7 +693,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
} }
} }
function composeSMask(ctx, smask, layerCtx) { function composeSMask(ctx, smask, layerCtx, webGLContext) {
var mask = smask.canvas; var mask = smask.canvas;
var maskCtx = smask.context; var maskCtx = smask.context;
@ -701,9 +701,15 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
smask.offsetX, smask.offsetY); smask.offsetX, smask.offsetY);
var backdrop = smask.backdrop || null; var backdrop = smask.backdrop || null;
if (!smask.transferMap && WebGLUtils.isEnabled) { if (!smask.transferMap && webGLContext.isEnabled) {
var composed = WebGLUtils.composeSMask(layerCtx.canvas, mask, let composed = webGLContext.composeSMask({
{ subtype: smask.subtype, backdrop, }); layer: layerCtx.canvas,
mask,
properties: {
subtype: smask.subtype,
backdrop,
},
});
ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.drawImage(composed, smask.offsetX, smask.offsetY); ctx.drawImage(composed, smask.offsetX, smask.offsetY);
return; return;
@ -851,7 +857,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
} }
this.cachedCanvases.clear(); this.cachedCanvases.clear();
WebGLUtils.clear(); this.webGLContext.clear();
if (this.imageLayer) { if (this.imageLayer) {
this.imageLayer.endLayout(); this.imageLayer.endLayout();
@ -988,7 +994,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
this.groupLevel--; this.groupLevel--;
this.ctx = this.groupStack.pop(); this.ctx = this.groupStack.pop();
composeSMask(this.ctx, this.current.activeSMask, groupCtx); composeSMask(this.ctx, this.current.activeSMask, groupCtx,
this.webGLContext);
this.ctx.restore(); this.ctx.restore();
this.ctx.save(); // save is needed since SMask will be resumed. this.ctx.save(); // save is needed since SMask will be resumed.
copyCtxState(groupCtx, this.ctx); copyCtxState(groupCtx, this.ctx);
@ -1023,7 +1030,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
this.groupLevel--; this.groupLevel--;
this.ctx = this.groupStack.pop(); this.ctx = this.groupStack.pop();
composeSMask(this.ctx, this.current.activeSMask, groupCtx); composeSMask(this.ctx, this.current.activeSMask, groupCtx,
this.webGLContext);
this.ctx.restore(); this.ctx.restore();
copyCtxState(groupCtx, this.ctx); copyCtxState(groupCtx, this.ctx);
// Transform was changed in the SMask canvas, reflecting this change on // Transform was changed in the SMask canvas, reflecting this change on

View File

@ -14,7 +14,6 @@
*/ */
import { FormatError, info, Util } from '../shared/util'; import { FormatError, info, Util } from '../shared/util';
import { WebGLUtils } from './webgl';
var ShadingIRs = {}; var ShadingIRs = {};
@ -145,7 +144,7 @@ var createMeshCanvas = (function createMeshCanvasClosure() {
} }
function createMeshCanvas(bounds, combinesScale, coords, colors, figures, function createMeshCanvas(bounds, combinesScale, coords, colors, figures,
backgroundColor, cachedCanvases) { backgroundColor, cachedCanvases, webGLContext) {
// we will increase scale on some weird factor to let antialiasing take // we will increase scale on some weird factor to let antialiasing take
// care of "rough" edges // care of "rough" edges
var EXPECTED_SCALE = 1.1; var EXPECTED_SCALE = 1.1;
@ -180,10 +179,14 @@ var createMeshCanvas = (function createMeshCanvasClosure() {
var paddedHeight = height + BORDER_SIZE * 2; var paddedHeight = height + BORDER_SIZE * 2;
var canvas, tmpCanvas, i, ii; var canvas, tmpCanvas, i, ii;
if (WebGLUtils.isEnabled) { if (webGLContext.isEnabled) {
canvas = WebGLUtils.drawFigures(width, height, backgroundColor, canvas = webGLContext.drawFigures({
figures, context); width,
height,
backgroundColor,
figures,
context,
});
// https://bugzilla.mozilla.org/show_bug.cgi?id=972126 // https://bugzilla.mozilla.org/show_bug.cgi?id=972126
tmpCanvas = cachedCanvases.getCanvas('mesh', paddedWidth, paddedHeight, tmpCanvas = cachedCanvases.getCanvas('mesh', paddedWidth, paddedHeight,
false); false);
@ -253,7 +256,7 @@ ShadingIRs.Mesh = {
// might cause OOM. // might cause OOM.
var temporaryPatternCanvas = createMeshCanvas(bounds, scale, coords, var temporaryPatternCanvas = createMeshCanvas(bounds, scale, coords,
colors, figures, shadingFill ? null : background, colors, figures, shadingFill ? null : background,
owner.cachedCanvases); owner.cachedCanvases, owner.webGLContext);
if (!shadingFill) { if (!shadingFill) {
ctx.setTransform.apply(ctx, owner.baseTransform); ctx.setTransform.apply(ctx, owner.baseTransform);

View File

@ -14,9 +14,35 @@
*/ */
/* eslint-disable no-multi-str */ /* eslint-disable no-multi-str */
import { getDefaultSetting } from './dom_utils';
import { shadow } from '../shared/util'; import { shadow } from '../shared/util';
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();
}
}
var WebGLUtils = (function WebGLUtilsClosure() { var WebGLUtils = (function WebGLUtilsClosure() {
function loadShader(gl, code, shaderType) { function loadShader(gl, code, shaderType) {
var shader = gl.createShader(shaderType); var shader = gl.createShader(shaderType);
@ -405,7 +431,20 @@ var WebGLUtils = (function WebGLUtilsClosure() {
return canvas; return canvas;
} }
function cleanup() { return {
tryInitGL() {
try {
generateGL();
return !!currentGL;
} catch (ex) { }
return false;
},
composeSMask,
drawFigures,
cleanup() {
if (smaskCache && smaskCache.canvas) { if (smaskCache && smaskCache.canvas) {
smaskCache.canvas.width = 0; smaskCache.canvas.width = 0;
smaskCache.canvas.height = 0; smaskCache.canvas.height = 0;
@ -416,26 +455,10 @@ var WebGLUtils = (function WebGLUtilsClosure() {
} }
smaskCache = null; smaskCache = null;
figuresCache = null; figuresCache = null;
}
return {
get isEnabled() {
if (getDefaultSetting('disableWebGL')) {
return false;
}
var enabled = false;
try {
generateGL();
enabled = !!currentGL;
} catch (e) { }
return shadow(this, 'isEnabled', enabled);
}, },
composeSMask,
drawFigures,
clear: cleanup,
}; };
})(); })();
export { export {
WebGLUtils, WebGLContext,
}; };