[Scene3D] Let we allow to release PixelData memory after upload for 3D cache
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-graphics-controller.h
1 #ifndef TEST_GRAPHICS_CONTROLLER_H
2 #define TEST_GRAPHICS_CONTROLLER_H
3
4 /*
5  * Copyright (c) 2023 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 #include <dali/graphics-api/graphics-controller.h>
21 #include <unordered_map>
22 #include "test-gl-abstraction.h"
23 #include "test-gl-context-helper-abstraction.h"
24 #include "test-graphics-command-buffer.h"
25 #include "test-graphics-program.h"
26 #include "test-graphics-reflection.h"
27 #include "test-graphics-sync-impl.h"
28
29 namespace Dali
30 {
31 std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo);
32 std::ostream& operator<<(std::ostream& o, const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo);
33 std::ostream& operator<<(std::ostream& o, const Graphics::TextureType& textureType);
34 std::ostream& operator<<(std::ostream& o, const Graphics::Extent2D extent);
35 std::ostream& operator<<(std::ostream& o, const Graphics::TextureCreateInfo& createInfo);
36 std::ostream& operator<<(std::ostream& o, Graphics::SamplerAddressMode addressMode);
37 std::ostream& operator<<(std::ostream& o, Graphics::SamplerFilter filterMode);
38 std::ostream& operator<<(std::ostream& o, Graphics::SamplerMipmapMode mipmapMode);
39 std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& createInfo);
40
41 template<typename T>
42 T* Uncast(const Graphics::CommandBuffer* object)
43 {
44   return const_cast<T*>(static_cast<const T*>(object));
45 }
46
47 template<typename T>
48 T* Uncast(const Graphics::Texture* object)
49 {
50   return const_cast<T*>(static_cast<const T*>(object));
51 }
52
53 template<typename T>
54 T* Uncast(const Graphics::Sampler* object)
55 {
56   return const_cast<T*>(static_cast<const T*>(object));
57 }
58
59 template<typename T>
60 T* Uncast(const Graphics::Buffer* object)
61 {
62   return const_cast<T*>(static_cast<const T*>(object));
63 }
64
65 template<typename T>
66 T* Uncast(const Graphics::Shader* object)
67 {
68   return const_cast<T*>(static_cast<const T*>(object));
69 }
70
71 template<typename T>
72 T* Uncast(const Graphics::Framebuffer* object)
73 {
74   return const_cast<T*>(static_cast<const T*>(object));
75 }
76
77 template<typename T>
78 T* Uncast(const Graphics::Pipeline* object)
79 {
80   return const_cast<T*>(static_cast<const T*>(object));
81 }
82
83 template<typename T>
84 T* Uncast(const Graphics::RenderTarget* object)
85 {
86   return const_cast<T*>(static_cast<const T*>(object));
87 }
88
89 template<typename T>
90 T* Uncast(const Graphics::SyncObject* object)
91 {
92   return const_cast<T*>(static_cast<const T*>(object));
93 }
94
95 class TestGraphicsController : public Dali::Graphics::Controller
96 {
97 public:
98   TestGraphicsController();
99
100   virtual ~TestGraphicsController() = default;
101
102   void Initialize()
103   {
104     mGl.Initialize();
105   }
106
107   Integration::GlAbstraction& GetGlAbstraction() override
108   {
109     return mGl;
110   }
111
112   Integration::GlContextHelperAbstraction& GetGlContextHelperAbstraction() override
113   {
114     return mGlContextHelperAbstraction;
115   }
116
117   TestGraphicsSyncImplementation& GetGraphicsSyncImpl()
118   {
119     return mGraphicsSyncImpl;
120   }
121
122   void SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo) override;
123
124   /**
125    * @brief Presents render target
126    * @param renderTarget render target to present
127    */
128   void PresentRenderTarget(Graphics::RenderTarget* renderTarget) override;
129
130   /**
131    * @brief Waits until the GPU is idle
132    */
133   void WaitIdle() override;
134
135   /**
136    * @brief Lifecycle pause event
137    */
138   void Pause() override;
139
140   /**
141    * @brief Lifecycle resume event
142    */
143   void Resume() override;
144
145   /**
146    * @brief Lifecycle shutdown event
147    */
148   void Shutdown() override;
149
150   /**
151    * @brief Lifecycle destroy event
152    */
153   void Destroy() override;
154
155   /**
156    * @brief Executes batch update of textures
157    *
158    * This function may perform full or partial update of many textures.
159    * The data source may come from:
160    * - CPU memory (client side)
161    * - GPU memory (another Texture or Buffer)
162    *
163    * UpdateTextures() is the only way to update unmappable Texture objects.
164    * It is recommended to batch updates as it may help with optimizing
165    * memory transfers based on dependencies.
166    *
167    */
168   void UpdateTextures(const std::vector<Graphics::TextureUpdateInfo>&       updateInfoList,
169                       const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList) override;
170
171   /**
172    * Auto generates mipmaps for the texture
173    * @param[in] texture The texture
174    */
175   void GenerateTextureMipmaps(const Graphics::Texture& texture) override;
176
177   /**
178    * TBD: do we need those functions in the new implementation?
179    */
180   bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override;
181
182   void RunGarbageCollector(size_t numberOfDiscardedRenderers) override;
183
184   void DiscardUnusedResources() override;
185
186   bool IsDiscardQueueEmpty() override;
187
188   /**
189    * @brief Test if the graphics subsystem has resumed & should force a draw
190    *
191    * @return true if the graphics subsystem requires a re-draw
192    */
193   bool IsDrawOnResumeRequired() override;
194
195   /**
196    * @brief Creates new Buffer object
197    *
198    * The Buffer object is created with underlying memory. The Buffer
199    * specification is immutable. Based on the BufferCreateInfo::usage,
200    * the memory may be client-side mappable or not.
201    *
202    * The old buffer may be passed as BufferCreateInfo::oldbuffer, however,
203    * it's up to the implementation whether the object will be reused or
204    * discarded and replaced by the new one.
205    *
206    * @param[in] bufferCreateInfo The valid BufferCreateInfo structure
207    * @return pointer to the Buffer object
208    */
209   Graphics::UniquePtr<Graphics::Buffer> CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer) override;
210
211   void DiscardBuffer(TestGraphicsBuffer* buffer);
212
213   /**
214    * @brief Creates new CommandBuffer object
215    *
216    * @param[in] bufferCreateInfo The valid BufferCreateInfo structure
217    * @return pointer to the CommandBuffer object
218    */
219   Graphics::UniquePtr<Graphics::CommandBuffer> CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer) override;
220
221   /**
222    * @brief Creates new RenderPass object
223    *
224    * @param[in] renderPassCreateInfo The valid RenderPassCreateInfo structure
225    * @return pointer to the RenderPass object
226    */
227   Graphics::UniquePtr<Graphics::RenderPass> CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass) override;
228
229   /**
230    * @brief Creates new Texture object
231    *
232    * @param[in] textureCreateInfo The valid TextureCreateInfo structure
233    * @return pointer to the TextureCreateInfo object
234    */
235   Graphics::UniquePtr<Graphics::Texture> CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture) override;
236
237   /**
238    * @brief Creates new Framebuffer object
239    *
240    * @param[in] framebufferCreateInfo The valid FramebufferCreateInfo structure
241    * @return pointer to the Framebuffer object
242    */
243   Graphics::UniquePtr<Graphics::Framebuffer> CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer) override;
244
245   /**
246    * @brief Creates new Pipeline object
247    *
248    * @param[in] pipelineCreateInfo The valid PipelineCreateInfo structure
249    * @return pointer to the Pipeline object
250    */
251   Graphics::UniquePtr<Graphics::Pipeline> CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline) override;
252
253   /**
254    * @brief Creates new Program object
255    *
256    * @param[in] programCreateInfo The valid ProgramCreateInfo structure
257    * @return pointer to the Program object
258    */
259   Graphics::UniquePtr<Graphics::Program> CreateProgram(const Graphics::ProgramCreateInfo& programCreateInfo, Graphics::UniquePtr<Graphics::Program>&& oldProgram) override;
260
261   /**
262    * @brief Creates new Shader object
263    *
264    * @param[in] shaderCreateInfo The valid ShaderCreateInfo structure
265    * @return pointer to the Shader object
266    */
267   Graphics::UniquePtr<Graphics::Shader> CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader) override;
268
269   /**
270    * @brief Creates new Sampler object
271    *
272    * @param[in] samplerCreateInfo The valid SamplerCreateInfo structure
273    * @return pointer to the Sampler object
274    */
275   Graphics::UniquePtr<Graphics::Sampler> CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Graphics::Sampler>&& oldSampler) override;
276
277   /**
278    * @brief Creates new RenderTarget object
279    *
280    * @param[in] renderTargetCreateInfo The valid RenderTargetCreateInfo structure
281    * @return pointer to the RenderTarget object
282    */
283   Graphics::UniquePtr<Graphics::RenderTarget> CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget) override;
284
285   /**
286    * @brief Creates new sync object
287    * Could add timeout etc to createinfo... but nah.
288    *
289    * @return pointer to the SyncObject
290    */
291   Graphics::UniquePtr<Graphics::SyncObject> CreateSyncObject(const Graphics::SyncObjectCreateInfo&       syncObjectCreateInfo,
292                                                              Graphics::UniquePtr<Graphics::SyncObject>&& oldSyncObject) override;
293
294   /**
295    * @brief Maps memory associated with Buffer object
296    *
297    * @param[in] mapInfo Filled details of mapped resource
298    *
299    * @return Returns pointer to Memory object or nullptr on error
300    */
301   Graphics::UniquePtr<Graphics::Memory> MapBufferRange(const Graphics::MapBufferInfo& mapInfo) override;
302
303   /**
304    * @brief Maps memory associated with the texture.
305    *
306    * Only Texture objects that are backed with linear memory (staging memory) can be mapped.
307    * Example:
308    * 1) GLES implementation may create PBO object as staging memory and couple it
309    * with the texture. Texture can be mapped and the memory can be read/write on demand.
310    *
311    * 2) Vulkan implementation may allocate DeviceMemory and use linear layout.
312    *
313    * @param[in] mapInfo Filled details of mapped resource
314    *
315    * @return Valid Memory object or nullptr on error
316    */
317   Graphics::UniquePtr<Graphics::Memory> MapTextureRange(const Graphics::MapTextureInfo& mapInfo) override;
318
319   /**
320    * @brief Unmaps memory and discards Memory object
321    *
322    * This function automatically removes lock if Memory has been
323    * previously locked.
324    *
325    * @param[in] memory Valid and previously mapped Memory object
326    */
327   void UnmapMemory(Graphics::UniquePtr<Graphics::Memory> memory) override;
328
329   /**
330    * @brief Returns memory requirements of the Texture object.
331    *
332    * Call this function whenever it's necessary to know how much memory
333    * is needed to store all the texture data and what memory alignment
334    * the data should follow.
335    *
336    * @return Returns memory requirements of Texture
337    */
338   Graphics::MemoryRequirements GetTextureMemoryRequirements(Graphics::Texture& texture) const override;
339
340   /**
341    * @brief Returns memory requirements of the Buffer object.
342    *
343    * Call this function whenever it's necessary to know how much memory
344    * is needed to store all the buffer data and what memory alignment
345    * the data should follow.
346    *
347    * @return Returns memory requirements of Buffer
348    */
349   Graphics::MemoryRequirements GetBufferMemoryRequirements(Graphics::Buffer& buffer) const override;
350
351   /**
352    * @brief Returns specification of the Texture object
353    *
354    * Function obtains specification of the Texture object. It may retrieve
355    * implementation dependent details like ie. whether the texture is
356    * emulated (for example, RGB emulated on RGBA), compressed etc.
357    *
358    * @return Returns the TextureProperties object
359    */
360   Graphics::TextureProperties GetTextureProperties(const Graphics::Texture& texture) override;
361
362   /**
363    * @brief Returns the reflection of the given program
364    *
365    * @param[in] program The program
366    * @return The reflection of the program
367    */
368   const Graphics::Reflection& GetProgramReflection(const Graphics::Program& program) override;
369
370   /**
371    * @brief Tests whether two Pipelines are the same.
372    *
373    * On the higher level, this function may help wit creating pipeline cache.
374    *
375    * @return true if pipeline objects match
376    */
377   bool PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const override;
378
379   /**
380    * @brief Retrieves program parameters
381    *
382    * This function can be used to retrieve data from internal implementation
383    *
384    * @param[in] program Valid program object
385    * @param[in] parameterId Integer parameter id
386    * @param[out] outData Pointer to output memory
387    * @return True on success
388    */
389   bool GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData) override;
390
391 public: // ResourceId relative API.
392   /**
393    * @brief Create Graphics::Texture as resourceId.
394    * The ownership of Graphics::Texture will be hold on this controller.
395    * @note If some Graphics::Texture already created before, assert.
396    * @post DiscardTextureFromResourceId() or ReleaseTextureFromResourceId() should be called when we don't use resourceId texture anymore.
397    *
398    * @param[in] resourceId The unique id of resouces.
399    * @return Pointer of Graphics::Texture, or nullptr if we fail to create.
400    */
401   Graphics::Texture* CreateTextureByResourceId(uint32_t resourceId, const Graphics::TextureCreateInfo& createInfo) override;
402
403   /**
404    * @brief Discard Graphics::Texture as resourceId.
405    *
406    * @param[in] resourceId The unique id of resouces.
407    */
408   void DiscardTextureFromResourceId(uint32_t resourceId) override;
409
410   /**
411    * @brief Get the Graphics::Texture as resourceId.
412    *
413    * @param[in] resourceId The unique id of resouces.
414    * @return Pointer of Graphics::Texture, or nullptr if there is no valid objects.
415    */
416   Graphics::Texture* GetTextureFromResourceId(uint32_t resourceId) override;
417
418   /**
419    * @brief Get the ownership of Graphics::Texture as resourceId.
420    *
421    * @param[in] resourceId The unique id of resouces.
422    * @return Pointer of Graphics::Texture.
423    */
424   Graphics::UniquePtr<Graphics::Texture> ReleaseTextureFromResourceId(uint32_t resourceId) override;
425
426 public: // Test Functions
427   void SetAutoAttrCreation(bool v)
428   {
429     mAutoAttrCreation = v;
430   }
431   bool AutoAttrCreation()
432   {
433     return mAutoAttrCreation;
434   }
435
436   void SetVertexFormats(Property::Array& vfs)
437   {
438     mVertexFormats = vfs;
439   }
440
441   void AddCustomUniforms(std::vector<UniformData>& customUniforms)
442   {
443     mCustomUniforms = customUniforms;
444   }
445
446   void AddCustomUniformBlock(const TestGraphicsReflection::TestUniformBlockInfo& blockInfo)
447   {
448     mCustomUniformBlocks.push_back(blockInfo);
449   }
450
451   void ClearSubmitStack()
452   {
453     mSubmitStack.clear();
454   }
455
456   void ProcessCommandBuffer(TestGraphicsCommandBuffer& commandBuffer);
457
458   void BindPipeline(TestGraphicsPipeline* pipeline);
459
460 public:
461   mutable TraceCallStack                    mCallStack;
462   mutable TraceCallStack                    mCommandBufferCallStack;
463   mutable TraceCallStack                    mFrameBufferCallStack;
464   mutable std::vector<Graphics::SubmitInfo> mSubmitStack;
465
466   TestGlAbstraction              mGl;
467   TestGraphicsSyncImplementation mGraphicsSyncImpl;
468   TestGlContextHelperAbstraction mGlContextHelperAbstraction;
469
470   bool            isDiscardQueueEmptyResult{true};
471   bool            isDrawOnResumeRequiredResult{true};
472   bool            mAutoAttrCreation{true};
473   Property::Array mVertexFormats;
474
475   struct ProgramCache
476   {
477     std::map<Graphics::PipelineStage, std::vector<uint8_t>> shaders;
478     TestGraphicsProgramImpl*                                programImpl;
479   };
480   std::vector<ProgramCache> mProgramCache;
481
482   std::vector<TestGraphicsBuffer*> mAllocatedBuffers;
483
484   std::unordered_map<uint32_t, Graphics::UniquePtr<Graphics::Texture>> mTextureUploadBindMapper;
485
486   struct PipelineCache
487   {
488   };
489
490   std::vector<UniformData>                                  mCustomUniforms;
491   std::vector<TestGraphicsReflection::TestUniformBlockInfo> mCustomUniformBlocks;
492 };
493
494 } // namespace Dali
495
496 #endif //TEST_GRAPHICS_CONTROLLER_H