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