Multiple context support
[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/internal/graphics/common/graphics-interface.h>
26 #include "gles-context.h"
27 #include "gles-graphics-buffer.h"
28 #include "gles-graphics-command-buffer.h"
29 #include "gles-graphics-framebuffer.h"
30 #include "gles-graphics-pipeline-cache.h"
31 #include "gles-graphics-pipeline.h"
32 #include "gles-graphics-reflection.h"
33 #include "gles-graphics-sampler.h"
34 #include "gles-graphics-shader.h"
35 #include "gles-graphics-texture.h"
36 #include "gles-graphics-types.h"
37 #include "gles2-graphics-memory.h"
38
39 namespace Dali
40 {
41 namespace Integration
42 {
43 class GlAbstraction;
44 class GlSyncAbstraction;
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 DALI_IMPORT_API 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::GlSyncAbstraction&          glSyncAbstraction,
85                   Integration::GlContextHelperAbstraction& glContextHelperAbstraction,
86                   Internal::Adaptor::GraphicsInterface&    graphicsInterface);
87
88   Integration::GlAbstraction&              GetGlAbstraction() override;
89   Integration::GlSyncAbstraction&          GetGlSyncAbstraction() override;
90   Integration::GlContextHelperAbstraction& GetGlContextHelperAbstraction() override;
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
104   /**
105    * @copydoc Dali::Graphics::WaitIdle()
106    */
107   void WaitIdle() override
108   {
109   }
110
111   /**
112    * @copydoc Dali::Graphics::Pause()
113    */
114   void Pause() override
115   {
116   }
117
118   /**
119    * @copydoc Dali::Graphics::Resume()
120    */
121   void Resume() override
122   {
123   }
124
125   /**
126    * @copydoc Dali::Graphics::Shutdown()
127    */
128   void Shutdown() override
129   {
130     mIsShuttingDown = true;
131   }
132
133   /**
134    * @copydoc Dali::Graphics::Destroy()
135    */
136   void Destroy() override
137   {
138     // Final flush
139     Flush();
140   }
141
142   /**
143    * @copydoc Dali::Graphics::UpdateTextures()
144    */
145   void UpdateTextures(const std::vector<TextureUpdateInfo>&       updateInfoList,
146                       const std::vector<TextureUpdateSourceInfo>& sourceList) override;
147
148   /**
149    * @copydoc Dali::Graphics::EnableDepthStencilBuffer()
150    */
151   bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override
152   {
153     return {};
154   }
155
156   /**
157    * @copydoc Dali::Graphics::RunGarbageCollector()
158    */
159   void RunGarbageCollector(size_t numberOfDiscardedRenderers) override
160   {
161   }
162
163   /**
164    * @copydoc Dali::Graphics::DiscardUnusedResources()
165    */
166   void DiscardUnusedResources() override
167   {
168   }
169
170   /**
171    * @copydoc Dali::Graphics::IsDiscardQueueEmpty()
172    */
173   bool IsDiscardQueueEmpty() override
174   {
175     return {};
176   }
177
178   /**
179    * @copydoc Dali::Graphics::IsDrawOnResumeRequired()
180    */
181   bool IsDrawOnResumeRequired() override
182   {
183     return {};
184   }
185
186   /**
187    * @copydoc Dali::Graphics::CreateBuffer()
188    */
189   Graphics::UniquePtr<Buffer> CreateBuffer(const BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Buffer>&& oldBuffer) override;
190
191   /**
192    * @copydoc Dali::Graphics::CreateCommandBuffer()
193    */
194   Graphics::UniquePtr<CommandBuffer> CreateCommandBuffer(const CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<CommandBuffer>&& oldCommandBuffer) override;
195
196   /**
197    * @copydoc Dali::Graphics::CreateRenderPass()
198    */
199   Graphics::UniquePtr<RenderPass> CreateRenderPass(const RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<RenderPass>&& oldRenderPass) override;
200
201   /**
202    * @copydoc Dali::Graphics::CreateTexture()
203    */
204   Graphics::UniquePtr<Texture> CreateTexture(const TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Texture>&& oldTexture) override;
205
206   /**
207    * @copydoc Dali::Graphics::CreateFramebuffer()
208    */
209   Graphics::UniquePtr<Framebuffer> CreateFramebuffer(const FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Framebuffer>&& oldFramebuffer) override;
210
211   /**
212    * @copydoc Dali::Graphics::CreatePipeline()
213    */
214   Graphics::UniquePtr<Pipeline> CreatePipeline(const PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Pipeline>&& oldPipeline) override;
215
216   /**
217    * @copydoc Dali::Graphics::CreateProgram()
218    */
219   Graphics::UniquePtr<Program> CreateProgram(const ProgramCreateInfo& programCreateInfo, UniquePtr<Program>&& oldProgram) override;
220
221   /**
222    * @copydoc Dali::Graphics::CreateShader()
223    */
224   Graphics::UniquePtr<Shader> CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader) override;
225
226   /**
227    * @copydoc Dali::Graphics::CreateSampler()
228    */
229   Graphics::UniquePtr<Sampler> CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler) override;
230
231   /**
232    * @copydoc Dali::Graphics::CreateRenderTarget()
233    */
234   Graphics::UniquePtr<RenderTarget> CreateRenderTarget(const RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<RenderTarget>&& oldRenderTarget) override;
235
236   /**
237    * @copydoc Dali::Graphics::MapBufferRange()
238    */
239   Graphics::UniquePtr<Memory> MapBufferRange(const MapBufferInfo& mapInfo) override;
240
241   /**
242    * @copydoc Dali::Graphics::MapTextureRange()
243    */
244   Graphics::UniquePtr<Memory> MapTextureRange(const MapTextureInfo& mapInfo) override
245   {
246     return nullptr;
247   }
248
249   /**
250    * @copydoc Dali::Graphics::UnmapMemory()
251    */
252   void UnmapMemory(Graphics::UniquePtr<Memory> memory) override
253   {
254   }
255   /**
256    * @copydoc Dali::Graphics::GetTextureMemoryRequirements()
257    */
258   MemoryRequirements GetTextureMemoryRequirements(Texture& texture) const override
259   {
260     return {};
261   }
262
263   /**
264    * @copydoc Dali::Graphics::GetBufferMemoryRequirements()
265    */
266   MemoryRequirements GetBufferMemoryRequirements(Buffer& buffer) const override
267   {
268     return {};
269   }
270
271   /**
272    * @copydoc Dali::Graphics::GetTextureProperties()
273    */
274   const TextureProperties& GetTextureProperties(const Texture& texture) override
275   {
276     // for compiler not to moan
277     static TextureProperties dummy{};
278     return dummy;
279   }
280
281   /**
282    * @copydoc Dali::Graphics::Controller::GetPipelineReflection()
283    */
284
285   [[nodiscard]] const Reflection& GetProgramReflection(const Graphics::Program& program) override;
286
287   /**
288    * @copydoc Dali::Graphics::PipelineEquals()
289    */
290   [[nodiscard]] bool PipelineEquals(const Pipeline& pipeline0, const Pipeline& pipeline1) const override
291   {
292     return {};
293   }
294
295   [[nodiscard]] Integration::GlAbstraction* GetGL() const
296   {
297     if(mIsShuttingDown)
298     {
299       return nullptr;
300     }
301     return mGlAbstraction;
302   }
303
304   [[nodiscard]] Internal::Adaptor::GraphicsInterface* GetGraphicsInterface() const
305   {
306     return mGraphics;
307   }
308
309   // Internal
310   void AddTexture(GLES::Texture& texture);
311
312   /**
313    * @brief Adds buffer to the creation queue
314    * @param buffer
315    */
316   void AddBuffer(GLES::Buffer& buffer);
317
318   /**
319    * @brief Adds framebuffer to the creation queue
320    * @param buffer
321    */
322   void AddFramebuffer(GLES::Framebuffer& framebuffer);
323
324   /**
325    * @brief Pushes Bufer to the discard queue
326    *
327    * Function is called from the UniquePtr custom deleter.
328    *
329    * @param[in] texture Pointer to the texture
330    */
331   void DiscardResource(GLES::Texture* texture)
332   {
333     mDiscardTextureQueue.push(texture);
334   }
335
336   /**
337    * @brief Pushes Buffer to the discard queue
338    *
339    * Function is called from the UniquePtr custom deleter.
340    *
341    * @param[in] buffer Pointer to the buffer object
342    */
343   void DiscardResource(GLES::Buffer* buffer)
344   {
345     mDiscardBufferQueue.push(buffer);
346   }
347
348   /**
349    * @brief Pushes framebuffer to the discard queue
350    *
351    * Function is called from the UniquePtr custom deleter.
352    *
353    * @param[in] framebuffer Pointer to the framebuffer object
354    */
355   void DiscardResource(GLES::Framebuffer* framebuffer)
356   {
357     mDiscardFramebufferQueue.push(framebuffer);
358   }
359
360   /**
361    * @brief Pushes Program to the discard queue
362    *
363    * Function is called from the UniquePtr custom deleter.
364    *
365    * @param[in] program Pointer to the program
366    */
367   void DiscardResource(GLES::Program* program)
368   {
369     mDiscardProgramQueue.push(program);
370   }
371
372   /**
373    * @brief Pushes Shader to the discard queue
374    *
375    * Function is called from the UniquePtr custom deleter.
376    *
377    * @param[in] program Pointer to the Shader
378    */
379   void DiscardResource(GLES::Shader* shader)
380   {
381     mDiscardShaderQueue.push(shader);
382   }
383
384   /**
385    * @brief Pushes CommandBuffer to the discard queue
386    *
387    * Function is called from the UniquePtr custom deleter.
388    *
389    * @param[in] program Pointer to the CommandBuffer
390    */
391   void DiscardResource(GLES::CommandBuffer* commandBuffer)
392   {
393     mDiscardCommandBufferQueue.push(commandBuffer);
394   }
395
396   /**
397    * @brief Pushes Sampler to the discard queue
398    *
399    * Function is called from the UniquePtr custom deleter.
400    *
401    * @param[in] program Pointer to the Sampler
402    */
403   void DiscardResource(GLES::Sampler* sampler)
404   {
405     mDiscardSamplerQueue.push(sampler);
406   }
407
408   /**
409    * @brief Pushes Pipeline to the discard queue
410    *
411    * Function is called from the UniquePtr custom deleter.
412    *
413    * @param[in] program Pointer to the pipeline
414    */
415   void DiscardResource(GLES::Pipeline* pipeline)
416   {
417     mDiscardPipelineQueue.push(pipeline);
418   }
419
420   /**
421    * @brief Flushes all pending updates
422    *
423    * Function flushes all pending resource constructions,
424    * executes command buffers and empties discard queues.
425    */
426   void Flush()
427   {
428     mGraphics->ActivateResourceContext();
429
430     // Process creations
431     ProcessCreateQueues();
432
433     // Process updates
434     ProcessTextureUpdateQueue();
435
436     // Process main command queue
437     ProcessCommandQueues();
438
439     // Process discards
440     ProcessDiscardQueues();
441
442     // Flush pipeline cache to remove unused pipelines
443     if(mPipelineCache)
444     {
445       mPipelineCache->FlushCache();
446     }
447   }
448
449   // Test update to tick controller, usually it will run own thread
450   void ProcessDiscardQueues();
451
452   /**
453    * @brief Processes a create queue for type specified
454    *
455    * @param[in,out] queue Reference to the create queue
456    */
457   template<class T>
458   void ProcessCreateQueue(T& queue)
459   {
460     while(!queue.empty())
461     {
462       auto* object = queue.front();
463       queue.pop();
464
465       // Initialize texture
466       if(!object->InitializeResource())
467       {
468         // TODO: handle error
469       }
470     }
471   }
472
473   /**
474    * @brief Processes a create queue for type specified
475    *
476    * @param[in,out] queue Reference to the create queue
477    */
478   template<class U, class T>
479   void ProcessDiscardQueue(T& queue)
480   {
481     while(!queue.empty())
482     {
483       auto* object = queue.front();
484
485       // Destroy
486       object->DestroyResource();
487
488       // Free
489       auto* clbk = object->GetCreateInfo().allocationCallbacks;
490       if(clbk)
491       {
492         // Call destructor
493         object->~U();
494
495         // Free memory
496         clbk->freeCallback(object, clbk->userData);
497       }
498       else
499       {
500         delete object;
501       }
502       queue.pop();
503     }
504   }
505
506   /**
507    * @brief Processes all resource create queues
508    */
509   void ProcessCreateQueues();
510
511   /**
512    * @brief Process command queues and buffers
513    */
514   void ProcessCommandQueues();
515
516   /**
517    * @brief Executes all pending texture updates
518    */
519   void ProcessTextureUpdateQueue();
520
521   /**
522    * @brief Returns program custom parameter
523    *
524    * This function can be used as a backdoor in order to retrieve
525    * certain data out of implementation
526    *
527    * @param[in] program Valid Program object
528    * @param parameterId Integer id of parameter
529    * @param outData Output data
530    * @return True if parameter retrieved
531    */
532   bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) override;
533
534   /**
535    * @brief Returns pipeline cache object
536    *
537    * @return Valid pipeline cache object
538    */
539   [[nodiscard]] GLES::PipelineCache& GetPipelineCache() const;
540
541   /**
542    * @brief Returns runtime supported GLES version
543    *
544    * @return GLES version enum
545    */
546   GLES::GLESVersion GetGLESVersion() const
547   {
548     // TODO: return proper version but for now we can
549     // test fallbacks
550     return GLES::GLESVersion::GLES_20;
551   }
552
553   bool IsShuttingDown() const
554   {
555     return mIsShuttingDown;
556   }
557
558   void ProcessCommandBuffer(GLES::CommandBuffer& commandBuffer);
559
560 private:
561   Integration::GlAbstraction*              mGlAbstraction{nullptr};
562   Integration::GlSyncAbstraction*          mGlSyncAbstraction{nullptr};
563   Integration::GlContextHelperAbstraction* mGlContextHelperAbstraction{nullptr};
564
565   Internal::Adaptor::GraphicsInterface* mGraphics{nullptr};
566
567   std::queue<GLES::Texture*> mCreateTextureQueue;  ///< Create queue for texture resource
568   std::queue<GLES::Texture*> mDiscardTextureQueue; ///< Discard queue for texture resource
569
570   std::queue<GLES::Buffer*> mCreateBufferQueue;  ///< Create queue for buffer resource
571   std::queue<GLES::Buffer*> mDiscardBufferQueue; ///< Discard queue for buffer resource
572
573   std::queue<GLES::Program*>       mDiscardProgramQueue;       ///< Discard queue for program resource
574   std::queue<GLES::Pipeline*>      mDiscardPipelineQueue;      ///< Discard queue of pipelines
575   std::queue<GLES::Shader*>        mDiscardShaderQueue;        ///< Discard queue of shaders
576   std::queue<GLES::Sampler*>       mDiscardSamplerQueue;       ///< Discard queue of samplers
577   std::queue<GLES::CommandBuffer*> mDiscardCommandBufferQueue; ///< Discard queue of command buffers
578   std::queue<GLES::Framebuffer*>   mCreateFramebufferQueue;    ///< Create queue for framebuffer resource
579   std::queue<GLES::Framebuffer*>   mDiscardFramebufferQueue;   ///< Discard queue for framebuffer resource
580
581   std::queue<GLES::CommandBuffer*> mCommandQueue; ///< we may have more in the future
582
583   using TextureUpdateRequest = std::pair<TextureUpdateInfo, TextureUpdateSourceInfo>;
584   std::queue<TextureUpdateRequest> mTextureUpdateRequests;
585
586   std::unique_ptr<GLES::Context> mContext{nullptr}; ///< Context object handling command buffers execution
587
588   std::unique_ptr<GLES::PipelineCache> mPipelineCache{nullptr}; ///< Internal pipeline cache
589
590   bool mIsShuttingDown{false}; ///< Indicates whether the controller is shutting down
591
592   // todo: to be removed after renderpass
593   const Graphics::Framebuffer* currentFramebuffer{nullptr};
594 };
595
596 } // namespace Graphics
597
598 } // namespace Dali
599
600 #endif //DALI_EGL_GRAPHICS_CONTROLLER_H