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