Protecting test cases from memory scribbling
[platform/core/uifw/dali-toolkit.git] / automated-tests / src / dali-toolkit / dali-toolkit-test-utils / test-graphics-controller.cpp
index adacc11..f970525 100644 (file)
@@ -54,6 +54,12 @@ T* Uncast(const Graphics::Buffer* object)
   return const_cast<T*>(static_cast<const T*>(object));
 }
 
+template<typename T>
+T* Uncast(const Graphics::Shader* object)
+{
+  return const_cast<T*>(static_cast<const T*>(object));
+}
+
 std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
 {
   return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
@@ -452,121 +458,156 @@ void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& su
   for(auto& graphicsCommandBuffer : submitInfo.cmdBuffer)
   {
     auto commandBuffer = Uncast<TestGraphicsCommandBuffer>(graphicsCommandBuffer);
-    for(auto& binding : commandBuffer->mTextureBindings)
+
+    auto value = commandBuffer->GetCommandsByType(0 | CommandType::BIND_TEXTURES);
+    if(!value.empty())
     {
-      if(binding.texture)
+      // must be fixed
+      for (auto &binding : value[0]->bindTextures.textureBindings)
       {
-        auto texture = Uncast<TestGraphicsTexture>(binding.texture);
+        if (binding.texture)
+        {
+          auto texture = Uncast<TestGraphicsTexture>(binding.texture);
 
-        texture->Bind(binding.binding);
+          texture->Bind(binding.binding);
 
-        if(binding.sampler)
-        {
-          auto sampler = Uncast<TestGraphicsSampler>(binding.sampler);
-          if(sampler)
+          if (binding.sampler)
           {
-            sampler->Apply(texture->GetTarget());
+            auto sampler = Uncast<TestGraphicsSampler>(binding.sampler);
+            if (sampler)
+            {
+              sampler->Apply(texture->GetTarget());
+            }
           }
-        }
 
-        texture->Prepare(); // Ensure native texture is ready
+          texture->Prepare(); // Ensure native texture is ready
+        }
       }
     }
 
     // IndexBuffer binding,
-    auto& indexBufferBinding = commandBuffer->mIndexBufferBinding;
-    if(indexBufferBinding.buffer)
+    auto bindIndexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_INDEX_BUFFER);
+    if (!bindIndexBufferCmds.empty())
     {
-      auto buffer = Uncast<TestGraphicsBuffer>(indexBufferBinding.buffer);
-      buffer->Bind();
+      auto &indexBufferBinding = bindIndexBufferCmds[0]->bindIndexBuffer;
+      if (indexBufferBinding.buffer)
+      {
+        auto buffer = Uncast<TestGraphicsBuffer>(indexBufferBinding.buffer);
+        buffer->Bind();
+      }
     }
 
     // VertexBuffer binding,
-    for(auto graphicsBuffer : commandBuffer->mVertexBufferBindings.buffers)
+    auto bindVertexBufferCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_VERTEX_BUFFERS);
+    if (!bindVertexBufferCmds.empty())
     {
-      auto vertexBuffer = Uncast<TestGraphicsBuffer>(graphicsBuffer);
-      vertexBuffer->Bind();
+      for (auto &binding : bindVertexBufferCmds[0]->bindVertexBuffers.vertexBufferBindings)
+      {
+        auto graphicsBuffer = binding.buffer;
+        auto vertexBuffer   = Uncast<TestGraphicsBuffer>(graphicsBuffer);
+        vertexBuffer->Bind();
+      }
     }
-
     // Pipeline attribute setup
-    auto& vi = commandBuffer->mPipeline->vertexInputState;
-    for(auto& attribute : vi.attributes)
-    {
-      mGl.EnableVertexAttribArray(attribute.location);
-      uint32_t attributeOffset = attribute.offset;
-      GLsizei  stride          = vi.bufferBindings[attribute.binding].stride;
-
-      mGl.VertexAttribPointer(attribute.location,
-                              GetNumComponents(attribute.format),
-                              GetGlType(attribute.format),
-                              GL_FALSE, // Not normalized
-                              stride,
-                              reinterpret_cast<void*>(attributeOffset));
-    }
-
-    // Cull face setup
-    auto& rasterizationState = commandBuffer->mPipeline->rasterizationState;
-    if(rasterizationState.cullMode == Graphics::CullMode::NONE)
-    {
-      mGl.Disable(GL_CULL_FACE);
-    }
-    else
+    auto bindPipelineCmds     = commandBuffer->GetCommandsByType(0 | CommandType::BIND_PIPELINE);
+    if (!bindPipelineCmds.empty())
     {
-      mGl.Enable(GL_CULL_FACE);
-      mGl.CullFace(GetCullFace(rasterizationState.cullMode));
-    }
-
-    mGl.FrontFace(GetFrontFace(rasterizationState.frontFace));
-    // We don't modify glPolygonMode in our context/abstraction from GL_FILL (the GL default),
-    // so it isn't present in the API (and won't have any tests!)
+      auto      pipeline = bindPipelineCmds[0]->bindPipeline.pipeline;
+      auto      &vi      = pipeline->vertexInputState;
+      for (auto &attribute : vi.attributes)
+      {
+        mGl.EnableVertexAttribArray(attribute.location);
+        uint32_t attributeOffset = attribute.offset;
+        GLsizei  stride          = vi.bufferBindings[attribute.binding].stride;
+
+        mGl.VertexAttribPointer(attribute.location,
+                                GetNumComponents(attribute.format),
+                                GetGlType(attribute.format),
+                                GL_FALSE, // Not normalized
+                                stride,
+                                reinterpret_cast<void *>(attributeOffset));
+      }
+      // Cull face setup
+      auto &rasterizationState = pipeline->rasterizationState;
+      if (rasterizationState.cullMode == Graphics::CullMode::NONE)
+      {
+        mGl.Disable(GL_CULL_FACE);
+      }
+      else
+      {
+        mGl.Enable(GL_CULL_FACE);
+        mGl.CullFace(GetCullFace(rasterizationState.cullMode));
+      }
 
-    // Blending setup
-    auto& colorBlendState = commandBuffer->mPipeline->colorBlendState;
-    if(colorBlendState.blendEnable)
-    {
-      mGl.Enable(GL_BLEND);
+      mGl.FrontFace(GetFrontFace(rasterizationState.frontFace));
+      // We don't modify glPolygonMode in our context/abstraction from GL_FILL (the GL default),
+      // so it isn't present in the API (and won't have any tests!)
 
-      mGl.BlendFuncSeparate(GetBlendFactor(colorBlendState.srcColorBlendFactor),
-                            GetBlendFactor(colorBlendState.dstColorBlendFactor),
-                            GetBlendFactor(colorBlendState.srcAlphaBlendFactor),
-                            GetBlendFactor(colorBlendState.dstAlphaBlendFactor));
-      if(colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
+      // Blending setup
+      auto &colorBlendState = pipeline->colorBlendState;
+      if (colorBlendState.blendEnable)
       {
-        mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp));
+        mGl.Enable(GL_BLEND);
+
+        mGl.BlendFuncSeparate(GetBlendFactor(colorBlendState.srcColorBlendFactor),
+                              GetBlendFactor(colorBlendState.dstColorBlendFactor),
+                              GetBlendFactor(colorBlendState.srcAlphaBlendFactor),
+                              GetBlendFactor(colorBlendState.dstAlphaBlendFactor));
+        if (colorBlendState.colorBlendOp != colorBlendState.alphaBlendOp)
+        {
+          mGl.BlendEquationSeparate(GetBlendOp(colorBlendState.colorBlendOp), GetBlendOp(colorBlendState.alphaBlendOp));
+        }
+        else
+        {
+          mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp));
+        }
+        mGl.BlendColor(colorBlendState.blendConstants[0],
+                       colorBlendState.blendConstants[1],
+                       colorBlendState.blendConstants[2],
+                       colorBlendState.blendConstants[3]);
       }
       else
       {
-        mGl.BlendEquation(GetBlendOp(colorBlendState.colorBlendOp));
+        mGl.Disable(GL_BLEND);
       }
-      mGl.BlendColor(colorBlendState.blendConstants[0],
-                     colorBlendState.blendConstants[1],
-                     colorBlendState.blendConstants[2],
-                     colorBlendState.blendConstants[3]);
-    }
-    else
-    {
-      mGl.Disable(GL_BLEND);
-    }
 
-    // draw call
-    auto topology = commandBuffer->mPipeline->inputAssemblyState.topology;
+      // draw call
+      auto topology = pipeline->inputAssemblyState.topology;
 
-    if(commandBuffer->drawCommand.drawType == TestGraphicsCommandBuffer::Draw::DrawType::Indexed)
-    {
-      mGl.DrawElements(GetTopology(topology),
-                       static_cast<GLsizei>(commandBuffer->drawCommand.u.indexedDraw.indexCount),
-                       GL_UNSIGNED_SHORT,
-                       reinterpret_cast<void*>(commandBuffer->drawCommand.u.indexedDraw.firstIndex));
-    }
-    else
-    {
-      mGl.DrawArrays(GetTopology(topology), 0, commandBuffer->drawCommand.u.unindexedDraw.vertexCount);
-    }
+      // UniformBuffer binding (once we know pipeline)
+      auto bindUniformBuffersCmds = commandBuffer->GetCommandsByType(0 | CommandType::BIND_UNIFORM_BUFFER);
+      if (!bindUniformBuffersCmds.empty())
+      {
+        auto buffer = bindUniformBuffersCmds[0]->bindUniformBuffers.standaloneUniformsBufferBinding;
 
-    // attribute clear
-    for(auto& attribute : vi.attributes)
-    {
-      mGl.DisableVertexAttribArray(attribute.location);
+        // based on reflection, issue gl calls
+        buffer.buffer->BindAsUniformBuffer( static_cast<const TestGraphicsProgram*>(pipeline->programState.program) );
+      }
+
+      auto drawCmds = commandBuffer->GetCommandsByType( 0 |
+        CommandType::DRAW |
+        CommandType::DRAW_INDEXED_INDIRECT |
+        CommandType::DRAW_INDEXED );
+
+      if(!drawCmds.empty())
+      {
+        if (drawCmds[0]->draw.type == DrawCallDescriptor::Type::DRAW_INDEXED )
+        {
+          mGl.DrawElements(GetTopology(topology),
+                           static_cast<GLsizei>(drawCmds[0]->draw.drawIndexed.indexCount),
+                           GL_UNSIGNED_SHORT,
+                           reinterpret_cast<void *>(drawCmds[0]->draw.drawIndexed.firstIndex));
+        }
+        else
+        {
+          mGl.DrawArrays(GetTopology(topology), 0, drawCmds[0]->draw.draw.vertexCount);
+        }
+      }
+      // attribute clear
+      for (auto &attribute : vi.attributes)
+      {
+        mGl.DisableVertexAttribArray(attribute.location);
+      }
     }
   }
 }
@@ -711,7 +752,38 @@ Graphics::UniquePtr<Graphics::Pipeline> TestGraphicsController::CreatePipeline(c
 Graphics::UniquePtr<Graphics::Program> TestGraphicsController::CreateProgram(const Graphics::ProgramCreateInfo& programCreateInfo, Graphics::UniquePtr<Graphics::Program>&& oldProgram)
 {
   mCallStack.PushCall("CreateProgram", "");
-  return Graphics::MakeUnique<TestGraphicsProgram>(mGl, programCreateInfo, mVertexFormats);
+
+  for(auto cacheEntry : mProgramCache)
+  {
+    bool found = true;
+    for(auto& shader : *(programCreateInfo.shaderState))
+    {
+      auto graphicsShader = Uncast<TestGraphicsShader>(shader.shader);
+      std::vector<uint8_t> source;
+      source.resize(graphicsShader->mCreateInfo.sourceSize);
+      memcpy(&source[0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize);
+
+      if(!std::equal(source.begin(), source.end(), cacheEntry.shaders[shader.pipelineStage].begin()))
+      {
+        found = false;
+        break;
+      }
+    }
+    if(found)
+    {
+      return Graphics::MakeUnique<TestGraphicsProgram>(cacheEntry.programImpl);
+    }
+  }
+
+  mProgramCache.emplace_back();
+  mProgramCache.back().programImpl = new TestGraphicsProgramImpl(mGl, programCreateInfo, mVertexFormats, mCustomUniforms);
+  for(auto& shader : *(programCreateInfo.shaderState))
+  {
+    auto graphicsShader                                = Uncast<TestGraphicsShader>(shader.shader);
+    mProgramCache.back().shaders[shader.pipelineStage].resize( graphicsShader->mCreateInfo.sourceSize );
+    memcpy(&mProgramCache.back().shaders[shader.pipelineStage][0], graphicsShader->mCreateInfo.sourceData, graphicsShader->mCreateInfo.sourceSize);
+  }
+  return Graphics::MakeUnique<TestGraphicsProgram>(mProgramCache.back().programImpl);
 }
 
 Graphics::UniquePtr<Graphics::Shader> TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader)
@@ -789,7 +861,7 @@ bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0,
   return false;
 }
 
-bool TestGraphicsController::GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData )
+bool TestGraphicsController::GetProgramParameter(Graphics::Program& program, uint32_t parameterId, void* outData)
 {
   mCallStack.PushCall("GetProgramParameter", "");
   auto graphicsProgram = Uncast<TestGraphicsProgram>(&program);