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