#import #include "drape/metal/metal_base_context.hpp" #include "drape/metal/metal_gpu_buffer_impl.hpp" #include "drape/pointers.hpp" #include "drape/vertex_array_buffer.hpp" #include "base/assert.hpp" #include "base/macros.hpp" #include #include #include namespace dp { namespace metal { class MetalVertexArrayBufferImpl : public VertexArrayBufferImpl { public: explicit MetalVertexArrayBufferImpl(ref_ptr buffer) : m_vertexArrayBuffer(buffer) {} bool Build(ref_ptr program) override { UNUSED_VALUE(program); return true; } bool Bind() override { return true; } void Unbind() override {} void BindBuffers(dp::BuffersMap const & buffers) const override {} void RenderRange(ref_ptr context, bool drawAsLine, IndicesRange const & range) override { CHECK(m_vertexArrayBuffer->HasBuffers(), ()); ref_ptr metalContext = context; if (!metalContext->HasAppliedPipelineState()) return; id encoder = metalContext->GetCommandEncoder(); uint32_t bufferIndex = 0; for (auto & buffer : m_vertexArrayBuffer->m_staticBuffers) { ref_ptr b = buffer.second->GetBuffer(); [encoder setVertexBuffer:b->GetMetalBuffer() offset:0 atIndex:bufferIndex]; bufferIndex++; } for (auto & buffer : m_vertexArrayBuffer->m_dynamicBuffers) { ref_ptr b = buffer.second->GetBuffer(); [encoder setVertexBuffer:b->GetMetalBuffer() offset:0 atIndex:bufferIndex]; bufferIndex++; } ref_ptr ib = m_vertexArrayBuffer->m_indexBuffer->GetBuffer(); auto const isSupported32bit = dp::IndexStorage::IsSupported32bit(); auto const indexType = isSupported32bit ? MTLIndexTypeUInt32 : MTLIndexTypeUInt16; auto const indexSize = isSupported32bit ? sizeof(unsigned int) : sizeof(unsigned short); [encoder drawIndexedPrimitives:(drawAsLine ? MTLPrimitiveTypeLine : MTLPrimitiveTypeTriangle) indexCount:range.m_idxCount indexType:indexType indexBuffer:ib->GetMetalBuffer() indexBufferOffset:range.m_idxStart * indexSize]; } private: ref_ptr m_vertexArrayBuffer; }; } // namespace metal drape_ptr VertexArrayBuffer::CreateImplForMetal(ref_ptr buffer) { return make_unique_dp(buffer); } } // namespace dp