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: 1.3.0
Show newest version
package ru.casperix.opengl.renderer.impl

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

@ExperimentalUnsignedTypes
class GraphicDataProvider(val stateController: StateController, val configProvider:()-> OpenGlRendererConfig) {

    private val shaderProvider = ShaderProvider()

    /**
     *  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 vertexData = shape.vertexData
        val vertices = vertexData.vertices
        if (vertices.size == 0) {
            return null
        }

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

        val config  = configProvider()

        val vertexAttributes = vertices.attributes
        val isStatic = config.cacheStaticUsing && indices.size >= config.cacheStaticSummaryIndicesMin
        if (isStatic) {
            val buffer = cacheStaticGeometry.getOrPut(vertexData) {
                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) {
        val config  = configProvider()
        if (cachedIndices <= config.cacheStaticSummaryIndicesMax) 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 <= config.cacheStaticSummaryIndicesMin) 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, configProvider())
        return DeviceShapeData(graphic, shader, buffer)
    }



}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy