Updated test harness to match dali-core : Textures 85/252985/4
authorDavid Steele <david.steele@samsung.com>
Wed, 3 Feb 2021 15:53:44 +0000 (15:53 +0000)
committerDavid Steele <david.steele@samsung.com>
Tue, 9 Feb 2021 17:00:32 +0000 (17:00 +0000)
Change-Id: I7bb7b4db2c540f5fee385d9f7a9775b006bc47e1

18 files changed:
automated-tests/src/dali-adaptor-internal/CMakeLists.txt
automated-tests/src/dali-adaptor/CMakeLists.txt
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-buffer.h [new file with mode: 0644]
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.cpp [new file with mode: 0644]
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.h [new file with mode: 0644]
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp [new file with mode: 0644]
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-sampler.cpp [new file with mode: 0644]
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-sampler.h [new file with mode: 0644]
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-texture.cpp [new file with mode: 0644]
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-texture.h [new file with mode: 0644]
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-native-image.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-native-image.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-trace-call-stack.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-trace-call-stack.h
automated-tests/src/dali-graphics/CMakeLists.txt
automated-tests/src/dali-platform-abstraction/CMakeLists.txt

index e83c487..4801027 100644 (file)
@@ -29,6 +29,10 @@ LIST(APPEND TC_SOURCES
     ../dali-adaptor/dali-test-suite-utils/test-application.cpp
     ../dali-adaptor/dali-test-suite-utils/test-gl-abstraction.cpp
     ../dali-adaptor/dali-test-suite-utils/test-gl-sync-abstraction.cpp
+    ../dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.cpp
+    ../dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp
+    ../dali-adaptor/dali-test-suite-utils/test-graphics-texture.cpp
+    ../dali-adaptor/dali-test-suite-utils/test-graphics-sampler.cpp
     ../dali-adaptor/dali-test-suite-utils/test-native-image.cpp
     ../dali-adaptor/dali-test-suite-utils/test-platform-abstraction.cpp
     ../dali-adaptor/dali-test-suite-utils/test-render-controller.cpp
index cfb9c7d..3349426 100644 (file)
@@ -28,6 +28,10 @@ LIST(APPEND TC_SOURCES
     dali-test-suite-utils/test-gesture-generator.cpp
     dali-test-suite-utils/test-gl-abstraction.cpp
     dali-test-suite-utils/test-gl-sync-abstraction.cpp
+    dali-test-suite-utils/test-graphics-command-buffer.cpp
+    dali-test-suite-utils/test-graphics-controller.cpp
+    dali-test-suite-utils/test-graphics-texture.cpp
+    dali-test-suite-utils/test-graphics-sampler.cpp
     dali-test-suite-utils/test-native-image.cpp
     dali-test-suite-utils/test-platform-abstraction.cpp
     dali-test-suite-utils/test-render-controller.cpp
index 861f4ae..2af9660 100644 (file)
@@ -2,7 +2,7 @@
 #define TEST_GL_ABSTRACTION_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -438,13 +438,13 @@ public:
   inline void DeleteTextures(GLsizei n, const GLuint* textures) override
   {
     std::stringstream out;
-    out << n << ", " << textures << " = [";
+    out << "n:" << n << " textures[";
 
     TraceCallStack::NamedParams namedParams;
 
     for(GLsizei i = 0; i < n; i++)
     {
-      out << textures[i] << ", ";
+      out << (i > 0 ? ", " : "") << textures[i];
       std::stringstream paramName;
       paramName << "texture[" << i << "]";
       namedParams[paramName.str()] = ToString(textures[i]);
@@ -1151,12 +1151,20 @@ public:
   inline void TexParameteri(GLenum target, GLenum pname, GLint param) override
   {
     std::stringstream out;
-    out << target << ", " << pname << ", " << param;
+    out << std::hex << target << ", " << pname << ", " << param;
+    std::string params = out.str();
+
+    out.str("");
+    out << std::hex << target;
     TraceCallStack::NamedParams namedParams;
-    namedParams["target"] = ToString(target);
-    namedParams["pname"]  = ToString(pname);
-    namedParams["param"]  = ToString(param);
-    mTexParamaterTrace.PushCall("TexParameteri", out.str(), namedParams);
+    namedParams["target"] = out.str();
+    out.str("");
+    out << std::hex << pname;
+    namedParams["pname"] = out.str();
+    out.str("");
+    out << std::hex << param;
+    namedParams["param"] = out.str();
+    mTexParamaterTrace.PushCall("TexParameteri", params, namedParams);
   }
 
   inline void TexParameteriv(GLenum target, GLenum pname, const GLint* params) override
@@ -2429,7 +2437,7 @@ private:
   TraceCallStack mCullFaceTrace;
   TraceCallStack mEnableDisableTrace;
   TraceCallStack mShaderTrace;
-  TraceCallStack mTextureTrace;
+  TraceCallStack mTextureTrace{"GlA Texture:"};
   TraceCallStack mTexParamaterTrace;
   TraceCallStack mDrawTrace;
   TraceCallStack mDepthFunctionTrace;
diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-buffer.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-buffer.h
new file mode 100644 (file)
index 0000000..6a0acac
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef DALI_TEST_GRAPHICS_BUFFER_H
+#define DALI_TEST_GRAPHICS_BUFFER_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/graphics-api/graphics-buffer.h>
+
+namespace Dali
+{
+class TestGraphicsBuffer : public Graphics::Buffer
+{
+public:
+  TestGraphicsBuffer() = default;
+};
+
+} // namespace Dali
+
+#endif //DALI_TEST_GRAPHICS_BUFFER_H
diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.cpp b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.cpp
new file mode 100644 (file)
index 0000000..a32eeef
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "test-graphics-command-buffer.h"
+
+namespace Dali
+{
+TestGraphicsCommandBuffer::TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction)
+: mCallStack(callstack),
+  mGlAbstraction(glAbstraction)
+{
+}
+
+void TestGraphicsCommandBuffer::BindVertexBuffers(uint32_t                             firstBinding,
+                                                  std::vector<const Graphics::Buffer*> buffers,
+                                                  std::vector<uint32_t>                offsets)
+{
+  mCallStack.PushCall("BindVertexBuffers", "");
+}
+
+void TestGraphicsCommandBuffer::BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings)
+{
+  mCallStack.PushCall("BindUniformBuffers", "");
+}
+
+void TestGraphicsCommandBuffer::BindPipeline(const Graphics::Pipeline& pipeline)
+{
+  mCallStack.PushCall("BindPipeline", "");
+}
+
+void TestGraphicsCommandBuffer::BindTextures(std::vector<Graphics::TextureBinding>& textureBindings)
+{
+  mCallStack.PushCall("BindTextures", "");
+  for(auto& binding : textureBindings)
+  {
+    mTextureBindings.push_back(binding);
+  }
+}
+
+void TestGraphicsCommandBuffer::BindSamplers(std::vector<Graphics::SamplerBinding>& samplerBindings)
+{
+  mCallStack.PushCall("BindSamplers", "");
+}
+
+void TestGraphicsCommandBuffer::BindPushConstants(void*    data,
+                                                  uint32_t size,
+                                                  uint32_t binding)
+{
+  mCallStack.PushCall("BindPushConstants", "");
+}
+
+void TestGraphicsCommandBuffer::BindIndexBuffer(const Graphics::Buffer& buffer,
+                                                uint32_t                offset,
+                                                Graphics::Format        format)
+{
+  mCallStack.PushCall("BindIndexBuffer", "");
+}
+
+void TestGraphicsCommandBuffer::BeginRenderPass(
+  Graphics::RenderPass&             renderPass,
+  Graphics::RenderTarget&           renderTarget,
+  Graphics::Extent2D                renderArea,
+  std::vector<Graphics::ClearValue> clearValues)
+{
+  mCallStack.PushCall("BeginRenderPass", "");
+}
+
+void TestGraphicsCommandBuffer::EndRenderPass()
+{
+  mCallStack.PushCall("EndRenderPass", "");
+}
+
+void TestGraphicsCommandBuffer::Draw(
+  uint32_t vertexCount,
+  uint32_t instanceCount,
+  uint32_t firstVertex,
+  uint32_t firstInstance)
+{
+  mCallStack.PushCall("Draw", "");
+}
+
+void TestGraphicsCommandBuffer::DrawIndexed(
+  uint32_t indexCount,
+  uint32_t instanceCount,
+  uint32_t firstIndex,
+  int32_t  vertexOffset,
+  uint32_t firstInstance)
+{
+  mCallStack.PushCall("DrawIndexed", "");
+}
+
+void TestGraphicsCommandBuffer::DrawIndexedIndirect(
+  Graphics::Buffer& buffer,
+  uint32_t          offset,
+  uint32_t          drawCount,
+  uint32_t          stride)
+{
+  mCallStack.PushCall("DrawIndexedIndirect", "");
+}
+
+void TestGraphicsCommandBuffer::Reset(Graphics::CommandBuffer& commandBuffer)
+{
+  mCallStack.PushCall("Reset", "");
+}
+
+void TestGraphicsCommandBuffer::SetScissor(Graphics::Extent2D value)
+{
+  mCallStack.PushCall("SetScissor", "");
+}
+
+void TestGraphicsCommandBuffer::SetScissorTestEnable(bool value)
+{
+  mCallStack.PushCall("SetScissorTestEnable", "");
+}
+
+void TestGraphicsCommandBuffer::SetViewport(Graphics::Viewport value)
+{
+  mCallStack.PushCall("SetViewport", "");
+}
+
+void TestGraphicsCommandBuffer::SetViewportEnable(bool value)
+{
+  mCallStack.PushCall("SetViewportEnable", "");
+}
+
+} // namespace Dali
diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.h
new file mode 100644 (file)
index 0000000..bd6c83a
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef DALI_TEST_GRAPHICS_COMMAND_BUFFER_H
+#define DALI_TEST_GRAPHICS_COMMAND_BUFFER_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/graphics-api/graphics-command-buffer-create-info.h>
+#include <dali/graphics-api/graphics-command-buffer.h>
+#include <dali/graphics-api/graphics-types.h>
+#include <cstdint>
+#include <vector>
+#include "test-gl-abstraction.h"
+#include "test-trace-call-stack.h"
+
+namespace Dali
+{
+class TestGraphicsCommandBuffer : public Graphics::CommandBuffer
+{
+public:
+  TestGraphicsCommandBuffer(TraceCallStack& callstack, TestGlAbstraction& glAbstraction);
+
+  void BindVertexBuffers(uint32_t                             firstBinding,
+                         std::vector<const Graphics::Buffer*> buffers,
+                         std::vector<uint32_t>                offsets);
+
+  void BindUniformBuffers(const std::vector<Graphics::UniformBufferBinding>& bindings);
+
+  void BindPipeline(const Graphics::Pipeline& pipeline);
+
+  void BindTextures(std::vector<Graphics::TextureBinding>& textureBindings);
+
+  void BindSamplers(std::vector<Graphics::SamplerBinding>& samplerBindings);
+
+  void BindPushConstants(void*    data,
+                         uint32_t size,
+                         uint32_t binding);
+
+  void BindIndexBuffer(const Graphics::Buffer& buffer,
+                       uint32_t                offset,
+                       Graphics::Format        format);
+
+  void BeginRenderPass(Graphics::RenderPass&             renderPass,
+                       Graphics::RenderTarget&           renderTarget,
+                       Graphics::Extent2D                renderArea,
+                       std::vector<Graphics::ClearValue> clearValues);
+
+  void EndRenderPass();
+
+  void Draw(
+    uint32_t vertexCount,
+    uint32_t instanceCount,
+    uint32_t firstVertex,
+    uint32_t firstInstance);
+
+  void DrawIndexed(
+    uint32_t indexCount,
+    uint32_t instanceCount,
+    uint32_t firstIndex,
+    int32_t  vertexOffset,
+    uint32_t firstInstance);
+
+  void DrawIndexedIndirect(
+    Graphics::Buffer& buffer,
+    uint32_t          offset,
+    uint32_t          drawCount,
+    uint32_t          stride);
+
+  void Reset(Graphics::CommandBuffer& commandBuffer);
+
+  void SetScissor(Graphics::Extent2D value);
+
+  void SetScissorTestEnable(bool value);
+
+  void SetViewport(Graphics::Viewport value);
+
+  void SetViewportEnable(bool value);
+
+public:
+  TraceCallStack     mCallStack;
+  TestGlAbstraction& mGlAbstraction;
+
+  std::vector<Graphics::TextureBinding> mTextureBindings;
+};
+
+} // namespace Dali
+
+#endif //DALI_TEST_GRAPHICS_COMMAND_BUFFER_H
diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp
new file mode 100644 (file)
index 0000000..4732a9a
--- /dev/null
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "test-graphics-controller.h"
+
+#include "test-graphics-buffer.h"
+#include "test-graphics-command-buffer.h"
+#include "test-graphics-sampler.h"
+#include "test-graphics-texture.h"
+
+#include <dali/integration-api/gl-defines.h>
+#include <iostream>
+#include <sstream>
+
+namespace Dali
+{
+std::ostream& operator<<(std::ostream& o, const Graphics::BufferCreateInfo& bufferCreateInfo)
+{
+  return o << "usage:" << std::hex << bufferCreateInfo.usage << ", size:" << std::dec << bufferCreateInfo.size;
+}
+
+std::ostream& operator<<(std::ostream& o, const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo)
+{
+  return o << "level:" << (commandBufferCreateInfo.level == Graphics::CommandBufferLevel::PRIMARY ? "PRIMARY" : "SECONDARY")
+           << ", fixedCapacity:" << std::dec << commandBufferCreateInfo.fixedCapacity;
+}
+
+std::ostream& operator<<(std::ostream& o, const Graphics::TextureType& textureType)
+{
+  switch(textureType)
+  {
+    case Graphics::TextureType::TEXTURE_2D:
+      o << "TEXTURE_2D";
+      break;
+    case Graphics::TextureType::TEXTURE_3D:
+      o << "TEXTURE_3D";
+      break;
+    case Graphics::TextureType::TEXTURE_CUBEMAP:
+      o << "TEXTURE_CUBEMAP";
+      break;
+  }
+  return o;
+}
+
+std::ostream& operator<<(std::ostream& o, const Graphics::Extent2D extent)
+{
+  o << "width:" << extent.width << ", height:" << extent.height;
+  return o;
+}
+
+std::ostream& operator<<(std::ostream& o, const Graphics::TextureCreateInfo& createInfo)
+{
+  o << "textureType:" << createInfo.textureType
+    << " size:" << createInfo.size
+    << " format:" << static_cast<uint32_t>(createInfo.format)
+    << " mipMapFlag:" << createInfo.mipMapFlag
+    << " layout:" << (createInfo.layout == Graphics::TextureLayout::LINEAR ? "LINEAR" : "OPTIMAL")
+    << " usageFlags:" << std::hex << createInfo.usageFlags
+    << " data:" << std::hex << createInfo.data
+    << " dataSize:" << std::dec << createInfo.dataSize
+    << " nativeImagePtr:" << std::hex << createInfo.nativeImagePtr;
+  return o;
+}
+
+std::ostream& operator<<(std::ostream& o, Graphics::SamplerAddressMode addressMode)
+{
+  switch(addressMode)
+  {
+    case Graphics::SamplerAddressMode::REPEAT:
+      o << "REPEAT";
+      break;
+    case Graphics::SamplerAddressMode::MIRRORED_REPEAT:
+      o << "MIRRORED_REPEAT";
+      break;
+    case Graphics::SamplerAddressMode::CLAMP_TO_EDGE:
+      o << "CLAMP_TO_EDGE";
+      break;
+    case Graphics::SamplerAddressMode::CLAMP_TO_BORDER:
+      o << "CLAMP_TO_BORDER";
+      break;
+    case Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE:
+      o << "MIRROR_CLAMP_TO_EDGE";
+      break;
+  }
+  return o;
+}
+
+std::ostream& operator<<(std::ostream& o, Graphics::SamplerFilter filterMode)
+{
+  switch(filterMode)
+  {
+    case Graphics::SamplerFilter::LINEAR:
+      o << "LINEAR";
+      break;
+    case Graphics::SamplerFilter::NEAREST:
+      o << "NEAREST";
+      break;
+  }
+  return o;
+}
+
+std::ostream& operator<<(std::ostream& o, Graphics::SamplerMipmapMode mipmapMode)
+{
+  switch(mipmapMode)
+  {
+    case Graphics::SamplerMipmapMode::NONE:
+      o << "NONE";
+      break;
+    case Graphics::SamplerMipmapMode::LINEAR:
+      o << "LINEAR";
+      break;
+    case Graphics::SamplerMipmapMode::NEAREST:
+      o << "NEAREST";
+      break;
+  }
+  return o;
+}
+
+std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& createInfo)
+{
+  o << "minFilter:" << createInfo.minFilter
+    << " magFilter:" << createInfo.magFilter
+    << " wrapModeU:" << createInfo.addressModeU
+    << " wrapModeV:" << createInfo.addressModeV
+    << " wrapModeW:" << createInfo.addressModeW
+    << " mipMapMode:" << createInfo.mipMapMode;
+  return o;
+}
+
+TestGraphicsController::TestGraphicsController()
+{
+  mCallStack.Enable(true);
+  mCallStack.EnableLogging(true);
+  mCommandBufferCallStack.Enable(true);
+  mCommandBufferCallStack.EnableLogging(true);
+  auto& trace = mGlAbstraction.GetTextureTrace();
+  trace.Enable(true);
+  trace.EnableLogging(true);
+}
+
+void TestGraphicsController::SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo)
+{
+  std::ostringstream          out;
+  TraceCallStack::NamedParams namedParams;
+  out << "cmdBuffer[" << submitInfo.cmdBuffer.size() << "], flags:" << std::hex << submitInfo.flags;
+  namedParams["submitInfo"] = out.str();
+
+  mCallStack.PushCall("SubmitCommandBuffers", "", namedParams);
+
+  for(auto& commandBuffer : submitInfo.cmdBuffer)
+  {
+    for(auto& binding : (static_cast<TestGraphicsCommandBuffer*>(commandBuffer))->mTextureBindings)
+    {
+      if(binding.texture)
+      {
+        auto texture = const_cast<TestGraphicsTexture*>(static_cast<const TestGraphicsTexture*>(binding.texture));
+
+        texture->Bind(binding.binding);
+
+        if(binding.sampler)
+        {
+          auto sampler = const_cast<TestGraphicsSampler*>(static_cast<const TestGraphicsSampler*>(binding.sampler));
+          if(sampler)
+          {
+            sampler->Apply(texture->GetTarget());
+          }
+        }
+
+        texture->Prepare(); // Ensure native texture is ready
+      }
+    }
+  }
+}
+
+/**
+ * @brief Presents render target
+ * @param renderTarget render target to present
+ */
+void TestGraphicsController::PresentRenderTarget(Graphics::RenderTarget* renderTarget)
+{
+  std::ostringstream          out;
+  TraceCallStack::NamedParams namedParams;
+  out << std::hex << renderTarget;
+  namedParams["renderTarget"] = out.str();
+  mCallStack.PushCall("PresentRenderTarget", "", namedParams);
+}
+
+/**
+ * @brief Waits until the GPU is idle
+ */
+void TestGraphicsController::WaitIdle()
+{
+  mCallStack.PushCall("WaitIdle", "");
+}
+
+/**
+ * @brief Lifecycle pause event
+ */
+void TestGraphicsController::Pause()
+{
+  mCallStack.PushCall("Pause", "");
+}
+
+/**
+ * @brief Lifecycle resume event
+ */
+void TestGraphicsController::Resume()
+{
+  mCallStack.PushCall("Resume", "");
+}
+
+void TestGraphicsController::UpdateTextures(const std::vector<Graphics::TextureUpdateInfo>&       updateInfoList,
+                                            const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList)
+{
+  std::ostringstream          out;
+  TraceCallStack::NamedParams namedParams;
+  out << "[" << updateInfoList.size() << "]:";
+  namedParams["updateInfoList"] = out.str();
+  out.str("");
+  out << "[" << sourceList.size() << "]:";
+  namedParams["sourceList"] = out.str();
+
+  mCallStack.PushCall("UpdateTextures", "", namedParams);
+
+  // Call either TexImage2D or TexSubImage2D
+  for(unsigned int i = 0; i < updateInfoList.size(); ++i)
+  {
+    auto& updateInfo = updateInfoList[i];
+    auto& source     = sourceList[i];
+
+    auto texture = static_cast<TestGraphicsTexture*>(updateInfo.dstTexture);
+    texture->Bind(0); // Use first texture unit during resource update
+    texture->Update(updateInfo, source);
+  }
+}
+
+bool TestGraphicsController::EnableDepthStencilBuffer(bool enableDepth, bool enableStencil)
+{
+  TraceCallStack::NamedParams namedParams;
+  namedParams["enableDepth"]   = enableDepth ? "T" : "F";
+  namedParams["enableStencil"] = enableStencil ? "T" : "F";
+  mCallStack.PushCall("EnableDepthStencilBuffer", "", namedParams);
+  return false;
+}
+
+void TestGraphicsController::RunGarbageCollector(size_t numberOfDiscardedRenderers)
+{
+  std::ostringstream out;
+  out << numberOfDiscardedRenderers;
+  TraceCallStack::NamedParams namedParams;
+  namedParams["numberOfDiscardedrenderers"] = out.str();
+  mCallStack.PushCall("RunGarbageCollector", "", namedParams);
+}
+
+void TestGraphicsController::DiscardUnusedResources()
+{
+  mCallStack.PushCall("DiscardUnusedResources", "");
+}
+
+bool TestGraphicsController::IsDiscardQueueEmpty()
+{
+  mCallStack.PushCall("IsDiscardQueueEmpty", "");
+  return isDiscardQueueEmptyResult;
+}
+
+/**
+ * @brief Test if the graphics subsystem has resumed & should force a draw
+ *
+ * @return true if the graphics subsystem requires a re-draw
+ */
+bool TestGraphicsController::IsDrawOnResumeRequired()
+{
+  mCallStack.PushCall("IsDrawOnResumeRequired", "");
+  return isDrawOnResumeRequiredResult;
+}
+
+Graphics::UniquePtr<Graphics::Buffer> TestGraphicsController::CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer)
+{
+  std::ostringstream oss;
+  oss << "bufferCreateInfo:" << bufferCreateInfo;
+  mCallStack.PushCall("CreateBuffer", oss.str());
+
+  return Graphics::MakeUnique<TestGraphicsBuffer>();
+}
+
+Graphics::UniquePtr<Graphics::CommandBuffer> TestGraphicsController::CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer)
+{
+  std::ostringstream oss;
+  oss << "commandBufferCreateInfo:" << commandBufferCreateInfo;
+  mCallStack.PushCall("CreateCommandBuffer", oss.str());
+  return Graphics::MakeUnique<TestGraphicsCommandBuffer>(mCommandBufferCallStack, mGlAbstraction);
+}
+
+Graphics::UniquePtr<Graphics::RenderPass> TestGraphicsController::CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass)
+{
+  mCallStack.PushCall("CreateRenderPass", "");
+  return nullptr;
+}
+
+Graphics::UniquePtr<Graphics::Texture> TestGraphicsController::CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture)
+{
+  std::ostringstream params, oss;
+  params << "textureCreateInfo:" << textureCreateInfo;
+  TraceCallStack::NamedParams namedParams;
+  oss << textureCreateInfo;
+  namedParams["textureCreateInfo"] = oss.str();
+  mCallStack.PushCall("CreateTexture", params.str(), namedParams);
+
+  return Graphics::MakeUnique<TestGraphicsTexture>(mGlAbstraction, textureCreateInfo);
+}
+
+Graphics::UniquePtr<Graphics::Framebuffer> TestGraphicsController::CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer)
+{
+  mCallStack.PushCall("CreateFramebuffer", "");
+  return nullptr;
+}
+
+Graphics::UniquePtr<Graphics::Pipeline> TestGraphicsController::CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline)
+{
+  mCallStack.PushCall("CreatePipeline", "");
+  return nullptr;
+}
+
+Graphics::UniquePtr<Graphics::Shader> TestGraphicsController::CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader)
+{
+  mCallStack.PushCall("CreateShader", "");
+  return nullptr;
+}
+
+Graphics::UniquePtr<Graphics::Sampler> TestGraphicsController::CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Graphics::Sampler>&& oldSampler)
+{
+  std::ostringstream params, oss;
+  params << "samplerCreateInfo:" << samplerCreateInfo;
+  TraceCallStack::NamedParams namedParams;
+  oss << samplerCreateInfo;
+  namedParams["samplerCreateInfo"] = oss.str();
+  mCallStack.PushCall("CreateSampler", params.str(), namedParams);
+
+  return Graphics::MakeUnique<TestGraphicsSampler>(mGlAbstraction, samplerCreateInfo);
+}
+
+Graphics::UniquePtr<Graphics::RenderTarget> TestGraphicsController::CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget)
+{
+  mCallStack.PushCall("CreateRenderTarget", "");
+  return nullptr;
+}
+
+Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapBufferRange(const Graphics::MapBufferInfo& mapInfo)
+{
+  mCallStack.PushCall("MapBufferRange", "");
+  return nullptr;
+}
+
+Graphics::UniquePtr<Graphics::Memory> TestGraphicsController::MapTextureRange(const Graphics::MapTextureInfo& mapInfo)
+{
+  mCallStack.PushCall("MapTextureRange", "");
+  return nullptr;
+}
+
+void TestGraphicsController::UnmapMemory(Graphics::UniquePtr<Graphics::Memory> memory)
+{
+  mCallStack.PushCall("UnmapMemory", "");
+}
+
+Graphics::MemoryRequirements TestGraphicsController::GetTextureMemoryRequirements(Graphics::Texture& texture) const
+{
+  mCallStack.PushCall("GetTextureMemoryRequirements", "");
+  return Graphics::MemoryRequirements{};
+}
+
+Graphics::MemoryRequirements TestGraphicsController::GetBufferMemoryRequirements(Graphics::Buffer& buffer) const
+{
+  mCallStack.PushCall("GetBufferMemoryRequirements", "");
+  return Graphics::MemoryRequirements{};
+}
+
+const Graphics::TextureProperties& TestGraphicsController::GetTextureProperties(const Graphics::Texture& texture)
+{
+  static Graphics::TextureProperties textureProperties{};
+  mCallStack.PushCall("GetTextureProperties", "");
+
+  return textureProperties;
+}
+
+bool TestGraphicsController::PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const
+{
+  mCallStack.PushCall("PipelineEquals", "");
+  return false;
+}
+
+} // namespace Dali
index 194698b..f218134 100644 (file)
@@ -37,9 +37,7 @@ std::ostream& operator<<(std::ostream& o, const Graphics::SamplerCreateInfo& cre
 class TestGraphicsController : public Dali::Graphics::Controller
 {
 public:
-  TestGraphicsController()
-  {
-  }
+  TestGraphicsController();
 
   virtual ~TestGraphicsController() = default;
 
@@ -63,38 +61,28 @@ public:
     return mGlContextHelperAbstraction;
   }
 
-  void SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo) override
-  {
-  }
+  void SubmitCommandBuffers(const Graphics::SubmitInfo& submitInfo) override;
 
   /**
    * @brief Presents render target
    * @param renderTarget render target to present
    */
-  void PresentRenderTarget(Graphics::RenderTarget* renderTarget) override
-  {
-  }
+  void PresentRenderTarget(Graphics::RenderTarget* renderTarget) override;
 
   /**
    * @brief Waits until the GPU is idle
    */
-  void WaitIdle() override
-  {
-  }
+  void WaitIdle() override;
 
   /**
    * @brief Lifecycle pause event
    */
-  void Pause() override
-  {
-  }
+  void Pause() override;
 
   /**
    * @brief Lifecycle resume event
    */
-  void Resume() override
-  {
-  }
+  void Resume() override;
 
   /**
    * @brief Executes batch update of textures
@@ -110,40 +98,25 @@ public:
    *
    */
   void UpdateTextures(const std::vector<Graphics::TextureUpdateInfo>&       updateInfoList,
-                      const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList) override
-  {
-  }
+                      const std::vector<Graphics::TextureUpdateSourceInfo>& sourceList) override;
 
   /**
    * TBD: do we need those functions in the new implementation?
    */
-  bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override
-  {
-    return {};
-  }
+  bool EnableDepthStencilBuffer(bool enableDepth, bool enableStencil) override;
 
-  void RunGarbageCollector(size_t numberOfDiscardedRenderers) override
-  {
-  }
+  void RunGarbageCollector(size_t numberOfDiscardedRenderers) override;
 
-  void DiscardUnusedResources() override
-  {
-  }
+  void DiscardUnusedResources() override;
 
-  bool IsDiscardQueueEmpty() override
-  {
-    return {};
-  }
+  bool IsDiscardQueueEmpty() override;
 
   /**
    * @brief Test if the graphics subsystem has resumed & should force a draw
    *
    * @return true if the graphics subsystem requires a re-draw
    */
-  bool IsDrawOnResumeRequired() override
-  {
-    return {};
-  }
+  bool IsDrawOnResumeRequired() override;
 
   /**
    * @brief Creates new Buffer object
@@ -159,10 +132,7 @@ public:
    * @param[in] bufferCreateInfo The valid BufferCreateInfo structure
    * @return pointer to the Buffer object
    */
-  Graphics::UniquePtr<Graphics::Buffer> CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::Buffer> CreateBuffer(const Graphics::BufferCreateInfo& bufferCreateInfo, Graphics::UniquePtr<Graphics::Buffer>&& oldBuffer) override;
 
   /**
    * @brief Creates new CommandBuffer object
@@ -170,10 +140,7 @@ public:
    * @param[in] bufferCreateInfo The valid BufferCreateInfo structure
    * @return pointer to the CommandBuffer object
    */
-  Graphics::UniquePtr<Graphics::CommandBuffer> CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::CommandBuffer> CreateCommandBuffer(const Graphics::CommandBufferCreateInfo& commandBufferCreateInfo, Graphics::UniquePtr<Graphics::CommandBuffer>&& oldCommandBuffer) override;
 
   /**
    * @brief Creates new RenderPass object
@@ -181,10 +148,7 @@ public:
    * @param[in] renderPassCreateInfo The valid RenderPassCreateInfo structure
    * @return pointer to the RenderPass object
    */
-  Graphics::UniquePtr<Graphics::RenderPass> CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::RenderPass> CreateRenderPass(const Graphics::RenderPassCreateInfo& renderPassCreateInfo, Graphics::UniquePtr<Graphics::RenderPass>&& oldRenderPass) override;
 
   /**
    * @brief Creates new Texture object
@@ -192,10 +156,7 @@ public:
    * @param[in] textureCreateInfo The valid TextureCreateInfo structure
    * @return pointer to the TextureCreateInfo object
    */
-  Graphics::UniquePtr<Graphics::Texture> CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::Texture> CreateTexture(const Graphics::TextureCreateInfo& textureCreateInfo, Graphics::UniquePtr<Graphics::Texture>&& oldTexture) override;
 
   /**
    * @brief Creates new Framebuffer object
@@ -203,10 +164,7 @@ public:
    * @param[in] framebufferCreateInfo The valid FramebufferCreateInfo structure
    * @return pointer to the Framebuffer object
    */
-  Graphics::UniquePtr<Graphics::Framebuffer> CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::Framebuffer> CreateFramebuffer(const Graphics::FramebufferCreateInfo& framebufferCreateInfo, Graphics::UniquePtr<Graphics::Framebuffer>&& oldFramebuffer) override;
 
   /**
    * @brief Creates new Pipeline object
@@ -214,10 +172,7 @@ public:
    * @param[in] pipelineCreateInfo The valid PipelineCreateInfo structure
    * @return pointer to the Pipeline object
    */
-  Graphics::UniquePtr<Graphics::Pipeline> CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::Pipeline> CreatePipeline(const Graphics::PipelineCreateInfo& pipelineCreateInfo, Graphics::UniquePtr<Graphics::Pipeline>&& oldPipeline) override;
 
   /**
    * @brief Creates new Shader object
@@ -225,10 +180,7 @@ public:
    * @param[in] shaderCreateInfo The valid ShaderCreateInfo structure
    * @return pointer to the Shader object
    */
-  Graphics::UniquePtr<Graphics::Shader> CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::Shader> CreateShader(const Graphics::ShaderCreateInfo& shaderCreateInfo, Graphics::UniquePtr<Graphics::Shader>&& oldShader) override;
 
   /**
    * @brief Creates new Sampler object
@@ -236,10 +188,7 @@ public:
    * @param[in] samplerCreateInfo The valid SamplerCreateInfo structure
    * @return pointer to the Sampler object
    */
-  Graphics::UniquePtr<Graphics::Sampler> CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Graphics::Sampler>&& oldSampler) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::Sampler> CreateSampler(const Graphics::SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Graphics::Sampler>&& oldSampler) override;
 
   /**
    * @brief Creates new RenderTarget object
@@ -247,10 +196,7 @@ public:
    * @param[in] renderTargetCreateInfo The valid RenderTargetCreateInfo structure
    * @return pointer to the RenderTarget object
    */
-  Graphics::UniquePtr<Graphics::RenderTarget> CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::RenderTarget> CreateRenderTarget(const Graphics::RenderTargetCreateInfo& renderTargetCreateInfo, Graphics::UniquePtr<Graphics::RenderTarget>&& oldRenderTarget) override;
 
   /**
    * @brief Maps memory associated with Buffer object
@@ -259,10 +205,7 @@ public:
    *
    * @return Returns pointer to Memory object or Graphicsnullptr on error
    */
-  Graphics::UniquePtr<Graphics::Memory> MapBufferRange(const Graphics::MapBufferInfo& mapInfo) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::Memory> MapBufferRange(const Graphics::MapBufferInfo& mapInfo) override;
 
   /**
    * @brief Maps memory associated with the texture.
@@ -278,10 +221,7 @@ public:
    *
    * @return Valid Memory object or nullptr on error
    */
-  Graphics::UniquePtr<Graphics::Memory> MapTextureRange(const Graphics::MapTextureInfo& mapInfo) override
-  {
-    return {};
-  }
+  Graphics::UniquePtr<Graphics::Memory> MapTextureRange(const Graphics::MapTextureInfo& mapInfo) override;
 
   /**
    * @brief Unmaps memory and discards Memory object
@@ -291,9 +231,7 @@ public:
    *
    * @param[in] memory Valid and previously mapped Memory object
    */
-  void UnmapMemory(Graphics::UniquePtr<Graphics::Memory> memory) override
-  {
-  }
+  void UnmapMemory(Graphics::UniquePtr<Graphics::Memory> memory) override;
 
   /**
    * @brief Returns memory requirements of the Texture object.
@@ -304,10 +242,7 @@ public:
    *
    * @return Returns memory requirements of Texture
    */
-  Graphics::MemoryRequirements GetTextureMemoryRequirements(Graphics::Texture& texture) const override
-  {
-    return {};
-  }
+  Graphics::MemoryRequirements GetTextureMemoryRequirements(Graphics::Texture& texture) const override;
 
   /**
    * @brief Returns memory requirements of the Buffer object.
@@ -318,10 +253,7 @@ public:
    *
    * @return Returns memory requirements of Buffer
    */
-  Graphics::MemoryRequirements GetBufferMemoryRequirements(Graphics::Buffer& buffer) const override
-  {
-    return {};
-  }
+  Graphics::MemoryRequirements GetBufferMemoryRequirements(Graphics::Buffer& buffer) const override;
 
   /**
    * @brief Returns specification of the Texture object
@@ -332,11 +264,7 @@ public:
    *
    * @return Returns the TextureProperties object
    */
-  const Graphics::TextureProperties& GetTextureProperties(const Graphics::Texture& texture) override
-  {
-    static Graphics::TextureProperties properties{};
-    return properties;
-  }
+  const Graphics::TextureProperties& GetTextureProperties(const Graphics::Texture& texture) override;
 
   /**
    * @brief Tests whether two Pipelines are the same.
@@ -345,12 +273,11 @@ public:
    *
    * @return true if pipeline objects match
    */
-  bool PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const override
-  {
-    return {};
-  }
+  bool PipelineEquals(const Graphics::Pipeline& pipeline0, const Graphics::Pipeline& pipeline1) const override;
 
 public:
+  mutable TraceCallStack mCallStack{"TestGraphics:"};
+  mutable TraceCallStack mCommandBufferCallStack{"TestCommandBuffer:"};
 
   TestGlAbstraction              mGlAbstraction;
   TestGlSyncAbstraction          mGlSyncAbstraction;
diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-sampler.cpp b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-sampler.cpp
new file mode 100644 (file)
index 0000000..f0651e4
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "test-graphics-sampler.h"
+
+namespace Dali
+{
+std::map<uint32_t, GLint> TestGraphicsSampler::mParamCache;
+
+TestGraphicsSampler::TestGraphicsSampler(TestGlAbstraction& glAbstraction, const Graphics::SamplerCreateInfo& createInfo)
+: mGlAbstraction(glAbstraction),
+  mCreateInfo(createInfo)
+{
+}
+
+GLint TestGraphicsSampler::FilterModeToGL(Graphics::SamplerFilter filterMode)
+{
+  switch(filterMode)
+  {
+    case Graphics::SamplerFilter::NEAREST:
+    {
+      return GL_NEAREST;
+    }
+    case Graphics::SamplerFilter::LINEAR:
+    {
+      return GL_LINEAR;
+    }
+  }
+  return GL_LINEAR;
+}
+
+GLint TestGraphicsSampler::FilterModeToGL(Graphics::SamplerFilter filterMode, Graphics::SamplerMipmapMode mipmapMode)
+{
+  if(filterMode == Graphics::SamplerFilter::NEAREST)
+  {
+    switch(mipmapMode)
+    {
+      case Graphics::SamplerMipmapMode::NONE:
+        return GL_NEAREST;
+      case Graphics::SamplerMipmapMode::NEAREST:
+        return GL_NEAREST_MIPMAP_NEAREST;
+      case Graphics::SamplerMipmapMode::LINEAR:
+        return GL_NEAREST_MIPMAP_LINEAR;
+    }
+  }
+  else
+  {
+    switch(mipmapMode)
+    {
+      case Graphics::SamplerMipmapMode::NONE:
+        return GL_LINEAR;
+      case Graphics::SamplerMipmapMode::NEAREST:
+        return GL_LINEAR_MIPMAP_NEAREST;
+      case Graphics::SamplerMipmapMode::LINEAR:
+        return GL_LINEAR_MIPMAP_LINEAR;
+    }
+  }
+  return GL_LINEAR;
+}
+
+/**
+ * @brief Convert from a WrapMode to its corresponding GL enumeration
+ * @param[in] wrapMode The wrap mode
+ * @param[in] defaultWrapMode The mode to use if WrapMode is Default
+ * @return The equivalent GL wrap mode
+ */
+GLint TestGraphicsSampler::WrapModeToGL(Graphics::SamplerAddressMode wrapMode)
+{
+  switch(wrapMode)
+  {
+    case Graphics::SamplerAddressMode::CLAMP_TO_EDGE:
+    {
+      return GL_CLAMP_TO_EDGE;
+    }
+    case Graphics::SamplerAddressMode::CLAMP_TO_BORDER:
+    {
+      return GL_CLAMP_TO_EDGE;
+    }
+    case Graphics::SamplerAddressMode::REPEAT:
+    {
+      return GL_REPEAT;
+    }
+    case Graphics::SamplerAddressMode::MIRRORED_REPEAT:
+    {
+      return GL_MIRRORED_REPEAT;
+    }
+    case Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE:
+    {
+      return GL_MIRRORED_REPEAT;
+    }
+  }
+  return GL_REPEAT;
+}
+
+void TestGraphicsSampler::Apply(GLuint target)
+{
+  SetTexParameter(mGlAbstraction, target, GL_TEXTURE_MIN_FILTER, FilterModeToGL(mCreateInfo.minFilter, mCreateInfo.mipMapMode));
+  SetTexParameter(mGlAbstraction, target, GL_TEXTURE_MAG_FILTER, FilterModeToGL(mCreateInfo.magFilter));
+  SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_S, WrapModeToGL(mCreateInfo.addressModeU));
+  SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_T, WrapModeToGL(mCreateInfo.addressModeV));
+  if(target == GL_TEXTURE_CUBE_MAP)
+  {
+    TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_R, WrapModeToGL(mCreateInfo.addressModeW));
+  }
+}
+
+uint32_t TestGraphicsSampler::GetTexParamHash(TestGlAbstraction& glAbstraction, GLuint target, GLenum pname)
+{
+  uint32_t targetFlags = 0;
+  switch(target)
+  {
+    case GL_TEXTURE_2D:
+      targetFlags = 0x01;
+      break;
+    case GL_TEXTURE_CUBE_MAP:
+      targetFlags = 0x02;
+      break;
+    default:
+      targetFlags = 0x03;
+      break;
+  }
+  switch(pname)
+  {
+    case GL_TEXTURE_WRAP_S:
+      targetFlags |= (0x01) << 2;
+      break;
+    case GL_TEXTURE_WRAP_T:
+      targetFlags |= (0x02) << 2;
+      break;
+    case GL_TEXTURE_WRAP_R:
+      targetFlags |= (0x03) << 2;
+      break;
+    case GL_TEXTURE_MAG_FILTER:
+      targetFlags |= (0x04) << 2;
+      break;
+    case GL_TEXTURE_MIN_FILTER:
+      targetFlags |= (0x05) << 2;
+      break;
+    default:
+      targetFlags |= (0x07) << 2;
+      break;
+  }
+  auto& textures = glAbstraction.GetBoundTextures(glAbstraction.GetActiveTextureUnit());
+  targetFlags |= (textures.back() << 5);
+
+  return targetFlags;
+}
+
+void TestGraphicsSampler::SetTexParameter(TestGlAbstraction& glAbstraction, GLuint target, GLenum pname, GLint value)
+{
+  // Works on the currently active texture
+
+  uint32_t hash = GetTexParamHash(glAbstraction, target, pname);
+
+  if(mParamCache.find(hash) != mParamCache.end())
+  {
+    if(mParamCache[hash] != value)
+    {
+      mParamCache[hash] = value;
+      glAbstraction.TexParameteri(target, pname, value);
+    }
+  }
+  else
+  {
+    mParamCache[hash] = value;
+    glAbstraction.TexParameteri(target, pname, value);
+  }
+}
+
+} // namespace Dali
diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-sampler.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-sampler.h
new file mode 100644 (file)
index 0000000..936e436
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef DALI_TEST_GRAPHICS_SAMPLER_H
+#define DALI_TEST_GRAPHICS_SAMPLER_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/graphics-api/graphics-sampler-create-info.h>
+#include <dali/graphics-api/graphics-sampler.h>
+#include <dali/graphics-api/graphics-types.h>
+#include <dali/integration-api/gl-defines.h>
+#include <cstdint>
+#include <map>
+#include "test-gl-abstraction.h"
+
+namespace Dali
+{
+/**
+ * Maintains a cache of parameters per texture/texture target
+ */
+class TestGraphicsSampler : public Graphics::Sampler
+{
+public:
+  TestGraphicsSampler(TestGlAbstraction& glAbstraction, const Graphics::SamplerCreateInfo& createInfo);
+
+  /**
+   * Apply sampler to target texture.
+   */
+  void Apply(GLuint target);
+
+  static void SetTexParameter(TestGlAbstraction& glAbstraction, GLuint target, GLenum pname, GLint value);
+
+  static GLint FilterModeToGL(Graphics::SamplerFilter filterMode);
+
+  static GLint FilterModeToGL(Graphics::SamplerFilter filterMode, Graphics::SamplerMipmapMode mipmapMode);
+
+  /**
+   * @brief Convert from a WrapMode to its corresponding GL enumeration
+   * @param[in] wrapMode The wrap mode
+   * @param[in] defaultWrapMode The mode to use if WrapMode is Default
+   * @return The equivalent GL wrap mode
+   */
+  static GLint WrapModeToGL(Graphics::SamplerAddressMode wrapMode);
+
+  static uint32_t GetTexParamHash(TestGlAbstraction& glAbstraction, GLuint target, GLenum pname);
+
+public:
+  static std::map<uint32_t, GLint> mParamCache;
+
+  TestGlAbstraction&          mGlAbstraction;
+  Graphics::SamplerCreateInfo mCreateInfo;
+};
+
+} // namespace Dali
+
+#endif //DALI_TEST_GRAPHICS_SAMPLER_H
diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-texture.cpp b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-texture.cpp
new file mode 100644 (file)
index 0000000..adeeeca
--- /dev/null
@@ -0,0 +1,968 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "test-graphics-texture.h"
+#include <iostream>
+#include <sstream>
+
+namespace
+{
+// These match the GL specification
+const GLint GL_MINIFY_DEFAULT  = GL_NEAREST_MIPMAP_LINEAR;
+const GLint GL_MAGNIFY_DEFAULT = GL_LINEAR;
+const GLint GL_WRAP_DEFAULT    = GL_CLAMP_TO_EDGE;
+
+// These are the Dali defaults
+const GLint DALI_MINIFY_DEFAULT  = GL_LINEAR;
+const GLint DALI_MAGNIFY_DEFAULT = GL_LINEAR;
+
+GLuint GetTextureTarget(Graphics::TextureType type)
+{
+  GLuint target{GL_TEXTURE_2D};
+
+  switch(type)
+  {
+    case Graphics::TextureType::TEXTURE_2D:
+      target = GL_TEXTURE_2D; // Native texture may override this with GL_TEXTURE_EXTERNAL_OES
+      break;
+    case Graphics::TextureType::TEXTURE_3D:
+      target = GL_TEXTURE_3D;
+      break;
+    case Graphics::TextureType::TEXTURE_CUBEMAP:
+      target = GL_TEXTURE_CUBE_MAP;
+      break;
+  }
+  return target;
+}
+
+/**
+ * @brief Whether specified pixel format is compressed.
+ *
+ * @param [in] pixelformat Pixel format
+ * @return true if format is compressed, false otherwise
+ */
+bool IsCompressedFormat(Graphics::Format pixelFormat)
+{
+  switch(pixelFormat)
+  {
+    case Graphics::Format::UNDEFINED:
+    case Graphics::Format::L8:
+    case Graphics::Format::L8A8:
+    case Graphics::Format::R4G4_UNORM_PACK8:
+    case Graphics::Format::R4G4B4A4_UNORM_PACK16:
+    case Graphics::Format::B4G4R4A4_UNORM_PACK16:
+    case Graphics::Format::R5G6B5_UNORM_PACK16:
+    case Graphics::Format::B5G6R5_UNORM_PACK16:
+    case Graphics::Format::R5G5B5A1_UNORM_PACK16:
+    case Graphics::Format::B5G5R5A1_UNORM_PACK16:
+    case Graphics::Format::A1R5G5B5_UNORM_PACK16:
+    case Graphics::Format::R8_UNORM:
+    case Graphics::Format::R8_SNORM:
+    case Graphics::Format::R8_USCALED:
+    case Graphics::Format::R8_SSCALED:
+    case Graphics::Format::R8_UINT:
+    case Graphics::Format::R8_SINT:
+    case Graphics::Format::R8_SRGB:
+    case Graphics::Format::R8G8_UNORM:
+    case Graphics::Format::R8G8_SNORM:
+    case Graphics::Format::R8G8_USCALED:
+    case Graphics::Format::R8G8_SSCALED:
+    case Graphics::Format::R8G8_UINT:
+    case Graphics::Format::R8G8_SINT:
+    case Graphics::Format::R8G8_SRGB:
+    case Graphics::Format::R8G8B8_UNORM:
+    case Graphics::Format::R8G8B8_SNORM:
+    case Graphics::Format::R8G8B8_USCALED:
+    case Graphics::Format::R8G8B8_SSCALED:
+    case Graphics::Format::R8G8B8_UINT:
+    case Graphics::Format::R8G8B8_SINT:
+    case Graphics::Format::R8G8B8_SRGB:
+    case Graphics::Format::B8G8R8_UNORM:
+    case Graphics::Format::B8G8R8_SNORM:
+    case Graphics::Format::B8G8R8_USCALED:
+    case Graphics::Format::B8G8R8_SSCALED:
+    case Graphics::Format::B8G8R8_UINT:
+    case Graphics::Format::B8G8R8_SINT:
+    case Graphics::Format::B8G8R8_SRGB:
+    case Graphics::Format::R8G8B8A8_UNORM:
+    case Graphics::Format::R8G8B8A8_SNORM:
+    case Graphics::Format::R8G8B8A8_USCALED:
+    case Graphics::Format::R8G8B8A8_SSCALED:
+    case Graphics::Format::R8G8B8A8_UINT:
+    case Graphics::Format::R8G8B8A8_SINT:
+    case Graphics::Format::R8G8B8A8_SRGB:
+    case Graphics::Format::B8G8R8A8_UNORM:
+    case Graphics::Format::B8G8R8A8_SNORM:
+    case Graphics::Format::B8G8R8A8_USCALED:
+    case Graphics::Format::B8G8R8A8_SSCALED:
+    case Graphics::Format::B8G8R8A8_UINT:
+    case Graphics::Format::B8G8R8A8_SINT:
+    case Graphics::Format::B8G8R8A8_SRGB:
+    case Graphics::Format::A8B8G8R8_UNORM_PACK32:
+    case Graphics::Format::A8B8G8R8_SNORM_PACK32:
+    case Graphics::Format::A8B8G8R8_USCALED_PACK32:
+    case Graphics::Format::A8B8G8R8_SSCALED_PACK32:
+    case Graphics::Format::A8B8G8R8_UINT_PACK32:
+    case Graphics::Format::A8B8G8R8_SINT_PACK32:
+    case Graphics::Format::A8B8G8R8_SRGB_PACK32:
+    case Graphics::Format::A2R10G10B10_UNORM_PACK32:
+    case Graphics::Format::A2R10G10B10_SNORM_PACK32:
+    case Graphics::Format::A2R10G10B10_USCALED_PACK32:
+    case Graphics::Format::A2R10G10B10_SSCALED_PACK32:
+    case Graphics::Format::A2R10G10B10_UINT_PACK32:
+    case Graphics::Format::A2R10G10B10_SINT_PACK32:
+    case Graphics::Format::A2B10G10R10_UNORM_PACK32:
+    case Graphics::Format::A2B10G10R10_SNORM_PACK32:
+    case Graphics::Format::A2B10G10R10_USCALED_PACK32:
+    case Graphics::Format::A2B10G10R10_SSCALED_PACK32:
+    case Graphics::Format::A2B10G10R10_UINT_PACK32:
+    case Graphics::Format::A2B10G10R10_SINT_PACK32:
+    case Graphics::Format::R16_UNORM:
+    case Graphics::Format::R16_SNORM:
+    case Graphics::Format::R16_USCALED:
+    case Graphics::Format::R16_SSCALED:
+    case Graphics::Format::R16_UINT:
+    case Graphics::Format::R16_SINT:
+    case Graphics::Format::R16_SFLOAT:
+    case Graphics::Format::R16G16_UNORM:
+    case Graphics::Format::R16G16_SNORM:
+    case Graphics::Format::R16G16_USCALED:
+    case Graphics::Format::R16G16_SSCALED:
+    case Graphics::Format::R16G16_UINT:
+    case Graphics::Format::R16G16_SINT:
+    case Graphics::Format::R16G16_SFLOAT:
+    case Graphics::Format::R16G16B16_UNORM:
+    case Graphics::Format::R16G16B16_SNORM:
+    case Graphics::Format::R16G16B16_USCALED:
+    case Graphics::Format::R16G16B16_SSCALED:
+    case Graphics::Format::R16G16B16_UINT:
+    case Graphics::Format::R16G16B16_SINT:
+    case Graphics::Format::R16G16B16_SFLOAT:
+    case Graphics::Format::R16G16B16A16_UNORM:
+    case Graphics::Format::R16G16B16A16_SNORM:
+    case Graphics::Format::R16G16B16A16_USCALED:
+    case Graphics::Format::R16G16B16A16_SSCALED:
+    case Graphics::Format::R16G16B16A16_UINT:
+    case Graphics::Format::R16G16B16A16_SINT:
+    case Graphics::Format::R16G16B16A16_SFLOAT:
+    case Graphics::Format::R32_UINT:
+    case Graphics::Format::R32_SINT:
+    case Graphics::Format::R32_SFLOAT:
+    case Graphics::Format::R32G32_UINT:
+    case Graphics::Format::R32G32_SINT:
+    case Graphics::Format::R32G32_SFLOAT:
+    case Graphics::Format::R32G32B32_UINT:
+    case Graphics::Format::R32G32B32_SINT:
+    case Graphics::Format::R32G32B32_SFLOAT:
+    case Graphics::Format::R32G32B32A32_UINT:
+    case Graphics::Format::R32G32B32A32_SINT:
+    case Graphics::Format::R32G32B32A32_SFLOAT:
+    case Graphics::Format::R64_UINT:
+    case Graphics::Format::R64_SINT:
+    case Graphics::Format::R64_SFLOAT:
+    case Graphics::Format::R64G64_UINT:
+    case Graphics::Format::R64G64_SINT:
+    case Graphics::Format::R64G64_SFLOAT:
+    case Graphics::Format::R64G64B64_UINT:
+    case Graphics::Format::R64G64B64_SINT:
+    case Graphics::Format::R64G64B64_SFLOAT:
+    case Graphics::Format::R64G64B64A64_UINT:
+    case Graphics::Format::R64G64B64A64_SINT:
+    case Graphics::Format::R64G64B64A64_SFLOAT:
+    case Graphics::Format::B10G11R11_UFLOAT_PACK32:
+    case Graphics::Format::E5B9G9R9_UFLOAT_PACK32:
+    case Graphics::Format::D16_UNORM:
+    case Graphics::Format::X8_D24_UNORM_PACK32:
+    case Graphics::Format::D32_SFLOAT:
+    case Graphics::Format::S8_UINT:
+    case Graphics::Format::D16_UNORM_S8_UINT:
+    case Graphics::Format::D24_UNORM_S8_UINT:
+    case Graphics::Format::D32_SFLOAT_S8_UINT:
+    case Graphics::Format::BC1_RGB_UNORM_BLOCK:
+    case Graphics::Format::BC1_RGB_SRGB_BLOCK:
+    case Graphics::Format::BC1_RGBA_UNORM_BLOCK:
+    case Graphics::Format::BC1_RGBA_SRGB_BLOCK:
+    case Graphics::Format::BC2_UNORM_BLOCK:
+    case Graphics::Format::BC2_SRGB_BLOCK:
+    case Graphics::Format::BC3_UNORM_BLOCK:
+    case Graphics::Format::BC3_SRGB_BLOCK:
+    case Graphics::Format::BC4_UNORM_BLOCK:
+    case Graphics::Format::BC4_SNORM_BLOCK:
+    case Graphics::Format::BC5_UNORM_BLOCK:
+    case Graphics::Format::BC5_SNORM_BLOCK:
+    case Graphics::Format::BC6H_UFLOAT_BLOCK:
+    case Graphics::Format::BC6H_SFLOAT_BLOCK:
+    case Graphics::Format::BC7_UNORM_BLOCK:
+    case Graphics::Format::BC7_SRGB_BLOCK:
+    {
+      return false;
+    }
+
+    case Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK:
+    case Graphics::Format::ETC2_R8G8B8_SRGB_BLOCK:
+    case Graphics::Format::ETC2_R8G8B8A1_UNORM_BLOCK:
+    case Graphics::Format::ETC2_R8G8B8A1_SRGB_BLOCK:
+    case Graphics::Format::ETC2_R8G8B8A8_UNORM_BLOCK:
+    case Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK:
+    case Graphics::Format::EAC_R11_UNORM_BLOCK:
+    case Graphics::Format::EAC_R11_SNORM_BLOCK:
+    case Graphics::Format::EAC_R11G11_UNORM_BLOCK:
+    case Graphics::Format::EAC_R11G11_SNORM_BLOCK:
+    case Graphics::Format::ASTC_4x4_UNORM_BLOCK:
+    case Graphics::Format::ASTC_4x4_SRGB_BLOCK:
+    case Graphics::Format::ASTC_5x4_UNORM_BLOCK:
+    case Graphics::Format::ASTC_5x4_SRGB_BLOCK:
+    case Graphics::Format::ASTC_5x5_UNORM_BLOCK:
+    case Graphics::Format::ASTC_5x5_SRGB_BLOCK:
+    case Graphics::Format::ASTC_6x5_UNORM_BLOCK:
+    case Graphics::Format::ASTC_6x5_SRGB_BLOCK:
+    case Graphics::Format::ASTC_6x6_UNORM_BLOCK:
+    case Graphics::Format::ASTC_6x6_SRGB_BLOCK:
+    case Graphics::Format::ASTC_8x5_UNORM_BLOCK:
+    case Graphics::Format::ASTC_8x5_SRGB_BLOCK:
+    case Graphics::Format::ASTC_8x6_UNORM_BLOCK:
+    case Graphics::Format::ASTC_8x6_SRGB_BLOCK:
+    case Graphics::Format::ASTC_8x8_UNORM_BLOCK:
+    case Graphics::Format::ASTC_8x8_SRGB_BLOCK:
+    case Graphics::Format::ASTC_10x5_UNORM_BLOCK:
+    case Graphics::Format::ASTC_10x5_SRGB_BLOCK:
+    case Graphics::Format::ASTC_10x6_UNORM_BLOCK:
+    case Graphics::Format::ASTC_10x6_SRGB_BLOCK:
+    case Graphics::Format::ASTC_10x8_UNORM_BLOCK:
+    case Graphics::Format::ASTC_10x8_SRGB_BLOCK:
+    case Graphics::Format::ASTC_10x10_UNORM_BLOCK:
+    case Graphics::Format::ASTC_10x10_SRGB_BLOCK:
+    case Graphics::Format::ASTC_12x10_UNORM_BLOCK:
+    case Graphics::Format::ASTC_12x10_SRGB_BLOCK:
+    case Graphics::Format::ASTC_12x12_UNORM_BLOCK:
+    case Graphics::Format::ASTC_12x12_SRGB_BLOCK:
+    case Graphics::Format::PVRTC1_2BPP_UNORM_BLOCK_IMG:
+    case Graphics::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG:
+    case Graphics::Format::PVRTC2_2BPP_UNORM_BLOCK_IMG:
+    case Graphics::Format::PVRTC2_4BPP_UNORM_BLOCK_IMG:
+    case Graphics::Format::PVRTC1_2BPP_SRGB_BLOCK_IMG:
+    case Graphics::Format::PVRTC1_4BPP_SRGB_BLOCK_IMG:
+    case Graphics::Format::PVRTC2_2BPP_SRGB_BLOCK_IMG:
+    case Graphics::Format::PVRTC2_4BPP_SRGB_BLOCK_IMG:
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+/**
+ * @brief Retrives the GL format, GL internal format and pixel data type from a Graphics::Format
+ * @param[in] pixelFormat The pixel format.
+ * @param[out] glFormat The gl format.
+ * @param[out] glInternalFormat The gl internal format.
+ * @param[out] pixelDataType The data type of the pixel data.
+ */
+void PixelFormatToGl(Graphics::Format pixelFormat, GLenum& glFormat, GLint& glInternalFormat, GLenum& pixelDataType)
+{
+  // Compressed textures have no pixelDataType, so init to an invalid value:
+  pixelDataType = -1;
+
+  switch(pixelFormat)
+  {
+    case Graphics::Format::R8_UNORM:
+    {
+      pixelDataType = GL_UNSIGNED_BYTE;
+      glFormat      = GL_ALPHA;
+      break;
+    }
+
+    case Graphics::Format::L8:
+    {
+      pixelDataType = GL_UNSIGNED_BYTE;
+      glFormat      = GL_LUMINANCE;
+      break;
+    }
+
+    case Graphics::Format::L8A8:
+    {
+      pixelDataType = GL_UNSIGNED_BYTE;
+      glFormat      = GL_LUMINANCE_ALPHA;
+      break;
+    }
+
+    case Graphics::Format::R5G6B5_UNORM_PACK16:
+    {
+      pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
+      glFormat      = GL_RGB;
+      break;
+    }
+
+    case Graphics::Format::B5G6R5_UNORM_PACK16:
+    {
+      pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
+#ifdef _ARCH_ARM_
+      glFormat = GL_BGRA_EXT; // alpha is reserved but not used
+#else
+      glFormat = GL_RGBA; // alpha is reserved but not used
+#endif
+      break;
+    }
+
+    case Graphics::Format::R4G4B4A4_UNORM_PACK16:
+    {
+      pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
+      glFormat      = GL_RGBA;
+      break;
+    }
+
+    case Graphics::Format::B4G4R4A4_UNORM_PACK16:
+    {
+      pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
+#ifdef _ARCH_ARM_
+      glFormat = GL_BGRA_EXT; // alpha is reserved but not used
+#else
+      glFormat = GL_RGBA; // alpha is reserved but not used
+#endif
+      break;
+    }
+
+    case Graphics::Format::R5G5B5A1_UNORM_PACK16:
+    {
+      pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
+      glFormat      = GL_RGBA;
+      break;
+    }
+
+    case Graphics::Format::B5G5R5A1_UNORM_PACK16:
+    {
+      pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
+#ifdef _ARCH_ARM_
+      glFormat = GL_BGRA_EXT; // alpha is reserved but not used
+#else
+      glFormat = GL_RGBA; // alpha is reserved but not used
+#endif
+      break;
+    }
+
+    case Graphics::Format::R8G8B8_UNORM:
+    {
+      pixelDataType = GL_UNSIGNED_BYTE;
+      glFormat      = GL_RGB;
+      break;
+    }
+
+    case Graphics::Format::R8G8B8A8_UNORM:
+    {
+      pixelDataType = GL_UNSIGNED_BYTE;
+      glFormat      = GL_RGBA; // alpha is reserved but not used
+      break;
+    }
+
+    case Graphics::Format::B8G8R8A8_UNORM:
+    {
+      pixelDataType = GL_UNSIGNED_BYTE;
+#ifdef GL_BGRA_EXT
+      glFormat = GL_BGRA_EXT; // alpha is reserved but not used
+#else
+      glFormat = GL_RGBA; // alpha is reserved but not used
+#endif
+      break;
+    }
+
+    case Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGB8_ETC2;
+      break;
+    }
+
+    case Graphics::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG:
+    {
+      glFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
+      break;
+    }
+
+    // GLES 3.0 standard compressed formats:
+    case Graphics::Format::EAC_R11_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_R11_EAC;
+      break;
+    }
+    case Graphics::Format::EAC_R11_SNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SIGNED_R11_EAC;
+      break;
+    }
+    case Graphics::Format::EAC_R11G11_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RG11_EAC;
+      break;
+    }
+    case Graphics::Format::EAC_R11G11_SNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SIGNED_RG11_EAC;
+      break;
+    }
+    case Graphics::Format::ETC2_R8G8B8_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ETC2;
+      break;
+    }
+    case Graphics::Format::ETC2_R8G8B8A1_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+      break;
+    }
+    case Graphics::Format::ETC2_R8G8B8A1_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
+      break;
+    }
+    case Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
+      break;
+    }
+
+    // GLES 3.1 extension compressed formats:
+    case Graphics::Format::ASTC_4x4_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_5x4_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_5x5_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_6x5_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_6x6_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_8x5_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_8x6_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_8x8_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_10x5_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_10x6_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_10x8_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_10x10_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_12x10_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_12x12_UNORM_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
+      break;
+    }
+
+    case Graphics::Format::ASTC_4x4_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_5x4_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_5x5_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_6x5_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_6x6_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_8x5_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_8x6_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_8x8_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_10x5_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_10x6_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_10x8_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_10x10_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_12x10_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
+      break;
+    }
+    case Graphics::Format::ASTC_12x12_SRGB_BLOCK:
+    {
+      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
+      break;
+    }
+
+    // GLES 3.0 floating point formats.
+    case Graphics::Format::R16G16B16_SFLOAT:
+    {
+      glFormat      = GL_RGB;
+      pixelDataType = GL_HALF_FLOAT;
+      break;
+    }
+    case Graphics::Format::R32G32B32_SFLOAT:
+    {
+      glFormat      = GL_RGB;
+      pixelDataType = GL_FLOAT;
+      break;
+    }
+
+    // GLES 3.0 depth and stencil formats
+    case Graphics::Format::D16_UNORM:
+    {
+      glFormat      = GL_DEPTH_COMPONENT;
+      pixelDataType = GL_UNSIGNED_INT;
+      break;
+    }
+
+    case Graphics::Format::D32_SFLOAT:
+    {
+      glFormat      = GL_DEPTH_COMPONENT;
+      pixelDataType = GL_FLOAT;
+      break;
+    }
+
+    case Graphics::Format::D24_UNORM_S8_UINT:
+    {
+      glFormat      = GL_DEPTH_STENCIL;
+      pixelDataType = GL_UNSIGNED_INT_24_8;
+      break;
+    }
+
+    case Graphics::Format::UNDEFINED:
+    {
+      //DALI_LOG_ERROR( "Invalid pixel format for bitmap\n" );
+      glFormat = 0;
+      break;
+    }
+
+    case Graphics::Format::R4G4_UNORM_PACK8:
+    case Graphics::Format::A1R5G5B5_UNORM_PACK16:
+    case Graphics::Format::R8_SNORM:
+    case Graphics::Format::R8_USCALED:
+    case Graphics::Format::R8_SSCALED:
+    case Graphics::Format::R8_UINT:
+    case Graphics::Format::R8_SINT:
+    case Graphics::Format::R8_SRGB:
+    case Graphics::Format::R8G8_UNORM:
+    case Graphics::Format::R8G8_SNORM:
+    case Graphics::Format::R8G8_USCALED:
+    case Graphics::Format::R8G8_SSCALED:
+    case Graphics::Format::R8G8_UINT:
+    case Graphics::Format::R8G8_SINT:
+    case Graphics::Format::R8G8_SRGB:
+    case Graphics::Format::R8G8B8_SNORM:
+    case Graphics::Format::R8G8B8_USCALED:
+    case Graphics::Format::R8G8B8_SSCALED:
+    case Graphics::Format::R8G8B8_UINT:
+    case Graphics::Format::R8G8B8_SINT:
+    case Graphics::Format::R8G8B8_SRGB:
+    case Graphics::Format::B8G8R8_UNORM:
+    case Graphics::Format::B8G8R8_SNORM:
+    case Graphics::Format::B8G8R8_USCALED:
+    case Graphics::Format::B8G8R8_SSCALED:
+    case Graphics::Format::B8G8R8_UINT:
+    case Graphics::Format::B8G8R8_SINT:
+    case Graphics::Format::B8G8R8_SRGB:
+    case Graphics::Format::R8G8B8A8_SNORM:
+    case Graphics::Format::R8G8B8A8_USCALED:
+    case Graphics::Format::R8G8B8A8_SSCALED:
+    case Graphics::Format::R8G8B8A8_UINT:
+    case Graphics::Format::R8G8B8A8_SINT:
+    case Graphics::Format::R8G8B8A8_SRGB:
+    case Graphics::Format::B8G8R8A8_SNORM:
+    case Graphics::Format::B8G8R8A8_USCALED:
+    case Graphics::Format::B8G8R8A8_SSCALED:
+    case Graphics::Format::B8G8R8A8_UINT:
+    case Graphics::Format::B8G8R8A8_SINT:
+    case Graphics::Format::B8G8R8A8_SRGB:
+    case Graphics::Format::A8B8G8R8_UNORM_PACK32:
+    case Graphics::Format::A8B8G8R8_SNORM_PACK32:
+    case Graphics::Format::A8B8G8R8_USCALED_PACK32:
+    case Graphics::Format::A8B8G8R8_SSCALED_PACK32:
+    case Graphics::Format::A8B8G8R8_UINT_PACK32:
+    case Graphics::Format::A8B8G8R8_SINT_PACK32:
+    case Graphics::Format::A8B8G8R8_SRGB_PACK32:
+    case Graphics::Format::A2R10G10B10_UNORM_PACK32:
+    case Graphics::Format::A2R10G10B10_SNORM_PACK32:
+    case Graphics::Format::A2R10G10B10_USCALED_PACK32:
+    case Graphics::Format::A2R10G10B10_SSCALED_PACK32:
+    case Graphics::Format::A2R10G10B10_UINT_PACK32:
+    case Graphics::Format::A2R10G10B10_SINT_PACK32:
+    case Graphics::Format::A2B10G10R10_UNORM_PACK32:
+    case Graphics::Format::A2B10G10R10_SNORM_PACK32:
+    case Graphics::Format::A2B10G10R10_USCALED_PACK32:
+    case Graphics::Format::A2B10G10R10_SSCALED_PACK32:
+    case Graphics::Format::A2B10G10R10_UINT_PACK32:
+    case Graphics::Format::A2B10G10R10_SINT_PACK32:
+    case Graphics::Format::R16_UNORM:
+    case Graphics::Format::R16_SNORM:
+    case Graphics::Format::R16_USCALED:
+    case Graphics::Format::R16_SSCALED:
+    case Graphics::Format::R16_UINT:
+    case Graphics::Format::R16_SINT:
+    case Graphics::Format::R16_SFLOAT:
+    case Graphics::Format::R16G16_UNORM:
+    case Graphics::Format::R16G16_SNORM:
+    case Graphics::Format::R16G16_USCALED:
+    case Graphics::Format::R16G16_SSCALED:
+    case Graphics::Format::R16G16_UINT:
+    case Graphics::Format::R16G16_SINT:
+    case Graphics::Format::R16G16_SFLOAT:
+    case Graphics::Format::R16G16B16_UNORM:
+    case Graphics::Format::R16G16B16_SNORM:
+    case Graphics::Format::R16G16B16_USCALED:
+    case Graphics::Format::R16G16B16_SSCALED:
+    case Graphics::Format::R16G16B16_UINT:
+    case Graphics::Format::R16G16B16_SINT:
+    case Graphics::Format::R16G16B16A16_UNORM:
+    case Graphics::Format::R16G16B16A16_SNORM:
+    case Graphics::Format::R16G16B16A16_USCALED:
+    case Graphics::Format::R16G16B16A16_SSCALED:
+    case Graphics::Format::R16G16B16A16_UINT:
+    case Graphics::Format::R16G16B16A16_SINT:
+    case Graphics::Format::R16G16B16A16_SFLOAT:
+    case Graphics::Format::R32_UINT:
+    case Graphics::Format::R32_SINT:
+    case Graphics::Format::R32_SFLOAT:
+    case Graphics::Format::R32G32_UINT:
+    case Graphics::Format::R32G32_SINT:
+    case Graphics::Format::R32G32_SFLOAT:
+    case Graphics::Format::R32G32B32_UINT:
+    case Graphics::Format::R32G32B32_SINT:
+    case Graphics::Format::R32G32B32A32_UINT:
+    case Graphics::Format::R32G32B32A32_SINT:
+    case Graphics::Format::R32G32B32A32_SFLOAT:
+    case Graphics::Format::R64_UINT:
+    case Graphics::Format::R64_SINT:
+    case Graphics::Format::R64_SFLOAT:
+    case Graphics::Format::R64G64_UINT:
+    case Graphics::Format::R64G64_SINT:
+    case Graphics::Format::R64G64_SFLOAT:
+    case Graphics::Format::R64G64B64_UINT:
+    case Graphics::Format::R64G64B64_SINT:
+    case Graphics::Format::R64G64B64_SFLOAT:
+    case Graphics::Format::R64G64B64A64_UINT:
+    case Graphics::Format::R64G64B64A64_SINT:
+    case Graphics::Format::R64G64B64A64_SFLOAT:
+    case Graphics::Format::B10G11R11_UFLOAT_PACK32:
+    case Graphics::Format::E5B9G9R9_UFLOAT_PACK32:
+    case Graphics::Format::X8_D24_UNORM_PACK32:
+    case Graphics::Format::S8_UINT:
+    case Graphics::Format::D16_UNORM_S8_UINT:
+    case Graphics::Format::D32_SFLOAT_S8_UINT:
+    case Graphics::Format::BC1_RGB_UNORM_BLOCK:
+    case Graphics::Format::BC1_RGB_SRGB_BLOCK:
+    case Graphics::Format::BC1_RGBA_UNORM_BLOCK:
+    case Graphics::Format::BC1_RGBA_SRGB_BLOCK:
+    case Graphics::Format::BC2_UNORM_BLOCK:
+    case Graphics::Format::BC2_SRGB_BLOCK:
+    case Graphics::Format::BC3_UNORM_BLOCK:
+    case Graphics::Format::BC3_SRGB_BLOCK:
+    case Graphics::Format::BC4_UNORM_BLOCK:
+    case Graphics::Format::BC4_SNORM_BLOCK:
+    case Graphics::Format::BC5_UNORM_BLOCK:
+    case Graphics::Format::BC5_SNORM_BLOCK:
+    case Graphics::Format::BC6H_UFLOAT_BLOCK:
+    case Graphics::Format::BC6H_SFLOAT_BLOCK:
+    case Graphics::Format::BC7_UNORM_BLOCK:
+    case Graphics::Format::BC7_SRGB_BLOCK:
+    case Graphics::Format::ETC2_R8G8B8A8_UNORM_BLOCK:
+    case Graphics::Format::PVRTC1_2BPP_UNORM_BLOCK_IMG:
+    case Graphics::Format::PVRTC2_2BPP_UNORM_BLOCK_IMG:
+    case Graphics::Format::PVRTC2_4BPP_UNORM_BLOCK_IMG:
+    case Graphics::Format::PVRTC1_2BPP_SRGB_BLOCK_IMG:
+    case Graphics::Format::PVRTC1_4BPP_SRGB_BLOCK_IMG:
+    case Graphics::Format::PVRTC2_2BPP_SRGB_BLOCK_IMG:
+    case Graphics::Format::PVRTC2_4BPP_SRGB_BLOCK_IMG:
+    {
+      glFormat = 0;
+      break;
+    }
+  }
+
+  switch(pixelFormat)
+  {
+    case Graphics::Format::R16G16B16A16_SFLOAT:
+    case Graphics::Format::R32G32B32A32_SFLOAT:
+    {
+      glInternalFormat = GL_R11F_G11F_B10F;
+      break;
+    }
+    case Graphics::Format::D32_SFLOAT:
+    {
+      glInternalFormat = GL_DEPTH_COMPONENT32F;
+      break;
+    }
+    case Graphics::Format::D24_UNORM_S8_UINT:
+    {
+      glInternalFormat = GL_DEPTH24_STENCIL8;
+      break;
+    }
+    default:
+    {
+      glInternalFormat = glFormat;
+    }
+  }
+}
+
+} // namespace
+
+TestGraphicsTexture::TestGraphicsTexture(TestGlAbstraction& glAbstraction, const Graphics::TextureCreateInfo& createInfo)
+: mGlAbstraction(glAbstraction),
+  mCreateInfo(createInfo),
+  mIsCompressed(IsCompressedFormat(createInfo.format))
+{
+  GLuint target = GetTarget();
+  if(mCreateInfo.nativeImagePtr)
+  {
+    InitializeNativeImage(target);
+  }
+  else
+  {
+    Initialize(target);
+
+    if(mCreateInfo.textureType == Graphics::TextureType::TEXTURE_2D)
+    {
+      if(!mIsCompressed)
+      {
+        glAbstraction.TexImage2D(target, 0, mGlInternalFormat, createInfo.size.width, createInfo.size.height, 0, mGlFormat, mPixelDataType, nullptr);
+      }
+      else
+      {
+        glAbstraction.CompressedTexImage2D(target, 0, mGlInternalFormat, createInfo.size.width, createInfo.size.height, 0, 0, nullptr);
+      }
+    }
+    else if(mCreateInfo.textureType == Graphics::TextureType::TEXTURE_CUBEMAP)
+    {
+      if(!mIsCompressed)
+      {
+        for(uint32_t i(0); i < 6; ++i)
+        {
+          glAbstraction.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, createInfo.size.width, createInfo.size.height, 0, mGlFormat, mPixelDataType, nullptr);
+        }
+      }
+      else
+      {
+        for(uint32_t i(0); i < 6; ++i)
+        {
+          glAbstraction.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, createInfo.size.width, createInfo.size.height, 0, 0, nullptr);
+        }
+      }
+      TestGraphicsSampler::SetTexParameter(glAbstraction, target, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT);
+    }
+  }
+}
+
+TestGraphicsTexture::~TestGraphicsTexture()
+{
+  mGlAbstraction.DeleteTextures(1, &mId);
+  if(mCreateInfo.nativeImagePtr)
+  {
+    mCreateInfo.nativeImagePtr->DestroyResource();
+  }
+}
+
+void TestGraphicsTexture::Initialize(GLuint target)
+{
+  PixelFormatToGl(mCreateInfo.format,
+                  mGlFormat,
+                  mGlInternalFormat,
+                  mPixelDataType);
+
+  mGlAbstraction.GenTextures(1, &mId);
+  mGlAbstraction.BindTexture(target, mId);
+  mGlAbstraction.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data
+
+  //Apply default sampling parameters
+  TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT);
+  TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT);
+  TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT);
+  TestGraphicsSampler::SetTexParameter(mGlAbstraction, target, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT);
+}
+
+void TestGraphicsTexture::InitializeNativeImage(GLuint target)
+{
+  mCreateInfo.nativeImagePtr->CreateResource();
+  Initialize(target);
+
+  if(mCreateInfo.nativeImagePtr->TargetTexture() != 0u) // This can definitely fail
+  {
+    mGlAbstraction.DeleteTextures(1, &mId);
+    mCreateInfo.nativeImagePtr->DestroyResource();
+    mId = 0u;
+  }
+}
+
+GLuint TestGraphicsTexture::GetTarget()
+{
+  GLuint target;
+  if(mCreateInfo.nativeImagePtr)
+  {
+    target = mCreateInfo.nativeImagePtr->GetTextureTarget(); // Could be GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES
+  }
+  else
+  {
+    target = GetTextureTarget(mCreateInfo.textureType);
+  }
+  return target;
+}
+
+void TestGraphicsTexture::Bind(uint32_t textureUnit)
+{
+  if(mCreateInfo.nativeImagePtr)
+  {
+    if(mId == 0)
+    {
+      InitializeNativeImage(GetTarget());
+    }
+  }
+  mGlAbstraction.ActiveTexture(textureUnit + GL_TEXTURE0);
+  mGlAbstraction.BindTexture(GetTarget(), mId);
+}
+
+void TestGraphicsTexture::Prepare()
+{
+  if(mCreateInfo.nativeImagePtr)
+  {
+    /***********************************************************************************
+     * If the native image source changes, we need to re-create the texture.           *
+     * In EGL, this is done in native image implementation in PrepareTexture below.    *
+     *                                                                                 *
+     * In Vulkan impl, this was done in dali-core side. I think we should make this    *
+     * work in the graphics implementation instead.                                    *
+     ***********************************************************************************/
+    if(mCreateInfo.nativeImagePtr->SourceChanged())
+    {
+      uint32_t width  = mCreateInfo.nativeImagePtr->GetWidth();
+      uint32_t height = mCreateInfo.nativeImagePtr->GetHeight();
+      mCreateInfo.SetSize({width, height}); // Size may change
+
+      // @todo Re-initialize this texture from the new create info.
+    }
+
+    // Ensure the native image is up-to-date
+    mCreateInfo.nativeImagePtr->PrepareTexture();
+  }
+}
+
+void TestGraphicsTexture::Update(Graphics::TextureUpdateInfo updateInfo, Graphics::TextureUpdateSourceInfo source)
+{
+  GLenum target{GetTarget()};
+  if(mCreateInfo.textureType == Graphics::TextureType::TEXTURE_CUBEMAP)
+  {
+    target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + updateInfo.layer;
+  }
+
+  mGlAbstraction.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data
+
+  const bool isSubImage(updateInfo.dstOffset2D.x != 0 || updateInfo.dstOffset2D.y != 0 ||
+                        updateInfo.srcExtent2D.width != (mCreateInfo.size.width / (1 << updateInfo.level)) ||
+                        updateInfo.srcExtent2D.height != (mCreateInfo.size.height / (1 << updateInfo.level)));
+
+  if(!isSubImage)
+  {
+    if(!mIsCompressed)
+    {
+      mGlAbstraction.TexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, mGlFormat, mPixelDataType, source.memorySource.memory);
+    }
+    else
+    {
+      mGlAbstraction.CompressedTexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, updateInfo.srcSize, source.memorySource.memory);
+    }
+  }
+  else
+  {
+    if(!mIsCompressed)
+    {
+      mGlAbstraction.TexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, mPixelDataType, source.memorySource.memory);
+    }
+    else
+    {
+      mGlAbstraction.CompressedTexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, updateInfo.srcSize, source.memorySource.memory);
+    }
+  }
+}
diff --git a/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-texture.h b/automated-tests/src/dali-adaptor/dali-test-suite-utils/test-graphics-texture.h
new file mode 100644 (file)
index 0000000..3eb54d3
--- /dev/null
@@ -0,0 +1,77 @@
+#ifndef DALI_TEST_GRAPHICS_TEXTURE_H
+#define DALI_TEST_GRAPHICS_TEXTURE_H
+
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dali/graphics-api/graphics-texture-create-info.h>
+#include <dali/graphics-api/graphics-texture.h>
+#include <dali/graphics-api/graphics-types.h>
+#include <dali/integration-api/gl-defines.h>
+#include "test-gl-abstraction.h"
+#include "test-graphics-sampler.h"
+
+namespace Dali
+{
+class TestGraphicsTexture : public Graphics::Texture
+{
+public:
+  TestGraphicsTexture(TestGlAbstraction& glAbstraction, const Graphics::TextureCreateInfo& createInfo);
+
+  ~TestGraphicsTexture();
+
+  /**
+   * Initialize the texture: allocate gl mem, apply default samplers
+   */
+  void Initialize(GLuint target);
+
+  /**
+   * Ensure native resource is created, bound and targeted.
+   */
+  void InitializeNativeImage(GLuint target);
+
+  /**
+   * Get the GL target of this texture
+   */
+  GLuint GetTarget();
+
+  /**
+   * Bind this texture, ensure Native image is initialized if necessary.
+   */
+  void Bind(uint32_t textureUnit);
+
+  /**
+   * Prepare ensures that the native texture is updated if necessary (SourceChanged)
+   */
+  void Prepare();
+
+  /**
+   * Writes actual texture data to GL.
+   */
+  void Update(Graphics::TextureUpdateInfo updateInfo, Graphics::TextureUpdateSourceInfo source);
+
+  GLuint                      mId{0};
+  TestGlAbstraction&          mGlAbstraction;
+  Graphics::TextureCreateInfo mCreateInfo;
+  bool                        mIsCompressed{false};
+  GLint                       mGlInternalFormat; ///< The gl internal format of the pixel data
+  GLenum                      mGlFormat;         ///< The gl format of the pixel data
+  GLenum                      mPixelDataType;    ///< The data type of the pixel data
+};
+
+} // namespace Dali
+
+#endif //DALI_TEST_GRAPHICS_TEXTURE_H
index 76c9e5e..9d78225 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,6 +34,7 @@ TestNativeImage::TestNativeImage(uint32_t width, uint32_t height)
   mTargetTextureCalls(0),
   createResult(true)
 {
+  mCallStack.EnableLogging(true);
 }
 
 TestNativeImage::~TestNativeImage()
index f7d4f78..7a4f552 100644 (file)
@@ -2,7 +2,7 @@
 #define TEST_NATIVE_IMAGE_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,40 +40,52 @@ public:
   inline virtual bool CreateResource()
   {
     ++mExtensionCreateCalls;
+    mCallStack.PushCall("CreateResource", "");
     return createResult;
   };
   inline virtual void DestroyResource()
   {
     ++mExtensionDestroyCalls;
+    mCallStack.PushCall("DestroyResource", "");
   };
   inline virtual GLenum TargetTexture()
   {
     ++mTargetTextureCalls;
-    return mTargetTextureError;
+    mCallStack.PushCall("TargetTexture", "");
+    return mTargetTextureError--;
+  };
+  inline virtual void PrepareTexture()
+  {
+    mCallStack.PushCall("PrepareTexture", "");
   };
-  inline virtual void     PrepareTexture(){};
   inline virtual uint32_t GetWidth() const
   {
+    mCallStack.PushCall("GetWidth", "");
     return mWidth;
   };
   inline virtual uint32_t GetHeight() const
   {
+    mCallStack.PushCall("GetHeight", "");
     return mHeight;
   };
   inline virtual bool RequiresBlending() const
   {
+    mCallStack.PushCall("RequiresBlending", "");
     return true;
   };
   inline virtual int GetTextureTarget() const
   {
+    mCallStack.PushCall("GetTextureTarget", "");
     return GL_TEXTURE_EXTERNAL_OES;
   };
   inline virtual const char* GetCustomFragmentPrefix() const
   {
+    mCallStack.PushCall("GetCustomFragmentPrefix", "");
     return "#extension GL_OES_EGL_image_external:require\n";
   };
   inline const char* GetCustomSamplerTypename() const override
   {
+    mCallStack.PushCall("GetCustomSamplerTypename", "");
     return "samplerExternalOES";
   };
 
@@ -99,11 +111,12 @@ private:
   uint32_t mHeight;
 
 public:
-  int32_t  mExtensionCreateCalls;
-  int32_t  mExtensionDestroyCalls;
-  int32_t  mTargetTextureCalls;
-  uint32_t mTargetTextureError = 0u;
-  bool     createResult;
+  int32_t                mExtensionCreateCalls;
+  int32_t                mExtensionDestroyCalls;
+  int32_t                mTargetTextureCalls;
+  uint32_t               mTargetTextureError{0u};
+  bool                   createResult;
+  mutable TraceCallStack mCallStack{"NativeImage:"};
 };
 
 } // namespace Dali
index 9fde7c4..dd063ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
 
 #include "test-trace-call-stack.h"
 
+#include <iostream>
 #include <sstream>
 
 namespace Dali
@@ -45,8 +46,9 @@ std::string ToString(float x)
 /**
  * Constructor
  */
-TraceCallStack::TraceCallStack()
-: mTraceActive(false)
+TraceCallStack::TraceCallStack(std::string prefix)
+: mTraceActive(false),
+  mPrefix(prefix)
 {
 }
 
@@ -70,6 +72,11 @@ bool TraceCallStack::IsEnabled()
   return mTraceActive;
 }
 
+void TraceCallStack::EnableLogging(bool enablelogging)
+{
+  mLogging = enablelogging;
+}
+
 /**
  * Push a call onto the stack if the trace is active
  * @param[in] method The name of the method
@@ -82,6 +89,10 @@ void TraceCallStack::PushCall(std::string method, std::string params)
     FunctionCall stackFrame(method, params);
     mCallStack.push_back(stackFrame);
   }
+  if(mLogging)
+  {
+    fprintf(stderr, "%s%s(%s)\n", mPrefix.c_str(), method.c_str(), params.c_str());
+  }
 }
 
 void TraceCallStack::PushCall(std::string method, std::string params, const TraceCallStack::NamedParams& altParams)
@@ -91,6 +102,10 @@ void TraceCallStack::PushCall(std::string method, std::string params, const Trac
     FunctionCall stackFrame(method, params, altParams);
     mCallStack.push_back(stackFrame);
   }
+  if(mLogging)
+  {
+    fprintf(stderr, "%s%s(%s)\n", mPrefix.c_str(), method.c_str(), params.c_str());
+  }
 }
 
 /**
@@ -109,6 +124,10 @@ bool TraceCallStack::FindMethod(std::string method) const
       break;
     }
   }
+  if(!found)
+  {
+    fprintf(stderr, "Search for %s failed\n", method.c_str());
+  }
   return found;
 }
 
@@ -124,6 +143,10 @@ bool TraceCallStack::FindMethodAndGetParameters(std::string method, std::string&
       break;
     }
   }
+  if(!found)
+  {
+    fprintf(stderr, "Search for %s(%s) failed\n", method.c_str(), params.c_str());
+  }
   return found;
 }
 
index 8cb5922..cbbdd14 100644 (file)
@@ -2,7 +2,7 @@
 #define TEST_TRACE_CALL_STACK_H
 
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ public:
   /**
    * Constructor
    */
-  TraceCallStack();
+  TraceCallStack(std::string prefix = "");
 
   /**
    * Destructor
@@ -61,6 +61,8 @@ public:
 
   bool IsEnabled();
 
+  void EnableLogging(bool enable);
+
   /**
    * Push a call onto the stack if the trace is active
    * @param[in] method The name of the method
@@ -174,7 +176,9 @@ public:
   }
 
 private:
-  bool mTraceActive; ///< True if the trace is active
+  bool        mTraceActive{false}; ///< True if the trace is active
+  bool        mLogging{false};     ///< True if the trace is logged to stdout
+  std::string mPrefix;
 
   struct FunctionCall
   {
index 8f39441..c28ef65 100644 (file)
@@ -14,6 +14,10 @@ LIST(APPEND TC_SOURCES
   ../dali-adaptor/dali-test-suite-utils/test-graphics-application.cpp
   ../dali-adaptor/dali-test-suite-utils/test-gl-abstraction.cpp
   ../dali-adaptor/dali-test-suite-utils/test-gl-sync-abstraction.cpp
+  ../dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.cpp
+  ../dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp
+  ../dali-adaptor/dali-test-suite-utils/test-graphics-texture.cpp
+  ../dali-adaptor/dali-test-suite-utils/test-graphics-sampler.cpp
   ../dali-adaptor/dali-test-suite-utils/test-native-image.cpp
   ../dali-adaptor/dali-test-suite-utils/test-platform-abstraction.cpp
   ../dali-adaptor/dali-test-suite-utils/test-render-controller.cpp
index 43f9817..5065fa7 100644 (file)
@@ -17,6 +17,10 @@ LIST(APPEND TC_SOURCES
     ../dali-adaptor/dali-test-suite-utils/test-application.cpp
     ../dali-adaptor/dali-test-suite-utils/test-gl-abstraction.cpp
     ../dali-adaptor/dali-test-suite-utils/test-gl-sync-abstraction.cpp
+    ../dali-adaptor/dali-test-suite-utils/test-graphics-command-buffer.cpp
+    ../dali-adaptor/dali-test-suite-utils/test-graphics-controller.cpp
+    ../dali-adaptor/dali-test-suite-utils/test-graphics-texture.cpp
+    ../dali-adaptor/dali-test-suite-utils/test-graphics-sampler.cpp
     ../dali-adaptor/dali-test-suite-utils/test-native-image.cpp
     ../dali-adaptor/dali-test-suite-utils/test-platform-abstraction.cpp
     ../dali-adaptor/dali-test-suite-utils/test-render-controller.cpp