Browse Source

tweak renderItem value changes handling

Alexander Rose 6 years ago
parent
commit
2285653c77
2 changed files with 32 additions and 12 deletions
  1. 3 3
      src/mol-gl/renderable.ts
  2. 29 9
      src/mol-gl/webgl/render-item.ts

+ 3 - 3
src/mol-gl/renderable.ts

@@ -28,7 +28,7 @@ export interface Renderable<T extends RenderableValues & BaseValues> {
 
 export function createRenderable<T extends Values<RenderableSchema> & BaseValues>(renderItem: RenderItem, values: T, state: RenderableState): Renderable<T> {
     let boundingSphere: Sphere3D | undefined
-    
+
     return {
         get values () { return values },
         get state () { return state },
@@ -41,8 +41,8 @@ export function createRenderable<T extends Values<RenderableSchema> & BaseValues
         render: (variant: RenderVariant) => renderItem.render(variant),
         getProgram: (variant: RenderVariant) => renderItem.getProgram(variant),
         update: () => {
-            renderItem.update()
-            boundingSphere = undefined
+            const valueChanges = renderItem.update()
+            if (valueChanges.attributes) boundingSphere = undefined
         },
         dispose: () => renderItem.destroy()
     }

+ 29 - 9
src/mol-gl/webgl/render-item.ts

@@ -37,7 +37,7 @@ export interface RenderItem {
     getProgram: (variant: RenderVariant) => Program
 
     render: (variant: RenderVariant) => void
-    update: () => void
+    update: () => Readonly<ValueChanges>
     destroy: () => void
 }
 
@@ -52,6 +52,14 @@ export type RenderVariant = keyof typeof RenderVariantDefines
 type ProgramVariants = { [k: string]: ReferenceItem<Program> }
 type VertexArrayVariants = { [k: string]: WebGLVertexArrayObjectOES | undefined }
 
+interface ValueChanges {
+    attributes: boolean
+    defines: boolean
+    elements: boolean
+    textures: boolean
+    uniforms: boolean
+}
+
 export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: ShaderCode, schema: RenderableSchema, values: RenderableValues): RenderItem {
     const id = getNextRenderItemId()
     const { programCache } = ctx
@@ -88,6 +96,14 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S
     let drawCount = values.drawCount.ref.value
     let instanceCount = values.instanceCount.ref.value
 
+    const valueChanges: ValueChanges = {
+        attributes: false,
+        defines: false,
+        elements: false,
+        textures: false,
+        uniforms: false
+    }
+
     let destroyed = false
 
     return {
@@ -112,17 +128,17 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S
             }
         },
         update: () => {
-            let defineChange = false
+            valueChanges.defines = false
             Object.keys(defineValues).forEach(k => {
                 const value = defineValues[k]
                 if (value.ref.version !== versions[k]) {
                     // console.log('define version changed', k)
-                    defineChange = true
+                    valueChanges.defines = true
                     versions[k] = value.ref.version
                 }
             })
 
-            if (defineChange) {
+            if (valueChanges.defines) {
                 // console.log('some defines changed, need to rebuild programs')
                 Object.keys(RenderVariantDefines).forEach(k => {
                     const variantDefineValues: Values<RenderableSchema> = (RenderVariantDefines as any)[k]
@@ -145,8 +161,7 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S
                 versions.instanceCount = values.instanceCount.ref.version
             }
 
-            let bufferChange = false
-
+            valueChanges.attributes = false
             Object.keys(attributeValues).forEach(k => {
                 const value = attributeValues[k]
                 if (value.ref.version !== versions[k]) {
@@ -159,12 +174,13 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S
                         attributeBuffers[k].destroy()
                         const spec = schema[k] as AttributeSpec<ArrayKind>
                         attributeBuffers[k] = createAttributeBuffer(ctx, value.ref.value, spec.itemSize, spec.divisor)
-                        bufferChange = true
+                        valueChanges.attributes = true
                     }
                     versions[k] = value.ref.version
                 }
             })
 
+            valueChanges.elements = false
             if (elementsBuffer && values.elements.ref.version !== versions.elements) {
                 if (elementsBuffer.length >= values.elements.ref.value.length) {
                     // console.log('elements array large enough to update')
@@ -173,12 +189,12 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S
                     // console.log('elements array to small, need to create new elements')
                     elementsBuffer.destroy()
                     elementsBuffer = createElementsBuffer(ctx, values.elements.ref.value)
-                    bufferChange = true
+                    valueChanges.elements = true
                 }
                 versions.elements = values.elements.ref.version
             }
 
-            if (defineChange || bufferChange) {
+            if (valueChanges.attributes || valueChanges.defines || valueChanges.elements) {
                 // console.log('program/defines or buffers changed, rebuild vaos')
                 Object.keys(RenderVariantDefines).forEach(k => {
                     deleteVertexArray(ctx, vertexArrays[k])
@@ -186,14 +202,18 @@ export function createRenderItem(ctx: Context, drawMode: DrawMode, shaderCode: S
                 })
             }
 
+            valueChanges.textures = false
             Object.keys(textureValues).forEach(k => {
                 const value = textureValues[k]
                 if (value.ref.version !== versions[k]) {
                     // console.log('texture version changed, uploading image', k)
                     textures[k].load(value.ref.value)
                     versions[k] = value.ref.version
+                    valueChanges.textures = true
                 }
             })
+
+            return valueChanges
         },
         destroy: () => {
             if (!destroyed) {