Updated test files to match dali-core Pipeline VtxFmt
[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 void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo)
322 {
323   TraceCallStack::NamedParams namedParams;
324   namedParams["submitInfo"] << "cmdBuffer[" << submitInfo.cmdBuffer.size()
325                             << "], flags:" << std::hex << submitInfo.flags;
326
327   mCallStack.PushCall("Controller::SubmitCommandBuffers", "", namedParams);
328
329   for(auto& graphicsCommandBuffer : submitInfo.cmdBuffer)
330   {
331     auto commandBuffer = Uncast<TestGraphicsCommandBuffer>(graphicsCommandBuffer);
332     for(auto& binding : commandBuffer->mTextureBindings)
333     {
334       if(binding.texture)
335       {
336         auto texture = Uncast<TestGraphicsTexture>(binding.texture);
337
338         texture->Bind(binding.binding);
339
340         if(binding.sampler)
341         {
342           auto sampler = Uncast<TestGraphicsSampler>(binding.sampler);
343           if(sampler)
344           {
345             sampler->Apply(texture->GetTarget());
346           }
347         }
348
349         texture->Prepare(); // Ensure native texture is ready
350       }
351     }
352
353     // IndexBuffer binding,
354     auto& indexBufferBinding = commandBuffer->mIndexBufferBinding;
355     if(indexBufferBinding.buffer)
356     {
357       auto buffer = Uncast<TestGraphicsBuffer>(indexBufferBinding.buffer);
358       buffer->Bind();
359     }
360
361     // VertexBuffer binding,
362     for(auto graphicsBuffer : commandBuffer->mVertexBufferBindings.buffers)
363     {
364       auto vertexBuffer = Uncast<TestGraphicsBuffer>(graphicsBuffer);
365       vertexBuffer->Bind();
366     }
367
368     // Pipeline attribute setup
369     auto& vi = commandBuffer->mPipeline->vertexInputState;
370     for(auto& attribute : vi.attributes)
371     {
372       mGl.EnableVertexAttribArray(attribute.location);
373       uint32_t attributeOffset = attribute.offset;
374       GLsizei  stride          = vi.bufferBindings[attribute.binding].stride;
375
376       mGl.VertexAttribPointer(attribute.location,
377                               GetNumComponents(attribute.format),
378                               GetGlType(attribute.format),
379                               GL_FALSE, // Not normalized
380                               stride,
381                               reinterpret_cast<void*>(attributeOffset));
382     }
383
384     // draw call
385     auto topology = commandBuffer->mPipeline->inputAssemblyState.topology;
386
387     if(commandBuffer->drawCommand.drawType == TestGraphicsCommandBuffer::Draw::DrawType::Indexed)
388     {
389       mGl.DrawElements(GetTopology(topology),
390                        static_cast<GLsizei>(commandBuffer->drawCommand.u.indexedDraw.indexCount),
391                        GL_UNSIGNED_SHORT,
392                        reinterpret_cast<void*>(commandBuffer->drawCommand.u.indexedDraw.firstIndex));
393     }
394     else
395     {
396       mGl.DrawArrays(GetTopology(topology), 0, commandBuffer->drawCommand.u.unindexedDraw.vertexCount);
397     }
398
399     // attribute clear
400     for(auto& attribute : vi.attributes)
401     {
402       mGl.DisableVertexAttribArray(attribute.location);
403     }
404   }
405 }
406
407 /**
408  * @brief Presents render target
409  * @param renderTarget render target to present
410  */
411 void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderTarget)
412 {
413   TraceCallStack::NamedParams namedParams;
414   namedParams["renderTarget"] << std::hex << renderTarget;
415   mCallStack.PushCall("Controller::PresentRenderTarget", "", namedParams);
416 }
417
418 /**
419  * @brief Waits until the GPU is idle
420  */
421 void TestGraphicsController::WaitIdle()
422 {
423   mCallStack.PushCall("Controller::WaitIdle", "");
424 }
425
426 /**
427  * @brief Lifecycle pause event
428  */
429 void TestGraphicsController::Pause()
430 {
431   mCallStack.PushCall("Controller::Pause", "");
432 }
433
434 /**
435  * @brief Lifecycle resume event
436  */
437 void TestGraphicsController::Resume()
438 {
439   mCallStack.PushCall("Controller::Resume", "");
440 }
441
442 void TestGraphicsController::UpdateTextures(const std::vector<Graphics::TextureUpdateInfo>&       updateInfoList,
443                                             const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList)
444 {
445   TraceCallStack::NamedParams namedParams;
446   namedParams["updateInfoList"] << "[" << updateInfoList.size() << "]:";
447   namedParams["sourceList"] << "[" << sourceList.size() << "]:";
448
449   mCallStack.PushCall("Controller::UpdateTextures", "", namedParams);
450
451   // Call either TexImage2D or TexSubImage2D
452   for(unsigned int i = 0; i < updateInfoList.size(); ++i)
453   {
454     auto& updateInfo = updateInfoList[i];
455     auto& source     = sourceList[i];
456
457     auto texture = static_cast<TestGraphicsTexture*>(updateInfo.dstTexture);
458     texture->Bind(0); // Use first texture unit during resource update
459     texture->Update(updateInfo, source);
460   }
461 }
462
463 bool TestGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil)
464 {
465   TraceCallStack::NamedParams namedParams;
466   namedParams["enableDepth"] << (enableDepth ? "T" : "F");
467   namedParams["enableStencil"] << (enableStencil ? "T" : "F");
468   mCallStack.PushCall("Controller::EnableDepthStencilBuffer", "", namedParams);
469   return false;
470 }
471
472 void TestGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers)
473 {
474   TraceCallStack::NamedParams namedParams;
475   namedParams["numberOfDiscardedRenderers"] << numberOfDiscardedRenderers;
476   mCallStack.PushCall("Controller::RunGarbageCollector", "", namedParams);
477 }
478
479 void TestGraphicsController::DiscardUnusedResources()
480 {
481   mCallStack.PushCall("Controller::DiscardUnusedResources", "");
482 }
483
484 bool TestGraphicsController::IsDiscardQueueEmpty()
485 {
486   mCallStack.PushCall("Controller::IsDiscardQueueEmpty", "");
487   return isDiscardQueueEmptyResult;
488 }
489
490 /**
491  * @brief Test if the graphics subsystem has resumed & should force a draw
492  *
493  * @return true if the graphics subsystem requires a re-draw
494  */
495 bool TestGraphicsController::IsDrawOnResumeRequired()
496 {
497   mCallStack.PushCall("Controller::IsDrawOnResumeRequired", "");
498   return isDrawOnResumeRequiredResult;
499 }
500
501 Graphics::UniquePtr<Graphics::Buffer> TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& createInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer)
502 {
503   std::ostringstream oss;
504   oss << "bufferCreateInfo:" << createInfo;
505   mCallStack.PushCall("Controller::CreateBuffer", oss.str());
506   return Graphics::MakeUnique<TestGraphicsBuffer>(mCallStack, mGl, createInfo.size, createInfo.usage);
507 }
508
509 Graphics::UniquePtr<Graphics::CommandBuffer> TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer)
510 {
511   std::ostringstream oss;
512   oss << "commandBufferCreateInfo:" << commandBufferCreateInfo;
513   mCallStack.PushCall("Controller::CreateCommandBuffer", oss.str());
514   return Graphics::MakeUnique<TestGraphicsCommandBuffer>(mCommandBufferCallStack, mGl);
515 }
516
517 Graphics::UniquePtr<Graphics::RenderPass> TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass)
518 {
519   mCallStack.PushCall("Controller::CreateRenderPass", "");
520   return nullptr;
521 }
522
523 Graphics::UniquePtr<Graphics::Texture> TestGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture)
524 {
525   TraceCallStack::NamedParams namedParams;
526   namedParams["textureCreateInfo"] << textureCreateInfo;
527   mCallStack.PushCall("Controller::CreateTexture", namedParams.str(), namedParams);
528
529   return Graphics::MakeUnique<TestGraphicsTexture>(mGl, textureCreateInfo);
530 }
531
532 Graphics::UniquePtr<Graphics::Framebuffer> TestGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer)
533 {
534   mCallStack.PushCall("Controller::CreateFramebuffer", "");
535   return nullptr;
536 }
537
538 Graphics::UniquePtr<Graphics::Pipeline> TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
539 {
540   mCallStack.PushCall("Controller::CreatePipeline", "");
541   return std::make_unique<TestGraphicsPipeline>(mGl, pipelineCreateInfo);
542 }
543
544 Graphics::UniquePtr<Graphics::Shader> TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader)
545 {
546   mCallStack.PushCall("Controller::CreateShader", "");
547   return nullptr;
548 }
549
550 Graphics::UniquePtr<Graphics::Sampler> TestGraphicsController::CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Graphics::Sampler>&& oldSampler)
551 {
552   TraceCallStack::NamedParams namedParams;
553   namedParams["samplerCreateInfo"] << samplerCreateInfo;
554   mCallStack.PushCall("Controller::CreateSampler", namedParams.str(), namedParams);
555
556   return Graphics::MakeUnique<TestGraphicsSampler>(mGl, samplerCreateInfo);
557 }
558
559 Graphics::UniquePtr<Graphics::RenderTarget> TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget)
560 {
561   mCallStack.PushCall("Controller::CreateRenderTarget", "");
562   return nullptr;
563 }
564
565 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo)
566 {
567   mCallStack.PushCall("Controller::MapBufferRange", "");
568
569   auto buffer = static_cast<TestGraphicsBuffer*>(mapInfo.buffer);
570   buffer->memory.resize(mapInfo.offset + mapInfo.size); // For initial testing, allow writes past capacity
571
572   return std::make_unique<TestGraphicsMemory>(mCallStack, *buffer, mapInfo.offset, mapInfo.size);
573 }
574
575 Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapTextureRange(const Graphics::MapTextureInfo& mapInfo)
576 {
577   mCallStack.PushCall("Controller::MapTextureRange", "");
578   return nullptr;
579 }
580
581 void TestGraphicsController::UnmapMemory(Graphics::UniquePtr<Graphics::Memory> memory)
582 {
583   mCallStack.PushCall("Controller::UnmapMemory", "");
584 }
585
586 Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirements(Graphics::Texture& texture) const
587 {
588   mCallStack.PushCall("Controller::GetTextureMemoryRequirements", "");
589   return Graphics::MemoryRequirements{};
590 }
591
592 Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const
593 {
594   mCallStack.PushCall("Controller::GetBufferMemoryRequirements", "");
595   return Graphics::MemoryRequirements{};
596 }
597
598 const Graphics::TextureProperties& TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture)
599 {
600   static Graphics::TextureProperties textureProperties{};
601   mCallStack.PushCall("Controller::GetTextureProperties", "");
602
603   return textureProperties;
604 }
605
606 bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const
607 {
608   mCallStack.PushCall("Controller::PipelineEquals", "");
609   return false;
610 }
611
612 } // namespace Dali