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