diff --git a/drape/metal/metal_base_context.hpp b/drape/metal/metal_base_context.hpp index 516a75f8b7..7450a340e9 100644 --- a/drape/metal/metal_base_context.hpp +++ b/drape/metal/metal_base_context.hpp @@ -65,6 +65,9 @@ public: drape_ptr && programClearDepth, drape_ptr && programClearColorAndDepth); + void ApplyPipelineState(id state); + bool HasAppliedPipelineState() const; + protected: void RecreateDepthTexture(m2::PointU const & screenSize); void RequestFrameDrawable(); @@ -84,6 +87,7 @@ protected: id m_frameDrawable; id m_frameCommandBuffer; id m_currentCommandEncoder; + id m_lastPipelineState; MetalCleaner m_cleaner; diff --git a/drape/metal/metal_base_context.mm b/drape/metal/metal_base_context.mm index 080e1c50b7..88d199f4c9 100644 --- a/drape/metal/metal_base_context.mm +++ b/drape/metal/metal_base_context.mm @@ -365,6 +365,7 @@ void MetalBaseContext::FinishCurrentEncoding() [m_currentCommandEncoder popDebugGroup]; [m_currentCommandEncoder endEncoding]; m_currentCommandEncoder = nil; + m_lastPipelineState = nil; } void MetalBaseContext::SetSystemPrograms(drape_ptr && programClearColor, @@ -375,6 +376,18 @@ void MetalBaseContext::SetSystemPrograms(drape_ptr && programClearCo std::move(programClearColorAndDepth)); } +void MetalBaseContext::ApplyPipelineState(id state) +{ + m_lastPipelineState = state; + if (state != nil) + [GetCommandEncoder() setRenderPipelineState:state]; +} + +bool MetalBaseContext::HasAppliedPipelineState() const +{ + return m_lastPipelineState != nil; +} + void MetalBaseContext::DebugSynchronizeWithCPU() { FinishCurrentEncoding(); diff --git a/drape/metal/metal_cleaner.mm b/drape/metal/metal_cleaner.mm index e0526ab174..a79633fb44 100644 --- a/drape/metal/metal_cleaner.mm +++ b/drape/metal/metal_cleaner.mm @@ -57,10 +57,13 @@ void MetalCleaner::RenderQuad(ref_ptr metalContext, id program) { id pipelineState = metalContext->GetPipelineState(program, false /* blendingEnabled */); - [encoder setRenderPipelineState:pipelineState]; - - [encoder setVertexBuffer:m_buffer offset:0 atIndex:0]; - [encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + if (pipelineState != nil) + { + [encoder setRenderPipelineState:pipelineState]; + + [encoder setVertexBuffer:m_buffer offset:0 atIndex:0]; + [encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0 vertexCount:4]; + } } void MetalCleaner::ClearDepth(ref_ptr context, id encoder) diff --git a/drape/metal/metal_mesh_object_impl.mm b/drape/metal/metal_mesh_object_impl.mm index f1f8645795..dbaaffb260 100644 --- a/drape/metal/metal_mesh_object_impl.mm +++ b/drape/metal/metal_mesh_object_impl.mm @@ -85,12 +85,15 @@ public: void DrawPrimitives(ref_ptr context, uint32_t verticesCount) override { ref_ptr metalContext = context; - id encoder = metalContext->GetCommandEncoder(); - for (size_t i = 0; i < m_geometryBuffers.size(); i++) - [encoder setVertexBuffer:m_geometryBuffers[i] offset:0 atIndex:i]; - - [encoder drawPrimitives:GetPrimitiveType(m_mesh->m_drawPrimitive) vertexStart:0 - vertexCount:verticesCount]; + if (metalContext->HasAppliedPipelineState()) + { + id encoder = metalContext->GetCommandEncoder(); + for (size_t i = 0; i < m_geometryBuffers.size(); i++) + [encoder setVertexBuffer:m_geometryBuffers[i] offset:0 atIndex:i]; + + [encoder drawPrimitives:GetPrimitiveType(m_mesh->m_drawPrimitive) vertexStart:0 + vertexCount:verticesCount]; + } } private: diff --git a/drape/metal/metal_vertex_array_buffer_impl.mm b/drape/metal/metal_vertex_array_buffer_impl.mm index 16fd631465..313251e2be 100644 --- a/drape/metal/metal_vertex_array_buffer_impl.mm +++ b/drape/metal/metal_vertex_array_buffer_impl.mm @@ -37,6 +37,9 @@ public: IndicesRange const & range) override { ref_ptr metalContext = context; + if (!metalContext->HasAppliedPipelineState()) + return; + id encoder = metalContext->GetCommandEncoder(); uint32_t bufferIndex = 0; diff --git a/drape/metal/render_state_metal.mm b/drape/metal/render_state_metal.mm index 9eede60da4..1fa8bbec5c 100644 --- a/drape/metal/render_state_metal.mm +++ b/drape/metal/render_state_metal.mm @@ -24,7 +24,7 @@ void ApplyPipelineStateForMetal(ref_ptr context, ref_ptr metalContext = context; id state = metalContext->GetPipelineState(std::move(program), blendingEnabled); - [metalContext->GetCommandEncoder() setRenderPipelineState:state]; + metalContext->ApplyPipelineState(state); } void ApplyTexturesForMetal(ref_ptr context, ref_ptr program,