Partially implement benchmarking for SVG.
This commit is contained in:
parent
f5a7032ca5
commit
30893fb9ad
|
@ -8,7 +8,9 @@
|
|||
</head>
|
||||
<body class="pf-unscrollable">
|
||||
{{>partials/navbar.html isTool=true}}
|
||||
<canvas id="pf-canvas" class="pf-draggable" width="400" height="300"></canvas>
|
||||
<canvas id="pf-canvas" class="pf-maximized-canvas pf-draggable" width="400"
|
||||
height="300"></canvas>
|
||||
<svg id="pf-svg" xmlns="http://www.w3.org/2000/svg" width="400" height="300"></svg>
|
||||
<div class="modal fade" id="pf-benchmark-modal" tabindex="-1" role="dialog"
|
||||
aria-labelledby="pf-benchmark-label" aria-hidden="false">
|
||||
<div class="modal-dialog" role="document">
|
||||
|
@ -21,22 +23,44 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form">
|
||||
<div class="form-group">
|
||||
<label for="pf-aa-level-select"
|
||||
class="col-form-label mr-sm-2">Antialiasing</label>
|
||||
<select id="pf-aa-level-select"
|
||||
class="form-control custom-select mr-sm-3">
|
||||
<option value="none" selected>None</option>
|
||||
<option value="ssaa-2">2×SSAA</option>
|
||||
<option value="ssaa-4">4×SSAA</option>
|
||||
<option value="xcaa">XCAA</option>
|
||||
</select>
|
||||
<ul class="nav nav-tabs" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" id="pf-benchmark-text-tab"
|
||||
data-toggle="tab" href="#pf-benchmark-text" role="tab"
|
||||
aria-controls="pf-benchmark-text" aria-selected="true">Text</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="pf-benchmark-svg-tab" data-toggle="tab"
|
||||
href="#pf-benchmark-svg" role="tab"
|
||||
aria-controls="pf-benchmark-svg" aria-selected="false">SVG</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane show active pt-3" id="pf-benchmark-text"
|
||||
role="tabpanel" aria-labelledby="pf-benchmark-text-tab">
|
||||
<form class="form" id="pf-benchmark-text-form">
|
||||
<div class="form-group" id="pf-aa-level-form-group">
|
||||
<label for="pf-aa-level-select"
|
||||
class="col-form-label mr-sm-2">Antialiasing</label>
|
||||
<select id="pf-aa-level-select"
|
||||
class="form-control custom-select mr-sm-3">
|
||||
<option value="none" selected>None</option>
|
||||
<option value="ssaa-2">2×SSAA</option>
|
||||
<option value="ssaa-4">4×SSAA</option>
|
||||
<option value="xcaa">XCAA</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group row justify-content-between">
|
||||
{{>partials/switch.html id="pf-subpixel-aa" title="Subpixel AA"}}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="form-group row justify-content-between">
|
||||
{{>partials/switch.html id="pf-subpixel-aa" title="Subpixel AA"}}
|
||||
<div class="tab-pane pt-3" id="pf-benchmark-svg"
|
||||
role="tabpanel" aria-labelledby="pf-benchmark-svg-tab">
|
||||
<form class="form" id="pf-benchmark-svg-form">
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<button id="pf-run-benchmark-button" type="button"
|
||||
class="btn btn-primary">
|
||||
|
@ -67,7 +91,7 @@
|
|||
<span id="pf-benchmark-results-partitioning-time">0</span> µs/glyph
|
||||
</div>
|
||||
<table class="table table-striped">
|
||||
<thead class="thead-default">
|
||||
<thead class="thead-default" id="pf-benchmark-results-table-header">
|
||||
<tr><th>Font size (px)</th><th>GPU time per glyph (µs)</th></tr>
|
||||
</thead>
|
||||
<tbody id="pf-benchmark-results-table-body"></tbody>
|
||||
|
|
|
@ -21,7 +21,7 @@ import PathfinderBufferTexture from "./buffer-texture";
|
|||
import {CameraView, PerspectiveCamera} from "./camera";
|
||||
import {UniformMap} from './gl-utils';
|
||||
import {PathfinderMeshData} from "./meshes";
|
||||
import {PathTransformBuffers, Renderer} from './renderer';
|
||||
import {BaseRenderer, PathTransformBuffers} from './renderer';
|
||||
import {ShaderMap, ShaderProgramSource} from "./shader-loader";
|
||||
import SSAAStrategy from "./ssaa-strategy";
|
||||
import {BUILTIN_FONT_URI, ExpandedMeshData} from "./text";
|
||||
|
@ -359,7 +359,7 @@ class ThreeDView extends DemoView implements TextRenderContext {
|
|||
newTimingsReceived(timings: Timings): void {}
|
||||
}
|
||||
|
||||
class ThreeDRenderer extends Renderer {
|
||||
class ThreeDRenderer extends BaseRenderer {
|
||||
renderContext: ThreeDView;
|
||||
|
||||
camera: PerspectiveCamera;
|
||||
|
|
|
@ -19,9 +19,11 @@ import PathfinderBufferTexture from './buffer-texture';
|
|||
import {OrthographicCamera} from './camera';
|
||||
import {UniformMap} from './gl-utils';
|
||||
import {PathfinderMeshData} from "./meshes";
|
||||
import {PathTransformBuffers, Renderer} from './renderer';
|
||||
import {BaseRenderer, PathTransformBuffers} from './renderer';
|
||||
import {ShaderMap, ShaderProgramSource} from "./shader-loader";
|
||||
import SSAAStrategy from './ssaa-strategy';
|
||||
import {BUILTIN_SVG_URI, SVGLoader} from './svg-loader';
|
||||
import {SVGRenderer} from './svg-renderer';
|
||||
import {BUILTIN_FONT_URI, ExpandedMeshData, GlyphStore, PathfinderFont, TextFrame} from "./text";
|
||||
import {computeStemDarkeningAmount, TextRun} from "./text";
|
||||
import {assert, lerp, PathfinderError, unwrapNull, unwrapUndef} from "./utils";
|
||||
|
@ -30,7 +32,8 @@ import {AdaptiveMonochromeXCAAStrategy} from './xcaa-strategy';
|
|||
|
||||
const STRING: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
const FONT: string = 'nimbus-sans';
|
||||
const DEFAULT_FONT: string = 'nimbus-sans';
|
||||
const DEFAULT_SVG_FILE: string = 'tiger';
|
||||
|
||||
const TEXT_COLOR: number[] = [0, 0, 0, 255];
|
||||
|
||||
|
@ -47,22 +50,48 @@ const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = {
|
|||
xcaa: AdaptiveMonochromeXCAAStrategy,
|
||||
};
|
||||
|
||||
interface BenchmarkModeMap<T> {
|
||||
text: T;
|
||||
svg: T;
|
||||
}
|
||||
|
||||
type BenchmarkMode = 'text' | 'svg';
|
||||
|
||||
interface AntialiasingStrategyTable {
|
||||
none: typeof NoAAStrategy;
|
||||
ssaa: typeof SSAAStrategy;
|
||||
xcaa: typeof AdaptiveMonochromeXCAAStrategy;
|
||||
}
|
||||
|
||||
const DISPLAY_HEADER_LABELS: BenchmarkModeMap<string[]> = {
|
||||
svg: ["Size (px)", "GPU time (ms)"],
|
||||
text: ["Font size (px)", "GPU time per glyph (µs)"],
|
||||
};
|
||||
|
||||
class BenchmarkAppController extends DemoAppController<BenchmarkTestView> {
|
||||
font: PathfinderFont | null;
|
||||
textRun: TextRun | null;
|
||||
|
||||
protected readonly defaultFile: string = FONT;
|
||||
protected readonly builtinFileURI: string = BUILTIN_FONT_URI;
|
||||
svgLoader: SVGLoader;
|
||||
|
||||
mode: BenchmarkMode;
|
||||
|
||||
protected get defaultFile(): string {
|
||||
if (this.mode === 'text')
|
||||
return DEFAULT_FONT;
|
||||
return DEFAULT_SVG_FILE;
|
||||
}
|
||||
|
||||
protected get builtinFileURI(): string {
|
||||
if (this.mode === 'text')
|
||||
return BUILTIN_FONT_URI;
|
||||
return BUILTIN_SVG_URI;
|
||||
}
|
||||
|
||||
private optionsModal: HTMLDivElement;
|
||||
|
||||
private resultsModal: HTMLDivElement;
|
||||
private resultsTableHeader: HTMLTableSectionElement;
|
||||
private resultsTableBody: HTMLTableSectionElement;
|
||||
private resultsPartitioningTimeLabel: HTMLSpanElement;
|
||||
|
||||
|
@ -79,11 +108,16 @@ class BenchmarkAppController extends DemoAppController<BenchmarkTestView> {
|
|||
start(): void {
|
||||
super.start();
|
||||
|
||||
this.mode = 'text';
|
||||
|
||||
this.optionsModal = unwrapNull(document.getElementById('pf-benchmark-modal')) as
|
||||
HTMLDivElement;
|
||||
|
||||
this.resultsModal = unwrapNull(document.getElementById('pf-benchmark-results-modal')) as
|
||||
HTMLDivElement;
|
||||
this.resultsTableHeader =
|
||||
unwrapNull(document.getElementById('pf-benchmark-results-table-header')) as
|
||||
HTMLTableSectionElement;
|
||||
this.resultsTableBody =
|
||||
unwrapNull(document.getElementById('pf-benchmark-results-table-body')) as
|
||||
HTMLTableSectionElement;
|
||||
|
@ -104,12 +138,56 @@ class BenchmarkAppController extends DemoAppController<BenchmarkTestView> {
|
|||
const runBenchmarkButton = unwrapNull(document.getElementById('pf-run-benchmark-button'));
|
||||
runBenchmarkButton.addEventListener('click', () => this.runBenchmark(), false);
|
||||
|
||||
const aaLevelFormGroup = unwrapNull(document.getElementById('pf-aa-level-form-group')) as
|
||||
HTMLDivElement;
|
||||
const benchmarkTextForm = unwrapNull(document.getElementById('pf-benchmark-text-form')) as
|
||||
HTMLFormElement;
|
||||
const benchmarkSVGForm = unwrapNull(document.getElementById('pf-benchmark-svg-form')) as
|
||||
HTMLFormElement;
|
||||
|
||||
window.jQuery(this.optionsModal).modal();
|
||||
|
||||
const benchmarkTextTab = document.getElementById('pf-benchmark-text-tab') as
|
||||
HTMLAnchorElement;
|
||||
const benchmarkSVGTab = document.getElementById('pf-benchmark-svg-tab') as
|
||||
HTMLAnchorElement;
|
||||
window.jQuery(benchmarkTextTab).on('shown.bs.tab', event => {
|
||||
this.mode = 'text';
|
||||
if (aaLevelFormGroup.parentElement != null)
|
||||
aaLevelFormGroup.parentElement.removeChild(aaLevelFormGroup);
|
||||
benchmarkTextForm.insertBefore(aaLevelFormGroup, benchmarkTextForm.firstChild);
|
||||
this.loadInitialFile(this.builtinFileURI);
|
||||
});
|
||||
window.jQuery(benchmarkSVGTab).on('shown.bs.tab', event => {
|
||||
this.mode = 'svg';
|
||||
if (aaLevelFormGroup.parentElement != null)
|
||||
aaLevelFormGroup.parentElement.removeChild(aaLevelFormGroup);
|
||||
benchmarkSVGForm.insertBefore(aaLevelFormGroup, benchmarkSVGForm.firstChild);
|
||||
this.loadInitialFile(this.builtinFileURI);
|
||||
});
|
||||
|
||||
this.loadInitialFile(this.builtinFileURI);
|
||||
}
|
||||
|
||||
protected fileLoaded(fileData: ArrayBuffer, builtinName: string | null): void {
|
||||
switch (this.mode) {
|
||||
case 'text':
|
||||
this.textFileLoaded(fileData, builtinName);
|
||||
return;
|
||||
case 'svg':
|
||||
this.svgFileLoaded(fileData, builtinName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
protected createView(gammaLUT: HTMLImageElement,
|
||||
commonShaderSource: string,
|
||||
shaderSources: ShaderMap<ShaderProgramSource>):
|
||||
BenchmarkTestView {
|
||||
return new BenchmarkTestView(this, gammaLUT, commonShaderSource, shaderSources);
|
||||
}
|
||||
|
||||
private textFileLoaded(fileData: ArrayBuffer, builtinName: string | null): void {
|
||||
const font = new PathfinderFont(fileData, builtinName);
|
||||
this.font = font;
|
||||
|
||||
|
@ -135,16 +213,22 @@ class BenchmarkAppController extends DemoAppController<BenchmarkTestView> {
|
|||
this.expandedMeshes = expandedMeshes;
|
||||
|
||||
this.view.then(view => {
|
||||
view.recreateRenderer();
|
||||
view.attachMeshes([expandedMeshes.meshes]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected createView(gammaLUT: HTMLImageElement,
|
||||
commonShaderSource: string,
|
||||
shaderSources: ShaderMap<ShaderProgramSource>):
|
||||
BenchmarkTestView {
|
||||
return new BenchmarkTestView(this, gammaLUT, commonShaderSource, shaderSources);
|
||||
private svgFileLoaded(fileData: ArrayBuffer, builtinName: string | null): void {
|
||||
this.svgLoader = new SVGLoader;
|
||||
this.svgLoader.loadFile(fileData);
|
||||
this.svgLoader.partition().then(meshes => {
|
||||
this.view.then(view => {
|
||||
view.recreateRenderer();
|
||||
view.attachMeshes([meshes]);
|
||||
view.initCameraBounds(this.svgLoader.svgBounds);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private reset(): void {
|
||||
|
@ -206,15 +290,26 @@ class BenchmarkAppController extends DemoAppController<BenchmarkTestView> {
|
|||
}
|
||||
|
||||
private showResults(): void {
|
||||
while (this.resultsTableHeader.lastChild != null)
|
||||
this.resultsTableHeader.removeChild(this.resultsTableHeader.lastChild);
|
||||
while (this.resultsTableBody.lastChild != null)
|
||||
this.resultsTableBody.removeChild(this.resultsTableBody.lastChild);
|
||||
|
||||
const tr = document.createElement('tr');
|
||||
for (const headerLabel of DISPLAY_HEADER_LABELS[this.mode]) {
|
||||
const th = document.createElement('th');
|
||||
th.appendChild(document.createTextNode(headerLabel));
|
||||
tr.appendChild(th);
|
||||
}
|
||||
this.resultsTableHeader.appendChild(tr);
|
||||
|
||||
for (const elapsedTime of this.elapsedTimes) {
|
||||
const tr = document.createElement('tr');
|
||||
const sizeTH = document.createElement('th');
|
||||
const timeTD = document.createElement('td');
|
||||
sizeTH.appendChild(document.createTextNode("" + elapsedTime.size));
|
||||
timeTD.appendChild(document.createTextNode("" + elapsedTime.time));
|
||||
const time = this.mode === 'svg' ? elapsedTime.timeInMS : elapsedTime.time;
|
||||
timeTD.appendChild(document.createTextNode("" + time));
|
||||
sizeTH.scope = 'row';
|
||||
tr.appendChild(sizeTH);
|
||||
tr.appendChild(timeTD);
|
||||
|
@ -246,7 +341,8 @@ class BenchmarkAppController extends DemoAppController<BenchmarkTestView> {
|
|||
}
|
||||
|
||||
class BenchmarkTestView extends DemoView {
|
||||
readonly renderer: BenchmarkRenderer;
|
||||
renderer: BenchmarkTextRenderer | BenchmarkSVGRenderer;
|
||||
|
||||
readonly appController: BenchmarkAppController;
|
||||
|
||||
renderingPromiseCallback: ((time: number) => void) | null;
|
||||
|
@ -256,7 +352,14 @@ class BenchmarkTestView extends DemoView {
|
|||
}
|
||||
|
||||
set pixelsPerEm(newPPEM: number) {
|
||||
this.renderer.pixelsPerEm = newPPEM;
|
||||
if (this.renderer instanceof BenchmarkTextRenderer) {
|
||||
this.renderer.pixelsPerEm = newPPEM;
|
||||
} else if (this.renderer instanceof BenchmarkSVGRenderer) {
|
||||
const camera = this.renderer.camera;
|
||||
camera.reset();
|
||||
camera.zoom(newPPEM / 100.0);
|
||||
camera.center();
|
||||
}
|
||||
}
|
||||
|
||||
constructor(appController: BenchmarkAppController,
|
||||
|
@ -264,24 +367,40 @@ class BenchmarkTestView extends DemoView {
|
|||
commonShaderSource: string,
|
||||
shaderSources: ShaderMap<ShaderProgramSource>) {
|
||||
super(gammaLUT, commonShaderSource, shaderSources);
|
||||
|
||||
this.appController = appController;
|
||||
this.renderer = new BenchmarkRenderer(this);
|
||||
|
||||
this.recreateRenderer();
|
||||
this.resizeToFit(true);
|
||||
}
|
||||
|
||||
recreateRenderer(): void {
|
||||
switch (this.appController.mode) {
|
||||
case 'svg':
|
||||
this.renderer = new BenchmarkSVGRenderer(this);
|
||||
break;
|
||||
case 'text':
|
||||
this.renderer = new BenchmarkTextRenderer(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
initCameraBounds(bounds: glmatrix.vec4): void {
|
||||
if (this.renderer instanceof BenchmarkSVGRenderer)
|
||||
this.renderer.initCameraBounds(bounds);
|
||||
}
|
||||
|
||||
protected renderingFinished(): void {
|
||||
if (this.renderingPromiseCallback == null)
|
||||
return;
|
||||
|
||||
const glyphCount = unwrapNull(this.appController.textRun).glyphIDs.length;
|
||||
const usPerGlyph = this.renderer.lastTimings.rendering * 1000.0 / glyphCount;
|
||||
this.renderingPromiseCallback(usPerGlyph);
|
||||
const appController = this.appController;
|
||||
let time = this.renderer.lastTimings.rendering * 1000.0;
|
||||
if (appController.mode === 'text')
|
||||
time /= unwrapNull(appController.textRun).glyphIDs.length;
|
||||
this.renderingPromiseCallback(time);
|
||||
}
|
||||
}
|
||||
|
||||
class BenchmarkRenderer extends Renderer {
|
||||
class BenchmarkTextRenderer extends BaseRenderer {
|
||||
renderContext: BenchmarkTestView;
|
||||
|
||||
camera: OrthographicCamera;
|
||||
|
@ -459,6 +578,22 @@ class BenchmarkRenderer extends Renderer {
|
|||
}
|
||||
}
|
||||
|
||||
class BenchmarkSVGRenderer extends SVGRenderer {
|
||||
renderContext: BenchmarkTestView;
|
||||
|
||||
protected get loader(): SVGLoader {
|
||||
return this.renderContext.appController.svgLoader;
|
||||
}
|
||||
|
||||
protected get canvas(): HTMLCanvasElement {
|
||||
return this.renderContext.canvas;
|
||||
}
|
||||
|
||||
constructor(renderContext: BenchmarkTestView) {
|
||||
super(renderContext);
|
||||
}
|
||||
}
|
||||
|
||||
function computeMedian(values: number[]): number | null {
|
||||
if (values.length === 0)
|
||||
return null;
|
||||
|
@ -481,6 +616,10 @@ class ElapsedTime {
|
|||
const median = computeMedian(this.times);
|
||||
return median == null ? 0.0 : median;
|
||||
}
|
||||
|
||||
get timeInMS(): number {
|
||||
return this.time / 1000.0;
|
||||
}
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
|
|
@ -123,9 +123,7 @@ export class OrthographicCamera extends Camera {
|
|||
this.scaleBounds = !!options.scaleBounds;
|
||||
this.ignoreBounds = !!options.ignoreBounds;
|
||||
|
||||
this.translation = glmatrix.vec2.create();
|
||||
this.scale = 1.0;
|
||||
this.rotationAngle = 0.0;
|
||||
this.reset();
|
||||
|
||||
this._bounds = glmatrix.vec4.create();
|
||||
|
||||
|
@ -139,6 +137,12 @@ export class OrthographicCamera extends Camera {
|
|||
this.onRotate = null;
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.translation = glmatrix.vec2.create();
|
||||
this.scale = 1.0;
|
||||
this.rotationAngle = 0.0;
|
||||
}
|
||||
|
||||
onWheel(event: MouseWheelEvent): void {
|
||||
if (this.canvas == null)
|
||||
throw new Error("onWheel() with no canvas?!");
|
||||
|
@ -174,6 +178,13 @@ export class OrthographicCamera extends Camera {
|
|||
this.scale = Math.min(this.canvas.width / width, this.canvas.height / height);
|
||||
|
||||
// Center.
|
||||
this.center();
|
||||
}
|
||||
|
||||
center(): void {
|
||||
const upperLeft = glmatrix.vec2.clone([this._bounds[0], this._bounds[1]]);
|
||||
const lowerRight = glmatrix.vec2.clone([this._bounds[2], this._bounds[3]]);
|
||||
|
||||
this.translation = glmatrix.vec2.create();
|
||||
glmatrix.vec2.lerp(this.translation, upperLeft, lowerRight, 0.5);
|
||||
glmatrix.vec2.scale(this.translation, this.translation, -this.scale);
|
||||
|
@ -269,7 +280,7 @@ export class OrthographicCamera extends Camera {
|
|||
}
|
||||
|
||||
private get centerPoint(): glmatrix.vec2 {
|
||||
return glmatrix.vec2.fromValues(this.canvas.width * 0.5, this.canvas.height * 0.5);
|
||||
return glmatrix.vec2.clone([this.canvas.width * 0.5, this.canvas.height * 0.5]);
|
||||
}
|
||||
|
||||
get bounds(): glmatrix.vec4 {
|
||||
|
|
|
@ -20,7 +20,7 @@ import {SUBPIXEL_GRANULARITY} from './atlas';
|
|||
import {OrthographicCamera} from './camera';
|
||||
import {UniformMap} from './gl-utils';
|
||||
import {PathfinderMeshData} from './meshes';
|
||||
import {PathTransformBuffers, Renderer} from "./renderer";
|
||||
import {BaseRenderer, PathTransformBuffers} from "./renderer";
|
||||
import {ShaderMap, ShaderProgramSource} from "./shader-loader";
|
||||
import SSAAStrategy from './ssaa-strategy';
|
||||
import {BUILTIN_FONT_URI, computeStemDarkeningAmount, ExpandedMeshData, GlyphStore} from "./text";
|
||||
|
@ -465,7 +465,7 @@ class ReferenceTestView extends DemoView {
|
|||
}
|
||||
}
|
||||
|
||||
class ReferenceTestRenderer extends Renderer {
|
||||
class ReferenceTestRenderer extends BaseRenderer {
|
||||
renderContext: ReferenceTestView;
|
||||
camera: OrthographicCamera;
|
||||
|
||||
|
|
|
@ -36,7 +36,43 @@ export interface PathTransformBuffers<T> {
|
|||
ext: T;
|
||||
}
|
||||
|
||||
export abstract class Renderer {
|
||||
export interface Renderer {
|
||||
readonly renderContext: RenderContext;
|
||||
readonly pathTransformBufferTextures: Array<PathTransformBuffers<PathfinderBufferTexture>>;
|
||||
readonly meshes: PathfinderMeshBuffers[] | null;
|
||||
readonly meshData: PathfinderMeshData[] | null;
|
||||
readonly usesSTTransform: boolean;
|
||||
readonly emboldenAmount: glmatrix.vec2;
|
||||
readonly bgColor: glmatrix.vec4;
|
||||
readonly fgColor: glmatrix.vec4 | null;
|
||||
readonly backgroundColor: glmatrix.vec4;
|
||||
readonly meshesAttached: boolean;
|
||||
readonly usesIntermediateRenderTargets: boolean;
|
||||
readonly destFramebuffer: WebGLFramebuffer | null;
|
||||
readonly destAllocatedSize: glmatrix.vec2;
|
||||
readonly destUsedSize: glmatrix.vec2;
|
||||
attachMeshes(meshes: PathfinderMeshData[]): void;
|
||||
pathBoundingRects(objectIndex: number): Float32Array;
|
||||
setHintsUniform(uniforms: UniformMap): void;
|
||||
setPathColorsUniform(objectIndex: number, uniforms: UniformMap, textureUnit: number): void;
|
||||
setEmboldenAmountUniform(objectIndex: number, uniforms: UniformMap): void;
|
||||
setAntialiasingOptions(aaType: AntialiasingStrategyName,
|
||||
aaLevel: number,
|
||||
aaOptions: AAOptions):
|
||||
void;
|
||||
redraw(): void;
|
||||
canvasResized(): void;
|
||||
meshIndexForObject(objectIndex: number): number;
|
||||
pathRangeForObject(objectIndex: number): Range;
|
||||
renderTaskTypeForObject(objectIndex: number): RenderTaskType;
|
||||
compositingOperationForObject(objectIndex: number): CompositingOperation | null;
|
||||
setTransformAndTexScaleUniformsForDest(uniforms: UniformMap): void;
|
||||
setTransformSTAndTexScaleUniformsForDest(uniforms: UniformMap): void;
|
||||
setTransformUniform(uniforms: UniformMap, objectIndex: number): void;
|
||||
setTransformSTUniform(uniforms: UniformMap, objectIndex: number): void;
|
||||
}
|
||||
|
||||
export abstract class BaseRenderer implements Renderer {
|
||||
readonly renderContext: RenderContext;
|
||||
|
||||
readonly pathTransformBufferTextures: Array<PathTransformBuffers<PathfinderBufferTexture>>;
|
||||
|
@ -240,7 +276,7 @@ export abstract class Renderer {
|
|||
gl.uniform2f(uniforms.uTexScale, usedSize[0], usedSize[1]);
|
||||
}
|
||||
|
||||
setTransformUniform(uniforms: UniformMap, objectIndex: number) {
|
||||
setTransformUniform(uniforms: UniformMap, objectIndex: number): void {
|
||||
const transform = glmatrix.mat4.clone(this.worldTransform);
|
||||
glmatrix.mat4.mul(transform, transform, this.getModelviewTransform(objectIndex));
|
||||
this.renderContext.gl.uniformMatrix4fv(uniforms.uTransform, false, transform);
|
||||
|
|
|
@ -16,7 +16,7 @@ import {OrthographicCamera} from "./camera";
|
|||
import {UniformMap} from './gl-utils';
|
||||
import {PathfinderMeshData} from './meshes';
|
||||
import {CompositingOperation, RenderTaskType} from './render-task';
|
||||
import {PathTransformBuffers, Renderer} from "./renderer";
|
||||
import {BaseRenderer, PathTransformBuffers} from "./renderer";
|
||||
import {ShaderMap} from './shader-loader';
|
||||
import SSAAStrategy from './ssaa-strategy';
|
||||
import {SVGLoader} from './svg-loader';
|
||||
|
@ -36,7 +36,7 @@ const ANTIALIASING_STRATEGIES: AntialiasingStrategyTable = {
|
|||
xcaa: ECAAMulticolorStrategy,
|
||||
};
|
||||
|
||||
export abstract class SVGRenderer extends Renderer {
|
||||
export abstract class SVGRenderer extends BaseRenderer {
|
||||
renderContext: RenderContext;
|
||||
|
||||
camera: OrthographicCamera;
|
||||
|
|
|
@ -24,7 +24,6 @@ import {createFramebuffer, createFramebufferColorTexture} from './gl-utils';
|
|||
import {createFramebufferDepthTexture, QUAD_ELEMENTS, setTextureParameters} from './gl-utils';
|
||||
import {UniformMap} from './gl-utils';
|
||||
import {PathfinderMeshBuffers, PathfinderMeshData} from './meshes';
|
||||
import {Renderer} from './renderer';
|
||||
import {PathfinderShaderProgram, ShaderMap, ShaderProgramSource} from './shader-loader';
|
||||
import SSAAStrategy from './ssaa-strategy';
|
||||
import {calculatePixelRectForGlyph, PathfinderFont} from "./text";
|
||||
|
@ -86,8 +85,14 @@ declare global {
|
|||
}
|
||||
}
|
||||
|
||||
interface TabShownEvent {
|
||||
target: EventTarget;
|
||||
relatedTarget: EventTarget;
|
||||
}
|
||||
|
||||
interface JQuerySubset {
|
||||
modal(options?: any): void;
|
||||
on(name: 'shown.bs.tab', handler: (event: TabShownEvent) => void): void;
|
||||
}
|
||||
|
||||
type Matrix4D = Float32Array;
|
||||
|
|
|
@ -17,7 +17,7 @@ import {Atlas, ATLAS_SIZE, AtlasGlyph, GlyphKey, SUBPIXEL_GRANULARITY} from './a
|
|||
import {CameraView, OrthographicCamera} from './camera';
|
||||
import {createFramebuffer, createFramebufferDepthTexture, QUAD_ELEMENTS} from './gl-utils';
|
||||
import {UniformMap} from './gl-utils';
|
||||
import {PathTransformBuffers, Renderer} from './renderer';
|
||||
import {BaseRenderer, PathTransformBuffers} from './renderer';
|
||||
import {ShaderMap} from './shader-loader';
|
||||
import SSAAStrategy from './ssaa-strategy';
|
||||
import {calculatePixelRectForGlyph, computeStemDarkeningAmount, GlyphStore, Hint} from "./text";
|
||||
|
@ -56,7 +56,7 @@ export interface TextRenderContext extends RenderContext {
|
|||
newTimingsReceived(timings: Timings): void;
|
||||
}
|
||||
|
||||
export abstract class TextRenderer extends Renderer {
|
||||
export abstract class TextRenderer extends BaseRenderer {
|
||||
renderContext: TextRenderContext;
|
||||
|
||||
camera: OrthographicCamera;
|
||||
|
|
|
@ -787,7 +787,8 @@ export abstract class ECAAStrategy extends XCAAStrategy {
|
|||
this.curveShaderProgramNames[1]);
|
||||
}
|
||||
|
||||
protected setAAUniforms(renderer: Renderer, uniforms: UniformMap, objectIndex: number): void {
|
||||
protected setAAUniforms(renderer: Renderer, uniforms: UniformMap, objectIndex: number):
|
||||
void {
|
||||
super.setAAUniforms(renderer, uniforms, objectIndex);
|
||||
renderer.setEmboldenAmountUniform(objectIndex, uniforms);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue