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