1 #ifndef DALI_EGL_GRAPHICS_CONTROLLER_H
2 #define DALI_EGL_GRAPHICS_CONTROLLER_H
5 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 #include <dali/graphics-api/graphics-controller.h>
25 #include <dali/integration-api/graphics-sync-abstraction.h>
26 #include <dali/internal/graphics/common/graphics-interface.h>
27 #include <dali/internal/graphics/gles-impl/gles-context.h>
28 #include <dali/internal/graphics/gles-impl/gles-graphics-buffer.h>
29 #include <dali/internal/graphics/gles-impl/gles-graphics-command-buffer.h>
30 #include <dali/internal/graphics/gles-impl/gles-graphics-framebuffer.h>
31 #include <dali/internal/graphics/gles-impl/gles-graphics-pipeline-cache.h>
32 #include <dali/internal/graphics/gles-impl/gles-graphics-pipeline.h>
33 #include <dali/internal/graphics/gles-impl/gles-graphics-reflection.h>
34 #include <dali/internal/graphics/gles-impl/gles-graphics-sampler.h>
35 #include <dali/internal/graphics/gles-impl/gles-graphics-shader.h>
36 #include <dali/internal/graphics/gles-impl/gles-graphics-texture.h>
37 #include <dali/internal/graphics/gles-impl/gles-graphics-types.h>
38 #include <dali/internal/graphics/gles-impl/gles2-graphics-memory.h>
45 class GlContextHelperAbstraction;
46 } // namespace Integration
57 * EGL Implementation of the graphics controller.
59 * Temporarily holds the old GL abstractions whilst dali-core is migrated to the new API.
61 class EglGraphicsController : public Graphics::Controller
65 * @brief Deault constructor
67 EglGraphicsController() = default;
72 ~EglGraphicsController() override;
75 * Initialize the GLES abstraction. This can be called from the main thread.
77 void InitializeGLES(Integration::GlAbstraction& glAbstraction);
80 * Initialize with a reference to the GL abstractions.
82 * Note, this is now executed in the render thread, after core initialization
84 void Initialize(Integration::GraphicsSyncAbstraction& syncImplementation,
85 Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
86 Internal::Adaptor::GraphicsInterface& graphicsInterface);
88 Integration::GlAbstraction& GetGlAbstraction() override;
89 Integration::GlContextHelperAbstraction& GetGlContextHelperAbstraction() override;
90 Internal::Adaptor::EglSyncImplementation& GetEglSyncImplementation();
93 * @copydoc Dali::Graphics::SubmitCommandBuffers()
95 void SubmitCommandBuffers(const SubmitInfo& submitInfo) override;
98 * @copydoc Dali::Graphics::PresentRenderTarget()
100 void PresentRenderTarget(RenderTarget* renderTarget) override;
103 * @copydoc Dali::Graphics::WaitIdle()
105 void WaitIdle() override
110 * @copydoc Dali::Graphics::Pause()
112 void Pause() override
117 * @copydoc Dali::Graphics::Resume()
119 void Resume() override
124 * @copydoc Dali::Graphics::Shutdown()
126 void Shutdown() override
128 mIsShuttingDown = true;
132 * @copydoc Dali::Graphics::Destroy()
134 void Destroy() override
139 ClearTextureUpdateQueue();
141 // Remove all create queue and command queue.
142 // Note that all memory are already deallocated at Final flush.
143 mCreateTextureQueue = {};
144 mCreateBufferQueue = {};
145 mCreateFramebufferQueue = {};
146 mTextureMipmapGenerationRequests = {};
151 mContext->GlContextDestroyed();
154 for(auto&& context : mSurfaceContexts)
158 context.second->GlContextDestroyed();
164 * @copydoc Dali::Graphics::UpdateTextures()
166 void UpdateTextures(const std::vector<TextureUpdateInfo>& updateInfoList,
167 const std::vector<TextureUpdateSourceInfo>& sourceList) override;
170 * @copydoc Dali::Graphics::GenerateTextureMipmaps()
172 void GenerateTextureMipmaps(const Texture& texture) override;
175 * @copydoc Dali::Graphics::EnableDepthStencilBuffer()
177 bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override
183 * @copydoc Dali::Graphics::RunGarbageCollector()
185 void RunGarbageCollector(size_t numberOfDiscardedRenderers) override
190 * @copydoc Dali::Graphics::DiscardUnusedResources()
192 void DiscardUnusedResources() override
197 * @copydoc Dali::Graphics::IsDiscardQueueEmpty()
199 bool IsDiscardQueueEmpty() override
205 * @copydoc Dali::Graphics::IsDrawOnResumeRequired()
207 bool IsDrawOnResumeRequired() override
213 * @copydoc Dali::Graphics::CreateBuffer()
215 Graphics::UniquePtr<Buffer> CreateBuffer(const BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Buffer>&& oldBuffer) override;
218 * @copydoc Dali::Graphics::CreateCommandBuffer()
220 Graphics::UniquePtr<CommandBuffer> CreateCommandBuffer(const CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<CommandBuffer>&& oldCommandBuffer) override;
223 * @copydoc Dali::Graphics::CreateRenderPass()
225 Graphics::UniquePtr<RenderPass> CreateRenderPass(const RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<RenderPass>&& oldRenderPass) override;
228 * @copydoc Dali::Graphics::CreateTexture()
230 Graphics::UniquePtr<Texture> CreateTexture(const TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Texture>&& oldTexture) override;
233 * @copydoc Dali::Graphics::CreateFramebuffer()
235 Graphics::UniquePtr<Framebuffer> CreateFramebuffer(const FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Framebuffer>&& oldFramebuffer) override;
238 * @copydoc Dali::Graphics::CreatePipeline()
240 Graphics::UniquePtr<Pipeline> CreatePipeline(const PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Pipeline>&& oldPipeline) override;
243 * @copydoc Dali::Graphics::CreateProgram()
245 Graphics::UniquePtr<Program> CreateProgram(const ProgramCreateInfo& programCreateInfo, UniquePtr<Program>&& oldProgram) override;
248 * @copydoc Dali::Graphics::CreateShader()
250 Graphics::UniquePtr<Shader> CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader) override;
253 * @copydoc Dali::Graphics::CreateSampler()
255 Graphics::UniquePtr<Sampler> CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler) override;
258 * @copydoc Dali::Graphics::CreateRenderTarget()
260 Graphics::UniquePtr<RenderTarget> CreateRenderTarget(const RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<RenderTarget>&& oldRenderTarget) override;
263 * @copydoc Dali::Graphics::CreateSyncObject()
265 Graphics::UniquePtr<SyncObject> CreateSyncObject(const SyncObjectCreateInfo& syncObjectCreateInfo,
266 Graphics::UniquePtr<SyncObject>&& oldSyncObject) override;
269 * @copydoc Dali::Graphics::MapBufferRange()
271 Graphics::UniquePtr<Memory> MapBufferRange(const MapBufferInfo& mapInfo) override;
274 * @copydoc Dali::Graphics::MapTextureRange()
276 Graphics::UniquePtr<Memory> MapTextureRange(const MapTextureInfo& mapInfo) override
282 * @copydoc Dali::Graphics::UnmapMemory()
284 void UnmapMemory(Graphics::UniquePtr<Memory> memory) override
288 * @copydoc Dali::Graphics::GetTextureMemoryRequirements()
290 MemoryRequirements GetTextureMemoryRequirements(Texture& texture) const override
296 * @copydoc Dali::Graphics::GetBufferMemoryRequirements()
298 MemoryRequirements GetBufferMemoryRequirements(Buffer& buffer) const override
304 * @copydoc Dali::Graphics::GetTextureProperties()
306 const TextureProperties& GetTextureProperties(const Texture& texture) override
308 // for compiler not to moan
309 static TextureProperties dummy{};
314 * @copydoc Dali::Graphics::Controller::GetPipelineReflection()
317 [[nodiscard]] const Reflection& GetProgramReflection(const Graphics::Program& program) override;
320 * @copydoc Dali::Graphics::PipelineEquals()
322 [[nodiscard]] bool PipelineEquals(const Pipeline& pipeline0, const Pipeline& pipeline1) const override
327 [[nodiscard]] Integration::GlAbstraction* GetGL() const
333 return mGlAbstraction;
336 [[nodiscard]] Internal::Adaptor::GraphicsInterface* GetGraphicsInterface() const
342 void AddTexture(GLES::Texture& texture);
345 * @brief Adds buffer to the creation queue
348 void AddBuffer(GLES::Buffer& buffer);
351 * @brief Adds framebuffer to the creation queue
354 void AddFramebuffer(GLES::Framebuffer& framebuffer);
357 * @brief Pushes Bufer to the discard queue
359 * Function is called from the UniquePtr custom deleter.
361 * @param[in] texture Pointer to the texture
363 void DiscardResource(GLES::Texture* texture)
365 mDiscardTextureQueue.push(texture);
369 * @brief Pushes Buffer to the discard queue
371 * Function is called from the UniquePtr custom deleter.
373 * @param[in] buffer Pointer to the buffer object
375 void DiscardResource(GLES::Buffer* buffer)
377 mDiscardBufferQueue.push(buffer);
381 * @brief Pushes framebuffer to the discard queue
383 * Function is called from the UniquePtr custom deleter.
385 * @param[in] framebuffer Pointer to the framebuffer object
387 void DiscardResource(GLES::Framebuffer* framebuffer)
389 mDiscardFramebufferQueue.push(framebuffer);
393 * @brief Pushes Program to the discard queue
395 * Function is called from the UniquePtr custom deleter.
397 * @param[in] program Pointer to the program
399 void DiscardResource(GLES::Program* program)
401 mDiscardProgramQueue.push(program);
405 * @brief Pushes Shader to the discard queue
407 * Function is called from the UniquePtr custom deleter.
409 * @param[in] program Pointer to the Shader
411 void DiscardResource(GLES::Shader* shader)
413 mDiscardShaderQueue.push(shader);
417 * @brief Pushes CommandBuffer to the discard queue
419 * Function is called from the UniquePtr custom deleter.
421 * @param[in] program Pointer to the CommandBuffer
423 void DiscardResource(GLES::CommandBuffer* commandBuffer)
425 mDiscardCommandBufferQueue.push(commandBuffer);
429 * @brief Pushes Sampler to the discard queue
431 * Function is called from the UniquePtr custom deleter.
433 * @param[in] program Pointer to the Sampler
435 void DiscardResource(GLES::Sampler* sampler)
437 mDiscardSamplerQueue.push(sampler);
441 * @brief Pushes Pipeline to the discard queue
443 * Function is called from the UniquePtr custom deleter.
445 * @param[in] program Pointer to the pipeline
447 void DiscardResource(GLES::Pipeline* pipeline)
449 mDiscardPipelineQueue.push(pipeline);
453 * @brief Clears the texture update queue
455 void ClearTextureUpdateQueue()
457 // Remove remained CPU-allocated texture memory
458 while(!mTextureUpdateRequests.empty())
460 auto& request = mTextureUpdateRequests.front();
461 auto& source = request.second;
463 if(source.sourceType == Graphics::TextureUpdateSourceInfo::Type::MEMORY)
465 // free staging memory
466 free(source.memorySource.memory);
468 mTextureUpdateRequests.pop();
473 * @brief Flushes all pending updates
475 * Function flushes all pending resource constructions,
476 * executes command buffers and empties discard queues.
480 if(DALI_LIKELY(!mIsShuttingDown))
482 if(!mCreateTextureQueue.empty() ||
483 !mCreateBufferQueue.empty() ||
484 !mCreateFramebufferQueue.empty() ||
485 !mTextureUpdateRequests.empty() ||
486 !mTextureMipmapGenerationRequests.empty())
488 mGraphics->ActivateResourceContext();
492 ProcessCreateQueues();
495 ProcessTextureUpdateQueue();
497 // Process texture mipmap generation requests
498 ProcessTextureMipmapGenerationQueue();
500 // Process main command queue
501 ProcessCommandQueues();
504 // Reset texture cache in the contexts while destroying textures
507 // Reset buffer cache in the contexts while destroying buffers
511 ProcessDiscardQueues();
513 // Flush pipeline cache to remove unused pipelines
516 mPipelineCache->FlushCache();
520 // Test update to tick controller, usually it will run own thread
521 void ProcessDiscardQueues();
524 * @brief Processes a create queue for type specified
526 * @param[in,out] queue Reference to the create queue
529 void ProcessCreateQueue(T& queue)
531 while(!queue.empty())
533 auto* object = queue.front();
536 // Initialize texture
537 if(!object->InitializeResource())
539 // TODO: handle error
545 * @brief Processes a discard queue for type specified
547 * @param[in,out] queue Reference to the discard queue
549 template<class U, class T>
550 void ProcessDiscardQueue(T& queue)
552 while(!queue.empty())
554 auto* object = const_cast<U*>(queue.front());
557 object->DestroyResource();
560 auto* clbk = object->GetCreateInfo().allocationCallbacks;
567 clbk->freeCallback(object, clbk->userData);
578 * @brief Processes a discard queue for pipeline
580 * @param[in,out] queue Reference to the create queue
582 void ProcessDiscardQueue(std::queue<GLES::Pipeline*>& queue)
584 while(!queue.empty())
586 auto* object = const_cast<GLES::Pipeline*>(queue.front());
588 // Inform the contexts to invalidate the pipeline if cached
591 mContext->InvalidateCachedPipeline(object);
594 for(auto&& context : mSurfaceContexts)
598 context.second->InvalidateCachedPipeline(object);
603 object->DestroyResource();
606 auto* clbk = object->GetCreateInfo().allocationCallbacks;
610 using GLESPipeline = GLES::Pipeline;
611 object->~GLESPipeline();
614 clbk->freeCallback(object, clbk->userData);
625 * @brief Processes all resource create queues
627 void ProcessCreateQueues();
630 * @brief Process command queues and buffers
632 void ProcessCommandQueues();
635 * @brief Executes all pending texture updates
637 void ProcessTextureUpdateQueue();
640 * @brief Executes all pending texture mipmap generation
642 void ProcessTextureMipmapGenerationQueue();
645 * @brief Returns program custom parameter
647 * This function can be used as a backdoor in order to retrieve
648 * certain data out of implementation
650 * @param[in] program Valid Program object
651 * @param parameterId Integer id of parameter
652 * @param outData Output data
653 * @return True if parameter retrieved
655 bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) override;
658 * @brief Returns pipeline cache object
660 * @return Valid pipeline cache object
662 [[nodiscard]] GLES::PipelineCache& GetPipelineCache() const;
665 * @brief Returns runtime supported GLES version
667 * @return GLES version enum
669 GLES::GLESVersion GetGLESVersion() const
675 * @brief Sets runtime supported GLES version
677 * @param[in] glesVersion The runtime supported GLES version
679 void SetGLESVersion(GLES::GLESVersion glesVersion)
681 mGLESVersion = glesVersion;
684 bool IsShuttingDown() const
686 return mIsShuttingDown;
690 * @brief Reset texture cache in the contexts
692 void ResetTextureCache()
696 mContext->GetGLStateCache().ResetTextureCache();
699 for(auto& context : mSurfaceContexts)
703 context.second->GetGLStateCache().ResetTextureCache();
709 * @brief Reset buffer cache in the contexts
711 void ResetBufferCache()
715 mContext->GetGLStateCache().ResetBufferCache();
718 for(auto& context : mSurfaceContexts)
722 context.second->GetGLStateCache().ResetBufferCache();
727 void ProcessCommandBuffer(const GLES::CommandBuffer& commandBuffer);
729 // Resolves presentation
730 void ResolvePresentRenderTarget(GLES::RenderTarget* renderTarget);
733 * Creates a GLES context for the given render surface
735 * @param[in] surface The surface whose GLES context to be created.
737 void CreateSurfaceContext(Dali::RenderSurfaceInterface* surface);
740 * Deletes a GLES context
742 * @param[in] surface The surface whose GLES context to be deleted.
744 void DeleteSurfaceContext(Dali::RenderSurfaceInterface* surface);
747 * Activate the resource context (shared surfaceless context)
749 void ActivateResourceContext();
752 * Activate the surface context
754 * @param[in] surface The surface whose context to be switched to.
756 void ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface);
759 * @brief Returns the current context
761 * @return the current context
763 GLES::Context* GetCurrentContext() const
765 return mCurrentContext;
769 Integration::GlAbstraction* mGlAbstraction{nullptr};
770 Integration::GlContextHelperAbstraction* mGlContextHelperAbstraction{nullptr};
772 Internal::Adaptor::EglSyncImplementation* mEglSyncImplementation{nullptr};
773 Internal::Adaptor::GraphicsInterface* mGraphics{nullptr}; // Pointer to owning structure via interface.
775 std::queue<GLES::Texture*> mCreateTextureQueue; ///< Create queue for texture resource
776 std::queue<GLES::Texture*> mDiscardTextureQueue; ///< Discard queue for texture resource
778 std::queue<GLES::Buffer*> mCreateBufferQueue; ///< Create queue for buffer resource
779 std::queue<GLES::Buffer*> mDiscardBufferQueue; ///< Discard queue for buffer resource
781 std::queue<GLES::Program*> mDiscardProgramQueue; ///< Discard queue for program resource
782 std::queue<GLES::Pipeline*> mDiscardPipelineQueue; ///< Discard queue of pipelines
783 std::queue<GLES::Shader*> mDiscardShaderQueue; ///< Discard queue of shaders
784 std::queue<GLES::Sampler*> mDiscardSamplerQueue; ///< Discard queue of samplers
785 std::queue<const GLES::CommandBuffer*> mDiscardCommandBufferQueue; ///< Discard queue of command buffers
786 std::queue<GLES::Framebuffer*> mCreateFramebufferQueue; ///< Create queue for framebuffer resource
787 std::queue<GLES::Framebuffer*> mDiscardFramebufferQueue; ///< Discard queue for framebuffer resource
789 std::queue<GLES::CommandBuffer*> mCommandQueue; ///< we may have more in the future
791 using TextureUpdateRequest = std::pair<TextureUpdateInfo, TextureUpdateSourceInfo>;
792 std::queue<TextureUpdateRequest> mTextureUpdateRequests;
794 std::queue<const GLES::Texture*> mTextureMipmapGenerationRequests; ///< Queue for texture mipmap generation requests
796 GLES::Context* mCurrentContext{nullptr}; ///< The current context
797 std::unique_ptr<GLES::Context> mContext{nullptr}; ///< Context object handling command buffers execution
798 using SurfaceContextPair = std::pair<Dali::RenderSurfaceInterface*, std::unique_ptr<GLES::Context>>;
799 std::vector<SurfaceContextPair> mSurfaceContexts; ///< Vector of surface context objects handling command buffers execution
801 std::unique_ptr<GLES::PipelineCache> mPipelineCache{nullptr}; ///< Internal pipeline cache
803 GLES::GLESVersion mGLESVersion{GLES::GLESVersion::GLES_20}; ///< Runtime supported GLES version
804 uint32_t mTextureUploadTotalCPUMemoryUsed{0u};
806 bool mIsShuttingDown{false}; ///< Indicates whether the controller is shutting down
808 std::queue<const GLES::CommandBuffer*> mPresentationCommandBuffers{}; ///< Queue of reusable command buffers used by presentation engine
811 } // namespace Graphics
815 #endif //DALI_EGL_GRAPHICS_CONTROLLER_H