All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.ru.casperix.opengl.renderer.impl.GraphicDataProvider.kt Maven / Gradle / Ivy

There is a newer version: 0.11.1
Show newest version
package ru.casperix.opengl.renderer.impl

import ru.casperix.renderer.vector.Geometry
import ru.casperix.renderer.vector.vertex.VertexAttributes
import ru.casperix.opengl.renderer.*
import ru.casperix.renderer.vector.VectorShape

@ExperimentalUnsignedTypes
class GraphicDataProvider(val stateController: StateController, val config: OpenGlRendererConfig) {
    private val staticConfig = config.cacheConfig.staticConfig

    private val shaderProvider = ShaderProvider(config)

    /**
     *  Many elements small and have equal vertex-attributes...
     */
    private val cacheDynamicBuffer = mutableMapOf()

    /**
     *  Big geometry is expensive for upload... But have chance that not changed.
     */
    private val cacheStaticGeometry = mutableMapOf()
    private var cachedIndices = 0

    fun getDynamicBufferAmount(): Int {
        return cacheDynamicBuffer.size
    }

    fun getStaticBufferAmount(): Int {
        return cacheStaticGeometry.size
    }

    fun get(stateController: StateController, shape: VectorShape, frameIndex: Long): DeviceShapeData? {

        val geometry = shape.geometry
        val vertices = geometry.vertices
        if (vertices.size == 0) {
            return null
        }

        val indices = geometry.indices
        if (indices.isEmpty()) {
            return null
        }

        val vertexAttributes = vertices.attributes
        val isStatic = staticConfig.using && indices.size >= staticConfig.itemMinIndices
        if (isStatic) {
            val buffer = cacheStaticGeometry.getOrPut((geometry)) {
                val geometryData = createDeviceGeometryData(vertexAttributes)
                geometryData.uploadData(stateController, vertices.data, indices, true)
                cachedIndices += geometryData.indicesAmount

                DeviceGeometryBuffer(geometryData, true)
            }

            buffer.lastFrame = frameIndex
            clearDeprecatedCache(frameIndex)

            return createDeviceGraphicData(shape, buffer)
        } else {
            val buffer = cacheDynamicBuffer.getOrPut(vertexAttributes) {
                DeviceGeometryBuffer(createDeviceGeometryData(vertexAttributes), false)
            }

            return createDeviceGraphicData(shape, buffer)
        }
    }

    private fun clearDeprecatedCache(frameIndex: Long) {
        if (cachedIndices <= staticConfig.summaryIndicesMax) return

        val deprecated = cacheStaticGeometry.entries.filter { it.value.lastFrame < frameIndex - 1 }

        deprecated.forEach { (key, buffer) ->
            buffer.dispose()
            cacheStaticGeometry.remove(key)
            cachedIndices -= buffer.data.indicesAmount
            if (cachedIndices <= staticConfig.summaryIndicesMin) return
        }
    }

    private fun createDeviceGeometryData(vertexAttributes: VertexAttributes): DeviceGeometryData {
        stateController.setGeometry(null)
        return DeviceGeometryData(vertexAttributes)
    }

    private fun createDeviceGraphicData(graphic: VectorShape, buffer: DeviceGeometryBuffer): DeviceShapeData {
        val shader = shaderProvider.getOrCreate(buffer.data.attributes, graphic.material)
        return DeviceShapeData(graphic, shader, buffer)
    }



}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy