1 #ifndef DALI_EGL_GRAPHICS_CONTROLLER_H
2 #define DALI_EGL_GRAPHICS_CONTROLLER_H
5 * Copyright (c) 2022 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/gles-sync-pool.h>
39 #include <dali/internal/graphics/gles-impl/gles-texture-dependency-checker.h>
40 #include <dali/internal/graphics/gles-impl/gles2-graphics-memory.h>
47 class GlContextHelperAbstraction;
48 } // namespace Integration
57 class TextureDependencyChecker;
61 * EGL Implementation of the graphics controller.
63 * Temporarily holds the old GL abstractions whilst dali-core is migrated to the new API.
65 class EglGraphicsController : public Graphics::Controller
71 EglGraphicsController();
76 ~EglGraphicsController() override;
79 * Initialize the GLES abstraction. This can be called from the main thread.
81 void InitializeGLES(Integration::GlAbstraction& glAbstraction);
84 * Initialize with a reference to the GL abstractions.
86 * Note, this is now executed in the render thread, after core initialization
88 void Initialize(Integration::GraphicsSyncAbstraction& syncImplementation,
89 Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
90 Internal::Adaptor::GraphicsInterface& graphicsInterface);
92 Integration::GlAbstraction& GetGlAbstraction() override;
93 Integration::GlContextHelperAbstraction& GetGlContextHelperAbstraction() override;
94 Internal::Adaptor::EglSyncImplementation& GetEglSyncImplementation();
97 * @copydoc Dali::Graphics::SubmitCommandBuffers()
99 void SubmitCommandBuffers(const SubmitInfo& submitInfo) override;
102 * @copydoc Dali::Graphics::PresentRenderTarget()
104 void PresentRenderTarget(RenderTarget* renderTarget) override;
107 * @copydoc Dali::Graphics::WaitIdle()
109 void WaitIdle() override
114 * @copydoc Dali::Graphics::Pause()
116 void Pause() override
121 * @copydoc Dali::Graphics::Resume()
123 void Resume() override
128 * @copydoc Dali::Graphics::Shutdown()
130 void Shutdown() override
132 mIsShuttingDown = true;
139 mContext->GlContextDestroyed();
142 for(auto&& context : mSurfaceContexts)
146 context.second->GlContextDestroyed();
152 * @copydoc Dali::Graphics::Destroy()
154 void Destroy() override
159 * @copydoc Dali::Graphics::UpdateTextures()
161 void UpdateTextures(const std::vector<TextureUpdateInfo>& updateInfoList,
162 const std::vector<TextureUpdateSourceInfo>& sourceList) override;
165 * @copydoc Dali::Graphics::GenerateTextureMipmaps()
167 void GenerateTextureMipmaps(const Texture& texture) override;
170 * @copydoc Dali::Graphics::EnableDepthStencilBuffer()
172 bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override
178 * @copydoc Dali::Graphics::RunGarbageCollector()
180 void RunGarbageCollector(size_t numberOfDiscardedRenderers) override
185 * @copydoc Dali::Graphics::DiscardUnusedResources()
187 void DiscardUnusedResources() override
192 * @copydoc Dali::Graphics::IsDiscardQueueEmpty()
194 bool IsDiscardQueueEmpty() override
200 * @copydoc Dali::Graphics::IsDrawOnResumeRequired()
202 bool IsDrawOnResumeRequired() override
208 * @copydoc Dali::Graphics::CreateBuffer()
210 Graphics::UniquePtr<Buffer> CreateBuffer(const BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Buffer>&& oldBuffer) override;
213 * @copydoc Dali::Graphics::CreateCommandBuffer()
215 Graphics::UniquePtr<CommandBuffer> CreateCommandBuffer(const CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<CommandBuffer>&& oldCommandBuffer) override;
218 * @copydoc Dali::Graphics::CreateRenderPass()
220 Graphics::UniquePtr<RenderPass> CreateRenderPass(const RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<RenderPass>&& oldRenderPass) override;
223 * @copydoc Dali::Graphics::CreateTexture()
225 Graphics::UniquePtr<Texture> CreateTexture(const TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Texture>&& oldTexture) override;
228 * @copydoc Dali::Graphics::CreateFramebuffer()
230 Graphics::UniquePtr<Framebuffer> CreateFramebuffer(const FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Framebuffer>&& oldFramebuffer) override;
233 * @copydoc Dali::Graphics::CreatePipeline()
235 Graphics::UniquePtr<Pipeline> CreatePipeline(const PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Pipeline>&& oldPipeline) override;
238 * @copydoc Dali::Graphics::CreateProgram()
240 Graphics::UniquePtr<Program> CreateProgram(const ProgramCreateInfo& programCreateInfo, UniquePtr<Program>&& oldProgram) override;
243 * @copydoc Dali::Graphics::CreateShader()
245 Graphics::UniquePtr<Shader> CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader) override;
248 * @copydoc Dali::Graphics::CreateSampler()
250 Graphics::UniquePtr<Sampler> CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler) override;
253 * @copydoc Dali::Graphics::CreateRenderTarget()
255 Graphics::UniquePtr<RenderTarget> CreateRenderTarget(const RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<RenderTarget>&& oldRenderTarget) override;
258 * @copydoc Dali::Graphics::CreateSyncObject()
260 Graphics::UniquePtr<SyncObject> CreateSyncObject(const SyncObjectCreateInfo& syncObjectCreateInfo,
261 Graphics::UniquePtr<SyncObject>&& oldSyncObject) override;
264 * @copydoc Dali::Graphics::MapBufferRange()
266 Graphics::UniquePtr<Memory> MapBufferRange(const MapBufferInfo& mapInfo) override;
269 * @copydoc Dali::Graphics::MapTextureRange()
271 Graphics::UniquePtr<Memory> MapTextureRange(const MapTextureInfo& mapInfo) override
277 * @copydoc Dali::Graphics::UnmapMemory()
279 void UnmapMemory(Graphics::UniquePtr<Memory> memory) override
283 * @copydoc Dali::Graphics::GetTextureMemoryRequirements()
285 MemoryRequirements GetTextureMemoryRequirements(Texture& texture) const override
291 * @copydoc Dali::Graphics::GetBufferMemoryRequirements()
293 MemoryRequirements GetBufferMemoryRequirements(Buffer& buffer) const override
299 * @copydoc Dali::Graphics::GetTextureProperties()
301 TextureProperties GetTextureProperties(const Texture& texture) override;
304 * @copydoc Dali::Graphics::Controller::GetPipelineReflection()
306 [[nodiscard]] const Reflection& GetProgramReflection(const Graphics::Program& program) override;
309 * @copydoc Dali::Graphics::PipelineEquals()
311 [[nodiscard]] bool PipelineEquals(const Pipeline& pipeline0, const Pipeline& pipeline1) const override
316 public: // Framebuffer Capture
317 void CaptureRenderingResult(Graphics::Framebuffer& framebuffer, CallbackBase* capturedCallback, uint8_t* capturedBuffer) override;
320 [[nodiscard]] Integration::GlAbstraction* GetGL() const
326 return mGlAbstraction;
329 [[nodiscard]] Internal::Adaptor::GraphicsInterface* GetGraphicsInterface() const
335 void AddTexture(GLES::Texture& texture);
338 * @brief Adds buffer to the creation queue
341 void AddBuffer(GLES::Buffer& buffer);
344 * @brief Adds framebuffer to the creation queue
347 void AddFramebuffer(GLES::Framebuffer& framebuffer);
350 * @brief Pushes Bufer to the discard queue
352 * Function is called from the UniquePtr custom deleter.
354 * @param[in] texture Pointer to the texture
356 void DiscardResource(GLES::Texture* texture)
358 mDiscardTextureQueue.push(texture);
362 * @brief Pushes Buffer to the discard queue
364 * Function is called from the UniquePtr custom deleter.
366 * @param[in] buffer Pointer to the buffer object
368 void DiscardResource(GLES::Buffer* buffer)
370 mDiscardBufferQueue.push(buffer);
374 * @brief Pushes framebuffer to the discard queue
376 * Function is called from the UniquePtr custom deleter.
378 * @param[in] framebuffer Pointer to the framebuffer object
380 void DiscardResource(GLES::Framebuffer* framebuffer)
382 mDiscardFramebufferQueue.push(framebuffer);
386 * @brief Pushes Program to the discard queue
388 * Function is called from the UniquePtr custom deleter.
390 * @param[in] program Pointer to the program
392 void DiscardResource(GLES::Program* program)
394 mDiscardProgramQueue.push(program);
398 * @brief Pushes RenderPass to the discard queue
400 * Function is called from the UniquePtr custom deleter.
402 * @param[in] program Pointer to the RenderPass
404 void DiscardResource(GLES::RenderPass* renderPass)
406 mDiscardRenderPassQueue.push(renderPass);
410 * @brief Pushes RenderTarget to the discard queue
412 * Function is called from the UniquePtr custom deleter.
414 * @param[in] program Pointer to the RenderTarget
416 void DiscardResource(GLES::RenderTarget* renderTarget)
418 mDiscardRenderTargetQueue.push(renderTarget);
422 * @brief Pushes Shader to the discard queue
424 * Function is called from the UniquePtr custom deleter.
426 * @param[in] program Pointer to the Shader
428 void DiscardResource(GLES::Shader* shader)
430 mDiscardShaderQueue.push(shader);
434 * @brief Pushes CommandBuffer to the discard queue
436 * Function is called from the UniquePtr custom deleter.
438 * @param[in] program Pointer to the CommandBuffer
440 void DiscardResource(GLES::CommandBuffer* commandBuffer)
442 mDiscardCommandBufferQueue.push(commandBuffer);
446 * @brief Pushes Sampler to the discard queue
448 * Function is called from the UniquePtr custom deleter.
450 * @param[in] program Pointer to the Sampler
452 void DiscardResource(GLES::Sampler* sampler)
454 mDiscardSamplerQueue.push(sampler);
458 * @brief Pushes Pipeline to the discard queue
460 * Function is called from the UniquePtr custom deleter.
462 * @param[in] program Pointer to the pipeline
464 void DiscardResource(GLES::Pipeline* pipeline)
466 mDiscardPipelineQueue.push(pipeline);
470 * @brief Flushes all pending updates
472 * Function flushes all pending resource constructions,
473 * executes command buffers and empties discard queues.
477 if(!mCreateTextureQueue.empty() ||
478 !mCreateBufferQueue.empty() ||
479 !mCreateFramebufferQueue.empty() ||
480 !mTextureUpdateRequests.empty() ||
481 !mTextureMipmapGenerationRequests.empty())
483 mGraphics->ActivateResourceContext();
487 ProcessCreateQueues();
490 ProcessTextureUpdateQueue();
492 // Process texture mipmap generation requests
493 ProcessTextureMipmapGenerationQueue();
495 // Process main command queue
496 ProcessCommandQueues();
498 // Reset texture cache in the contexts while destroying textures
501 // Reset buffer cache in the contexts while destroying buffers
505 ProcessDiscardQueues();
507 // Flush pipeline cache to remove unused pipelines
510 mPipelineCache->FlushCache();
514 // Test update to tick controller, usually it will run own thread
515 void ProcessDiscardQueues();
518 * @brief Processes a create queue for type specified
520 * @param[in,out] queue Reference to the create queue
523 void ProcessCreateQueue(T& queue)
525 while(!queue.empty())
527 auto* object = queue.front();
530 // Initialize texture
531 if(!object->InitializeResource())
533 // TODO: handle error
539 * @brief Processes a discard queue for type specified
541 * @param[in,out] queue Reference to the discard queue
543 template<class U, class T>
544 void ProcessDiscardQueue(T& queue)
546 while(!queue.empty())
548 auto* object = const_cast<U*>(queue.front());
551 object->DestroyResource();
554 auto* clbk = object->GetCreateInfo().allocationCallbacks;
561 clbk->freeCallback(object, clbk->userData);
572 * @brief Processes a discard queue for pipeline
574 * @param[in,out] queue Reference to the create queue
576 void ProcessDiscardQueue(std::queue<GLES::Pipeline*>& queue)
578 while(!queue.empty())
580 auto* object = const_cast<GLES::Pipeline*>(queue.front());
582 // Inform the contexts to invalidate the pipeline if cached
585 mContext->InvalidateCachedPipeline(object);
588 for(auto&& context : mSurfaceContexts)
592 context.second->InvalidateCachedPipeline(object);
597 object->DestroyResource();
600 auto* clbk = object->GetCreateInfo().allocationCallbacks;
604 using GLESPipeline = GLES::Pipeline;
605 object->~GLESPipeline();
608 clbk->freeCallback(object, clbk->userData);
619 * @brief Processes all resource create queues
621 void ProcessCreateQueues();
624 * @brief Process command queues and buffers
626 void ProcessCommandQueues();
629 * @brief Executes all pending texture updates
631 void ProcessTextureUpdateQueue();
634 * @brief Executes all pending texture mipmap generation
636 void ProcessTextureMipmapGenerationQueue();
639 * @brief Returns program custom parameter
641 * This function can be used as a backdoor in order to retrieve
642 * certain data out of implementation
644 * @param[in] program Valid Program object
645 * @param parameterId Integer id of parameter
646 * @param outData Output data
647 * @return True if parameter retrieved
649 bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) override;
652 * @brief Returns pipeline cache object
654 * @return Valid pipeline cache object
656 [[nodiscard]] GLES::PipelineCache& GetPipelineCache() const;
659 * @brief Returns runtime supported GLES version
661 * @return GLES version enum
663 GLES::GLESVersion GetGLESVersion() const
669 * @brief Sets runtime supported GLES version
671 * @param[in] glesVersion The runtime supported GLES version
673 void SetGLESVersion(GLES::GLESVersion glesVersion)
675 mGLESVersion = glesVersion;
678 bool IsShuttingDown() const
680 return mIsShuttingDown;
684 * @brief Reset texture cache in the contexts
686 void ResetTextureCache()
690 mContext->GetGLStateCache().ResetTextureCache();
693 for(auto& context : mSurfaceContexts)
697 context.second->GetGLStateCache().ResetTextureCache();
703 * @brief Reset buffer cache in the contexts
705 void ResetBufferCache()
709 mContext->GetGLStateCache().ResetBufferCache();
712 for(auto& context : mSurfaceContexts)
716 context.second->GetGLStateCache().ResetBufferCache();
721 void ProcessCommandBuffer(const GLES::CommandBuffer& commandBuffer);
723 // Resolves presentation
724 void ResolvePresentRenderTarget(GLES::RenderTarget* renderTarget);
727 * Invoked after all rendering has finished. Used to clean up sync resources
732 * Creates a GLES context for the given render surface
734 * @param[in] surface The surface whose GLES context to be created.
736 void CreateSurfaceContext(Dali::RenderSurfaceInterface* surface);
739 * Deletes a GLES context
741 * @param[in] surface The surface whose GLES context to be deleted.
743 void DeleteSurfaceContext(Dali::RenderSurfaceInterface* surface);
746 * Activate the resource context (shared surfaceless context)
748 void ActivateResourceContext();
751 * Activate the surface context
753 * @param[in] surface The surface whose context to be switched to.
755 void ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface);
758 * @brief Returns the current context
760 * @return the current context
762 GLES::Context* GetCurrentContext() const
764 return mCurrentContext;
768 * @brief Returns EGL shared context
770 * @return valid EGL shared context
772 void* GetSharedContext() const
774 return mSharedContext;
777 GLES::SyncPool& GetSyncPool()
783 Integration::GlAbstraction* mGlAbstraction{nullptr};
784 Integration::GlContextHelperAbstraction* mGlContextHelperAbstraction{nullptr};
786 Internal::Adaptor::EglSyncImplementation* mEglSyncImplementation{nullptr};
787 Internal::Adaptor::GraphicsInterface* mGraphics{nullptr}; // Pointer to owning structure via interface.
789 std::queue<GLES::Texture*> mCreateTextureQueue; ///< Create queue for texture resource
790 std::queue<GLES::Texture*> mDiscardTextureQueue; ///< Discard queue for texture resource
792 std::queue<GLES::Buffer*> mCreateBufferQueue; ///< Create queue for buffer resource
793 std::queue<GLES::Buffer*> mDiscardBufferQueue; ///< Discard queue for buffer resource
795 std::queue<GLES::Program*> mDiscardProgramQueue; ///< Discard queue for program resource
796 std::queue<GLES::Pipeline*> mDiscardPipelineQueue; ///< Discard queue of pipelines
797 std::queue<GLES::RenderPass*> mDiscardRenderPassQueue; ///< Discard queue for renderpass resource
798 std::queue<GLES::RenderTarget*> mDiscardRenderTargetQueue; ///< Discard queue for rendertarget resource
799 std::queue<GLES::Shader*> mDiscardShaderQueue; ///< Discard queue of shaders
800 std::queue<GLES::Sampler*> mDiscardSamplerQueue; ///< Discard queue of samplers
801 std::queue<const GLES::CommandBuffer*> mDiscardCommandBufferQueue; ///< Discard queue of command buffers
802 std::queue<GLES::Framebuffer*> mCreateFramebufferQueue; ///< Create queue for framebuffer resource
803 std::queue<GLES::Framebuffer*> mDiscardFramebufferQueue; ///< Discard queue for framebuffer resource
805 std::queue<GLES::CommandBuffer*> mCommandQueue; ///< we may have more in the future
807 using TextureUpdateRequest = std::pair<TextureUpdateInfo, TextureUpdateSourceInfo>;
808 std::queue<TextureUpdateRequest> mTextureUpdateRequests;
810 std::queue<const GLES::Texture*> mTextureMipmapGenerationRequests; ///< Queue for texture mipmap generation requests
812 GLES::Context* mCurrentContext{nullptr}; ///< The current context
813 std::unique_ptr<GLES::Context> mContext{nullptr}; ///< Context object handling command buffers execution
814 using SurfaceContextPair = std::pair<Dali::RenderSurfaceInterface*, std::unique_ptr<GLES::Context>>;
815 std::vector<SurfaceContextPair> mSurfaceContexts; ///< Vector of surface context objects handling command buffers execution
817 std::unique_ptr<GLES::PipelineCache> mPipelineCache{nullptr}; ///< Internal pipeline cache
819 GLES::GLESVersion mGLESVersion{GLES::GLESVersion::GLES_20}; ///< Runtime supported GLES version
820 uint32_t mTextureUploadTotalCPUMemoryUsed{0u};
822 bool mIsShuttingDown{false}; ///< Indicates whether the controller is shutting down
824 std::queue<const GLES::CommandBuffer*> mPresentationCommandBuffers{}; ///< Queue of reusable command buffers used by presentation engine
826 void* mSharedContext{nullptr}; ///< Shared EGL context
828 GLES::TextureDependencyChecker mTextureDependencyChecker; // Checks if FBO textures need syncing
829 GLES::SyncPool mSyncPool;
832 } // namespace Graphics
836 #endif //DALI_EGL_GRAPHICS_CONTROLLER_H