Added framebuffer 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 "gles-context.h"
26 #include "gles-graphics-buffer.h"
27 #include "gles-graphics-command-buffer.h"
28 #include "gles-graphics-framebuffer.h"
29 #include "gles-graphics-pipeline-cache.h"
30 #include "gles-graphics-pipeline.h"
31 #include "gles-graphics-reflection.h"
32 #include "gles-graphics-sampler.h"
33 #include "gles-graphics-shader.h"
34 #include "gles-graphics-texture.h"
35 #include "gles-graphics-types.h"
36 #include "gles2-graphics-memory.h"
37
38 namespace Dali
39 {
40 namespace Integration
41 {
42 class GlAbstraction;
43 class GlSyncAbstraction;
44 class GlContextHelperAbstraction;
45 } // namespace Integration
46
47 namespace Graphics
48 {
49 namespace GLES
50 {
51 class CommandBuffer;
52 class PipelineCache;
53 } // namespace GLES
54
55 /**
56  * EGL Implementation of the graphics controller.
57  *
58  * Temporarily holds the old GL abstractions whilst dali-core is migrated to the new API.
59  */
60 DALI_IMPORT_API class EglGraphicsController : public Graphics::Controller
61 {
62 public:
63   /**
64    * @brief Deault constructor
65    */
66   EglGraphicsController() = default;
67
68   /**
69    * @brief Destructor
70    */
71   ~EglGraphicsController() override;
72
73   /**
74    * Initialize the GLES abstraction. This can be called from the main thread.
75    */
76   void InitializeGLES(Integration::GlAbstraction& glAbstraction);
77
78   /**
79    * Initialize with a reference to the GL abstractions.
80    *
81    * Note, this is now executed in the render thread, after core initialization
82    */
83   void Initialize(Integration::GlSyncAbstraction&          glSyncAbstraction,
84                   Integration::GlContextHelperAbstraction& glContextHelperAbstraction);
85
86   Integration::GlAbstraction&              GetGlAbstraction() override;
87   Integration::GlSyncAbstraction&          GetGlSyncAbstraction() override;
88   Integration::GlContextHelperAbstraction& GetGlContextHelperAbstraction() override;
89
90   /**
91    * @copydoc Dali::Graphics::SubmitCommandBuffers()
92    */
93   void SubmitCommandBuffers(const SubmitInfo& submitInfo) override;
94
95   /**
96    * @copydoc Dali::Graphics::PresentRenderTarget()
97    */
98   void PresentRenderTarget(RenderTarget* renderTarget) override
99   {
100   }
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     return nullptr;
200   }
201
202   /**
203    * @copydoc Dali::Graphics::CreateTexture()
204    */
205   Graphics::UniquePtr<Texture> CreateTexture(const TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Texture>&& oldTexture) override;
206
207   /**
208    * @copydoc Dali::Graphics::CreateFramebuffer()
209    */
210   Graphics::UniquePtr<Framebuffer> CreateFramebuffer(const FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Framebuffer>&& oldFramebuffer) override;
211
212   /**
213    * @copydoc Dali::Graphics::CreatePipeline()
214    */
215   Graphics::UniquePtr<Pipeline> CreatePipeline(const PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Pipeline>&& oldPipeline) override;
216
217   /**
218    * @copydoc Dali::Graphics::CreateProgram()
219    */
220   Graphics::UniquePtr<Program> CreateProgram(const ProgramCreateInfo& programCreateInfo, UniquePtr<Program>&& oldProgram) override;
221
222   /**
223    * @copydoc Dali::Graphics::CreateShader()
224    */
225   Graphics::UniquePtr<Shader> CreateShader(const ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Shader>&& oldShader) override;
226
227   /**
228    * @copydoc Dali::Graphics::CreateSampler()
229    */
230   Graphics::UniquePtr<Sampler> CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler) override;
231
232   /**
233    * @copydoc Dali::Graphics::CreateRenderTarget()
234    */
235   Graphics::UniquePtr<RenderTarget> CreateRenderTarget(const RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<RenderTarget>&& oldRenderTarget) override
236   {
237     return nullptr;
238   }
239
240   /**
241    * @copydoc Dali::Graphics::MapBufferRange()
242    */
243   Graphics::UniquePtr<Memory> MapBufferRange(const MapBufferInfo& mapInfo) override;
244
245   /**
246    * @copydoc Dali::Graphics::MapTextureRange()
247    */
248   Graphics::UniquePtr<Memory> MapTextureRange(const MapTextureInfo& mapInfo) override
249   {
250     return nullptr;
251   }
252
253   /**
254    * @copydoc Dali::Graphics::UnmapMemory()
255    */
256   void UnmapMemory(Graphics::UniquePtr<Memory> memory) override
257   {
258   }
259   /**
260    * @copydoc Dali::Graphics::GetTextureMemoryRequirements()
261    */
262   MemoryRequirements GetTextureMemoryRequirements(Texture& texture) const override
263   {
264     return {};
265   }
266
267   /**
268    * @copydoc Dali::Graphics::GetBufferMemoryRequirements()
269    */
270   MemoryRequirements GetBufferMemoryRequirements(Buffer& buffer) const override
271   {
272     return {};
273   }
274
275   /**
276    * @copydoc Dali::Graphics::GetTextureProperties()
277    */
278   const TextureProperties& GetTextureProperties(const Texture& texture) override
279   {
280     // for compiler not to moan
281     static TextureProperties dummy{};
282     return dummy;
283   }
284
285   /**
286    * @copydoc Dali::Graphics::Controller::GetPipelineReflection()
287    */
288
289   [[nodiscard]] const Reflection& GetProgramReflection(const Graphics::Program& program) override;
290
291   /**
292    * @copydoc Dali::Graphics::PipelineEquals()
293    */
294   [[nodiscard]] bool PipelineEquals(const Pipeline& pipeline0, const Pipeline& pipeline1) const override
295   {
296     return {};
297   }
298
299   [[nodiscard]] Integration::GlAbstraction* GetGL() const
300   {
301     if(mIsShuttingDown)
302     {
303       return nullptr;
304     }
305     return mGlAbstraction;
306   }
307
308   // Internal
309   void AddTexture(GLES::Texture& texture);
310
311   /**
312    * @brief Adds buffer to the creation queue
313    * @param buffer
314    */
315   void AddBuffer(GLES::Buffer& buffer);
316
317   /**
318    * @brief Adds framebuffer to the creation queue
319    * @param buffer
320    */
321   void AddFramebuffer(GLES::Framebuffer& framebuffer);
322
323   /**
324    * @brief Pushes Bufer to the discard queue
325    *
326    * Function is called from the UniquePtr custom deleter.
327    *
328    * @param[in] texture Pointer to the texture
329    */
330   void DiscardResource(GLES::Texture* texture)
331   {
332     mDiscardTextureQueue.push(texture);
333   }
334
335   /**
336    * @brief Pushes Buffer to the discard queue
337    *
338    * Function is called from the UniquePtr custom deleter.
339    *
340    * @param[in] buffer Pointer to the buffer object
341    */
342   void DiscardResource(GLES::Buffer* buffer)
343   {
344     mDiscardBufferQueue.push(buffer);
345   }
346
347   /**
348    * @brief Pushes framebuffer to the discard queue
349    *
350    * Function is called from the UniquePtr custom deleter.
351    *
352    * @param[in] framebuffer Pointer to the framebuffer object
353    */
354   void DiscardResource(GLES::Framebuffer* framebuffer)
355   {
356     mDiscardFramebufferQueue.push(framebuffer);
357   }
358
359   /**
360    * @brief Pushes Program to the discard queue
361    *
362    * Function is called from the UniquePtr custom deleter.
363    *
364    * @param[in] program Pointer to the program
365    */
366   void DiscardResource(GLES::Program* program)
367   {
368     mDiscardProgramQueue.push(program);
369   }
370
371   /**
372    * @brief Pushes Shader to the discard queue
373    *
374    * Function is called from the UniquePtr custom deleter.
375    *
376    * @param[in] program Pointer to the Shader
377    */
378   void DiscardResource(GLES::Shader* shader)
379   {
380     mDiscardShaderQueue.push(shader);
381   }
382
383   /**
384    * @brief Pushes CommandBuffer to the discard queue
385    *
386    * Function is called from the UniquePtr custom deleter.
387    *
388    * @param[in] program Pointer to the CommandBuffer
389    */
390   void DiscardResource(GLES::CommandBuffer* commandBuffer)
391   {
392     mDiscardCommandBufferQueue.push(commandBuffer);
393   }
394
395   /**
396    * @brief Pushes Sampler to the discard queue
397    *
398    * Function is called from the UniquePtr custom deleter.
399    *
400    * @param[in] program Pointer to the Sampler
401    */
402   void DiscardResource(GLES::Sampler* sampler)
403   {
404     mDiscardSamplerQueue.push(sampler);
405   }
406
407   /**
408    * @brief Pushes Pipeline to the discard queue
409    *
410    * Function is called from the UniquePtr custom deleter.
411    *
412    * @param[in] program Pointer to the pipeline
413    */
414   void DiscardResource(GLES::Pipeline* pipeline)
415   {
416     mDiscardPipelineQueue.push(pipeline);
417   }
418
419   /**
420    * @brief Flushes all pending updates
421    *
422    * Function flushes all pending resource constructions,
423    * executes command buffers and empties discard queues.
424    */
425   void Flush()
426   {
427     // Process creations
428     ProcessCreateQueues();
429
430     // Process updates
431     ProcessTextureUpdateQueue();
432
433     // Process main command queue
434     ProcessCommandQueues();
435
436     // Process discards
437     ProcessDiscardQueues();
438
439     // Flush pipeline cache to remove unused pipelines
440     if(mPipelineCache)
441     {
442       mPipelineCache->FlushCache();
443     }
444   }
445
446   // Test update to tick controller, usually it will run own thread
447   void ProcessDiscardQueues();
448
449   /**
450    * @brief Processes a create queue for type specified
451    *
452    * @param[in,out] queue Reference to the create queue
453    */
454   template<class T>
455   void ProcessCreateQueue(T& queue)
456   {
457     while(!queue.empty())
458     {
459       auto* object = queue.front();
460       queue.pop();
461
462       // Initialize texture
463       if(!object->InitializeResource())
464       {
465         // TODO: handle error
466       }
467     }
468   }
469
470   /**
471    * @brief Processes a create queue for type specified
472    *
473    * @param[in,out] queue Reference to the create queue
474    */
475   template<class U, class T>
476   void ProcessDiscardQueue(T& queue)
477   {
478     while(!queue.empty())
479     {
480       auto* object = queue.front();
481
482       // Destroy
483       object->DestroyResource();
484
485       // Free
486       auto* clbk = object->GetCreateInfo().allocationCallbacks;
487       if(clbk)
488       {
489         // Call destructor
490         object->~U();
491
492         // Free memory
493         clbk->freeCallback(object, clbk->userData);
494       }
495       else
496       {
497         delete object;
498       }
499       queue.pop();
500     }
501   }
502
503   /**
504    * @brief Processes all resource create queues
505    */
506   void ProcessCreateQueues();
507
508   /**
509    * @brief Process command queues and buffers
510    */
511   void ProcessCommandQueues();
512
513   /**
514    * @brief Executes all pending texture updates
515    */
516   void ProcessTextureUpdateQueue();
517
518   /**
519    * @brief Returns program custom parameter
520    *
521    * This function can be used as a backdoor in order to retrieve
522    * certain data out of implementation
523    *
524    * @param[in] program Valid Program object
525    * @param parameterId Integer id of parameter
526    * @param outData Output data
527    * @return True if parameter retrieved
528    */
529   bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) override;
530
531   /**
532    * @brief Returns pipeline cache object
533    *
534    * @return Valid pipeline cache object
535    */
536   [[nodiscard]] GLES::PipelineCache& GetPipelineCache() const;
537
538   /**
539    * @brief Returns runtime supported GLES version
540    *
541    * @return GLES version enum
542    */
543   GLES::GLESVersion GetGLESVersion() const
544   {
545     // TODO: return proper version but for now we can
546     // test fallbacks
547     return GLES::GLESVersion::GLES_20;
548   }
549
550   bool IsShuttingDown() const
551   {
552     return mIsShuttingDown;
553   }
554
555 private:
556   Integration::GlAbstraction*              mGlAbstraction{nullptr};
557   Integration::GlSyncAbstraction*          mGlSyncAbstraction{nullptr};
558   Integration::GlContextHelperAbstraction* mGlContextHelperAbstraction{nullptr};
559
560   std::queue<GLES::Texture*> mCreateTextureQueue;  ///< Create queue for texture resource
561   std::queue<GLES::Texture*> mDiscardTextureQueue; ///< Discard queue for texture resource
562
563   std::queue<GLES::Buffer*> mCreateBufferQueue;  ///< Create queue for buffer resource
564   std::queue<GLES::Buffer*> mDiscardBufferQueue; ///< Discard queue for buffer resource
565
566   std::queue<GLES::Program*>       mDiscardProgramQueue;       ///< Discard queue for program resource
567   std::queue<GLES::Pipeline*>      mDiscardPipelineQueue;      ///< Discard queue of pipelines
568   std::queue<GLES::Shader*>        mDiscardShaderQueue;        ///< Discard queue of shaders
569   std::queue<GLES::Sampler*>       mDiscardSamplerQueue;       ///< Discard queue of samplers
570   std::queue<GLES::CommandBuffer*> mDiscardCommandBufferQueue; ///< Discard queue of command buffers
571   std::queue<GLES::Framebuffer*>   mCreateFramebufferQueue;    ///< Create queue for framebuffer resource
572   std::queue<GLES::Framebuffer*>   mDiscardFramebufferQueue;   ///< Discard queue for framebuffer resource
573
574   std::queue<GLES::CommandBuffer*> mCommandQueue; ///< we may have more in the future
575
576   using TextureUpdateRequest = std::pair<TextureUpdateInfo, TextureUpdateSourceInfo>;
577   std::queue<TextureUpdateRequest> mTextureUpdateRequests;
578
579   std::unique_ptr<GLES::Context> mContext{nullptr}; ///< Context object handling command buffers execution
580
581   std::unique_ptr<GLES::PipelineCache> mPipelineCache{nullptr}; ///< Internal pipeline cache
582
583   bool mIsShuttingDown{false}; ///< Indicates whether the controller is shutting down
584 };
585
586 } // namespace Graphics
587
588 } // namespace Dali
589
590 #endif //DALI_EGL_GRAPHICS_CONTROLLER_H