From c535958e84d8d651ea16e5c757ac399e470412eb Mon Sep 17 00:00:00 2001
From: Alexander Rose <alex.rose@rcsb.org>
Date: Tue, 5 Mar 2019 16:58:10 -0800
Subject: [PATCH] ensure texture dimensions are correct

---
 src/mol-geo/geometry/color-data.ts     | 8 ++++----
 src/mol-geo/geometry/marker-data.ts    | 4 +---
 src/mol-geo/geometry/overpaint-data.ts | 4 +---
 src/mol-geo/geometry/size-data.ts      | 6 +++---
 src/mol-gl/_spec/renderer.spec.ts      | 2 +-
 src/mol-gl/renderable/util.ts          | 5 +++--
 src/mol-gl/webgl/texture.ts            | 6 ++----
 7 files changed, 15 insertions(+), 20 deletions(-)

diff --git a/src/mol-geo/geometry/color-data.ts b/src/mol-geo/geometry/color-data.ts
index d244746fd..19acb4e33 100644
--- a/src/mol-geo/geometry/color-data.ts
+++ b/src/mol-geo/geometry/color-data.ts
@@ -41,7 +41,7 @@ export function createValueColor(value: Color, colorData?: ColorData): ColorData
     } else {
         return {
             uColor: ValueCell.create(Color.toRgbNormalized(value) as Vec3),
-            tColor: ValueCell.create({ disabled: true, array: new Uint8Array(3), width: 1, height: 1 }),
+            tColor: ValueCell.create({ array: new Uint8Array(3), width: 1, height: 1 }),
             uColorTexDim: ValueCell.create(Vec2.create(1, 1)),
             dColorType: ValueCell.create('uniform'),
         }
@@ -74,7 +74,7 @@ export function createTextureColor(colors: TextureImage<Uint8Array>, type: Color
 /** Creates color texture with color for each instance/unit */
 export function createInstanceColor(locationIt: LocationIterator, color: LocationColor, colorData?: ColorData): ColorData {
     const { instanceCount } = locationIt
-    const colors = colorData && colorData.tColor.ref.value.array.length >= instanceCount * 3 ? colorData.tColor.ref.value : createTextureImage(instanceCount, 3)
+    const colors = createTextureImage(Math.max(1, instanceCount), 3, colorData && colorData.tColor.ref.value.array)
     locationIt.reset()
     while (locationIt.hasNext) {
         const { location, isSecondary, instanceIndex } = locationIt.move()
@@ -87,7 +87,7 @@ export function createInstanceColor(locationIt: LocationIterator, color: Locatio
 /** Creates color texture with color for each group (i.e. shared across instances/units) */
 export function createGroupColor(locationIt: LocationIterator, color: LocationColor, colorData?: ColorData): ColorData {
     const { groupCount } = locationIt
-    const colors = colorData && colorData.tColor.ref.value.array.length >= groupCount * 3 ? colorData.tColor.ref.value : createTextureImage(groupCount, 3)
+    const colors = createTextureImage(Math.max(1, groupCount), 3, colorData && colorData.tColor.ref.value.array)
     locationIt.reset()
     while (locationIt.hasNext && !locationIt.isNextNewInstance) {
         const { location, isSecondary, groupIndex } = locationIt.move()
@@ -100,7 +100,7 @@ export function createGroupColor(locationIt: LocationIterator, color: LocationCo
 export function createGroupInstanceColor(locationIt: LocationIterator, color: LocationColor, colorData?: ColorData): ColorData {
     const { groupCount, instanceCount } = locationIt
     const count = instanceCount * groupCount
-    const colors = colorData && colorData.tColor.ref.value.array.length >= count * 3 ? colorData.tColor.ref.value : createTextureImage(count, 3)
+    const colors = createTextureImage(Math.max(1, count), 3, colorData && colorData.tColor.ref.value.array)
     locationIt.reset()
     while (locationIt.hasNext) {
         const { location, isSecondary, index } = locationIt.move()
diff --git a/src/mol-geo/geometry/marker-data.ts b/src/mol-geo/geometry/marker-data.ts
index 22733a6ff..2c49bd1b2 100644
--- a/src/mol-geo/geometry/marker-data.ts
+++ b/src/mol-geo/geometry/marker-data.ts
@@ -65,9 +65,7 @@ export function applyMarkerAction(array: Uint8Array, start: number, end: number,
 }
 
 export function createMarkers(count: number, markerData?: MarkerData): MarkerData {
-    const markers = markerData && markerData.tMarker.ref.value.array.length >= count
-        ? markerData.tMarker.ref.value
-        : createTextureImage(count, 1)
+    const markers = createTextureImage(Math.max(1, count), 1, markerData && markerData.tMarker.ref.value.array)
     if (markerData) {
         ValueCell.update(markerData.tMarker, markers)
         ValueCell.update(markerData.uMarkerTexDim, Vec2.create(markers.width, markers.height))
diff --git a/src/mol-geo/geometry/overpaint-data.ts b/src/mol-geo/geometry/overpaint-data.ts
index e10c73d3c..f7f4546cc 100644
--- a/src/mol-geo/geometry/overpaint-data.ts
+++ b/src/mol-geo/geometry/overpaint-data.ts
@@ -24,9 +24,7 @@ export function applyOverpaintColor(array: Uint8Array, start: number, end: numbe
 }
 
 export function createOverpaint(count: number, overpaintData?: OverpaintData): OverpaintData {
-    const overpaint = overpaintData && overpaintData.tOverpaint.ref.value.array.length >= count * 4
-        ? overpaintData.tOverpaint.ref.value
-        : createTextureImage(count, 4)
+    const overpaint = createTextureImage(Math.max(1, count), 4, overpaintData && overpaintData.tOverpaint.ref.value.array)
     if (overpaintData) {
         ValueCell.update(overpaintData.tOverpaint, overpaint)
         ValueCell.update(overpaintData.uOverpaintTexDim, Vec2.create(overpaint.width, overpaint.height))
diff --git a/src/mol-geo/geometry/size-data.ts b/src/mol-geo/geometry/size-data.ts
index fa96fc266..fb4b94b85 100644
--- a/src/mol-geo/geometry/size-data.ts
+++ b/src/mol-geo/geometry/size-data.ts
@@ -101,7 +101,7 @@ export function createTextureSize(sizes: TextureImage<Uint8Array>, type: SizeTyp
 /** Creates size texture with size for each instance/unit */
 export function createInstanceSize(locationIt: LocationIterator, sizeFn: LocationSize, sizeData?: SizeData): SizeData {
     const { instanceCount} = locationIt
-    const sizes = sizeData && sizeData.tSize.ref.value.array.length >= instanceCount ? sizeData.tSize.ref.value : createTextureImage(instanceCount, 1)
+    const sizes = createTextureImage(Math.max(1, instanceCount), 1, sizeData && sizeData.tSize.ref.value.array)
     locationIt.reset()
     while (locationIt.hasNext && !locationIt.isNextNewInstance) {
         const v = locationIt.move()
@@ -114,7 +114,7 @@ export function createInstanceSize(locationIt: LocationIterator, sizeFn: Locatio
 /** Creates size texture with size for each group (i.e. shared across instances/units) */
 export function createGroupSize(locationIt: LocationIterator, sizeFn: LocationSize, sizeData?: SizeData): SizeData {
     const { groupCount } = locationIt
-    const sizes = sizeData && sizeData.tSize.ref.value.array.length >= groupCount ? sizeData.tSize.ref.value : createTextureImage(groupCount, 1)
+    const sizes = createTextureImage(Math.max(1, groupCount), 1, sizeData && sizeData.tSize.ref.value.array)
     locationIt.reset()
     while (locationIt.hasNext && !locationIt.isNextNewInstance) {
         const v = locationIt.move()
@@ -127,7 +127,7 @@ export function createGroupSize(locationIt: LocationIterator, sizeFn: LocationSi
 export function createGroupInstanceSize(locationIt: LocationIterator, sizeFn: LocationSize, sizeData?: SizeData): SizeData {
     const { groupCount, instanceCount } = locationIt
     const count = instanceCount * groupCount
-    const sizes = sizeData && sizeData.tSize.ref.value.array.length >= count ? sizeData.tSize.ref.value : createTextureImage(count, 1)
+    const sizes = createTextureImage(Math.max(1, count), 1, sizeData && sizeData.tSize.ref.value.array)
     locationIt.reset()
     while (locationIt.hasNext && !locationIt.isNextNewInstance) {
         const v = locationIt.move()
diff --git a/src/mol-gl/_spec/renderer.spec.ts b/src/mol-gl/_spec/renderer.spec.ts
index 0ec689e49..5803a9a18 100644
--- a/src/mol-gl/_spec/renderer.spec.ts
+++ b/src/mol-gl/_spec/renderer.spec.ts
@@ -133,7 +133,7 @@ describe('renderer', () => {
 
         scene.add(points)
         expect(ctx.bufferCount).toBe(4);
-        expect(ctx.textureCount).toBe(3);
+        expect(ctx.textureCount).toBe(4);
         expect(ctx.vaoCount).toBe(4);
         expect(ctx.programCache.count).toBe(4);
         expect(ctx.shaderCache.count).toBe(8);
diff --git a/src/mol-gl/renderable/util.ts b/src/mol-gl/renderable/util.ts
index 2d70433f1..a8d4d0c8b 100644
--- a/src/mol-gl/renderable/util.ts
+++ b/src/mol-gl/renderable/util.ts
@@ -29,9 +29,10 @@ export interface TextureVolume<T extends Uint8Array | Float32Array> {
     readonly depth: number
 }
 
-export function createTextureImage(n: number, itemSize: number): TextureImage<Uint8Array> {
+export function createTextureImage(n: number, itemSize: number, array?: Uint8Array): TextureImage<Uint8Array> {
     const { length, width, height } = calculateTextureInfo(n, itemSize)
-    return { array: new Uint8Array(length), width, height }
+    array = array && array.length >= length ? array : new Uint8Array(length)
+    return { array, width, height }
 }
 
 export function printTextureImage(textureImage: TextureImage<any>, scale = 1) {
diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts
index b08790f33..c5128cc4a 100644
--- a/src/mol-gl/webgl/texture.ts
+++ b/src/mol-gl/webgl/texture.ts
@@ -183,8 +183,7 @@ export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: Tex
             width = _width, height = _height, depth = _depth || 0
             gl.bindTexture(target, texture)
             if (target === gl.TEXTURE_2D) {
-                // TODO remove cast when webgl2 types are fixed
-                (gl as WebGLRenderingContext).texImage2D(target, 0, internalFormat, width, height, 0, format, type, null)
+                gl.texImage2D(target, 0, internalFormat, width, height, 0, format, type, null)
             } else if (target === (gl as WebGL2RenderingContext).TEXTURE_3D && depth !== undefined) {
                 (gl as WebGL2RenderingContext).texImage3D(target, 0, internalFormat, width, height, depth, 0, format, type, null)
             } else {
@@ -200,8 +199,7 @@ export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: Tex
             if (target === gl.TEXTURE_2D) {
                 const { array, width: _width, height: _height } = data as TextureImage<any>
                 width = _width, height = _height;
-                // TODO remove cast when webgl2 types are fixed
-                (gl as WebGLRenderingContext).texImage2D(target, 0, internalFormat, width, height, 0, format, type, array)
+                gl.texImage2D(target, 0, internalFormat, width, height, 0, format, type, array)
             } else if (target === (gl as WebGL2RenderingContext).TEXTURE_3D) {
                 const { array, width: _width, height: _height, depth: _depth } = data as TextureVolume<any>
                 width = _width, height = _height, depth = _depth;
-- 
GitLab