a8357c16934bc298144cf118bcde05e615260ecd
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-graphics-controller.cpp
1 /*
2  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "test-graphics-controller.h"
18
19 #include "test-graphics-buffer.h"
20 #include "test-graphics-command-buffer.h"
21 #include "test-graphics-sampler.h"
22 #include "test-graphics-texture.h"
23
24 #include <dali/integration-api/gl-defines.h>
25 #include <cstdio>
26 #include <iostream>
27 #include <sstream>
28
29 namespace Dali
30 {
31 template<typename T>
32 T* Uncast(const Graphics::CommandBuffer* object)
33 {
34   return const_cast<T*>(static_cast<const T*>(object));
35 }
36
37 template<typename T>
38 T* Uncast(const Graphics::Texture* object)
39 {
40   return const_cast<T*>(static_cast<const T*>(object));
41 }
42
43 template<typename T>
44 T* Uncast(const Graphics::Sampler* object)
45 {
46   return const_cast<T*>(static_cast<const T*>(object));
47 }
48
49 template<typename T>
50 T* Uncast(const Graphics::Buffer* object)
51 {
52   return const_cast<T*>(static_cast<const T*>(object));
53 }
54
55 std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
56 {
57   return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
58 }
59
60 std::ostream& operator<<(std::ostream& o, const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo)
61 {
62   return o << "level:" << (commandBufferCreateInfo.level == Graphics::CommandBufferLevel::PRIMARY ? "PRIMARY" : "SECONDARY")
63            << ", fixedCapacity:" << std::dec << commandBufferCreateInfo.fixedCapacity;
64 }
65
66 std::ostream& operator<<(std::ostream& o, const Graphics::TextureType& textureType)
67 {
68   switch(textureType)
69   {
70     case Graphics::TextureType::TEXTURE_2D:
71       o << "TEXTURE_2D";
72       break;
73     case Graphics::TextureType::TEXTURE_3D:
74       o << "TEXTURE_3D";
75       break;
76     case Graphics::TextureType::TEXTURE_CUBEMAP:
77       o << "TEXTURE_CUBEMAP";
78       break;
79   }
80   return o;
81 }
82
83 std::ostream& operator<<(std::ostream& o, const Graphics::Extent2D extent)
84 {
85   o << "width:" << extent.width << ", height:" << extent.height;
86   return o;
87 }
88
89 std::ostream& operator<<(std::ostream& o, const Graphics::TextureCreateInfo& createInfo)
90 {
91   o << "textureType:" << createInfo.textureType
92     << " size:" << createInfo.size
93     << " format:" << static_cast<uint32_t>(createInfo.format)
94     << " mipMapFlag:" << createInfo.mipMapFlag
95     << " layout:" << (createInfo.layout == Graphics::TextureLayout::LINEAR ? "LINEAR" : "OPTIMAL")
96     << " usageFlags:" << std::hex << createInfo.usageFlags
97     << " data:" << std::hex << createInfo.data
98     << " dataSize:" << std::dec << createInfo.dataSize
99     << " nativeImagePtr:" << std::hex << createInfo.nativeImagePtr;
100   return o;
101 }
102
103 std::ostream& operator<<(std::ostream& o, Graphics::SamplerAddressMode addressMode)
104 {
105   switch(addressMode)
106   {
107     case Graphics::SamplerAddressMode::REPEAT:
108       o << "REPEAT";
109       break;
110     case Graphics::SamplerAddressMode::MIRRORED_REPEAT:
111       o << "MIRRORED_REPEAT";
112       break;
113     case Graphics::SamplerAddressMode::CLAMP_TO_EDGE:
114       o << "CLAMP_TO_EDGE";
115       break;
116     case Graphics::SamplerAddressMode::CLAMP_TO_BORDER:
117       o << "CLAMP_TO_BORDER";
118       break;
119     case Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE:
120       o << "MIRROR_CLAMP_TO_EDGE";
121       break;
122   }
123   return o;
124 }
125
126 std::ostream& operator<<(std::ostream& o, Graphics::SamplerFilter filterMode)
127 {
128   switch(filterMode)
129   {
130     case Graphics::SamplerFilter::LINEAR:
131       o << "LINEAR";
132       break;
133     case Graphics::SamplerFilter::NEAREST:
134       o << "NEAREST";
135       break;
136   }
137   return o;
138 }
139
140 std::ostream& operator<<(std::ostream& o, Graphics::SamplerMipmapMode mipmapMode)
141 {
142   switch(mipmapMode)
143   {
144     case Graphics::SamplerMipmapMode::NONE:
145       o << "NONE";
146       break;
147     case Graphics::SamplerMipmapMode::LINEAR:
148       o << "LINEAR";
149       break;
150     case Graphics::SamplerMipmapMode::NEAREST:
151       o << "NEAREST";
152       break;
153   }
154   return o;
155 }
156
157 std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& createInfo)
158 {
159   o << "minFilter:" << createInfo.minFilter
160     << " magFilter:" << createInfo.magFilter
161     << " wrapModeU:" << createInfo.addressModeU
162     << " wrapModeV:" << createInfo.addressModeV
163     << " wrapModeW:" << createInfo.addressModeW
164     << " mipMapMode:" << createInfo.mipMapMode;
165   return o;
166 }
167
168 class TestGraphicsMemory : public Graphics::Memory
169 {
170 public:
171   TestGraphicsMemory(TraceCallStack& callStack, TestGraphicsBuffer& buffer, uint32_t mappedOffset, uint32_t mappedSize)
172   : mCallStack(callStack),
173     mBuffer(buffer),
174     mMappedOffset(mappedOffset),
175     mMappedSize(mappedSize)
176   {
177   }
178
179   void* LockRegion(uint32_t offset, uint32_t size) override
180   {
181     std::ostringstream o;
182     o << offset << ", " << size;
183     mCallStack.PushCall("Memory::LockRegion", o.str());
184
185     if(offset > mMappedOffset + mMappedSize ||
186        size + offset > mMappedOffset + mMappedSize)
187     {
188       fprintf(stderr, "TestGraphics.Memory::LockRegion() Out of bounds");
189       mBuffer.memory.resize(mMappedOffset + offset + size); // Grow to prevent memcpy from crashing
190     }
191     mLockedOffset = offset;
192     mLockedSize   = size;
193     return &mBuffer.memory[mMappedOffset + offset];
194   }
195
196   void Unlock(bool flush) override
197   {
198     mCallStack.PushCall("Memory::Unlock", (flush ? "Flush" : "NoFlush"));
199     if(flush)
200     {
201       Flush();
202     }
203   }
204
205   void Flush() override
206   {
207     mCallStack.PushCall("Memory::Flush", "");
208     mBuffer.Bind();
209     mBuffer.Upload(mMappedOffset + mLockedOffset, mLockedSize);
210     mBuffer.Unbind();
211   }
212
213   TraceCallStack&     mCallStack;
214   TestGraphicsBuffer& mBuffer;
215   uint32_t            mMappedOffset;
216   uint32_t            mMappedSize;
217   uint32_t            mLockedOffset;
218   uint32_t            mLockedSize;
219 };
220
221 TestGraphicsController::TestGraphicsController()
222 : mCallStack(true, "TestGraphicsController."),
223   mCommandBufferCallStack(true, "TestCommandBuffer.")
224 {
225   mCallStack.Enable(true);
226   mCommandBufferCallStack.Enable(true);
227   auto& trace = mGl.GetTextureTrace();
228   trace.Enable(true);
229   trace.EnableLogging(true);
230 }
231
232 int GetNumComponents(Graphics::VertexInputFormat vertexFormat)
233 {
234   switch(vertexFormat)
235   {
236     case Graphics::VertexInputFormat::UNDEFINED:
237     case Graphics::VertexInputFormat::FLOAT:
238     case Graphics::VertexInputFormat::INTEGER:
239       return 1;
240     case Graphics::VertexInputFormat::IVECTOR2:
241     case Graphics::VertexInputFormat::FVECTOR2:
242       return 2;
243     case Graphics::VertexInputFormat::IVECTOR3:
244     case Graphics::VertexInputFormat::FVECTOR3:
245       return 3;
246     case Graphics::VertexInputFormat::FVECTOR4:
247     case Graphics::VertexInputFormat::IVECTOR4:
248       return 4;
249   }
250   return 1;
251 }
252
253 GLint GetSize(Graphics::VertexInputFormat vertexFormat)
254 {
255   switch(vertexFormat)
256   {
257     case Graphics::VertexInputFormat::UNDEFINED:
258       return 1u;
259     case Graphics::VertexInputFormat::INTEGER:
260     case Graphics::VertexInputFormat::IVECTOR2:
261     case Graphics::VertexInputFormat::IVECTOR3:
262     case Graphics::VertexInputFormat::IVECTOR4:
263       return 2u;
264     case Graphics::VertexInputFormat::FLOAT:
265     case Graphics::VertexInputFormat::FVECTOR2:
266     case Graphics::VertexInputFormat::FVECTOR3:
267     case Graphics::VertexInputFormat::FVECTOR4:
268       return 4u;
269   }
270   return 1u;
271 }
272
273 GLint GetGlType(Graphics::VertexInputFormat vertexFormat)
274 {
275   switch(vertexFormat)
276   {
277     case Graphics::VertexInputFormat::UNDEFINED:
278       return GL_BYTE;
279     case Graphics::VertexInputFormat::INTEGER:
280     case Graphics::VertexInputFormat::IVECTOR2:
281     case Graphics::VertexInputFormat::IVECTOR3:
282     case Graphics::VertexInputFormat::IVECTOR4:
283       return GL_SHORT;
284     case Graphics::VertexInputFormat::FLOAT:
285     case Graphics::VertexInputFormat::FVECTOR2:
286     case Graphics::VertexInputFormat::FVECTOR3:
287     case Graphics::VertexInputFormat::FVECTOR4:
288       return GL_FLOAT;
289   }
290   return GL_BYTE;
291 }
292
293 GLenum GetTopology(Graphics::PrimitiveTopology topology)
294 {
295   switch(topology)
296   {
297     case Graphics::PrimitiveTopology::POINT_LIST:
298       return GL_POINTS;
299
300     case Graphics::PrimitiveTopology::LINE_LIST:
301       return GL_LINES;
302
303     case Graphics::PrimitiveTopology::LINE_LOOP:
304       return GL_LINE_LOOP;
305
306     case Graphics::PrimitiveTopology::LINE_STRIP:
307       return GL_LINE_STRIP;
308
309     case Graphics::PrimitiveTopology::TRIANGLE_LIST:
310       return GL_TRIANGLES;
311
312     case Graphics::PrimitiveTopology::TRIANGLE_STRIP:
313       return GL_TRIANGLE_STRIP;
314
315     case Graphics::PrimitiveTopology::TRIANGLE_FAN:
316       return GL_TRIANGLE_FAN;
317   }
318   return GL_TRIANGLES;
319 }
320
321 GLenum GetCullFace(Graphics::CullMode cullMode)
322 {
323   switch(cullMode)
324   {
325     case Graphics::CullMode::NONE:
326       return GL_NONE;
327     case Graphics::CullMode::FRONT:
328       return GL_FRONT;
329     case Graphics::CullMode::BACK:
330       return GL_BACK;
331     case Graphics::CullMode::FRONT_AND_BACK:
332       return GL_FRONT_AND_BACK;
333   }
334   return GL_NONE;
335 }
336
337 GLenum GetFrontFace(Graphics::FrontFace frontFace)
338 {
339   if(frontFace == Graphics::FrontFace::CLOCKWISE)
340   {
341     return GL_CW;
342   }
343   return GL_CCW;
344 }
345
346 GLenum GetBlendFactor(Graphics::BlendFactor blendFactor)
347 {
348   GLenum glFactor = GL_ZERO;
349
350   switch(blendFactor)
351   {
352     case Graphics::BlendFactor::ZERO:
353       glFactor = GL_ZERO;
354       break;
355     case Graphics::BlendFactor::ONE:
356       glFactor = GL_ONE;
357       break;
358     case Graphics::BlendFactor::SRC_COLOR:
359       glFactor = GL_SRC_COLOR;
360       break;
361     case Graphics::BlendFactor::ONE_MINUS_SRC_COLOR:
362       glFactor = GL_ONE_MINUS_SRC_COLOR;
363       break;
364     case Graphics::BlendFactor::DST_COLOR:
365       glFactor = GL_DST_COLOR;
366       break;
367     case Graphics::BlendFactor::ONE_MINUS_DST_COLOR:
368       glFactor = GL_ONE_MINUS_DST_COLOR;
369       break;
370     case Graphics::BlendFactor::SRC_ALPHA:
371       glFactor = GL_SRC_ALPHA;
372       break;
373     case Graphics::BlendFactor::ONE_MINUS_SRC_ALPHA:
374       glFactor = GL_ONE_MINUS_SRC_ALPHA;
375       break;
376     case Graphics::BlendFactor::DST_ALPHA:
377       glFactor = GL_DST_ALPHA;
378       break;
379     case Graphics::BlendFactor::ONE_MINUS_DST_ALPHA:
380       glFactor = GL_ONE_MINUS_DST_ALPHA;
381       break;
382     case Graphics::BlendFactor::CONSTANT_COLOR:
383       glFactor = GL_CONSTANT_COLOR;
384       break;
385     case Graphics::BlendFactor::ONE_MINUS_CONSTANT_COLOR:
386       glFactor = GL_ONE_MINUS_CONSTANT_COLOR;
387       break;
388     case Graphics::BlendFactor::CONSTANT_ALPHA:
389       glFactor = GL_CONSTANT_ALPHA;
390       break;
391     case Graphics::BlendFactor::ONE_MINUS_CONSTANT_ALPHA:
392       glFactor = GL_ONE_MINUS_CONSTANT_ALPHA;
393       break;
394     case Graphics::BlendFactor::SRC_ALPHA_SATURATE:
395       glFactor = GL_SRC_ALPHA_SATURATE;
396       break;
397       // GLES doesn't appear to have dual source blending.
398     case Graphics::BlendFactor::SRC1_COLOR:
399       glFactor = GL_SRC_COLOR;
400       break;
401     case Graphics::BlendFactor::ONE_MINUS_SRC1_COLOR:
402       glFactor = GL_ONE_MINUS_SRC_COLOR;
403       break;
404     case Graphics::BlendFactor::SRC1_ALPHA:
405       glFactor = GL_SRC_ALPHA;
406       break;
407     case Graphics::BlendFactor::ONE_MINUS_SRC1_ALPHA:
408       glFactor = GL_ONE_MINUS_SRC_ALPHA;
409       break;
410   }
411   return glFactor;
412 }
413
414 GLenum GetBlendOp(Graphics::BlendOp blendOp)
415 {
416   GLenum op = GL_FUNC_ADD;
417   switch(blendOp)
418   {
419     case Graphics::BlendOp::ADD:
420       op = GL_FUNC_ADD;
421       break;
422     case Graphics::BlendOp::SUBTRACT:
423       op = GL_FUNC_SUBTRACT;
424       break;
425     case Graphics::BlendOp::REVERSE_SUBTRACT:
426       op = GL_FUNC_REVERSE_SUBTRACT;
427       break;
428     case Graphics::BlendOp::MIN:
429       op = GL_MIN;
430       break;
431     case Graphics::BlendOp::MAX:
432       op = GL_MAX;
433       break;
434
435       // @todo Add advanced blend equations
436   }
437   return op;
438 }
439
440 void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo)
441 {
442   TraceCallStack::NamedParams namedParams;
443   namedParams["submitInfo"] << "cmdBuffer[" << submitInfo.cmdBuffer.size()
444                             << "], flags:" << std::hex << submitInfo.flags;
445
446   mCallStack.PushCall("Controller::SubmitCommandBuffers", "", namedParams);
447
448   for(auto& graphicsCommandBuffer : submitInfo.cmdBuffer)
449   {
450     auto commandBuffer = Uncast<TestGraphicsCommandBuffer>(graphicsCommandBuffer);
451     for(auto& binding : commandBuffer->mTextureBindings)
452     {
453       if(binding.texture)
454       {
455         auto texture = Uncast<TestGraphicsTexture>(binding.texture);
456
457         texture->Bind(binding.binding);
458
459         if(binding.sampler)
460         {
461           auto sampler = Uncast<TestGraphicsSampler>(binding.sampler);
462           if(sampler)
463           {
464             sampler->Apply(texture->GetTarget());
465           }
466         }
467
468         texture->Prepare(); // Ensure native texture is ready
469       }
470     }
471
472     // IndexBuffer binding,
473     auto& indexBufferBinding = commandBuffer->mIndexBufferBinding;
474     if(indexBufferBinding.buffer)
475     {
476       auto buffer = Uncast<TestGraphicsBuffer>(indexBufferBinding.buffer);
477       buffer->Bind();
478     }
479
480     // VertexBuffer binding,
481     for(auto graphicsBuffer : commandBuffer->mVertexBufferBindings.buffers)
482     {
483       auto vertexBuffer = Uncast<TestGraphicsBuffer>(graphicsBuffer);
484       vertexBuffer->Bind();
485     }
486
487     // Pipeline attribute setup
488     auto& vi = commandBuffer->mPipeline->vertexInputState;
489     for(auto& attribute : vi.attributes)
490     {
491       mGl.EnableVertexAttribArray(attribute.location);
492       uint32_t attributeOffset = attribute.offset;
493       GLsizei  stride          = vi.bufferBindings[attribute.binding].stride;
494
495       mGl.VertexAttribPointer(attribute.location,
496                               GetNumComponents(attribute.format),
497                               GetGlType(attribute.format),
498                               GL_FALSE, // Not normalized
499                               stride,
500                               reinterpret_cast<void*>(attributeOffset));
501     }
502
503     // Cull face setup
504     auto& rasterizationState = commandBuffer->mPipeline->rasterizationState;
505     if(rasterizationState.cullMode == Graphics::CullMode::NONE)
506     {
507       mGl.Disable(GL_CULL_FACE);
508     }
509     else
510     {
511       mGl.Enable(GL_CULL_FACE);
512       mGl.CullFace(GetCullFace(rasterizationState.cullMode));
513     }
514
515     mGl.FrontFace(GetFrontFace(rasterizationState.frontFace));
516     // We don't modify glPolygonMode in our context/abstraction from GL_FILL (the GL default),
517     // so it isn't present in the API (and won't have any tests!)
518
519     // Blending setup
520     auto& colorBlendState = commandBuffer->mPipeline->colorBlendState;
521     if(colorBlendState.blendEnable)
522     {
523       mGl.Enable(GL_BLEND);
524
525       mGl.BlendFuncSeparate(GetBlendFactor(colorBlendState.srcColorBlendFactor),
526                             GetBlendFactor(colorBlendState.dstColorBlendFactor),
527                             GetBlendFactor(colorBlendState.srcAlphaBlendFactor),
528                             GetBlendFactor(colorBlendState.dstAlphaBlendFactor));
529       if(colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
530       {
531         mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp));
532       }
533       else
534       {
535         mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp));
536       }
537       mGl.BlendColor(colorBlendState.blendConstants[0],
538                      colorBlendState.blendConstants[1],
539                      colorBlendState.blendConstants[2],
540                      colorBlendState.blendConstants[3]);
541     }
542     else
543     {
544       mGl.Disable(GL_BLEND);
545     }
546
547     // draw call
548     auto topology = commandBuffer->mPipeline->inputAssemblyState.topology;
549
550     if(commandBuffer->drawCommand.drawType == TestGraphicsCommandBuffer::Draw::DrawType::Indexed)
551     {
552       mGl.DrawElements(GetTopology(topology),
553                        static_cast<GLsizei>(commandBuffer->drawCommand.u.indexedDraw.indexCount),
554                        GL_UNSIGNED_SHORT,
555                        reinterpret_cast<void*>(commandBuffer->drawCommand.u.indexedDraw.firstIndex));
556     }
557     else
558     {
559       mGl.DrawArrays(GetTopology(topology), 0, commandBuffer->drawCommand.u.unindexedDraw.vertexCount);
560     }
561
562     // attribute clear
563     for(auto& attribute : vi.attributes)
564     {
565       mGl.DisableVertexAttribArray(attribute.location);
566     }
567   }
568 }
569
570 /**
571  * @brief Presents render target
572  * @param renderTarget render target to present
573  */
574 void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderTarget)
575 {
576   TraceCallStack::NamedParams namedParams;
577   namedParams["renderTarget"] << std::hex << renderTarget;
578   mCallStack.PushCall("Controller::PresentRenderTarget", "", namedParams);
579 }
580
581 /**
582  * @brief Waits until the GPU is idle
583  */
584 void TestGraphicsController::WaitIdle()
585 {
586   mCallStack.PushCall("Controller::WaitIdle", "");
587 }
588
589 /**
590  * @brief Lifecycle pause event
591  */
592 void TestGraphicsController::Pause()
593 {
594   mCallStack.PushCall("Controller::Pause", "");
595 }
596
597 /**
598  * @brief Lifecycle resume event
599  */
600 void TestGraphicsController::Resume()
601 {
602   mCallStack.PushCall("Controller::Resume", "");
603 }
604
605 void TestGraphicsController::UpdateTextures(const std::vector<Graphics::TextureUpdateInfo>&       updateInfoList,
606                                             const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList)
607 {
608   TraceCallStack::NamedParams namedParams;
609   namedParams["updateInfoList"] << "[" << updateInfoList.size() << "]:";
610   namedParams["sourceList"] << "[" << sourceList.size() << "]:";
611
612   mCallStack.PushCall("Controller::UpdateTextures", "", namedParams);
613
614   // Call either TexImage2D or TexSubImage2D
615   for(unsigned int i = 0; i < updateInfoList.size(); ++i)
616   {
617     auto& updateInfo = updateInfoList[i];
618     auto& source     = sourceList[i];
619
620     auto texture = static_cast<TestGraphicsTexture*>(updateInfo.dstTexture);
621     texture->Bind(0); // Use first texture unit during resource update
622     texture->Update(updateInfo, source);
623   }
624 }
625
626 bool TestGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil)
627 {
628   TraceCallStack::NamedParams namedParams;
629   namedParams["enableDepth"] << (enableDepth ? "T" : "F");
630   namedParams["enableStencil"] << (enableStencil ? "T" : "F");
631   mCallStack.PushCall("Controller::EnableDepthStencilBuffer", "", namedParams);
632   return false;
633 }
634
635 void TestGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers)
636 {
637   TraceCallStack::NamedParams namedParams;
638   namedParams["numberOfDiscardedRenderers"] << numberOfDiscardedRenderers;
639   mCallStack.PushCall("Controller::RunGarbageCollector", "", namedParams);
640 }
641
642 void TestGraphicsController::DiscardUnusedResources()
643 {
644   mCallStack.PushCall("Controller::DiscardUnusedResources", "");
645 }
646
647 bool TestGraphicsController::IsDiscardQueueEmpty()
648 {
649   mCallStack.PushCall("Controller::IsDiscardQueueEmpty", "");
650   return isDiscardQueueEmptyResult;
651 }
652
653 /**
654  * @brief Test if the graphics subsystem has resumed & should force a draw
655  *
656  * @return true if the graphics subsystem requires a re-draw
657  */
658 bool TestGraphicsController::IsDrawOnResumeRequired()
659 {
660   mCallStack.PushCall("Controller::IsDrawOnResumeRequired", "");
661   return isDrawOnResumeRequiredResult;
662 }
663
664 Graphics::UniquePtr<Graphics::Buffer> TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& createInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer)
665 {
666   std::ostringstream oss;
667   oss << "bufferCreateInfo:" << createInfo;
668   mCallStack.PushCall("Controller::CreateBuffer", oss.str());
669   return Graphics::MakeUnique<TestGraphicsBuffer>(mCallStack, mGl, createInfo.size, createInfo.usage);
670 }
671
672 Graphics::UniquePtr<Graphics::CommandBuffer> TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer)
673 {
674   std::ostringstream oss;
675   oss << "commandBufferCreateInfo:" << commandBufferCreateInfo;
676   mCallStack.PushCall("Controller::CreateCommandBuffer", oss.str());
677   return Graphics::MakeUnique<TestGraphicsCommandBuffer>(mCommandBufferCallStack, mGl);
678 }
679
680 Graphics::UniquePtr<Graphics::RenderPass> TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass)
681 {
682   mCallStack.PushCall("Controller::CreateRenderPass", "");
683   return nullptr;
684 }
685
686 Graphics::UniquePtr<Graphics::Texture> TestGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture)
687 {
688   TraceCallStack::NamedParams namedParams;
689   namedParams["textureCreateInfo"] << textureCreateInfo;
690   mCallStack.PushCall("Controller::CreateTexture", namedParams.str(), namedParams);
691
692   return Graphics::MakeUnique<TestGraphicsTexture>(mGl, textureCreateInfo);
693 }
694
695 Graphics::UniquePtr<Graphics::Framebuffer> TestGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer)
696 {
697   mCallStack.PushCall("Controller::CreateFramebuffer", "");
698   return nullptr;
699 }
700
701 Graphics::UniquePtr<Graphics::Pipeline> TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
702 {
703   mCallStack.PushCall("Controller::CreatePipeline", "");
704   return std::make_unique<TestGraphicsPipeline>(mGl, pipelineCreateInfo);
705 }
706
707 Graphics::UniquePtr<Graphics::Shader> TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader)
708 {
709   mCallStack.PushCall("Controller::CreateShader", "");
710   return nullptr;
711 }
712
713 Graphics::UniquePtr<Graphics::Sampler> TestGraphicsController::CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Graphics::Sampler>&& oldSampler)
714 {
715   TraceCallStack::NamedParams namedParams;
716   namedParams["samplerCreateInfo"] << samplerCreateInfo;
717   mCallStack.PushCall("Controller::CreateSampler", namedParams.str(), namedParams);
718
719   return Graphics::MakeUnique<TestGraphicsSampler>(mGl, samplerCreateInfo);
720 }
721
722 Graphics::UniquePtr<Graphics::RenderTarget> TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget)
723 {
724   mCallStack.PushCall("Controller::CreateRenderTarget", "");
725   return nullptr;
726 }
727
728 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo)
729 {
730   mCallStack.PushCall("Controller::MapBufferRange", "");
731
732   auto buffer = static_cast<TestGraphicsBuffer*>(mapInfo.buffer);
733   buffer->memory.resize(mapInfo.offset + mapInfo.size); // For initial testing, allow writes past capacity
734
735   return std::make_unique<TestGraphicsMemory>(mCallStack, *buffer, mapInfo.offset, mapInfo.size);
736 }
737
738 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapTextureRange(const Graphics::MapTextureInfo& mapInfo)
739 {
740   mCallStack.PushCall("Controller::MapTextureRange", "");
741   return nullptr;
742 }
743
744 void TestGraphicsController::UnmapMemory(Graphics::UniquePtr<Graphics::Memory> memory)
745 {
746   mCallStack.PushCall("Controller::UnmapMemory", "");
747 }
748
749 Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirements(Graphics::Texture& texture) const
750 {
751   mCallStack.PushCall("Controller::GetTextureMemoryRequirements", "");
752   return Graphics::MemoryRequirements{};
753 }
754
755 Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const
756 {
757   mCallStack.PushCall("Controller::GetBufferMemoryRequirements", "");
758   return Graphics::MemoryRequirements{};
759 }
760
761 const Graphics::TextureProperties& TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture)
762 {
763   static Graphics::TextureProperties textureProperties{};
764   mCallStack.PushCall("Controller::GetTextureProperties", "");
765
766   return textureProperties;
767 }
768
769 bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const
770 {
771   mCallStack.PushCall("Controller::PipelineEquals", "");
772   return false;
773 }
774
775 } // namespace Dali