Syncing test harness
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-graphics-command-buffer.h
1 #ifndef DALI_TEST_GRAPHICS_COMMAND_BUFFER_H
2 #define DALI_TEST_GRAPHICS_COMMAND_BUFFER_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 #include <dali/graphics-api/graphics-command-buffer-create-info.h>
21 #include <dali/graphics-api/graphics-command-buffer.h>
22 #include <dali/graphics-api/graphics-pipeline.h>
23 #include <dali/graphics-api/graphics-types.h>
24 #include <cstdint>
25 #include <vector>
26 #include "test-gl-abstraction.h"
27 #include "test-graphics-buffer.h"
28 #include "test-graphics-pipeline.h"
29 #include "test-trace-call-stack.h"
30
31 namespace Dali
32 {
33 class TestGraphicsTexture;
34 class TestGraphicsBuffer;
35 class TestGraphicsCommandBuffer;
36 class TestGraphicsSampler;
37 class TestGraphicsPipeline;
38
39 enum class CommandType
40 {
41   FLUSH                   = 1 << 0,
42   BIND_TEXTURES           = 1 << 1,
43   BIND_SAMPLERS           = 1 << 2,
44   BIND_VERTEX_BUFFERS     = 1 << 3,
45   BIND_INDEX_BUFFER       = 1 << 4,
46   BIND_UNIFORM_BUFFER     = 1 << 5,
47   BIND_PIPELINE           = 1 << 6,
48   DRAW                    = 1 << 7,
49   DRAW_INDEXED            = 1 << 8,
50   DRAW_INDEXED_INDIRECT   = 1 << 9,
51   SET_SCISSOR             = 1 << 10,
52   SET_SCISSOR_TEST        = 1 << 11,
53   SET_VIEWPORT            = 1 << 12,
54   SET_VIEWPORT_TEST       = 1 << 13,
55   BEGIN_RENDER_PASS       = 1 << 14,
56   END_RENDER_PASS         = 1 << 15,
57   EXECUTE_COMMAND_BUFFERS = 1 << 16
58 };
59
60 using CommandTypeMask = uint32_t;
61 template<typename T>
62 inline CommandTypeMask operator|(T flags, CommandType bit)
63 {
64   return static_cast<CommandTypeMask>(flags) | static_cast<CommandTypeMask>(bit);
65 }
66
67 /**
68  * @brief Descriptor of single buffer binding within
69  * command buffer.
70  */
71 struct VertexBufferBindingDescriptor
72 {
73   const TestGraphicsBuffer* buffer{nullptr};
74   uint32_t                  offset{0u};
75 };
76
77 /**
78  * @brief Descriptor of ix buffer binding within
79  * command buffer.
80  */
81 struct IndexBufferBindingDescriptor
82 {
83   const TestGraphicsBuffer* buffer{nullptr};
84   uint32_t                  offset{};
85   Graphics::Format          format{};
86 };
87
88 /**
89  * @brief Descriptor of uniform buffer binding within
90  * command buffer.
91  */
92 struct UniformBufferBindingDescriptor
93 {
94   const TestGraphicsBuffer* buffer{nullptr};
95   uint32_t                  binding{0u};
96   uint32_t                  offset{0u};
97   bool                      emulated; ///<true if UBO is emulated for old gfx API
98 };
99
100 /**
101  * @brief The descriptor of draw call
102  */
103 struct DrawCallDescriptor
104 {
105   /**
106    * @brief Enum specifying type of the draw call
107    */
108   enum class Type
109   {
110     DRAW,
111     DRAW_INDEXED,
112     DRAW_INDEXED_INDIRECT
113   };
114
115   Type type{}; ///< Type of the draw call
116
117   /**
118    * Union contains data for all types of draw calls.
119    */
120   union
121   {
122     /**
123      * @brief Vertex array draw
124      */
125     struct
126     {
127       uint32_t vertexCount;
128       uint32_t instanceCount;
129       uint32_t firstVertex;
130       uint32_t firstInstance;
131     } draw;
132
133     /**
134      * @brief Indexed draw
135      */
136     struct
137     {
138       uint32_t indexCount;
139       uint32_t instanceCount;
140       uint32_t firstIndex;
141       int32_t  vertexOffset;
142       uint32_t firstInstance;
143     } drawIndexed;
144
145     /**
146      * @brief Indexed draw indirect
147      */
148     struct
149     {
150       const TestGraphicsBuffer* buffer;
151       uint32_t                  offset;
152       uint32_t                  drawCount;
153       uint32_t                  stride;
154     } drawIndexedIndirect;
155   };
156 };
157
158 /**
159  * Command structure allocates memory to store a single command
160  */
161 struct Command
162 {
163   Command()
164   {
165   }
166
167   Command(CommandType type)
168   : type(type)
169   {
170     // do non-trivial initialization
171     switch(type)
172     {
173       case CommandType::BEGIN_RENDER_PASS:
174       {
175         new(&data.beginRenderPass) CommandData::BeginRenderPassDescriptor();
176         break;
177       }
178       default:
179       {
180       }
181     }
182   }
183
184   ~Command()
185   {
186     switch(type)
187     {
188       case CommandType::BEGIN_RENDER_PASS:
189       {
190         data.beginRenderPass.~BeginRenderPassDescriptor();
191         break;
192       }
193       default:
194       {
195         break;
196       }
197     }
198   }
199
200   /**
201    * @brief Copy constructor
202    * @param[in] rhs Command
203    */
204   Command(const Command& rhs)
205   {
206     switch(rhs.type)
207     {
208       case CommandType::BEGIN_RENDER_PASS:
209       {
210         new(&data.beginRenderPass) CommandData::BeginRenderPassDescriptor(rhs.data.beginRenderPass);
211         break;
212       }
213       case CommandType::END_RENDER_PASS:
214       {
215         data.endRenderPass = rhs.data.endRenderPass;
216         break;
217       }
218       case CommandType::EXECUTE_COMMAND_BUFFERS:
219       {
220         data.executeCommandBuffers = rhs.data.executeCommandBuffers;
221         break;
222       }
223
224       case CommandType::BIND_VERTEX_BUFFERS:
225       {
226         data.bindVertexBuffers = rhs.data.bindVertexBuffers;
227         break;
228       }
229       case CommandType::BIND_INDEX_BUFFER:
230       {
231         data.bindIndexBuffer = rhs.data.bindIndexBuffer;
232         break;
233       }
234       case CommandType::BIND_SAMPLERS:
235       {
236         data.bindSamplers = rhs.data.bindSamplers;
237         break;
238       }
239       case CommandType::BIND_TEXTURES:
240       {
241         data.bindTextures = rhs.data.bindTextures;
242         break;
243       }
244       case CommandType::BIND_PIPELINE:
245       {
246         data.bindPipeline = rhs.data.bindPipeline;
247         break;
248       }
249       case CommandType::BIND_UNIFORM_BUFFER:
250       {
251         data.bindUniformBuffers = rhs.data.bindUniformBuffers;
252         break;
253       }
254       case CommandType::DRAW:
255       {
256         data.draw.type = rhs.data.draw.type;
257         data.draw.draw = rhs.data.draw.draw;
258         break;
259       }
260       case CommandType::DRAW_INDEXED:
261       {
262         data.draw.type        = rhs.data.draw.type;
263         data.draw.drawIndexed = rhs.data.draw.drawIndexed;
264         break;
265       }
266       case CommandType::DRAW_INDEXED_INDIRECT:
267       {
268         data.draw.type                = rhs.data.draw.type;
269         data.draw.drawIndexedIndirect = rhs.data.draw.drawIndexedIndirect;
270         break;
271       }
272       case CommandType::FLUSH:
273       {
274         // Nothing to do
275         break;
276       }
277       case CommandType::SET_SCISSOR:
278       {
279         data.scissor.region = rhs.data.scissor.region;
280         break;
281       }
282       case CommandType::SET_SCISSOR_TEST:
283       {
284         data.scissorTest.enable = rhs.data.scissorTest.enable;
285         break;
286       }
287       case CommandType::SET_VIEWPORT:
288       {
289         data.viewport.region = rhs.data.viewport.region;
290         break;
291       }
292       case CommandType::SET_VIEWPORT_TEST:
293       {
294         data.viewportTest.enable = rhs.data.viewportTest.enable;
295         break;
296       }
297     }
298     type = rhs.type;
299   }
300
301   /**
302    * @brief move constructor
303    * @param[in] rhs Command
304    */
305   Command(Command&& rhs) noexcept
306   {
307     switch(rhs.type)
308     {
309       case CommandType::BEGIN_RENDER_PASS:
310       {
311         new(&data.beginRenderPass) CommandData::BeginRenderPassDescriptor(std::move(rhs.data.beginRenderPass));
312         break;
313       }
314       case CommandType::END_RENDER_PASS:
315       {
316         data.endRenderPass = std::move(rhs.data.endRenderPass);
317         break;
318       }
319       case CommandType::EXECUTE_COMMAND_BUFFERS:
320       {
321         data.executeCommandBuffers = std::move(rhs.data.executeCommandBuffers);
322         break;
323       }
324       case CommandType::BIND_VERTEX_BUFFERS:
325       {
326         data.bindVertexBuffers = std::move(rhs.data.bindVertexBuffers);
327         break;
328       }
329       case CommandType::BIND_INDEX_BUFFER:
330       {
331         data.bindIndexBuffer = rhs.data.bindIndexBuffer;
332         break;
333       }
334       case CommandType::BIND_UNIFORM_BUFFER:
335       {
336         data.bindUniformBuffers = std::move(rhs.data.bindUniformBuffers);
337         break;
338       }
339       case CommandType::BIND_SAMPLERS:
340       {
341         data.bindSamplers = std::move(rhs.data.bindSamplers);
342         break;
343       }
344       case CommandType::BIND_TEXTURES:
345       {
346         data.bindTextures = std::move(rhs.data.bindTextures);
347         break;
348       }
349       case CommandType::BIND_PIPELINE:
350       {
351         data.bindPipeline = rhs.data.bindPipeline;
352         break;
353       }
354       case CommandType::DRAW:
355       {
356         data.draw.type = rhs.data.draw.type;
357         data.draw.draw = rhs.data.draw.draw;
358         break;
359       }
360       case CommandType::DRAW_INDEXED:
361       {
362         data.draw.type        = rhs.data.draw.type;
363         data.draw.drawIndexed = rhs.data.draw.drawIndexed;
364         break;
365       }
366       case CommandType::DRAW_INDEXED_INDIRECT:
367       {
368         data.draw.type                = rhs.data.draw.type;
369         data.draw.drawIndexedIndirect = rhs.data.draw.drawIndexedIndirect;
370         break;
371       }
372       case CommandType::FLUSH:
373       {
374         // Nothing to do
375         break;
376       }
377       case CommandType::SET_SCISSOR:
378       {
379         data.scissor.region = rhs.data.scissor.region;
380         break;
381       }
382       case CommandType::SET_SCISSOR_TEST:
383       {
384         data.scissorTest.enable = rhs.data.scissorTest.enable;
385         break;
386       }
387       case CommandType::SET_VIEWPORT:
388       {
389         data.viewport.region = rhs.data.viewport.region;
390         break;
391       }
392       case CommandType::SET_VIEWPORT_TEST:
393       {
394         data.viewportTest.enable = rhs.data.viewportTest.enable;
395         break;
396       }
397     }
398     type = rhs.type;
399   }
400
401   CommandType type{CommandType::FLUSH}; ///< Type of command
402
403   union CommandData
404   {
405     CommandData()
406     {
407     }
408
409     ~CommandData()
410     {
411     } // do nothing
412
413     struct
414     {
415       std::vector<Graphics::TextureBinding> textureBindings;
416     } bindTextures{};
417
418     // BindSampler command
419     struct
420     {
421       std::vector<Graphics::SamplerBinding> samplerBindings;
422     } bindSamplers;
423
424     struct
425     {
426       using Binding = VertexBufferBindingDescriptor;
427       std::vector<Binding> vertexBufferBindings;
428     } bindVertexBuffers;
429
430     struct : public IndexBufferBindingDescriptor
431     {
432     } bindIndexBuffer;
433
434     struct
435     {
436       std::vector<UniformBufferBindingDescriptor> uniformBufferBindings{};
437       UniformBufferBindingDescriptor              standaloneUniformsBufferBinding{};
438     } bindUniformBuffers;
439
440     struct
441     {
442       const TestGraphicsPipeline* pipeline{nullptr};
443     } bindPipeline;
444
445     struct : public DrawCallDescriptor
446     {
447     } draw;
448
449     struct
450     {
451       Graphics::Rect2D region;
452     } scissor;
453     struct
454     {
455       bool enable;
456     } scissorTest;
457     struct
458     {
459       Graphics::Viewport region;
460     } viewport;
461     struct
462     {
463       bool enable;
464     } viewportTest;
465
466     struct BeginRenderPassDescriptor
467     {
468       Graphics::RenderPass*             renderPass;
469       Graphics::RenderTarget*           renderTarget;
470       Graphics::Rect2D                  renderArea;
471       std::vector<Graphics::ClearValue> clearValues;
472     } beginRenderPass;
473
474     struct
475     {
476     } endRenderPass;
477
478     struct
479     {
480       std::vector<const TestGraphicsCommandBuffer*> buffers;
481     } executeCommandBuffers;
482
483   } data;
484 };
485
486 class TestGraphicsCommandBuffer : public Graphics::CommandBuffer
487 {
488 public:
489   TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction);
490   ~TestGraphicsCommandBuffer()
491   {
492   }
493
494   void BindVertexBuffers(uint32_t                             firstBinding,
495                          std::vector<const Graphics::Buffer*> buffers,
496                          std::vector<uint32_t>                offsets) override
497   {
498     mCommands.emplace_back();
499     mCommands.back().type = CommandType::BIND_VERTEX_BUFFERS;
500     auto& bindings        = mCommands.back().data.bindVertexBuffers.vertexBufferBindings;
501     if(bindings.size() < firstBinding + buffers.size())
502     {
503       bindings.resize(firstBinding + buffers.size());
504       auto index = firstBinding;
505       for(auto& buf : buffers)
506       {
507         bindings[index].buffer = static_cast<const TestGraphicsBuffer*>(buf);
508         bindings[index].offset = offsets[index - firstBinding];
509         index++;
510       }
511     }
512     mCallStack.PushCall("BindVertexBuffers", "");
513   }
514
515   void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings) override
516   {
517     mCommands.emplace_back();
518     auto& cmd     = mCommands.back();
519     cmd.type      = CommandType::BIND_UNIFORM_BUFFER;
520     auto& bindCmd = cmd.data.bindUniformBuffers;
521     for(const auto& binding : bindings)
522     {
523       if(binding.buffer)
524       {
525         auto testBuffer = static_cast<const TestGraphicsBuffer*>(binding.buffer);
526         if(testBuffer->IsCPUAllocated()) // standalone uniforms
527         {
528           bindCmd.standaloneUniformsBufferBinding.buffer   = testBuffer;
529           bindCmd.standaloneUniformsBufferBinding.offset   = binding.offset;
530           bindCmd.standaloneUniformsBufferBinding.binding  = binding.binding;
531           bindCmd.standaloneUniformsBufferBinding.emulated = true;
532         }
533         else // Bind regular UBO
534         {
535           // resize binding slots
536           if(binding.binding >= bindCmd.uniformBufferBindings.size())
537           {
538             bindCmd.uniformBufferBindings.resize(binding.binding + 1);
539           }
540           auto& slot    = bindCmd.uniformBufferBindings[binding.binding];
541           slot.buffer   = testBuffer;
542           slot.offset   = binding.offset;
543           slot.binding  = binding.binding;
544           slot.emulated = false;
545         }
546       }
547     }
548     mCallStack.PushCall("BindUniformBuffers", "");
549   }
550
551   void BindPipeline(const Graphics::Pipeline& pipeline) override
552   {
553     mCommands.emplace_back();
554     mCommands.back().type                       = CommandType::BIND_PIPELINE;
555     mCommands.back().data.bindPipeline.pipeline = static_cast<const TestGraphicsPipeline*>(&pipeline);
556     mCallStack.PushCall("BindPipeline", "");
557   }
558
559   void BindTextures(std::vector<Graphics::TextureBinding>& textureBindings) override
560   {
561     mCommands.emplace_back();
562     mCommands.back().type                              = CommandType::BIND_TEXTURES;
563     mCommands.back().data.bindTextures.textureBindings = std::move(textureBindings);
564     mCallStack.PushCall("BindTextures", "");
565   }
566
567   void BindSamplers(std::vector<Graphics::SamplerBinding>& samplerBindings) override
568   {
569     mCommands.emplace_back();
570     mCommands.back().data.bindSamplers.samplerBindings = std::move(samplerBindings);
571     mCallStack.PushCall("BindSamplers", "");
572   }
573
574   void BindPushConstants(void*    data,
575                          uint32_t size,
576                          uint32_t binding) override
577   {
578     mCallStack.PushCall("BindPushConstants", "");
579   }
580
581   void BindIndexBuffer(const Graphics::Buffer& buffer,
582                        uint32_t                offset,
583                        Graphics::Format        format) override
584   {
585     mCommands.emplace_back();
586     mCommands.back().type                        = CommandType::BIND_INDEX_BUFFER;
587     mCommands.back().data.bindIndexBuffer.buffer = static_cast<const TestGraphicsBuffer*>(&buffer);
588     mCommands.back().data.bindIndexBuffer.offset = offset;
589     mCommands.back().data.bindIndexBuffer.format = format;
590     mCallStack.PushCall("BindIndexBuffer", "");
591   }
592
593   void BeginRenderPass(
594     Graphics::RenderPass*             renderPass,
595     Graphics::RenderTarget*           renderTarget,
596     Graphics::Rect2D                  renderArea,
597     std::vector<Graphics::ClearValue> clearValues) override
598   {
599     mCommands.emplace_back(CommandType::BEGIN_RENDER_PASS);
600     auto& cmd                             = mCommands.back();
601     cmd.data.beginRenderPass.renderPass   = renderPass;
602     cmd.data.beginRenderPass.renderTarget = renderTarget;
603     cmd.data.beginRenderPass.renderArea   = renderArea;
604     cmd.data.beginRenderPass.clearValues  = clearValues;
605
606     TraceCallStack::NamedParams namedParams;
607     namedParams["renderPass"] << std::hex << renderPass;
608     namedParams["renderTarget"] << std::hex << renderTarget;
609     namedParams["renderArea"] << renderArea.width << ", " << renderArea.height;
610     mCallStack.PushCall("BeginRenderPass", namedParams.str(), namedParams);
611   }
612
613   /**
614    * @brief Ends current render pass
615    *
616    * This command must be issued in order to finalize the render pass.
617    * It's up to the implementation whether anything has to be done but
618    * the Controller may use end RP marker in order to resolve resource
619    * dependencies (for example, to know when target texture is ready
620    * before passing it to another render pass).
621    */
622   void EndRenderPass() override
623   {
624     mCallStack.PushCall("EndRenderPass", "");
625   }
626
627   void ExecuteCommandBuffers(std::vector<const CommandBuffer*>&& commandBuffers) override
628   {
629     mCommands.emplace_back();
630     auto& cmd = mCommands.back();
631     cmd.type  = CommandType::EXECUTE_COMMAND_BUFFERS;
632     cmd.data.executeCommandBuffers.buffers.reserve(commandBuffers.size());
633     for(auto&& item : commandBuffers)
634     {
635       cmd.data.executeCommandBuffers.buffers.emplace_back(static_cast<const TestGraphicsCommandBuffer*>(item));
636     }
637     mCallStack.PushCall("ExecuteCommandBuffers", "");
638   }
639
640   void Draw(
641     uint32_t vertexCount,
642     uint32_t instanceCount,
643     uint32_t firstVertex,
644     uint32_t firstInstance) override
645   {
646     mCommands.emplace_back();
647     mCommands.back().type  = CommandType::DRAW;
648     auto& cmd              = mCommands.back().data.draw;
649     cmd.type               = DrawCallDescriptor::Type::DRAW;
650     cmd.draw.vertexCount   = vertexCount;
651     cmd.draw.instanceCount = instanceCount;
652     cmd.draw.firstInstance = firstInstance;
653     cmd.draw.firstVertex   = firstVertex;
654     mCallStack.PushCall("Draw", "");
655   }
656
657   void DrawIndexed(
658     uint32_t indexCount,
659     uint32_t instanceCount,
660     uint32_t firstIndex,
661     int32_t  vertexOffset,
662     uint32_t firstInstance) override
663   {
664     mCommands.emplace_back();
665     mCommands.back().type         = CommandType::DRAW_INDEXED;
666     auto& cmd                     = mCommands.back().data.draw;
667     cmd.type                      = DrawCallDescriptor::Type::DRAW_INDEXED;
668     cmd.drawIndexed.firstIndex    = firstIndex;
669     cmd.drawIndexed.firstInstance = firstInstance;
670     cmd.drawIndexed.indexCount    = indexCount;
671     cmd.drawIndexed.vertexOffset  = vertexOffset;
672     cmd.drawIndexed.instanceCount = instanceCount;
673     mCallStack.PushCall("DrawIndexed", "");
674   }
675
676   void DrawIndexedIndirect(
677     Graphics::Buffer& buffer,
678     uint32_t          offset,
679     uint32_t          drawCount,
680     uint32_t          stride) override
681   {
682     mCommands.emplace_back();
683     mCommands.back().type             = CommandType::DRAW_INDEXED_INDIRECT;
684     auto& cmd                         = mCommands.back().data.draw;
685     cmd.type                          = DrawCallDescriptor::Type::DRAW_INDEXED_INDIRECT;
686     cmd.drawIndexedIndirect.buffer    = static_cast<const TestGraphicsBuffer*>(&buffer);
687     cmd.drawIndexedIndirect.offset    = offset;
688     cmd.drawIndexedIndirect.drawCount = drawCount;
689     cmd.drawIndexedIndirect.stride    = stride;
690     mCallStack.PushCall("DrawIndexedIndirect", "");
691   }
692
693   void Reset() override
694   {
695     mCommands.clear();
696     mCallStack.PushCall("Reset", "");
697   }
698
699   void SetScissor(Graphics::Rect2D value) override
700   {
701     TraceCallStack::NamedParams params;
702     params["x"] << value.x;
703     params["y"] << value.y;
704     params["width"] << value.width;
705     params["height"] << value.height;
706     mCallStack.PushCall("SetScissor", params.str(), params);
707
708     mCommands.emplace_back();
709     mCommands.back().type                = CommandType::SET_SCISSOR;
710     mCommands.back().data.scissor.region = value;
711   }
712
713   void SetScissorTestEnable(bool value) override
714   {
715     TraceCallStack::NamedParams params;
716     params["value"] << (value ? "T" : "F");
717     mCallStack.PushCall("SetScissorTestEnable", params.str(), params);
718
719     mCommands.emplace_back();
720     mCommands.back().type                    = CommandType::SET_SCISSOR_TEST;
721     mCommands.back().data.scissorTest.enable = value;
722   }
723
724   void SetViewport(Graphics::Viewport value) override
725   {
726     TraceCallStack::NamedParams params;
727     params["x"] << value.x;
728     params["y"] << value.y;
729     params["width"] << value.width;
730     params["height"] << value.height;
731     params["minDepth"] << value.minDepth;
732     params["maxDepth"] << value.maxDepth;
733     mCallStack.PushCall("SetViewport", params.str(), params);
734
735     mCommands.emplace_back();
736     mCommands.back().type                 = CommandType::SET_VIEWPORT;
737     mCommands.back().data.viewport.region = value;
738   }
739
740   void SetViewportEnable(bool value) override
741   {
742     TraceCallStack::NamedParams params;
743     params["value"] << (value ? "T" : "F");
744     mCallStack.PushCall("SetViewportEnable", params.str(), params);
745
746     mCommands.emplace_back();
747     mCommands.back().type                     = CommandType::SET_VIEWPORT_TEST;
748     mCommands.back().data.viewportTest.enable = value;
749   }
750
751   [[nodiscard]] const std::vector<Command>& GetCommands() const
752   {
753     return mCommands;
754   }
755
756   /**
757    * Returns number of draw commands
758    * @return
759    */
760   int GetDrawCallsCount();
761
762   /**
763    * Retrieves state resolve for selected draw call
764    * @param drawCommandIndex
765    */
766   void GetStateForDrawCall(int drawCallIndex);
767
768   /**
769    * Retrieves commands of specified type
770    */
771   std::vector<const Command*> GetCommandsByType(CommandTypeMask mask) const;
772
773   std::vector<const Command*> GetChildCommandsByType(CommandTypeMask mask) const;
774
775 private:
776   TraceCallStack&    mCallStack;
777   TestGlAbstraction& mGlAbstraction;
778
779   std::vector<Command> mCommands;
780 };
781
782 } // namespace Dali
783
784 #endif //DALI_TEST_GRAPHICS_COMMAND_BUFFER_H