Skip to content
Snippets Groups Projects
Commit ce86231f authored by Alexander Rose's avatar Alexander Rose
Browse files

renderItem.update tweaks

parent 73fc787a
No related branches found
No related tags found
No related merge requests found
......@@ -77,6 +77,20 @@ export function splitValues(schema: RenderableSchema, values: RenderableValues)
return { attributeValues, defineValues, textureValues, uniformValues }
}
export function splitKeys(schema: RenderableSchema) {
const attributeKeys: string[] = []
const defineKeys: string[] = []
const textureKeys: string[] = []
const uniformKeys: string[] = []
Object.keys(schema).forEach(k => {
if (schema[k].type === 'attribute') attributeKeys.push(k)
if (schema[k].type === 'define') defineKeys.push(k)
if (schema[k].type === 'texture') textureKeys.push(k)
if (schema[k].type === 'uniform') uniformKeys.push(k)
})
return { attributeKeys, defineKeys, textureKeys, uniformKeys }
}
export type Versions<T extends RenderableValues> = { [k in keyof T]: number }
export function getValueVersions<T extends RenderableValues>(values: T) {
const versions: Versions<any> = {}
......
......@@ -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 } from '../renderable/schema';
import { RenderableSchema, RenderableValues, AttributeSpec, getValueVersions, splitValues, Values, splitKeys } from '../renderable/schema';
import { idFactory } from 'mol-util/id-factory';
import { deleteVertexArray, createVertexArray } from './vertex-array';
import { ValueCell } from 'mol-util';
......@@ -60,6 +60,22 @@ interface ValueChanges {
textures: boolean
uniforms: boolean
}
function createValueChanges() {
return {
attributes: false,
defines: false,
elements: false,
textures: false,
uniforms: false,
}
}
function resetValueChanges(valueChanges: ValueChanges) {
valueChanges.attributes = false
valueChanges.defines = false
valueChanges.elements = false
valueChanges.textures = false
valueChanges.uniforms = false
}
// TODO make `RenderVariantDefines` a parameter for `createRenderItem`
......@@ -74,6 +90,7 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
const { instancedArrays, vertexArrayObject } = ctx.extensions
const { attributeValues, defineValues, textureValues, uniformValues } = splitValues(schema, values)
const { attributeKeys, defineKeys, textureKeys } = splitKeys(schema)
const versions = getValueVersions(values)
const glDrawMode = getDrawMode(ctx, drawMode)
......@@ -109,13 +126,7 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
ctx.instanceCount += instanceCount
ctx.instancedDrawCount += instanceCount * drawCount
const valueChanges: ValueChanges = {
attributes: false,
defines: false,
elements: false,
textures: false,
uniforms: false
}
const valueChanges = createValueChanges()
let destroyed = false
......@@ -130,7 +141,7 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
program.setUniforms(uniformValues)
if (vertexArrayObject && vertexArray) {
vertexArrayObject.bindVertexArray(vertexArray)
// need to bind elements buffer explicitely since it is not always recorded in the VAO
// need to bind elements buffer explicitly since it is not always recorded in the VAO
if (elementsBuffer) elementsBuffer.bind()
} else {
if (elementsBuffer) elementsBuffer.bind()
......@@ -144,15 +155,17 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
}
},
update: () => {
valueChanges.defines = false
Object.keys(defineValues).forEach(k => {
resetValueChanges(valueChanges)
for (let i = 0, il = defineKeys.length; i < il; ++i) {
const k = defineKeys[i]
const value = defineValues[k]
if (value.ref.version !== versions[k]) {
// console.log('define version changed', k)
valueChanges.defines = true
versions[k] = value.ref.version
}
})
}
if (valueChanges.defines) {
// console.log('some defines changed, need to rebuild programs')
......@@ -182,26 +195,25 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
versions.instanceCount = values.instanceCount.ref.version
}
valueChanges.attributes = false
Object.keys(attributeValues).forEach(k => {
for (let i = 0, il = attributeKeys.length; i < il; ++i) {
const k = attributeKeys[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)
attributeBuffers[k].updateData(value.ref.value)
buffer.updateData(value.ref.value)
} else {
// console.log('attribute array to small, need to create new attribute', k, value.ref.id, value.ref.version)
attributeBuffers[k].destroy()
buffer.destroy()
const { itemSize, divisor } = schema[k] as AttributeSpec<ArrayKind>
attributeBuffers[k] = createAttributeBuffer(ctx, value.ref.value, itemSize, divisor)
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', values.elements.ref.id, values.elements.ref.version)
......@@ -232,8 +244,8 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
}
}
valueChanges.textures = false
Object.keys(textureValues).forEach(k => {
for (let i = 0, il = textureKeys.length; i < il; ++i) {
const k = textureKeys[i]
const value = textureValues[k]
if (value.ref.version !== versions[k]) {
// update of textures with kind 'texture' is done externally
......@@ -244,7 +256,7 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
valueChanges.textures = true
}
}
})
}
return valueChanges
},
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment