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