figureone 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js
CHANGED
|
@@ -7174,6 +7174,11 @@ var GLObject = /*#__PURE__*/function (_DrawingObject) {
|
|
|
7174
7174
|
// is precomputed so the draw loop allocates nothing). A mask with an empty
|
|
7175
7175
|
// src is a transparent placeholder - an index-preserving no-op slot.
|
|
7176
7176
|
|
|
7177
|
+
// The webgl texture id this object currently holds a base-texture reference to
|
|
7178
|
+
// (acquired by initTexture, or adopted from a shared atlas via
|
|
7179
|
+
// setBaseTextureRef). resetTextureBuffer releases exactly this id, so the
|
|
7180
|
+
// release can never be unbalanced with the acquire. null = no reference held.
|
|
7181
|
+
|
|
7177
7182
|
function GLObject(webgl) {
|
|
7178
7183
|
var _this;
|
|
7179
7184
|
var vertexShader = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
@@ -7203,6 +7208,7 @@ var GLObject = /*#__PURE__*/function (_DrawingObject) {
|
|
|
7203
7208
|
_this.numVertices = 0;
|
|
7204
7209
|
_this.uniforms = {};
|
|
7205
7210
|
_this.texture = null;
|
|
7211
|
+
_this.acquiredBaseTextureId = null;
|
|
7206
7212
|
_this.maskTextures = [];
|
|
7207
7213
|
// this.selectorProgramIndex = this.webgl.getProgram(selectorVertexShader, selectorFragShader);
|
|
7208
7214
|
_this.initProgram();
|
|
@@ -7463,6 +7469,10 @@ var GLObject = /*#__PURE__*/function (_DrawingObject) {
|
|
|
7463
7469
|
// gl.STATIC_DRAW,
|
|
7464
7470
|
// );
|
|
7465
7471
|
webgl.addTexture(id, data || src, loadColor, repeat, this.executeOnLoad.bind(this), force);
|
|
7472
|
+
// addTexture took/holds a reference to this id; record it so
|
|
7473
|
+
// resetTextureBuffer releases exactly what was acquired. (For a forced
|
|
7474
|
+
// update the id is unchanged, so this is idempotent.)
|
|
7475
|
+
this.acquiredBaseTextureId = id;
|
|
7466
7476
|
this.state = webgl.textures[texture.id].state;
|
|
7467
7477
|
|
|
7468
7478
|
// Register the optional mask textures (textureMap color mode). Each loads
|
|
@@ -7527,6 +7537,30 @@ var GLObject = /*#__PURE__*/function (_DrawingObject) {
|
|
|
7527
7537
|
// }
|
|
7528
7538
|
}
|
|
7529
7539
|
|
|
7540
|
+
/**
|
|
7541
|
+
* Adopt a base-texture reference to an already-registered texture (e.g. a
|
|
7542
|
+
* shared font atlas uploaded by the Atlas, whose id this object renders with
|
|
7543
|
+
* but does not upload itself).
|
|
7544
|
+
*
|
|
7545
|
+
* Releases any previously-held base reference first (so a font/atlas change
|
|
7546
|
+
* rebalances correctly) and is idempotent when the id is unchanged. If the
|
|
7547
|
+
* texture isn't registered yet, no reference is taken and acquiredBaseTextureId
|
|
7548
|
+
* is cleared, so the later resetTextureBuffer release stays balanced (it only
|
|
7549
|
+
* releases a reference that was actually acquired).
|
|
7550
|
+
*/
|
|
7551
|
+
}, {
|
|
7552
|
+
key: "setBaseTextureRef",
|
|
7553
|
+
value: function setBaseTextureRef(id) {
|
|
7554
|
+
if (this.acquiredBaseTextureId === id) {
|
|
7555
|
+
return;
|
|
7556
|
+
}
|
|
7557
|
+
var webgl = this.webgl;
|
|
7558
|
+
if (this.acquiredBaseTextureId != null) {
|
|
7559
|
+
webgl.deleteTexture(this.acquiredBaseTextureId);
|
|
7560
|
+
}
|
|
7561
|
+
this.acquiredBaseTextureId = webgl.acquireTexture(id) ? id : null;
|
|
7562
|
+
}
|
|
7563
|
+
|
|
7530
7564
|
// A texture map is a texture coords point that lines up with the texture
|
|
7531
7565
|
// vertex point. So, if the vertex shape is rectangular, centered at the
|
|
7532
7566
|
// origin and wants to incorporate the entire texture, then the map would
|
|
@@ -7707,14 +7741,15 @@ var GLObject = /*#__PURE__*/function (_DrawingObject) {
|
|
|
7707
7741
|
maskTextures = this.maskTextures,
|
|
7708
7742
|
webgl = this.webgl,
|
|
7709
7743
|
gl = this.gl;
|
|
7710
|
-
if (
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7744
|
+
if (deleteTexture && this.acquiredBaseTextureId != null) {
|
|
7745
|
+
// Release exactly the base reference this object acquired, so a failed
|
|
7746
|
+
// acquire (e.g. an atlas not registered yet) can never over-release.
|
|
7747
|
+
webgl.deleteTexture(this.acquiredBaseTextureId);
|
|
7748
|
+
this.acquiredBaseTextureId = null;
|
|
7749
|
+
}
|
|
7750
|
+
if (texture && texture.buffer != null) {
|
|
7751
|
+
gl.deleteBuffer(texture.buffer);
|
|
7752
|
+
texture.buffer = null;
|
|
7718
7753
|
}
|
|
7719
7754
|
if (deleteTexture) {
|
|
7720
7755
|
maskTextures.forEach(function (maskTexture) {
|
|
@@ -7994,6 +8029,9 @@ var GLObject = /*#__PURE__*/function (_DrawingObject) {
|
|
|
7994
8029
|
gl.uniform1f(locations.u_z, this.z);
|
|
7995
8030
|
gl.uniform4f(locations.u_color, color[0], color[1], color[2], color[3]);
|
|
7996
8031
|
var texture = this.texture;
|
|
8032
|
+
// Set when a textured object's base texture can't be bound, so we skip the
|
|
8033
|
+
// draw rather than sampling a stale/wrong texture (see below).
|
|
8034
|
+
var skipDraw = false;
|
|
7997
8035
|
if (texture != null && targetTexture === false) {
|
|
7998
8036
|
// Tell the position attribute how to get data out of positionBuffer (ARRAY_BUFFER)
|
|
7999
8037
|
var texSize = 2; // 2 components per iteration
|
|
@@ -8007,27 +8045,49 @@ var GLObject = /*#__PURE__*/function (_DrawingObject) {
|
|
|
8007
8045
|
gl.enableVertexAttribArray(locations.a_texcoord);
|
|
8008
8046
|
gl.bindBuffer(gl.ARRAY_BUFFER, texture.buffer);
|
|
8009
8047
|
gl.vertexAttribPointer(locations.a_texcoord, texSize, texType, texNormalize, texStride, texOffset);
|
|
8010
|
-
|
|
8011
|
-
|
|
8012
|
-
|
|
8013
|
-
|
|
8014
|
-
//
|
|
8015
|
-
//
|
|
8016
|
-
|
|
8017
|
-
|
|
8018
|
-
|
|
8019
|
-
|
|
8020
|
-
|
|
8021
|
-
|
|
8022
|
-
|
|
8023
|
-
|
|
8024
|
-
|
|
8048
|
+
// Assign content texture units for this draw from the shared pool. Unit 0
|
|
8049
|
+
// is reserved for the target/selector framebuffer texture, so content
|
|
8050
|
+
// starts at unit 1: the base texture, then each mask texture in turn.
|
|
8051
|
+
// bindTextureToUnit only issues a bindTexture when the unit isn't already
|
|
8052
|
+
// pointing at that texture, so runs of draws sharing a texture (e.g. text
|
|
8053
|
+
// sharing a font atlas) issue no bind calls.
|
|
8054
|
+
var textureUnit = 1;
|
|
8055
|
+
if (webglInstance.bindTextureToUnit(texture.id, textureUnit)) {
|
|
8056
|
+
gl.uniform1i(locations.u_use_texture, 1);
|
|
8057
|
+
gl.uniform1i(locations.u_texture, textureUnit);
|
|
8058
|
+
textureUnit += 1;
|
|
8059
|
+
|
|
8060
|
+
// Bind the mask textures (textureMap color mode), each to its own
|
|
8061
|
+
// texture unit and precomputed u_mask{i} sampler. They reuse the
|
|
8062
|
+
// a_texcoord / v_texcoord bound above, so no extra attribute is needed.
|
|
8063
|
+
// Only assign the sampler if the bind succeeds — otherwise the uniform
|
|
8064
|
+
// would default to sampler 0 (the reserved target texture) and recolor
|
|
8065
|
+
// with garbage. Uses an indexed loop with precomputed uniform names to
|
|
8066
|
+
// avoid per-frame allocation.
|
|
8067
|
+
var maskTextures = this.maskTextures;
|
|
8068
|
+
for (var i = 0; i < maskTextures.length; i += 1) {
|
|
8069
|
+
var maskTexture = maskTextures[i];
|
|
8070
|
+
var maskLocation = locations[maskTexture.uniformName];
|
|
8071
|
+
if (maskLocation != null && webglInstance.bindTextureToUnit(maskTexture.id, textureUnit)) {
|
|
8072
|
+
gl.uniform1i(maskLocation, textureUnit);
|
|
8073
|
+
textureUnit += 1;
|
|
8074
|
+
}
|
|
8025
8075
|
}
|
|
8076
|
+
} else {
|
|
8077
|
+
// The base texture isn't available (e.g. a shared texture was deleted by
|
|
8078
|
+
// another element's cleanup while this one still references it). The
|
|
8079
|
+
// composed texture shaders sample u_texture unconditionally, so there is
|
|
8080
|
+
// no safe in-shader fallback — skip this object's draw this frame rather
|
|
8081
|
+
// than sampling whatever stale texture occupies the unit.
|
|
8082
|
+
gl.uniform1i(locations.u_use_texture, 0);
|
|
8083
|
+
skipDraw = true;
|
|
8026
8084
|
}
|
|
8027
8085
|
} else {
|
|
8028
8086
|
gl.uniform1i(locations.u_use_texture, 0);
|
|
8029
8087
|
}
|
|
8030
|
-
|
|
8088
|
+
if (!skipDraw) {
|
|
8089
|
+
gl.drawArrays(this.glPrimitive, 0, numDrawVertices);
|
|
8090
|
+
}
|
|
8031
8091
|
if (texture) {
|
|
8032
8092
|
gl.disableVertexAttribArray(locations.a_texcoord);
|
|
8033
8093
|
}
|
|
@@ -52888,11 +52948,20 @@ var FigureElementPrimitiveGLText = /*#__PURE__*/function (_FigureElementPrimiti)
|
|
|
52888
52948
|
scene: scene,
|
|
52889
52949
|
font: this.font
|
|
52890
52950
|
});
|
|
52951
|
+
var textureID = this.atlas.font.getTextureID();
|
|
52891
52952
|
if (this.drawingObject.texture == null) {
|
|
52892
|
-
this.drawingObject.addTexture(
|
|
52953
|
+
this.drawingObject.addTexture(textureID);
|
|
52893
52954
|
} else {
|
|
52894
|
-
this.drawingObject.texture.id =
|
|
52895
|
-
}
|
|
52955
|
+
this.drawingObject.texture.id = textureID;
|
|
52956
|
+
}
|
|
52957
|
+
// Take a webgl reference to the shared atlas texture so it survives other
|
|
52958
|
+
// elements' cleanup. The Atlas registers/uploads the texture; this element
|
|
52959
|
+
// only adopts its id (GLObject.addTexture above doesn't touch webgl), so
|
|
52960
|
+
// without this its resetTextureBuffer release would be unbalanced and the
|
|
52961
|
+
// first element's cleanup would free the atlas for the others.
|
|
52962
|
+
// setBaseTextureRef releases any previously-held id (createAtlas re-runs on
|
|
52963
|
+
// font changes) and is idempotent when the id is unchanged.
|
|
52964
|
+
this.drawingObject.setBaseTextureRef(textureID);
|
|
52896
52965
|
// console.log(this.atlas)
|
|
52897
52966
|
this.setText(this.text);
|
|
52898
52967
|
this.atlasNotificationsID = this.atlas.notifications.add('updated', this.loaded.bind(this));
|
|
@@ -67165,6 +67234,20 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67165
67234
|
value:
|
|
67166
67235
|
// locations: Object;
|
|
67167
67236
|
|
|
67237
|
+
// Content texture units are a small shared pool reused across draws. Unit 0 is
|
|
67238
|
+
// reserved for the target/selector framebuffer texture, so content starts at
|
|
67239
|
+
// unit 1. boundUnits[u] tracks which texture id is currently bound to GL unit
|
|
67240
|
+
// u, so bindTextureToUnit can skip redundant binds (bind-on-change).
|
|
67241
|
+
|
|
67242
|
+
// Monotonic source for texture handles (never reused, so deleting a texture
|
|
67243
|
+
// can never cause a later texture to collide with a live one).
|
|
67244
|
+
|
|
67245
|
+
// gl.MAX_TEXTURE_IMAGE_UNITS (the fragment-shader sampler limit), queried once
|
|
67246
|
+
// for a diagnostic warning. Matches the per-object mask guard in
|
|
67247
|
+
// FigurePrimitives.gl().
|
|
67248
|
+
|
|
67249
|
+
// Set once the unit-budget warning has fired, so it isn't logged every frame.
|
|
67250
|
+
|
|
67168
67251
|
/*
|
|
67169
67252
|
Add, or update a texture. If the texture already exists, then do nothing.
|
|
67170
67253
|
A texture is referenced with a unique id, and defined by either a url (string), Image or html canvas element.
|
|
@@ -67180,45 +67263,52 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67180
67263
|
var onLoad = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
67181
67264
|
var force = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;
|
|
67182
67265
|
/*
|
|
67183
|
-
|
|
67184
|
-
|
|
67185
|
-
|
|
67266
|
+
A texture id can be shared by multiple owners (e.g. several GLText elements
|
|
67267
|
+
using the same font atlas, plus the Atlas itself). Each addTexture call
|
|
67268
|
+
that isn't a forced content update acquires one reference; deleteTexture
|
|
67269
|
+
releases one, and the GL texture is freed only when the last owner releases
|
|
67270
|
+
it. This lets one element's cleanup() drop its reference without pulling a
|
|
67271
|
+
still-shared texture out from under the survivors.
|
|
67272
|
+
If the texture already exists and is still loading, the onLoad callback is
|
|
67273
|
+
added to the list to be called once the texture loads.
|
|
67186
67274
|
*/
|
|
67187
67275
|
if (!force && this.textures[id] != null) {
|
|
67188
|
-
|
|
67189
|
-
|
|
67190
|
-
|
|
67191
|
-
|
|
67276
|
+
// Another owner (or the same owner re-acquiring) references an existing
|
|
67277
|
+
// texture: take a reference and (re)register the load callback.
|
|
67278
|
+
var existingTexture = this.textures[id];
|
|
67279
|
+
existingTexture.refCount += 1;
|
|
67280
|
+
if (onLoad != null) {
|
|
67281
|
+
existingTexture.onLoad.push(onLoad);
|
|
67282
|
+
}
|
|
67283
|
+
if (existingTexture.state === 'loaded') {
|
|
67192
67284
|
this.onLoad(id);
|
|
67193
|
-
return this.textures[id].index;
|
|
67194
67285
|
}
|
|
67195
|
-
|
|
67286
|
+
return existingTexture.handle;
|
|
67287
|
+
}
|
|
67288
|
+
var gl = this.gl;
|
|
67289
|
+
if (this.textures[id] != null) {
|
|
67290
|
+
// Forced content update of an existing texture: keep its identity AND
|
|
67291
|
+
// reference count so other owners survive the update. setTextureData
|
|
67292
|
+
// (below) frees and replaces the old glTexture, so the entry — including
|
|
67293
|
+
// its glTexture pointer — is preserved here rather than recreated.
|
|
67294
|
+
// Append (don't replace) onLoad so pending callbacks other owners
|
|
67295
|
+
// registered while the texture was still loading aren't silently dropped.
|
|
67296
|
+
this.textures[id].state = 'loading';
|
|
67196
67297
|
if (onLoad != null) {
|
|
67197
67298
|
this.textures[id].onLoad.push(onLoad);
|
|
67198
67299
|
}
|
|
67199
|
-
return this.textures[id].index;
|
|
67200
|
-
// removed by dead control flow
|
|
67201
|
-
|
|
67202
|
-
}
|
|
67203
|
-
var index = 0;
|
|
67204
|
-
if (this.textures[id] != null) {
|
|
67205
|
-
index = this.textures[id].index;
|
|
67206
67300
|
} else {
|
|
67207
|
-
|
|
67301
|
+
// Brand new texture: the first owner holds the only reference.
|
|
67302
|
+
this.textures[id] = {
|
|
67303
|
+
id: id,
|
|
67304
|
+
state: 'loading',
|
|
67305
|
+
onLoad: onLoad != null ? [onLoad] : [],
|
|
67306
|
+
handle: this.nextTextureHandle,
|
|
67307
|
+
refCount: 1
|
|
67308
|
+
};
|
|
67309
|
+
this.nextTextureHandle += 1;
|
|
67208
67310
|
}
|
|
67209
|
-
// If a texture already exists, then unload it
|
|
67210
|
-
this.deleteTexture(id);
|
|
67211
|
-
var gl = this.gl;
|
|
67212
|
-
this.textures[id] = {
|
|
67213
|
-
id: id,
|
|
67214
|
-
state: 'loading',
|
|
67215
|
-
onLoad: [],
|
|
67216
|
-
index: index
|
|
67217
|
-
};
|
|
67218
67311
|
var texture = this.textures[id];
|
|
67219
|
-
if (onLoad != null) {
|
|
67220
|
-
texture.onLoad.push(onLoad);
|
|
67221
|
-
}
|
|
67222
67312
|
// If the data is a url string, then load the data into an image
|
|
67223
67313
|
if (typeof data === 'string') {
|
|
67224
67314
|
this.setTextureData(id, loadColor);
|
|
@@ -67237,7 +67327,7 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67237
67327
|
this.onLoad(id);
|
|
67238
67328
|
texture.state = 'loaded';
|
|
67239
67329
|
}
|
|
67240
|
-
return this.textures[id].
|
|
67330
|
+
return this.textures[id].handle;
|
|
67241
67331
|
}
|
|
67242
67332
|
}, {
|
|
67243
67333
|
key: "getAtlas",
|
|
@@ -67273,6 +67363,27 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67273
67363
|
throw errors[0];
|
|
67274
67364
|
}
|
|
67275
67365
|
}
|
|
67366
|
+
|
|
67367
|
+
// Take an additional reference to an already-registered texture, without
|
|
67368
|
+
// re-uploading it or touching its load callbacks. Used when an element adopts
|
|
67369
|
+
// a texture another owner created and uploaded (e.g. a GLText element sharing
|
|
67370
|
+
// a font atlas registered by the Atlas). Returns false if the texture isn't
|
|
67371
|
+
// registered yet, in which case no reference was taken. Release with
|
|
67372
|
+
// deleteTexture.
|
|
67373
|
+
}, {
|
|
67374
|
+
key: "acquireTexture",
|
|
67375
|
+
value: function acquireTexture(id) {
|
|
67376
|
+
var texture = this.textures[id];
|
|
67377
|
+
if (texture == null) {
|
|
67378
|
+
return false;
|
|
67379
|
+
}
|
|
67380
|
+
texture.refCount += 1;
|
|
67381
|
+
return true;
|
|
67382
|
+
}
|
|
67383
|
+
|
|
67384
|
+
// Release one reference to a texture. The GL texture is freed only once the
|
|
67385
|
+
// last owner releases it, so one element's cleanup can't delete a texture
|
|
67386
|
+
// another element still shares (see addTexture for the rationale).
|
|
67276
67387
|
}, {
|
|
67277
67388
|
key: "deleteTexture",
|
|
67278
67389
|
value: function deleteTexture(id) {
|
|
@@ -67280,13 +67391,27 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67280
67391
|
if (texture == null) {
|
|
67281
67392
|
return;
|
|
67282
67393
|
}
|
|
67283
|
-
|
|
67394
|
+
texture.refCount -= 1;
|
|
67395
|
+
if (texture.refCount <= 0) {
|
|
67396
|
+
this.freeTexture(id);
|
|
67397
|
+
}
|
|
67398
|
+
}
|
|
67284
67399
|
|
|
67285
|
-
|
|
67400
|
+
// Unconditionally free a texture regardless of reference count. Used for
|
|
67401
|
+
// teardown (cleanup), where every owner is going away at once.
|
|
67402
|
+
}, {
|
|
67403
|
+
key: "freeTexture",
|
|
67404
|
+
value: function freeTexture(id) {
|
|
67405
|
+
var texture = this.textures[id];
|
|
67406
|
+
if (texture == null) {
|
|
67407
|
+
return;
|
|
67408
|
+
}
|
|
67409
|
+
var gl = this.gl;
|
|
67410
|
+
// gl.deleteTexture unbinds it from any unit it was bound to, so we just drop
|
|
67411
|
+
// the stale cache entries.
|
|
67286
67412
|
if (texture.glTexture != null) {
|
|
67287
|
-
gl.activeTexture(gl.TEXTURE0 + texture.index);
|
|
67288
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
67289
67413
|
gl.deleteTexture(texture.glTexture);
|
|
67414
|
+
this.clearBoundUnits(id);
|
|
67290
67415
|
}
|
|
67291
67416
|
this.cancel(id);
|
|
67292
67417
|
delete this.textures[id];
|
|
@@ -67298,6 +67423,53 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67298
67423
|
Object.keys(this.textures).forEach(function (id) {
|
|
67299
67424
|
_this3.textures[id].glTexture = null;
|
|
67300
67425
|
});
|
|
67426
|
+
// The new context starts with nothing bound, so the bind cache is stale.
|
|
67427
|
+
this.boundUnits = [];
|
|
67428
|
+
}
|
|
67429
|
+
|
|
67430
|
+
// Drop any working-unit cache entries that point at this texture id, so a
|
|
67431
|
+
// future draw re-binds rather than trusting a stale/deleted glTexture.
|
|
67432
|
+
}, {
|
|
67433
|
+
key: "clearBoundUnits",
|
|
67434
|
+
value: function clearBoundUnits(id) {
|
|
67435
|
+
for (var u = 0; u < this.boundUnits.length; u += 1) {
|
|
67436
|
+
if (this.boundUnits[u] === id) {
|
|
67437
|
+
this.boundUnits[u] = null;
|
|
67438
|
+
}
|
|
67439
|
+
}
|
|
67440
|
+
}
|
|
67441
|
+
|
|
67442
|
+
/*
|
|
67443
|
+
Bind a registered texture to a content texture unit for the current draw.
|
|
67444
|
+
Content units are a small shared pool (unit 0 is reserved for the
|
|
67445
|
+
target/selector framebuffer texture). bindTexture is only issued when the
|
|
67446
|
+
unit is not already pointing at this texture, so runs of draws that share a
|
|
67447
|
+
texture (e.g. text sharing a font atlas) issue zero bind calls.
|
|
67448
|
+
*/
|
|
67449
|
+
}, {
|
|
67450
|
+
key: "bindTextureToUnit",
|
|
67451
|
+
value: function bindTextureToUnit(id, unit) {
|
|
67452
|
+
var texture = this.textures[id];
|
|
67453
|
+
if (texture == null || texture.glTexture == null) {
|
|
67454
|
+
return false;
|
|
67455
|
+
}
|
|
67456
|
+
if (unit >= this.maxTextureUnits) {
|
|
67457
|
+
// Out of unit budget: warn once (not every frame) and don't issue an
|
|
67458
|
+
// out-of-range bind. The caller treats false as "not bound".
|
|
67459
|
+
if (!this.warnedUnitOverflow) {
|
|
67460
|
+
(0,_tools_tools__WEBPACK_IMPORTED_MODULE_2__.Console)("FigureOne WebGL warning: texture unit ".concat(unit, " exceeds this device's ") + "MAX_TEXTURE_IMAGE_UNITS (".concat(this.maxTextureUnits, "). Reduce the ") + 'number of simultaneous textures/masks.');
|
|
67461
|
+
this.warnedUnitOverflow = true;
|
|
67462
|
+
}
|
|
67463
|
+
return false;
|
|
67464
|
+
}
|
|
67465
|
+
if (this.boundUnits[unit] === id) {
|
|
67466
|
+
return true;
|
|
67467
|
+
}
|
|
67468
|
+
var gl = this.gl;
|
|
67469
|
+
gl.activeTexture(gl.TEXTURE0 + unit);
|
|
67470
|
+
gl.bindTexture(gl.TEXTURE_2D, texture.glTexture);
|
|
67471
|
+
this.boundUnits[unit] = id;
|
|
67472
|
+
return true;
|
|
67301
67473
|
}
|
|
67302
67474
|
}, {
|
|
67303
67475
|
key: "cleanup",
|
|
@@ -67311,9 +67483,10 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67311
67483
|
}
|
|
67312
67484
|
});
|
|
67313
67485
|
this.programs = [];
|
|
67314
|
-
//
|
|
67486
|
+
// Free all textures outright, ignoring reference counts — every owner is
|
|
67487
|
+
// going away in this teardown.
|
|
67315
67488
|
Object.keys(this.textures).forEach(function (id) {
|
|
67316
|
-
_this4.
|
|
67489
|
+
_this4.freeTexture(id);
|
|
67317
67490
|
});
|
|
67318
67491
|
this.textures = {};
|
|
67319
67492
|
// Clean up atlases
|
|
@@ -67334,20 +67507,27 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67334
67507
|
return (value & value - 1) === 0;
|
|
67335
67508
|
}
|
|
67336
67509
|
var texture = this.textures[id];
|
|
67337
|
-
var index = texture.index;
|
|
67338
67510
|
var gl = this.gl;
|
|
67511
|
+
// Upload happens on the first content unit as scratch. Any cache entry for
|
|
67512
|
+
// this id refers to the old glTexture we're about to replace, so invalidate
|
|
67513
|
+
// them all before binding the new one.
|
|
67514
|
+
var uploadUnit = 1;
|
|
67515
|
+
this.clearBoundUnits(id);
|
|
67339
67516
|
|
|
67340
67517
|
// If texture exists, then delete it
|
|
67341
67518
|
if (texture.glTexture != null) {
|
|
67342
|
-
gl.activeTexture(gl.TEXTURE0 +
|
|
67519
|
+
gl.activeTexture(gl.TEXTURE0 + uploadUnit);
|
|
67343
67520
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
67344
67521
|
gl.deleteTexture(texture.glTexture);
|
|
67345
67522
|
}
|
|
67346
67523
|
// Create a texture
|
|
67347
67524
|
var glTexture = gl.createTexture();
|
|
67348
67525
|
texture.glTexture = glTexture;
|
|
67349
|
-
gl.activeTexture(gl.TEXTURE0 +
|
|
67526
|
+
gl.activeTexture(gl.TEXTURE0 + uploadUnit);
|
|
67350
67527
|
gl.bindTexture(gl.TEXTURE_2D, glTexture);
|
|
67528
|
+
// The new glTexture is now bound to the upload unit; record it so a draw
|
|
67529
|
+
// that needs it on this unit can skip a redundant bind.
|
|
67530
|
+
this.boundUnits[uploadUnit] = id;
|
|
67351
67531
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
|
|
67352
67532
|
|
|
67353
67533
|
// If image is a color, then create s ingle pixel image of that color
|
|
@@ -67411,7 +67591,7 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67411
67591
|
value: function onLoad(id) {
|
|
67412
67592
|
var _this5 = this;
|
|
67413
67593
|
this.textures[id].onLoad.forEach(function (f) {
|
|
67414
|
-
return _this5.fnMap.exec(f, true, _this5.textures[id].
|
|
67594
|
+
return _this5.fnMap.exec(f, true, _this5.textures[id].handle);
|
|
67415
67595
|
});
|
|
67416
67596
|
this.textures[id].onLoad = [];
|
|
67417
67597
|
}
|
|
@@ -67420,7 +67600,7 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67420
67600
|
value: function cancel(id) {
|
|
67421
67601
|
var _this6 = this;
|
|
67422
67602
|
this.textures[id].onLoad.forEach(function (f) {
|
|
67423
|
-
return _this6.fnMap.exec(f, false, _this6.textures[id].
|
|
67603
|
+
return _this6.fnMap.exec(f, false, _this6.textures[id].handle);
|
|
67424
67604
|
});
|
|
67425
67605
|
this.textures[id].onLoad = [];
|
|
67426
67606
|
}
|
|
@@ -67485,6 +67665,11 @@ var WebGLInstance = /*#__PURE__*/function () {
|
|
|
67485
67665
|
value: function init(gl) {
|
|
67486
67666
|
this.gl = gl;
|
|
67487
67667
|
this.textures = {};
|
|
67668
|
+
this.boundUnits = [];
|
|
67669
|
+
this.nextTextureHandle = 1;
|
|
67670
|
+
this.warnedUnitOverflow = false;
|
|
67671
|
+
var maxUnits = gl.getParameter ? gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS) : 0;
|
|
67672
|
+
this.maxTextureUnits = maxUnits || 8;
|
|
67488
67673
|
this.programs = [];
|
|
67489
67674
|
this.targetTexture = null;
|
|
67490
67675
|
this.lastUsedProgram = null;
|
|
@@ -82098,8 +82283,8 @@ var tools = {
|
|
|
82098
82283
|
*/
|
|
82099
82284
|
|
|
82100
82285
|
var Fig = {
|
|
82101
|
-
version: "1.
|
|
82102
|
-
gitHash: "
|
|
82286
|
+
version: "1.9.0",
|
|
82287
|
+
gitHash: "2e042f98b",
|
|
82103
82288
|
tools: tools,
|
|
82104
82289
|
Figure: _js_figure_Figure__WEBPACK_IMPORTED_MODULE_5__["default"],
|
|
82105
82290
|
Recorder: _js_figure_Recorder_Recorder__WEBPACK_IMPORTED_MODULE_7__.Recorder,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figureone",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Draw, animate and interact with shapes, text, plots and equations in Javascript. Create interactive slide shows, and interactive videos.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "types/index.d.ts",
|
|
@@ -76,6 +76,7 @@ declare class GLObject extends DrawingObject {
|
|
|
76
76
|
fragmentShader: TypeFragmentShader;
|
|
77
77
|
selectorVertexShader: TypeVertexShader;
|
|
78
78
|
selectorFragmentShader: TypeFragmentShader;
|
|
79
|
+
acquiredBaseTextureId: string | null;
|
|
79
80
|
constructor(webgl: WebGLInstance, vertexShader?: TypeVertexShader, fragmentShader?: TypeFragmentShader, selectorVertexShader?: TypeVertexShader, selectorFragShader?: TypeFragmentShader);
|
|
80
81
|
init(webgl: WebGLInstance): void;
|
|
81
82
|
initProgram(): void;
|
|
@@ -105,6 +106,18 @@ declare class GLObject extends DrawingObject {
|
|
|
105
106
|
addMaskTexture(location?: string, loadColor?: TypeColor): void;
|
|
106
107
|
updateTexture(data: HTMLImageElement): void;
|
|
107
108
|
initTexture(force?: boolean): void;
|
|
109
|
+
/**
|
|
110
|
+
* Adopt a base-texture reference to an already-registered texture (e.g. a
|
|
111
|
+
* shared font atlas uploaded by the Atlas, whose id this object renders with
|
|
112
|
+
* but does not upload itself).
|
|
113
|
+
*
|
|
114
|
+
* Releases any previously-held base reference first (so a font/atlas change
|
|
115
|
+
* rebalances correctly) and is idempotent when the id is unchanged. If the
|
|
116
|
+
* texture isn't registered yet, no reference is taken and acquiredBaseTextureId
|
|
117
|
+
* is cleared, so the later resetTextureBuffer release stays balanced (it only
|
|
118
|
+
* releases a reference that was actually acquired).
|
|
119
|
+
*/
|
|
120
|
+
setBaseTextureRef(id: string): void;
|
|
108
121
|
createTextureMap(xMinGL?: number, xMaxGL?: number, yMinGL?: number, yMaxGL?: number, xMinTex?: number, xMaxTex?: number, yMinTex?: number, yMaxTex?: number): void;
|
|
109
122
|
addVertices(vertices: Array<number>, dimension?: 2 | 3, usage?: TypeGLBufferUsage): void;
|
|
110
123
|
addVertices3(vertices: Array<number>, usage?: TypeGLBufferUsage): void;
|
|
@@ -12,11 +12,16 @@ declare class WebGLInstance {
|
|
|
12
12
|
textures: {
|
|
13
13
|
[name: string]: {
|
|
14
14
|
glTexture: WebGLTexture;
|
|
15
|
-
|
|
15
|
+
handle: number;
|
|
16
|
+
refCount: number;
|
|
16
17
|
state: 'loading' | 'loaded';
|
|
17
18
|
onLoad: Array<((b: boolean, n: number) => void) | string>;
|
|
18
19
|
};
|
|
19
20
|
};
|
|
21
|
+
boundUnits: Array<string | null>;
|
|
22
|
+
nextTextureHandle: number;
|
|
23
|
+
maxTextureUnits: number;
|
|
24
|
+
warnedUnitOverflow: boolean;
|
|
20
25
|
atlases: {
|
|
21
26
|
[atlasId: string]: Atlas;
|
|
22
27
|
};
|
|
@@ -39,8 +44,12 @@ declare class WebGLInstance {
|
|
|
39
44
|
addTexture(id: string, data: string | HTMLImageElement | HTMLCanvasElement, loadColor?: TypeColor, repeat?: boolean, onLoad?: null | string | ((b: boolean, n: number) => void), force?: boolean): number;
|
|
40
45
|
getAtlas(options: OBJ_Atlas): Atlas;
|
|
41
46
|
recreateAtlases(): void;
|
|
47
|
+
acquireTexture(id: string): boolean;
|
|
42
48
|
deleteTexture(id: string): void;
|
|
49
|
+
freeTexture(id: string): void;
|
|
43
50
|
contextLost(): void;
|
|
51
|
+
clearBoundUnits(id: string): void;
|
|
52
|
+
bindTextureToUnit(id: string, unit: number): boolean;
|
|
44
53
|
cleanup(): void;
|
|
45
54
|
setTextureData(id: string, image: Record<string, any> | TypeColor, // image data
|
|
46
55
|
repeat?: boolean): boolean;
|