Added recycling of Graphics resources.
[platform/core/uifw/dali-adaptor.git] / dali / internal / graphics / gles-impl / egl-graphics-controller.h
1 #ifndef DALI_EGL_GRAPHICS_CONTROLLER_H
2 #define DALI_EGL_GRAPHICS_CONTROLLER_H
3
4 /*
5  * Copyright (c) 2023 Samsung Electronics Co., Ltd.
6  *
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
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <dali/graphics-api/graphics-controller.h>
22 #include <queue>
23
24 // INTERNAL INCLUDES
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>
41
42 namespace Dali
43 {
44 namespace Integration
45 {
46 class GlAbstraction;
47 class GlContextHelperAbstraction;
48 } // namespace Integration
49
50 namespace Graphics
51 {
52 namespace GLES
53 {
54 class CommandBuffer;
55 class PipelineCache;
56 class SyncPool;
57 class TextureDependencyChecker;
58 } // namespace GLES
59
60 /**
61  * EGL Implementation of the graphics controller.
62  *
63  * Temporarily holds the old GL abstractions whilst dali-core is migrated to the new API.
64  */
65 class EglGraphicsController : public Graphics::Controller
66 {
67 public:
68   /**
69    * @brief Constructor
70    */
71   EglGraphicsController();
72
73   /**
74    * @brief Destructor
75    */
76   ~EglGraphicsController() override;
77
78   /**
79    * Initialize the GLES abstraction. This can be called from the main thread.
80    */
81   void InitializeGLES(Integration::GlAbstraction& glAbstraction);
82
83   /**
84    * Initialize with a reference to the GL abstractions.
85    *
86    * Note, this is now executed in the render thread, after core initialization
87    */
88   void Initialize(Integration::GraphicsSyncAbstraction&    syncImplementation,
89                   Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
90                   Internal::Adaptor::GraphicsInterface&    graphicsInterface);
91
92   Integration::GlAbstraction&               GetGlAbstraction() override;
93   Integration::GlContextHelperAbstraction&  GetGlContextHelperAbstraction() override;
94   Internal::Adaptor::EglSyncImplementation& GetEglSyncImplementation();
95
96   /**
97    * Mark the start of the frame.
98    *
99    * Note, this is used for logging & debugging, so is not part of the main Graphics API.
100    */
101   void FrameStart();
102
103   /**
104    * @copydoc Dali::Graphics::SubmitCommandBuffers()
105    */
106   void SubmitCommandBuffers(const SubmitInfo& submitInfo) override;
107
108   /**
109    * @copydoc Dali::Graphics::PresentRenderTarget()
110    */
111   void PresentRenderTarget(RenderTarget* renderTarget) override;
112
113   /**
114    * @copydoc Dali::Graphics::WaitIdle()
115    */
116   void WaitIdle() override;
117
118   /**
119    * @copydoc Dali::Graphics::Pause()
120    */
121   void Pause() override
122   {
123   }
124
125   /**
126    * @copydoc Dali::Graphics::Resume()
127    */
128   void Resume() override
129   {
130   }
131
132   /**
133    * @copydoc Dali::Graphics::Shutdown()
134    */
135   void Shutdown() override
136   {
137     mIsShuttingDown = true;
138
139     // Final flush
140     Flush();
141
142     if(mContext)
143     {
144       mContext->GlContextDestroyed();
145     }
146
147     for(auto&& context : mSurfaceContexts)
148     {
149       if(context.second)
150       {
151         context.second->GlContextDestroyed();
152       }
153     }
154   }
155
156   /**
157    * @copydoc Dali::Graphics::Destroy()
158    */
159   void Destroy() override
160   {
161   }
162
163   /**
164    * @copydoc Dali::Graphics::UpdateTextures()
165    */
166   void UpdateTextures(const std::vector<TextureUpdateInfo>&       updateInfoList,
167                       const std::vector<TextureUpdateSourceInfo>& sourceList) override;
168
169   /**
170    * @copydoc Dali::Graphics::GenerateTextureMipmaps()
171    */
172   void GenerateTextureMipmaps(const Texture& texture) override;
173
174   /**
175    * @copydoc Dali::Graphics::EnableDepthStencilBuffer()
176    */
177   bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override
178   {
179     return {};
180   }
181
182   /**
183    * @copydoc Dali::Graphics::RunGarbageCollector()
184    */
185   void RunGarbageCollector(size_t numberOfDiscardedRenderers) override
186   {
187   }
188
189   /**
190    * @copydoc Dali::Graphics::DiscardUnusedResources()
191    */
192   void DiscardUnusedResources() override
193   {
194   }
195
196   /**
197    * @copydoc Dali::Graphics::IsDiscardQueueEmpty()
198    */
199   bool IsDiscardQueueEmpty() override
200   {
201     return {};
202   }
203
204   /**
205    * @copydoc Dali::Graphics::IsDrawOnResumeRequired()
206    */
207   bool IsDrawOnResumeRequired() override
208   {
209     return {};
210   }
211
212   /**
213    * @copydoc Dali::Graphics::CreateBuffer()
214    */
215   Graphics::UniquePtr<Buffer> CreateBuffer(const BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Buffer>&& oldBuffer) override;
216
217   /**
218    * @copydoc Dali::Graphics::CreateCommandBuffer()
219    */
220   Graphics::UniquePtr<CommandBuffer> CreateCommandBuffer(const CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<CommandBuffer>&& oldCommandBuffer) override;
221
222   /**
223    * @copydoc Dali::Graphics::CreateRenderPass()
224    */
225   Graphics::UniquePtr<RenderPass> CreateRenderPass(const RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<RenderPass>&& oldRenderPass) override;
226
227   /**
228    * @copydoc Dali::Graphics::CreateTexture()
229    */
230   Graphics::UniquePtr<Texture> CreateTexture(const TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Texture>&& oldTexture) override;
231
232   /**
233    * @copydoc Dali::Graphics::CreateFramebuffer()
234    */
235   Graphics::UniquePtr<Framebuffer> CreateFramebuffer(const FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Framebuffer>&& oldFramebuffer) override;
236
237   /**
238    * @copydoc Dali::Graphics::CreatePipeline()
239    */
240   Graphics::UniquePtr<Pipeline> CreatePipeline(const PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Pipeline>&& oldPipeline) override;
241
242   /**
243    * @copydoc Dali::Graphics::CreateProgram()
244    */
245   Graphics::UniquePtr<Program> CreateProgram(const ProgramCreateInfo& programCreateInfo, UniquePtr<Program>&& oldProgram) override;
246
247   /**
248    * @copydoc Dali::Graphics::CreateShader()
249    */
250   Graphics::UniquePtr<Shader> CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader) override;
251
252   /**
253    * @copydoc Dali::Graphics::CreateSampler()
254    */
255   Graphics::UniquePtr<Sampler> CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler) override;
256
257   /**
258    * @copydoc Dali::Graphics::CreateRenderTarget()
259    */
260   Graphics::UniquePtr<RenderTarget> CreateRenderTarget(const RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<RenderTarget>&& oldRenderTarget) override;
261
262   /**
263    * @copydoc Dali::Graphics::CreateSyncObject()
264    */
265   Graphics::UniquePtr<SyncObject> CreateSyncObject(const SyncObjectCreateInfo&       syncObjectCreateInfo,
266                                                    Graphics::UniquePtr<SyncObject>&& oldSyncObject) override;
267
268   /**
269    * @copydoc Dali::Graphics::MapBufferRange()
270    */
271   Graphics::UniquePtr<Memory> MapBufferRange(const MapBufferInfo& mapInfo) override;
272
273   /**
274    * @copydoc Dali::Graphics::MapTextureRange()
275    */
276   Graphics::UniquePtr<Memory> MapTextureRange(const MapTextureInfo& mapInfo) override
277   {
278     return nullptr;
279   }
280
281   /**
282    * @copydoc Dali::Graphics::UnmapMemory()
283    */
284   void UnmapMemory(Graphics::UniquePtr<Memory> memory) override
285   {
286   }
287   /**
288    * @copydoc Dali::Graphics::GetTextureMemoryRequirements()
289    */
290   MemoryRequirements GetTextureMemoryRequirements(Texture& texture) const override
291   {
292     return {};
293   }
294
295   /**
296    * @copydoc Dali::Graphics::GetBufferMemoryRequirements()
297    */
298   MemoryRequirements GetBufferMemoryRequirements(Buffer& buffer) const override
299   {
300     return {};
301   }
302
303   /**
304    * @copydoc Dali::Graphics::GetTextureProperties()
305    */
306   TextureProperties GetTextureProperties(const Texture& texture) override;
307
308   /**
309    * @copydoc Dali::Graphics::Controller::GetPipelineReflection()
310    */
311   [[nodiscard]] const Reflection& GetProgramReflection(const Graphics::Program& program) override;
312
313   /**
314    * @copydoc Dali::Graphics::PipelineEquals()
315    */
316   [[nodiscard]] bool PipelineEquals(const Pipeline& pipeline0, const Pipeline& pipeline1) const override
317   {
318     return {};
319   }
320
321   [[nodiscard]] Integration::GlAbstraction* GetGL() const
322   {
323     if(mIsShuttingDown)
324     {
325       return nullptr;
326     }
327     return mGlAbstraction;
328   }
329
330   [[nodiscard]] Internal::Adaptor::GraphicsInterface* GetGraphicsInterface() const
331   {
332     return mGraphics;
333   }
334
335   // Internal
336   void AddTexture(GLES::Texture& texture);
337
338   /**
339    * @brief Adds buffer to the creation queue
340    * @param buffer
341    */
342   void AddBuffer(GLES::Buffer& buffer);
343
344   /**
345    * @brief Adds framebuffer to the creation queue
346    * @param buffer
347    */
348   void AddFramebuffer(GLES::Framebuffer& framebuffer);
349
350   /**
351    * @brief Pushes Bufer to the discard queue
352    *
353    * Function is called from the UniquePtr custom deleter.
354    *
355    * @param[in] texture Pointer to the texture
356    */
357   void DiscardResource(GLES::Texture* texture)
358   {
359     mDiscardTextureQueue.push(texture);
360   }
361
362   /**
363    * @brief Pushes Buffer to the discard queue
364    *
365    * Function is called from the UniquePtr custom deleter.
366    *
367    * @param[in] buffer Pointer to the buffer object
368    */
369   void DiscardResource(GLES::Buffer* buffer)
370   {
371     mDiscardBufferQueue.push(buffer);
372   }
373
374   /**
375    * @brief Pushes framebuffer to the discard queue
376    *
377    * Function is called from the UniquePtr custom deleter.
378    *
379    * @param[in] framebuffer Pointer to the framebuffer object
380    */
381   void DiscardResource(GLES::Framebuffer* framebuffer)
382   {
383     mDiscardFramebufferQueue.push(framebuffer);
384   }
385
386   /**
387    * @brief Pushes Program to the discard queue
388    *
389    * Function is called from the UniquePtr custom deleter.
390    *
391    * @param[in] program Pointer to the program
392    */
393   void DiscardResource(GLES::Program* program)
394   {
395     mDiscardProgramQueue.push(program);
396   }
397
398   /**
399    * @brief Pushes RenderPass to the discard queue
400    *
401    * Function is called from the UniquePtr custom deleter.
402    *
403    * @param[in] program Pointer to the RenderPass
404    */
405   void DiscardResource(GLES::RenderPass* renderPass)
406   {
407     mDiscardRenderPassQueue.push(renderPass);
408   }
409
410   /**
411    * @brief Pushes RenderTarget to the discard queue
412    *
413    * Function is called from the UniquePtr custom deleter.
414    *
415    * @param[in] program Pointer to the RenderTarget
416    */
417   void DiscardResource(GLES::RenderTarget* renderTarget)
418   {
419     mDiscardRenderTargetQueue.push(renderTarget);
420   }
421
422   /**
423    * @brief Pushes Shader to the discard queue
424    *
425    * Function is called from the UniquePtr custom deleter.
426    *
427    * @param[in] program Pointer to the Shader
428    */
429   void DiscardResource(GLES::Shader* shader)
430   {
431     mDiscardShaderQueue.push(shader);
432   }
433
434   /**
435    * @brief Pushes CommandBuffer to the discard queue
436    *
437    * Function is called from the UniquePtr custom deleter.
438    *
439    * @param[in] program Pointer to the CommandBuffer
440    */
441   void DiscardResource(GLES::CommandBuffer* commandBuffer)
442   {
443     mDiscardCommandBufferQueue.push(commandBuffer);
444   }
445
446   /**
447    * @brief Pushes Sampler to the discard queue
448    *
449    * Function is called from the UniquePtr custom deleter.
450    *
451    * @param[in] program Pointer to the Sampler
452    */
453   void DiscardResource(GLES::Sampler* sampler)
454   {
455     mDiscardSamplerQueue.push(sampler);
456   }
457
458   /**
459    * @brief Pushes Pipeline to the discard queue
460    *
461    * Function is called from the UniquePtr custom deleter.
462    *
463    * @param[in] program Pointer to the pipeline
464    */
465   void DiscardResource(GLES::Pipeline* pipeline)
466   {
467     mDiscardPipelineQueue.push(pipeline);
468   }
469
470   /**
471    * @brief Flushes all pending updates
472    *
473    * Function flushes all pending resource constructions,
474    * executes command buffers and empties discard queues.
475    */
476   void Flush()
477   {
478     if(!mCreateTextureQueue.empty() ||
479        !mCreateBufferQueue.empty() ||
480        !mCreateFramebufferQueue.empty() ||
481        !mTextureUpdateRequests.empty() ||
482        !mTextureMipmapGenerationRequests.empty())
483     {
484       mGraphics->ActivateResourceContext();
485     }
486
487     // Process creations
488     ProcessCreateQueues();
489
490     // Process updates
491     ProcessTextureUpdateQueue();
492
493     // Process texture mipmap generation requests
494     ProcessTextureMipmapGenerationQueue();
495
496     // Process main command queue
497     ProcessCommandQueues();
498
499     // Reset texture cache in the contexts while destroying textures
500     ResetTextureCache();
501
502     // Reset buffer cache in the contexts while destroying buffers
503     ResetBufferCache();
504
505     // Process discards
506     ProcessDiscardQueues();
507
508     // Flush pipeline cache to remove unused pipelines
509     if(mPipelineCache)
510     {
511       mPipelineCache->FlushCache();
512     }
513   }
514
515   // Test update to tick controller, usually it will run own thread
516   void ProcessDiscardQueues();
517
518   /**
519    * @brief Processes a create queue for type specified
520    *
521    * @param[in,out] queue Reference to the create queue
522    */
523   template<class T>
524   void ProcessCreateQueue(T& queue)
525   {
526     while(!queue.empty())
527     {
528       auto* object = queue.front();
529       queue.pop();
530
531       // Initialize texture
532       if(!object->InitializeResource())
533       {
534         // TODO: handle error
535       }
536     }
537   }
538
539   /**
540    * @brief Processes a discard queue for type specified
541    *
542    * @param[in,out] queue Reference to the discard queue
543    */
544   template<class U, class T>
545   void ProcessDiscardQueue(T& queue)
546   {
547     while(!queue.empty())
548     {
549       auto* object = const_cast<U*>(queue.front());
550
551       // Destroy
552       object->DestroyResource();
553
554       // Free
555       auto* clbk = object->GetCreateInfo().allocationCallbacks;
556       if(clbk)
557       {
558         // Call destructor
559         object->~U();
560
561         // Free memory
562         clbk->freeCallback(object, clbk->userData);
563       }
564       else
565       {
566         delete object;
567       }
568       queue.pop();
569     }
570   }
571
572   /**
573    * @brief Processes a discard queue for pipeline
574    *
575    * @param[in,out] queue Reference to the create queue
576    */
577   void ProcessDiscardQueue(std::queue<GLES::Pipeline*>& queue)
578   {
579     while(!queue.empty())
580     {
581       auto* object = const_cast<GLES::Pipeline*>(queue.front());
582
583       // Inform the contexts to invalidate the pipeline if cached
584       if(mContext)
585       {
586         mContext->InvalidateCachedPipeline(object);
587       }
588
589       for(auto&& context : mSurfaceContexts)
590       {
591         if(context.second)
592         {
593           context.second->InvalidateCachedPipeline(object);
594         }
595       }
596
597       // Destroy
598       object->DestroyResource();
599
600       // Free
601       auto* clbk = object->GetCreateInfo().allocationCallbacks;
602       if(clbk)
603       {
604         // Call destructor
605         using GLESPipeline = GLES::Pipeline;
606         object->~GLESPipeline();
607
608         // Free memory
609         clbk->freeCallback(object, clbk->userData);
610       }
611       else
612       {
613         delete object;
614       }
615       queue.pop();
616     }
617   }
618
619   /**
620    * @brief Processes all resource create queues
621    */
622   void ProcessCreateQueues();
623
624   /**
625    * @brief Process command queues and buffers
626    */
627   void ProcessCommandQueues();
628
629   /**
630    * @brief Executes all pending texture updates
631    */
632   void ProcessTextureUpdateQueue();
633
634   /**
635    * @brief Executes all pending texture mipmap generation
636    */
637   void ProcessTextureMipmapGenerationQueue();
638
639   /**
640    * @brief Returns program custom parameter
641    *
642    * This function can be used as a backdoor in order to retrieve
643    * certain data out of implementation
644    *
645    * @param[in] program Valid Program object
646    * @param parameterId Integer id of parameter
647    * @param outData Output data
648    * @return True if parameter retrieved
649    */
650   bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) override;
651
652   /**
653    * @brief Returns pipeline cache object
654    *
655    * @return Valid pipeline cache object
656    */
657   [[nodiscard]] GLES::PipelineCache& GetPipelineCache() const;
658
659   /**
660    * @brief Returns runtime supported GLES version
661    *
662    * @return GLES version enum
663    */
664   GLES::GLESVersion GetGLESVersion() const
665   {
666     return mGLESVersion;
667   }
668
669   /**
670    * @brief Sets runtime supported GLES version
671    *
672    * @param[in] glesVersion The runtime supported GLES version
673    */
674   void SetGLESVersion(GLES::GLESVersion glesVersion)
675   {
676     mGLESVersion = glesVersion;
677   }
678
679   bool IsShuttingDown() const
680   {
681     return mIsShuttingDown;
682   }
683
684   /**
685    * @brief Reset texture cache in the contexts
686    */
687   void ResetTextureCache()
688   {
689     if(mContext)
690     {
691       mContext->GetGLStateCache().ResetTextureCache();
692     }
693
694     for(auto& context : mSurfaceContexts)
695     {
696       if(context.second)
697       {
698         context.second->GetGLStateCache().ResetTextureCache();
699       }
700     }
701   }
702
703   /**
704    * @brief Reset buffer cache in the contexts
705    */
706   void ResetBufferCache()
707   {
708     if(mContext)
709     {
710       mContext->GetGLStateCache().ResetBufferCache();
711     }
712
713     for(auto& context : mSurfaceContexts)
714     {
715       if(context.second)
716       {
717         context.second->GetGLStateCache().ResetBufferCache();
718       }
719     }
720   }
721
722   void ProcessCommandBuffer(const GLES::CommandBuffer& commandBuffer);
723
724   // Resolves presentation
725   void ResolvePresentRenderTarget(GLES::RenderTarget* renderTarget);
726
727   /**
728    * Invoked after all rendering has finished. Used to clean up sync resources
729    */
730   void PostRender();
731
732   /**
733    * Creates a GLES context for the given render surface
734    *
735    * @param[in] surface The surface whose GLES context to be created.
736    */
737   void CreateSurfaceContext(Dali::RenderSurfaceInterface* surface);
738
739   /**
740    * Deletes a GLES context
741    *
742    * @param[in] surface The surface whose GLES context to be deleted.
743    */
744   void DeleteSurfaceContext(Dali::RenderSurfaceInterface* surface);
745
746   /**
747    * Activate the resource context (shared surfaceless context)
748    */
749   void ActivateResourceContext();
750
751   /**
752    * Activate the surface context
753    *
754    * @param[in] surface The surface whose context to be switched to.
755    */
756   void ActivateSurfaceContext(Dali::RenderSurfaceInterface* surface);
757
758   /**
759    * @brief Returns the current context
760    *
761    * @return the current context
762    */
763   GLES::Context* GetCurrentContext() const
764   {
765     return mCurrentContext;
766   }
767
768   /**
769    * @brief Returns EGL shared context
770    *
771    * @return valid EGL shared context
772    */
773   void* GetSharedContext() const
774   {
775     return mSharedContext;
776   }
777
778   GLES::SyncPool& GetSyncPool()
779   {
780     return mSyncPool;
781   }
782
783   std::size_t GetCapacity() const
784   {
785     return mCapacity;
786   }
787
788 private:
789   Integration::GlAbstraction*              mGlAbstraction{nullptr};
790   Integration::GlContextHelperAbstraction* mGlContextHelperAbstraction{nullptr};
791
792   Internal::Adaptor::EglSyncImplementation* mEglSyncImplementation{nullptr};
793   Internal::Adaptor::GraphicsInterface*     mGraphics{nullptr}; // Pointer to owning structure via interface.
794
795   std::queue<GLES::Texture*> mCreateTextureQueue;  ///< Create queue for texture resource
796   std::queue<GLES::Texture*> mDiscardTextureQueue; ///< Discard queue for texture resource
797
798   std::queue<GLES::Buffer*> mCreateBufferQueue;  ///< Create queue for buffer resource
799   std::queue<GLES::Buffer*> mDiscardBufferQueue; ///< Discard queue for buffer resource
800
801   std::queue<GLES::Program*>             mDiscardProgramQueue;       ///< Discard queue for program resource
802   std::queue<GLES::Pipeline*>            mDiscardPipelineQueue;      ///< Discard queue of pipelines
803   std::queue<GLES::RenderPass*>          mDiscardRenderPassQueue;    ///< Discard queue for renderpass resource
804   std::queue<GLES::RenderTarget*>        mDiscardRenderTargetQueue;  ///< Discard queue for rendertarget resource
805   std::queue<GLES::Shader*>              mDiscardShaderQueue;        ///< Discard queue of shaders
806   std::queue<GLES::Sampler*>             mDiscardSamplerQueue;       ///< Discard queue of samplers
807   std::queue<const GLES::CommandBuffer*> mDiscardCommandBufferQueue; ///< Discard queue of command buffers
808   std::queue<GLES::Framebuffer*>         mCreateFramebufferQueue;    ///< Create queue for framebuffer resource
809   std::queue<GLES::Framebuffer*>         mDiscardFramebufferQueue;   ///< Discard queue for framebuffer resource
810
811   std::queue<GLES::CommandBuffer*> mCommandQueue; ///< we may have more in the future
812
813   using TextureUpdateRequest = std::pair<TextureUpdateInfo, TextureUpdateSourceInfo>;
814   std::queue<TextureUpdateRequest> mTextureUpdateRequests;
815
816   std::queue<const GLES::Texture*> mTextureMipmapGenerationRequests; ///< Queue for texture mipmap generation requests
817
818   GLES::Context*                 mCurrentContext{nullptr}; ///< The current context
819   std::unique_ptr<GLES::Context> mContext{nullptr};        ///< Context object handling command buffers execution
820   using SurfaceContextPair = std::pair<Dali::RenderSurfaceInterface*, std::unique_ptr<GLES::Context>>;
821   std::vector<SurfaceContextPair> mSurfaceContexts; ///< Vector of surface context objects handling command buffers execution
822
823   std::unique_ptr<GLES::PipelineCache> mPipelineCache{nullptr}; ///< Internal pipeline cache
824
825   GLES::GLESVersion mGLESVersion{GLES::GLESVersion::GLES_20}; ///< Runtime supported GLES version
826   uint32_t          mTextureUploadTotalCPUMemoryUsed{0u};
827
828   bool mIsShuttingDown{false}; ///< Indicates whether the controller is shutting down
829
830   std::queue<const GLES::CommandBuffer*> mPresentationCommandBuffers{}; ///< Queue of reusable command buffers used by presentation engine
831
832   void* mSharedContext{nullptr}; ///< Shared EGL context
833
834   GLES::TextureDependencyChecker mTextureDependencyChecker; // Checks if FBO textures need syncing
835   GLES::SyncPool                 mSyncPool;
836   std::size_t                    mCapacity{0u}; ///< Memory Usage (of command buffers)
837 };
838
839 } // namespace Graphics
840
841 } // namespace Dali
842
843 #endif // DALI_EGL_GRAPHICS_CONTROLLER_H