API iPhone Metal занимает слишком много времени (более нескольких секунд) - PullRequest
0 голосов
/ 07 ноября 2018

Я попытался нарисовать простой график, используя Metal API. Я проделал аналогичную работу, используя OpenGL в Android, и это занимает 0,2 ~ 3 на старой машине. Но, используя Metal API, в iPhone6s требуется более 2 ~ 3 секунд.

Я звоню render() после assignVertices(...) каждые 1 секунду. И vertexData имеет более 25000 вершин. (Для справки 5000 вершин хорошо работает за 0,2 секунды).

Как я могу ускорить следующий код?

Спасибо!

var commandBuffer : MTLCommandBuffer!
var renderEncoder : MTLRenderCommandEncoder!

func assignVertices(vertices: Array<Vertex>, device: MTLDevice) {
    var vertexData = Array<Float>()
    for vertex in vertices{
        vertexData += vertex.floatBuffer()
    }

    // 2
    let dataSize = vertexData.count * MemoryLayout.size(ofValue: vertexData[0])
    vertexBuffer = device.makeBuffer(bytes: vertexData, length: dataSize, options: [])!

    // 3
    vertexCount = vertices.count
}



func render(commandQueue: MTLCommandQueue, pipelineState: MTLRenderPipelineState, drawable: CAMetalDrawable, parentModelViewMatrix: Matrix4, projectionMatrix: Matrix4, clearColor: MTLClearColor?) {

    let renderPassDescriptor = MTLRenderPassDescriptor()
    renderPassDescriptor.colorAttachments[0].texture = drawable.texture
    renderPassDescriptor.colorAttachments[0].loadAction = .clear
    renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0)
    renderPassDescriptor.colorAttachments[0].storeAction = .store

    renderEncoder = commandBuffer.makeRenderCommandEncoder(descriptor: renderPassDescriptor)!


    renderEncoder.setRenderPipelineState(pipelineState)
    renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)
    let nodeModelMatrix = self.modelMatrix()
    nodeModelMatrix.multiplyLeft(parentModelViewMatrix)
    let uniformBuffer = device.makeBuffer(length: MemoryLayout<Float>.size * Matrix4.numberOfElements() * 2, options: [])
    let bufferPointer = uniformBuffer!.contents()
    memcpy(bufferPointer, nodeModelMatrix.raw(), MemoryLayout<Float>.size * Matrix4.numberOfElements())

    renderEncoder.setVertexBuffer(uniformBuffer, offset: 0, index: 1)
    memcpy(bufferPointer + MemoryLayout<Float>.size * Matrix4.numberOfElements(), projectionMatrix.raw(), MemoryLayout<Float>.size * Matrix4.numberOfElements())
    renderEncoder.drawPrimitives(type: .triangle, vertexStart: 0, vertexCount: vertexCount, instanceCount: vertexCount / 3)

    renderEncoder.endEncoding()

    commandBuffer.present(drawable)
    commandBuffer.commit()
}
...