#pragma once #import #include "drape/graphics_context.hpp" #include "drape/gpu_program.hpp" #include "drape/metal/metal_cleaner.hpp" #include "drape/metal/metal_states.hpp" #include "drape/metal/metal_texture.hpp" #include "drape/pointers.hpp" #include "drape/texture_types.hpp" #include "geometry/point2d.hpp" #include #include namespace dp { namespace metal { class MetalBaseContext : public dp::GraphicsContext { public: using DrawableRequest = std::function()>; MetalBaseContext(id device, m2::PointU const & screenSize, DrawableRequest && drawableRequest); bool BeginRendering() override; void EndRendering() override; void Present() override; void MakeCurrent() override {} void DoneCurrent() override {} bool Validate() override { return true; } void Resize(int w, int h) override; void SetFramebuffer(ref_ptr framebuffer) override; void ApplyFramebuffer(std::string const & framebufferLabel) override; void Init(ApiVersion apiVersion) override; ApiVersion GetApiVersion() const override; std::string GetRendererName() const override; std::string GetRendererVersion() const override; void DebugSynchronizeWithCPU() override; void PushDebugLabel(std::string const & label) override; void PopDebugLabel() override; void SetClearColor(Color const & color) override; void Clear(uint32_t clearBits, uint32_t storeBits) override; void Flush() override {} void SetViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override; void SetDepthTestEnabled(bool enabled) override; void SetDepthTestFunction(TestFunction depthFunction) override; void SetStencilTestEnabled(bool enabled) override; void SetStencilFunction(StencilFace face, TestFunction stencilFunction) override; void SetStencilActions(StencilFace face, StencilAction stencilFailAction, StencilAction depthFailAction, StencilAction passAction) override; void SetStencilReferenceValue(uint32_t stencilReferenceValue) override { m_stencilReferenceValue = stencilReferenceValue; } id GetMetalDevice() const; id GetCommandEncoder() const; id GetDepthStencilState(); id GetPipelineState(ref_ptr program, bool blendingEnabled); id GetSamplerState(TextureFilter filter, TextureWrapping wrapSMode, TextureWrapping wrapTMode); void SetSystemPrograms(drape_ptr && programClearColor, drape_ptr && programClearDepth, drape_ptr && programClearColorAndDepth); void ApplyPipelineState(id state); bool HasAppliedPipelineState() const; void ResetPipelineStatesCache(); protected: void RecreateDepthTexture(m2::PointU const & screenSize); void RequestFrameDrawable(); void ResetFrameDrawable(); void FinishCurrentEncoding(); id m_device; DrawableRequest m_drawableRequest; drape_ptr m_depthTexture; MTLRenderPassDescriptor * m_renderPassDescriptor; id m_commandQueue; ref_ptr m_currentFramebuffer; MetalStates::DepthStencilKey m_currentDepthStencilKey; MetalStates m_metalStates; // These objects are recreated each frame. They MUST NOT be stored anywhere. id m_frameDrawable; id m_frameCommandBuffer; id m_currentCommandEncoder; id m_lastPipelineState; MetalCleaner m_cleaner; uint32_t m_stencilReferenceValue = 1; }; } // namespace metal } // namespace dp