Selaa lähdekoodia

renderer refactoring (avoid object usage)

Alexander Rose 6 vuotta sitten
vanhempi
commit
2c42ea895e

+ 0 - 13
src/mol-gl/renderable/schema.ts

@@ -83,19 +83,6 @@ export function splitValues(schema: RenderableSchema, values: RenderableValues)
     return { attributeValues, defineValues, textureValues, uniformValues, materialUniformValues }
 }
 
-export function splitKeys(schema: RenderableSchema) {
-    const attributeKeys: string[] = []
-    const defineKeys: string[] = []
-    const textureKeys: string[] = []
-    Object.keys(schema).forEach(k => {
-        const spec = schema[k]
-        if (spec.type === 'attribute') attributeKeys.push(k)
-        if (spec.type === 'define') defineKeys.push(k)
-        if (spec.type === 'texture') textureKeys.push(k)
-    })
-    return { attributeKeys, defineKeys, textureKeys }
-}
-
 export type Versions<T extends RenderableValues> = { [k in keyof T]: number }
 export function getValueVersions<T extends RenderableValues>(values: T) {
     const versions: Versions<any> = {}

+ 2 - 1
src/mol-gl/renderer.ts

@@ -105,6 +105,7 @@ namespace Renderer {
 
             uPickingAlphaThreshold: ValueCell.create(pickingAlphaThreshold),
         }
+        const globalUniformList = Object.entries(globalUniforms)
 
         let globalUniformsNeedUpdate = true
         const renderObject = (r: Renderable<RenderableValues & BaseValues>, variant: RenderVariant) => {
@@ -118,7 +119,7 @@ namespace Renderer {
                 program.use()
                 if (globalUniformsNeedUpdate) {
                     // console.log('globalUniformsNeedUpdate')
-                    program.setUniforms(globalUniforms)
+                    program.setUniforms(globalUniformList)
                     globalUniformsNeedUpdate = false
                 }
 

+ 4 - 4
src/mol-gl/webgl/buffer.ts

@@ -152,7 +152,7 @@ export type AttributeDefs = {
     [k: string]: { kind: ArrayKind, itemSize: AttributeItemSize, divisor: number }
 }
 export type AttributeValues = { [k: string]: ValueCell<ArrayType> }
-export type AttributeBuffers = { [k: string]: AttributeBuffer }
+export type AttributeBuffers = [string, AttributeBuffer][]
 
 export interface AttributeBuffer extends Buffer {
     bind: (location: number) => void
@@ -185,14 +185,14 @@ export function createAttributeBuffer<T extends ArrayType, S extends AttributeIt
 }
 
 export function createAttributeBuffers(ctx: WebGLContext, schema: RenderableSchema, values: AttributeValues) {
-    const buffers: AttributeBuffers = {}
+    const buffers: AttributeBuffers = []
     Object.keys(schema).forEach(k => {
         const spec = schema[k]
         if (spec.type === 'attribute') {
-            buffers[k] = createAttributeBuffer(ctx, values[k].ref.value, spec.itemSize, spec.divisor)
+            buffers[buffers.length] = [k, createAttributeBuffer(ctx, values[k].ref.value, spec.itemSize, spec.divisor)]
         }
     })
-    return buffers as AttributeBuffers
+    return buffers
 }
 
 //

+ 15 - 22
src/mol-gl/webgl/program.ts

@@ -1,15 +1,14 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
 import { ShaderCode, DefineValues, addShaderDefines } from '../shader-code'
 import { WebGLContext } from './context';
-import { UniformValues, getUniformSetters } from './uniform';
+import { getUniformSetters, UniformsList } from './uniform';
 import { AttributeBuffers } from './buffer';
-// import { AttributeBuffers, UniformBuffers, createUniformBuffer } from './buffer';
-import { Textures, TextureId } from './texture';
+import { TextureId, Textures } from './texture';
 import { createReferenceCache, ReferenceCache } from 'mol-util/reference-cache';
 import { idFactory } from 'mol-util/id-factory';
 import { RenderableSchema } from '../renderable/schema';
@@ -21,7 +20,7 @@ export interface Program {
     readonly id: number
 
     use: () => void
-    setUniforms: (uniformValues: UniformValues) => void
+    setUniforms: (uniformValues: UniformsList) => void
     bindAttributes: (attribueBuffers: AttributeBuffers) => void
     bindTextures: (textures: Textures) => void
 
@@ -88,32 +87,26 @@ export function createProgram(ctx: WebGLContext, props: ProgramProps): Program {
             ctx.currentProgramId = programId
             gl.useProgram(program)
         },
-        setUniforms: (uniformValues: UniformValues) => {
-            const uniformKeys = Object.keys(uniformValues)
-            for (let i = 0, il = uniformKeys.length; i < il; ++i) {
-                const k = uniformKeys[i]
-                const l = locations[k]
-                const v = uniformValues[k]
-                if (v) uniformSetters[k](gl, l, v.ref.value)
+        setUniforms: (uniformValues: UniformsList) => {
+            for (let i = 0, il = uniformValues.length; i < il; ++i) {
+                const [k, v] = uniformValues[i]
+                if (v) uniformSetters[k](gl, locations[k], v.ref.value)
             }
         },
         bindAttributes: (attribueBuffers: AttributeBuffers) => {
-            const attributeKeys = Object.keys(attribueBuffers)
-            for (let i = 0, il = attributeKeys.length; i < il; ++i) {
-                const k = attributeKeys[i]
+            for (let i = 0, il = attribueBuffers.length; i < il; ++i) {
+                const [k, buffer] = attribueBuffers[i]
                 const l = locations[k]
-                if (l !== -1) attribueBuffers[k].bind(l)
+                if (l !== -1) buffer.bind(l)
             }
         },
         bindTextures: (textures: Textures) => {
-            const textureKeys = Object.keys(textures)
-            for (let i = 0, il = textureKeys.length; i < il; ++i) {
-                const k = textureKeys[i]
-                const l = locations[k]
-                textures[k].bind(i as TextureId)
+            for (let i = 0, il = textures.length; i < il; ++i) {
+                const [k, texture] = textures[i]
+                texture.bind(i as TextureId)
                 // TODO if the order and count of textures in a material can be made invariant
                 //      this needs to be set only when the material changes
-                uniformSetters[k](gl, l, i as TextureId)
+                uniformSetters[k](gl, locations[k], i as TextureId)
             }
         },
 

+ 19 - 18
src/mol-gl/webgl/render-item.ts

@@ -9,7 +9,7 @@ import { createTextures } from './texture';
 import { WebGLContext } from './context';
 import { ShaderCode } from '../shader-code';
 import { Program } from './program';
-import { RenderableSchema, RenderableValues, AttributeSpec, getValueVersions, splitValues, Values, splitKeys } from '../renderable/schema';
+import { RenderableSchema, RenderableValues, AttributeSpec, getValueVersions, splitValues, Values } from '../renderable/schema';
 import { idFactory } from 'mol-util/id-factory';
 import { deleteVertexArray, createVertexArray } from './vertex-array';
 import { ValueCell } from 'mol-util';
@@ -58,7 +58,6 @@ interface ValueChanges {
     defines: boolean
     elements: boolean
     textures: boolean
-    // uniforms: boolean
 }
 function createValueChanges() {
     return {
@@ -88,7 +87,11 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
     const { instancedArrays, vertexArrayObject } = ctx.extensions
 
     const { attributeValues, defineValues, textureValues, uniformValues, materialUniformValues } = splitValues(schema, values)
-    const { attributeKeys, defineKeys, textureKeys } = splitKeys(schema)
+
+    const uniformValueEntries = Object.entries(uniformValues)
+    const materialUniformValueEntries = Object.entries(materialUniformValues)
+    const defineValueEntries = Object.entries(defineValues)
+
     const versions = getValueVersions(values)
 
     const glDrawMode = getDrawMode(ctx, drawMode)
@@ -136,10 +139,10 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
             if (drawCount === 0 || instanceCount === 0) return
             const program = programs[variant].value
             const vertexArray = vertexArrays[variant]
-            program.setUniforms(uniformValues)
+            program.setUniforms(uniformValueEntries)
             if (materialId === -1 || materialId !== ctx.currentMaterialId) {
                 // console.log('materialId changed or -1', materialId)
-                program.setUniforms(materialUniformValues)
+                program.setUniforms(materialUniformValueEntries)
                 ctx.currentMaterialId = materialId
             }
             program.bindTextures(textures)
@@ -160,9 +163,8 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
         update: () => {
             resetValueChanges(valueChanges)
 
-            for (let i = 0, il = defineKeys.length; i < il; ++i) {
-                const k = defineKeys[i]
-                const value = defineValues[k]
+            for (let i = 0, il = defineValueEntries.length; i < il; ++i) {
+                const [k, value] = defineValueEntries[i]
                 if (value.ref.version !== versions[k]) {
                     // console.log('define version changed', k)
                     valueChanges.defines = true
@@ -198,11 +200,10 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
                 versions.instanceCount = values.instanceCount.ref.version
             }
 
-            for (let i = 0, il = attributeKeys.length; i < il; ++i) {
-                const k = attributeKeys[i]
+            for (let i = 0, il = attributeBuffers.length; i < il; ++i) {
+                const [k, buffer] = attributeBuffers[i]
                 const value = attributeValues[k]
                 if (value.ref.version !== versions[k]) {
-                    const buffer = attributeBuffers[k]
                     if (buffer.length >= value.ref.value.length) {
                         // console.log('attribute array large enough to update', k, value.ref.id, value.ref.version)
                         buffer.updateData(value.ref.value)
@@ -210,7 +211,7 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
                         // console.log('attribute array to small, need to create new attribute', k, value.ref.id, value.ref.version)
                         buffer.destroy()
                         const { itemSize, divisor } = schema[k] as AttributeSpec<ArrayKind>
-                        attributeBuffers[k] = createAttributeBuffer(ctx, value.ref.value, itemSize, divisor)
+                        attributeBuffers[i] = [k, createAttributeBuffer(ctx, value.ref.value, itemSize, divisor)]
                         valueChanges.attributes = true
                     }
                     versions[k] = value.ref.version
@@ -247,14 +248,14 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
                 }
             }
 
-            for (let i = 0, il = textureKeys.length; i < il; ++i) {
-                const k = textureKeys[i]
+            for (let i = 0, il = textures.length; i < il; ++i) {
+                const [k, texture] = textures[i]
                 const value = textureValues[k]
                 if (value.ref.version !== versions[k]) {
                     // update of textures with kind 'texture' is done externally
                     if (schema[k].kind !== 'texture') {
                         // console.log('texture version changed, uploading image', k)
-                        textures[k].load(value.ref.value as TextureImage<any> | TextureVolume<any>)
+                        texture.load(value.ref.value as TextureImage<any> | TextureVolume<any>)
                         versions[k] = value.ref.version
                         valueChanges.textures = true
                     }
@@ -269,13 +270,13 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
                     programs[k].free()
                     deleteVertexArray(ctx, vertexArrays[k])
                 })
-                Object.keys(textures).forEach(k => {
+                textures.forEach(([k, texture]) => {
                     // lifetime of textures with kind 'texture' is defined externally
                     if (schema[k].kind !== 'texture') {
-                        textures[k].destroy()
+                        texture.destroy()
                     }
                 })
-                Object.keys(attributeBuffers).forEach(k => attributeBuffers[k].destroy())
+                attributeBuffers.forEach(([_, buffer]) => buffer.destroy())
                 if (elementsBuffer) elementsBuffer.destroy()
                 destroyed = true
             }

+ 5 - 5
src/mol-gl/webgl/texture.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -139,7 +139,7 @@ export interface Texture {
 export type TextureId = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15
 
 export type TextureValues = { [k: string]: ValueCell<TextureValueType> }
-export type Textures = { [k: string]: Texture }
+export type Textures = [string, Texture][]
 
 export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: TextureFormat, _type: TextureType, _filter: TextureFilter): Texture {
     const id = getNextTextureId()
@@ -244,16 +244,16 @@ export function createTexture(ctx: WebGLContext, kind: TextureKind, _format: Tex
 }
 
 export function createTextures(ctx: WebGLContext, schema: RenderableSchema, values: TextureValues) {
-    const textures: Textures = {}
+    const textures: Textures = []
     Object.keys(schema).forEach((k, i) => {
         const spec = schema[k]
         if (spec.type === 'texture') {
             if (spec.kind === 'texture') {
-                textures[k] = values[k].ref.value as Texture
+                textures[textures.length] = [k, values[k].ref.value as Texture]
             } else {
                 const texture = createTexture(ctx, spec.kind, spec.format, spec.dataType, spec.filter)
                 texture.load(values[k].ref.value as TextureImage<any> | TextureVolume<any>)
-                textures[k] = texture
+                textures[textures.length] = [k, texture]
             }
         }
     })

+ 2 - 1
src/mol-gl/webgl/uniform.ts

@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
@@ -23,6 +23,7 @@ export type UniformKind = keyof UniformKindValue
 export type UniformType = number | Vec2 | Vec3 | Vec4 | Mat3 | Mat4
 
 export type UniformValues = { [k: string]: ValueCell<UniformType> }
+export type UniformsList = [string, ValueCell<UniformType>][]
 
 export function setUniform(gl: GLRenderingContext, location: WebGLUniformLocation | null, kind: UniformKind, value: any) {
     switch (kind) {

+ 1 - 1
src/mol-gl/webgl/vertex-array.ts

@@ -6,7 +6,7 @@
 
 import { WebGLContext } from './context';
 import { Program } from './program';
-import { AttributeBuffers, ElementsBuffer } from './buffer';
+import { ElementsBuffer, AttributeBuffers } from './buffer';
 
 export function createVertexArray(ctx: WebGLContext, program: Program, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer) {
     const { vertexArrayObject } = ctx.extensions