Migrating render-texture and render-sampler to new API 80/252980/8
authorDavid Steele <david.steele@samsung.com>
Tue, 19 Jan 2021 16:03:30 +0000 (16:03 +0000)
committerDavid Steele <david.steele@samsung.com>
Tue, 9 Feb 2021 13:37:45 +0000 (13:37 +0000)
Implementation of CommandBuffer::BindTextures &
Controller::SubmitCommandBuffers to handle binding textures
before drawing.

Upgrading test harness to allow traced calls to be logged.

Added first pass of TestGraphicsController with enough setup to
emulate textures using the GlAbstraction.

Added test-graphics-samplers.

All gl tests are now passing, w/exception of GenerateMipmaps, which
has been commented out.

Change-Id: I08050f1e9784fa9e73b3a2959f304c4187babddc

35 files changed:
automated-tests/src/dali-internal/CMakeLists.txt
automated-tests/src/dali/CMakeLists.txt
automated-tests/src/dali/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali/dali-test-suite-utils/test-graphics-buffer.h [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.cpp [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-graphics-command-buffer.h [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.cpp [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-graphics-controller.h
automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.cpp [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-graphics-sampler.h [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.cpp [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-graphics-texture.h [new file with mode: 0644]
automated-tests/src/dali/dali-test-suite-utils/test-native-image.cpp
automated-tests/src/dali/dali-test-suite-utils/test-native-image.h
automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.cpp
automated-tests/src/dali/dali-test-suite-utils/test-trace-call-stack.h
automated-tests/src/dali/utc-Dali-Actor.cpp
automated-tests/src/dali/utc-Dali-RenderTask.cpp
automated-tests/src/dali/utc-Dali-Renderer.cpp
automated-tests/src/dali/utc-Dali-Sampler.cpp
automated-tests/src/dali/utc-Dali-Texture.cpp
automated-tests/src/dali/utc-Dali-TextureSet.cpp
build/tizen/CMakeLists.txt
dali/internal/file.list
dali/internal/render/common/render-algorithms.cpp
dali/internal/render/common/render-algorithms.h
dali/internal/render/common/render-manager.cpp
dali/internal/render/renderers/render-frame-buffer.cpp
dali/internal/render/renderers/render-frame-buffer.h
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-renderer.h
dali/internal/render/renderers/render-sampler.cpp [new file with mode: 0644]
dali/internal/render/renderers/render-sampler.h
dali/internal/render/renderers/render-texture.cpp
dali/internal/render/renderers/render-texture.h

index 5bc1c4a277c0b5c6c017c444be9d01bd00bbe63c..db51810ec7fb978ac4af377ed8449759470e2248 100644 (file)
@@ -32,6 +32,10 @@ LIST(APPEND TC_SOURCES
         ../dali/dali-test-suite-utils/test-application.cpp
         ../dali/dali-test-suite-utils/test-gl-abstraction.cpp
         ../dali/dali-test-suite-utils/test-gl-sync-abstraction.cpp
+        ../dali/dali-test-suite-utils/test-graphics-controller.cpp
+        ../dali/dali-test-suite-utils/test-graphics-command-buffer.cpp
+        ../dali/dali-test-suite-utils/test-graphics-texture.cpp
+        ../dali/dali-test-suite-utils/test-graphics-sampler.cpp
         ../dali/dali-test-suite-utils/test-native-image.cpp
         ../dali/dali-test-suite-utils/test-platform-abstraction.cpp
         ../dali/dali-test-suite-utils/test-render-controller.cpp
index 67aceac5e2a0c431b7082dc37b732250a5ce7699..864d923070e885f3ab26cdd0f1df02ae45178007 100644 (file)
@@ -112,6 +112,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 861f4ae8586f1e350e87bd3f895bab1b762f077a..2af966043099dd3e472946a6e2042b82ce253204 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/dali-test-suite-utils/test-graphics-buffer.h b/automated-tests/src/dali/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/dali-test-suite-utils/test-graphics-command-buffer.cpp b/automated-tests/src/dali/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/dali-test-suite-utils/test-graphics-command-buffer.h b/automated-tests/src/dali/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/dali-test-suite-utils/test-graphics-controller.cpp b/automated-tests/src/dali/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 194698b1279ed28c95c397d8c11b02cb58ef898c..f2181340382aa18eb7ab8fa6b004d0012512b5fa 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/dali-test-suite-utils/test-graphics-sampler.cpp b/automated-tests/src/dali/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/dali-test-suite-utils/test-graphics-sampler.h b/automated-tests/src/dali/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/dali-test-suite-utils/test-graphics-texture.cpp b/automated-tests/src/dali/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/dali-test-suite-utils/test-graphics-texture.h b/automated-tests/src/dali/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 76c9e5e7319d35621c3110bb32c985c756a32504..9d78225d4d97b0a62fa719f825b229794f9a93c6 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 f7d4f785b88cae877240f253b2d90e59f8caeda2..7a4f552fe18c231be74586888873536eae251a56 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 9fde7c4a2d6a24a56494134fab109fa41440a787..dd063edfeb3c36e7b43314fb5c716485324f140d 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 8cb592286daf04b2b02c7f67d44d8aa182475755..cbbdd14a2c4e0a1076e15ed947b3dab34c810544 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 75835a4dd72b777e3717c1fd149858781d62b683..d702b7f812a64a3084b1debb03fe99cedc2b5d51 100644 (file)
@@ -59,6 +59,17 @@ static bool gTestConstraintCalled;
 
 LayoutDirection::Type gLayoutDirectionType;
 
+Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height)
+{
+  Texture texture = Texture::New(type, format, width, height);
+
+  int       bufferSize = width * height * 2;
+  uint8_t*  buffer     = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+  PixelData pixelData  = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE);
+  texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height);
+  return texture;
+}
+
 struct TestConstraint
 {
   void operator()(Vector4& color, const PropertyInputContainer& /* inputs */)
@@ -2963,9 +2974,9 @@ int UtcDaliActorSetDrawModeOverlayRender(void)
   ids.push_back(10); // third rendered actor
   application.GetGlAbstraction().SetNextTextureIds(ids);
 
-  Texture imageA = Texture::New(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16);
-  Texture imageB = Texture::New(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16);
-  Texture imageC = Texture::New(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16);
+  Texture imageA = CreateTexture(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16);
+  Texture imageB = CreateTexture(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16);
+  Texture imageC = CreateTexture(TextureType::TEXTURE_2D, Pixel::Format::RGBA8888, 16, 16);
   Actor   a      = CreateRenderableActor(imageA);
   Actor   b      = CreateRenderableActor(imageB);
   Actor   c      = CreateRenderableActor(imageC);
@@ -4104,7 +4115,7 @@ int UtcDaliActorRemoveRendererN(void)
 // Clipping test helper functions:
 Actor CreateActorWithContent(uint32_t width, uint32_t height)
 {
-  Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
   Actor   actor = CreateRenderableActor(image);
 
   // Setup dimensions and position so actor is not skipped by culling.
@@ -4412,7 +4423,7 @@ int UtcDaliActorPropertyClippingActorDrawOrder(void)
   Actor actors[5];
   for(int i = 0; i < 5; ++i)
   {
-    Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
+    Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
     Actor   actor = CreateRenderableActor(image);
 
     // Setup dimensions and position so actor is not skipped by culling.
@@ -4783,7 +4794,7 @@ int UtcDaliActorPropertyClippingActorWithRendererOverride(void)
   // Check stencil functions are not called.
   DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilFunc"));
   // TODO: Temporarily commented out the line below when caching is disabled. Will need to add it back.
-//  DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilMask"));
+  //  DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilMask"));
   DALI_TEST_CHECK(!stencilTrace.FindMethod("StencilOp"));
 
   // Check that scissor clipping is overriden by the renderer properties.
@@ -8081,7 +8092,7 @@ int utcDaliActorPartialUpdateSetProperty(void)
   DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
   application.RenderWithPartialUpdate(damagedRects, clippingRect);
 
-  Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 4u, 4u);
+  Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 4u, 4u);
   Actor   actor = CreateRenderableActor(image, RENDER_SHADOW_VERTEX_SOURCE, RENDER_SHADOW_FRAGMENT_SOURCE);
   actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
   actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
index e58f206f5ad0c8a36ca3ebbbc32ae2d9d44edca8..0bb0706fc5cf69f3d1cda879c82b6f212b81b389 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.
@@ -174,9 +174,20 @@ Actor CreateRenderableActorSuccess(TestApplication& application, std::string fil
   return actor;
 }
 
+Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height)
+{
+  Texture texture = Texture::New(type, format, width, height);
+
+  int       bufferSize = width * height * 2;
+  uint8_t*  buffer     = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+  PixelData pixelData  = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE);
+  texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height);
+  return texture;
+}
+
 Texture CreateTexture()
 {
-  return Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 80u, 80u);
+  return CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 80, 80);
 }
 
 RenderTask CreateRenderTask(TestApplication& application,
@@ -346,7 +357,7 @@ int UtcDaliRenderTaskSetSourceActorP01(void)
   Actor actor = task.GetSourceActor();
   DALI_TEST_CHECK(actor);
 
-  Texture img      = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Texture img      = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
   Actor   newActor = CreateRenderableActor(img);
   newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
   stage.Add(newActor);
@@ -390,7 +401,7 @@ int UtcDaliRenderTaskSetSourceActorP02(void)
   Actor actor = task.GetSourceActor();
   DALI_TEST_CHECK(actor);
 
-  Texture img      = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Texture img      = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
   Actor   newActor = CreateRenderableActor(img);
   newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
   stage.Add(newActor);
@@ -449,7 +460,7 @@ int UtcDaliRenderTaskSetSourceActorOffScene(void)
   TraceCallStack&    drawTrace = gl.GetDrawTrace();
   drawTrace.Enable(true);
 
-  Texture img      = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Texture img      = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
   Actor   newActor = CreateRenderableActor(img);
   newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
   task.SetSourceActor(newActor);
@@ -498,7 +509,7 @@ int UtcDaliRenderTaskSetSourceActorEmpty(void)
   Actor actor = task.GetSourceActor();
   DALI_TEST_CHECK(actor);
 
-  Texture img      = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Texture img      = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
   Actor   newActor = CreateRenderableActor(img);
   newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
   stage.Add(newActor);
@@ -548,7 +559,7 @@ int UtcDaliRenderTaskSetSourceActorDestroyed(void)
   Actor actor = task.GetSourceActor();
   DALI_TEST_CHECK(actor);
 
-  Texture img = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Texture img = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
 
   Actor newActor = CreateRenderableActor(img);
   newActor.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
@@ -643,7 +654,7 @@ int UtcDaliRenderTaskSetExclusive(void)
   ids.push_back(10); // 10 = actor3
   application.GetGlAbstraction().SetNextTextureIds(ids);
 
-  Texture img1   = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Texture img1   = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
   Actor   actor1 = CreateRenderableActor(img1);
   actor1.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
   application.GetScene().Add(actor1);
@@ -658,15 +669,11 @@ int UtcDaliRenderTaskSetExclusive(void)
 
   if(boundTextures.size())
   {
-    int c = 0;
-    DALI_TEST_EQUALS(boundTextures[c++], 8u /*unique to actor1*/, TEST_LOCATION);
-    if(boundTextures.size() > 1)
-    {
-      DALI_TEST_EQUALS(boundTextures[c++], 8u /*unique to actor1*/, TEST_LOCATION);
-    }
+    int a = boundTextures.size() - 1;
+    DALI_TEST_EQUALS(boundTextures[a], 8u /*unique to actor1*/, TEST_LOCATION);
   }
 
-  Texture img2 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Texture img2 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
 
   Actor actor2 = CreateRenderableActor(img2);
   actor2.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
@@ -685,18 +692,15 @@ int UtcDaliRenderTaskSetExclusive(void)
   // Check that the actors were rendered
   DALI_TEST_GREATER(boundTextures.size(), static_cast<std::vector<GLuint>::size_type>(1), TEST_LOCATION);
 
-  if(boundTextures.size())
+  if(boundTextures.size() >= 2)
   {
-    int c = 0;
-    DALI_TEST_EQUALS(boundTextures[c++], 9u /*unique to actor2*/, TEST_LOCATION);
-    if(boundTextures.size() > 2)
-    {
-      DALI_TEST_EQUALS(boundTextures[c++], 9u /*unique to actor1*/, TEST_LOCATION);
-    }
-    DALI_TEST_EQUALS(boundTextures[c++], 8u /*unique to actor1*/, TEST_LOCATION);
+    int a = boundTextures.size() - 2;
+    int b = boundTextures.size() - 1;
+    DALI_TEST_EQUALS(boundTextures[a], 9u /*unique to actor2*/, TEST_LOCATION);
+    DALI_TEST_EQUALS(boundTextures[b], 8u /*unique to actor1*/, TEST_LOCATION);
   }
 
-  Texture img3   = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Texture img3   = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
   Actor   actor3 = CreateRenderableActor(img3);
   actor3.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
 
@@ -714,16 +718,14 @@ int UtcDaliRenderTaskSetExclusive(void)
   // Check that the actors were rendered
   DALI_TEST_GREATER(boundTextures.size(), static_cast<std::vector<GLuint>::size_type>(2), TEST_LOCATION);
 
-  if(boundTextures.size())
+  if(boundTextures.size() >= 3)
   {
-    int c = 0;
-    DALI_TEST_EQUALS(boundTextures[c++], 10u /*unique to actor3*/, TEST_LOCATION);
-    if(boundTextures.size() > 3)
-    {
-      DALI_TEST_EQUALS(boundTextures[c++], 10u /*unique to actor2*/, TEST_LOCATION);
-    }
-    DALI_TEST_EQUALS(boundTextures[c++], 9u /*unique to actor2*/, TEST_LOCATION);
-    DALI_TEST_EQUALS(boundTextures[c++], 8u /*unique to actor1*/, TEST_LOCATION);
+    int a = boundTextures.size() - 3;
+    int b = boundTextures.size() - 2;
+    int c = boundTextures.size() - 1;
+    DALI_TEST_EQUALS(boundTextures[a], 10u /*unique to actor3*/, TEST_LOCATION);
+    DALI_TEST_EQUALS(boundTextures[b], 9u /*unique to actor2*/, TEST_LOCATION);
+    DALI_TEST_EQUALS(boundTextures[c], 8u /*unique to actor1*/, TEST_LOCATION);
   }
 
   // Both actors are now connected to the root node
@@ -743,17 +745,19 @@ int UtcDaliRenderTaskSetExclusive(void)
   application.SendNotification();
   application.Render();
 
-  DALI_TEST_EQUALS(boundTextures.size(), 4u, TEST_LOCATION);
-
-  if(boundTextures.size() == 4)
+  if(boundTextures.size() >= 4)
   {
     // Test that task 1 renders actor3, then actor2 & then actor1
-    DALI_TEST_CHECK(boundTextures[0] == 10u);
-    DALI_TEST_CHECK(boundTextures[1] == 9u);
-    DALI_TEST_CHECK(boundTextures[2] == 8u);
+    int a = boundTextures.size() - 4;
+    int b = boundTextures.size() - 3;
+    int c = boundTextures.size() - 2;
+    int d = boundTextures.size() - 1;
+    DALI_TEST_EQUALS(boundTextures[a], 10u /*unique to actor3*/, TEST_LOCATION);
+    DALI_TEST_EQUALS(boundTextures[b], 9u /*unique to actor2*/, TEST_LOCATION);
+    DALI_TEST_EQUALS(boundTextures[c], 8u /*unique to actor1*/, TEST_LOCATION);
 
     // Test that task 2 renders actor2
-    DALI_TEST_EQUALS(boundTextures[3], 9u, TEST_LOCATION);
+    DALI_TEST_EQUALS(boundTextures[d], 9u, TEST_LOCATION);
   }
 
   // Make actor2 exclusive to task2
@@ -796,7 +800,7 @@ int UtcDaliRenderTaskSetExclusive02(void)
   ids.push_back(8); // 8 = actor1
   application.GetGlAbstraction().SetNextTextureIds(ids);
 
-  Texture img1   = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
+  Texture img1   = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 1, 1);
   Actor   actor1 = CreateRenderableActor(img1);
   actor1.SetProperty(Actor::Property::SIZE, Vector2(1.0f, 1.0f));
   application.GetScene().Add(actor1);
@@ -1796,7 +1800,7 @@ int UtcDaliRenderTaskSignalFinished(void)
 
   application.GetScene().Add(offscreenCameraActor);
 
-  Texture image     = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10);
+  Texture image     = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10);
   Actor   rootActor = CreateRenderableActor(image);
   rootActor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
   application.GetScene().Add(rootActor);
@@ -2469,7 +2473,7 @@ int UtcDaliRenderTaskFinishInvisibleSourceActor(void)
 
   application.GetScene().Add(offscreenCameraActor);
 
-  Texture image     = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10);
+  Texture image     = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10);
   Actor   rootActor = CreateRenderableActor(image);
   rootActor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
   rootActor.SetProperty(Actor::Property::VISIBLE, false);
@@ -2552,7 +2556,7 @@ int UtcDaliRenderTaskFinishMissingImage(void)
 
   Integration::Scene stage = application.GetScene();
 
-  Texture image     = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10);
+  Texture image     = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 10, 10);
   Actor   rootActor = CreateRenderableActor(image);
   rootActor.SetProperty(Actor::Property::SIZE, Vector2(10.0f, 10.0f));
   stage.Add(rootActor);
index 3f7014e44a786a3c64fd4786441d1d1b3e35a00b..0e2adb4f39f350a082699f8bfd4291e30f6cf3bd 100644 (file)
@@ -77,6 +77,42 @@ void TestConstraintNoBlue(Vector4& current, const PropertyInputContainer& inputs
   current.b = 0.0f;
 }
 
+Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height)
+{
+  Texture texture = Texture::New(type, format, width, height);
+
+  int       bufferSize = width * height * Pixel::GetBytesPerPixel(format);
+  uint8_t*  buffer     = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+  PixelData pixelData  = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE);
+  texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height);
+  return texture;
+}
+
+Renderer CreateRenderer(Actor actor, Geometry geometry, Shader shader, int depthIndex)
+{
+  Texture    image0      = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGB888, 64, 64);
+  TextureSet textureSet0 = CreateTextureSet(image0);
+  Renderer   renderer0   = Renderer::New(geometry, shader);
+  renderer0.SetTextures(textureSet0);
+  renderer0.SetProperty(Renderer::Property::DEPTH_INDEX, depthIndex);
+  actor.AddRenderer(renderer0);
+  return renderer0;
+}
+
+Actor CreateActor(Actor parent, int siblingOrder, const char* location)
+{
+  Actor actor = Actor::New();
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+  actor.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
+  actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+  parent.Add(actor);
+  actor.SetProperty(Dali::DevelActor::Property::SIBLING_ORDER, siblingOrder);
+  DALI_TEST_EQUALS(actor.GetProperty<int>(Dali::DevelActor::Property::SIBLING_ORDER), siblingOrder, TEST_INNER_LOCATION(location));
+
+  return actor;
+}
+
 } // unnamed namespace
 
 void renderer_test_startup(void)
@@ -1811,31 +1847,6 @@ int UtcDaliRendererUniformMapMultipleUniforms02(void)
   END_TEST;
 }
 
-Renderer CreateRenderer(Actor actor, Geometry geometry, Shader shader, int depthIndex)
-{
-  Texture    image0      = Texture::New(TextureType::TEXTURE_2D, Pixel::RGB888, 64, 64);
-  TextureSet textureSet0 = CreateTextureSet(image0);
-  Renderer   renderer0   = Renderer::New(geometry, shader);
-  renderer0.SetTextures(textureSet0);
-  renderer0.SetProperty(Renderer::Property::DEPTH_INDEX, depthIndex);
-  actor.AddRenderer(renderer0);
-  return renderer0;
-}
-
-Actor CreateActor(Actor parent, int siblingOrder, const char* location)
-{
-  Actor actor = Actor::New();
-  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
-  actor.SetProperty(Actor::Property::PARENT_ORIGIN, AnchorPoint::CENTER);
-  actor.SetProperty(Actor::Property::POSITION, Vector2(0.0f, 0.0f));
-  actor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
-  parent.Add(actor);
-  actor.SetProperty(Dali::DevelActor::Property::SIBLING_ORDER, siblingOrder);
-  DALI_TEST_EQUALS(actor.GetProperty<int>(Dali::DevelActor::Property::SIBLING_ORDER), siblingOrder, TEST_INNER_LOCATION(location));
-
-  return actor;
-}
-
 int UtcDaliRendererRenderOrder2DLayer(void)
 {
   TestApplication application;
@@ -1884,6 +1895,7 @@ int UtcDaliRendererRenderOrder2DLayer(void)
   application.Render(0);
 
   TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.GetTextureTrace().Reset();
   gl.EnableTextureCallTrace(true);
   application.SendNotification();
   application.Render(0);
@@ -1951,6 +1963,7 @@ int UtcDaliRendererRenderOrder2DLayerMultipleRenderers(void)
   application.Render(0);
 
   TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.GetTextureTrace().Reset();
   gl.EnableTextureCallTrace(true);
   application.SendNotification();
   application.Render(0);
@@ -2039,6 +2052,7 @@ int UtcDaliRendererRenderOrder2DLayerSiblingOrder(void)
   application.Render();
 
   TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.GetTextureTrace().Reset();
   gl.EnableTextureCallTrace(true);
   application.SendNotification();
   application.Render(0);
@@ -2140,6 +2154,7 @@ int UtcDaliRendererRenderOrder2DLayerOverlay(void)
   actor0.Add(actor3);
 
   TestGlAbstraction& gl = application.GetGlAbstraction();
+  gl.GetTextureTrace().Reset();
   gl.EnableTextureCallTrace(true);
   application.SendNotification();
   application.Render(0);
index f90ed2b0414226d5e2b13e53b8f0af647fc8817f..9c60de8e1bd3987dcb1aa3056a59e75e965f1546 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.
@@ -36,6 +36,20 @@ void sampler_test_cleanup(void)
   test_return_value = TET_PASS;
 }
 
+namespace
+{
+Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height)
+{
+  Texture texture = Texture::New(type, format, width, height);
+
+  int       bufferSize = width * height * 2;
+  uint8_t*  buffer     = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+  PixelData pixelData  = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE);
+  texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height);
+  return texture;
+}
+} // namespace
+
 int UtcDaliSamplerNew01(void)
 {
   TestApplication application;
@@ -152,7 +166,7 @@ int UtcSamplerSetFilterMode(void)
 {
   TestApplication application;
 
-  Texture image   = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture image   = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
   Sampler sampler = Sampler::New();
 
   TextureSet textureSet = CreateTextureSet();
@@ -176,6 +190,7 @@ int UtcSamplerSetFilterMode(void)
   TraceCallStack& texParameterTrace = gl.GetTexParameterTrace();
   texParameterTrace.Reset();
   texParameterTrace.Enable(true);
+  texParameterTrace.EnableLogging(true);
 
   sampler.SetFilterMode(FilterMode::DEFAULT, FilterMode::DEFAULT);
   application.SendNotification();
@@ -189,7 +204,7 @@ int UtcSamplerSetFilterMode(void)
   DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 4, TEST_LOCATION);
 
   std::stringstream out;
-  out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_LINEAR;
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_LINEAR;
   DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION);
 
   /**************************************************************/
@@ -227,11 +242,11 @@ int UtcSamplerSetFilterMode(void)
   DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 2, TEST_LOCATION);
 
   out.str("");
-  out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST;
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST;
   DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION);
 
   out.str("");
-  out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MAG_FILTER << ", " << GL_NEAREST;
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MAG_FILTER << ", " << GL_NEAREST;
   DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(1, "TexParameteri", out.str()), true, TEST_LOCATION);
 
   /**************************************************************/
@@ -251,7 +266,87 @@ int UtcSamplerSetFilterMode(void)
   DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION);
 
   out.str("");
-  out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MAG_FILTER << ", " << GL_LINEAR;
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MAG_FILTER << ", " << GL_LINEAR;
+  DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION);
+
+  /**************************************************************/
+  // Nearest+mipmap nearest/Linear
+  texParameterTrace.Reset();
+  texParameterTrace.Enable(true);
+
+  sampler.SetFilterMode(FilterMode::NEAREST_MIPMAP_NEAREST, FilterMode::LINEAR);
+
+  // Flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  texParameterTrace.Enable(false);
+
+  // Verify actor gl state
+  DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION);
+
+  out.str("");
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST_MIPMAP_NEAREST;
+  DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION);
+
+  /**************************************************************/
+  // Nearest+mipmap linear/Linear
+  texParameterTrace.Reset();
+  texParameterTrace.Enable(true);
+
+  sampler.SetFilterMode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::LINEAR);
+
+  // Flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  texParameterTrace.Enable(false);
+
+  // Verify actor gl state
+  DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION);
+
+  out.str("");
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST_MIPMAP_LINEAR;
+  DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION);
+
+  /**************************************************************/
+  // linear+mipmap nearest/Linear
+  texParameterTrace.Reset();
+  texParameterTrace.Enable(true);
+
+  sampler.SetFilterMode(FilterMode::LINEAR_MIPMAP_NEAREST, FilterMode::LINEAR);
+
+  // Flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  texParameterTrace.Enable(false);
+
+  // Verify actor gl state
+  DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION);
+
+  out.str("");
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_LINEAR_MIPMAP_NEAREST;
+  DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION);
+
+  /**************************************************************/
+  // linear+mipmap linear/Linear
+  texParameterTrace.Reset();
+  texParameterTrace.Enable(true);
+
+  sampler.SetFilterMode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR);
+
+  // Flush the queue and render once
+  application.SendNotification();
+  application.Render();
+
+  texParameterTrace.Enable(false);
+
+  // Verify actor gl state
+  DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION);
+
+  out.str("");
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_LINEAR_MIPMAP_LINEAR;
   DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION);
 
   /**************************************************************/
@@ -271,7 +366,7 @@ int UtcSamplerSetFilterMode(void)
   DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 1, TEST_LOCATION);
 
   out.str("");
-  out << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST_MIPMAP_LINEAR;
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_MIN_FILTER << ", " << GL_NEAREST_MIPMAP_LINEAR;
   DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(0, "TexParameteri", out.str()), true, TEST_LOCATION);
 
   END_TEST;
@@ -281,7 +376,7 @@ int UtcSamplerSetWrapMode1(void)
 {
   TestApplication application;
 
-  Texture    image      = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture    image      = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
   TextureSet textureSet = CreateTextureSet();
   Sampler    sampler    = Sampler::New();
   textureSet.SetTexture(0u, image);
@@ -305,6 +400,7 @@ int UtcSamplerSetWrapMode1(void)
   TraceCallStack& texParameterTrace = gl.GetTexParameterTrace();
   texParameterTrace.Reset();
   texParameterTrace.Enable(true);
+  texParameterTrace.EnableLogging(true);
 
   application.SendNotification();
   application.Render();
@@ -317,11 +413,11 @@ int UtcSamplerSetWrapMode1(void)
   DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 4, TEST_LOCATION);
 
   std::stringstream out;
-  out << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_CLAMP_TO_EDGE;
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_S << ", " << GL_CLAMP_TO_EDGE;
   DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(2, "TexParameteri", out.str()), true, TEST_LOCATION);
 
   out.str("");
-  out << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_CLAMP_TO_EDGE;
+  out << std::hex << GL_TEXTURE_2D << ", " << GL_TEXTURE_WRAP_T << ", " << GL_CLAMP_TO_EDGE;
   DALI_TEST_EQUALS(texParameterTrace.TestMethodAndParams(3, "TexParameteri", out.str()), true, TEST_LOCATION);
 
   texParameterTrace.Reset();
@@ -352,7 +448,7 @@ int UtcSamplerSetWrapMode2(void)
   // Create a cube-map texture.
   unsigned int width   = 8u;
   unsigned int height  = 8u;
-  Texture      texture = Texture::New(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height);
+  Texture      texture = CreateTexture(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height);
 
   // Create source image data.
   unsigned int   bufferSize(width * height * 4);
@@ -395,6 +491,7 @@ int UtcSamplerSetWrapMode2(void)
   TraceCallStack& texParameterTrace = gl.GetTexParameterTrace();
   texParameterTrace.Reset();
   texParameterTrace.Enable(true);
+  texParameterTrace.EnableLogging(true);
 
   // Call the 3 dimensional wrap mode API.
   sampler.SetWrapMode(WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE);
@@ -405,7 +502,7 @@ int UtcSamplerSetWrapMode2(void)
   // Verify that no TexParameteri calls occurred since wrap mode hasn't changed.
   DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 0u, TEST_LOCATION);
 
-  sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::REPEAT, WrapMode::REPEAT);
+  sampler.SetWrapMode(WrapMode::MIRRORED_REPEAT, WrapMode::REPEAT, WrapMode::REPEAT);
   texParameterTrace.Reset();
   application.SendNotification();
   application.Render();
@@ -413,6 +510,9 @@ int UtcSamplerSetWrapMode2(void)
   texParameterTrace.Enable(false);
 
   // Verify that 3 TexParameteri calls occurred.
+  std::ostringstream out;
+  out << std::hex << GL_TEXTURE_CUBE_MAP << ", " << GL_TEXTURE_WRAP_R << ", " << GL_MIRRORED_REPEAT;
+  DALI_TEST_CHECK(texParameterTrace.FindMethodAndParams("TexParameteri", out.str()));
   DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 3u, TEST_LOCATION);
   END_TEST;
 }
index 95cb6c84479edb2906bac613d0b45d8026972511..00b3d75a1a875f11f436da74515c689696488f54 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.
@@ -35,6 +35,17 @@ void texture_set_cleanup(void)
   test_return_value = TET_PASS;
 }
 
+Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height)
+{
+  Texture texture = Texture::New(type, format, width, height);
+
+  int       bufferSize = width * height * Pixel::GetBytesPerPixel(format);
+  uint8_t*  buffer     = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+  PixelData pixelData  = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE);
+  texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height);
+  return texture;
+}
+
 int UtcDaliTextureNew01(void)
 {
   TestApplication application;
@@ -178,7 +189,7 @@ int UtcDaliTextureUpload01(void)
   //Create the texture
   unsigned int width(64);
   unsigned int height(64);
-  Texture      texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture      texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
 
   application.GetGlAbstraction().EnableTextureCallTrace(true);
 
@@ -187,13 +198,6 @@ int UtcDaliTextureUpload01(void)
 
   TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
 
-  //TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu
-  {
-    std::stringstream out;
-    out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height;
-    DALI_TEST_CHECK(callStack.FindMethodAndParams("TexImage2D", out.str().c_str()));
-  }
-
   //Upload data to the texture
   callStack.Reset();
 
@@ -237,7 +241,7 @@ int UtcDaliTextureUpload02(void)
   //Create the texture
   unsigned int width(64);
   unsigned int height(64);
-  Texture      texture = Texture::New(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height);
+  Texture      texture = CreateTexture(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height);
 
   application.GetGlAbstraction().EnableTextureCallTrace(true);
 
@@ -246,7 +250,7 @@ int UtcDaliTextureUpload02(void)
 
   TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
 
-  //TexImage2D should be called six times with a null pointer to reserve storage for the six textures of the cube map
+  tet_infoline("TexImage2D should be called six times with a null pointer to reserve storage for the six textures of the cube map");
   for(unsigned int i(0); i < 6; ++i)
   {
     std::stringstream out;
@@ -363,7 +367,7 @@ int UtcDaliTextureUpload03(void)
   unsigned int widthMipmap1(32);
   unsigned int heightMipmap1(32);
 
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
 
   application.GetGlAbstraction().EnableTextureCallTrace(true);
 
@@ -372,7 +376,7 @@ int UtcDaliTextureUpload03(void)
 
   TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
 
-  //TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu
+  tet_infoline("TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu");
   {
     std::stringstream out;
     out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height;
@@ -419,7 +423,7 @@ int UtcDaliTextureUpload04(void)
   unsigned int widthMipmap1(32);
   unsigned int heightMipmap1(32);
 
-  Texture texture = Texture::New(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height);
+  Texture texture = CreateTexture(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height);
 
   application.GetGlAbstraction().EnableTextureCallTrace(true);
   TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
@@ -506,7 +510,7 @@ int UtcDaliTextureUpload05(void)
     //Create a texture with a compressed format
     unsigned int width(64);
     unsigned int height(64);
-    Texture      texture = Texture::New(TextureType::TEXTURE_2D, COMPRESSED_PIXEL_FORMATS[index], width, height);
+    Texture      texture = CreateTexture(TextureType::TEXTURE_2D, COMPRESSED_PIXEL_FORMATS[index], width, height);
 
     application.GetGlAbstraction().EnableTextureCallTrace(true);
 
@@ -515,7 +519,7 @@ int UtcDaliTextureUpload05(void)
 
     TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
 
-    //CompressedTexImage2D should be called with a null pointer to reserve storage for the texture in the gpu
+    tet_infoline("CompressedTexImage2D should be called with a null pointer to reserve storage for the texture in the gpu");
     {
       std::stringstream out;
       out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height;
@@ -569,7 +573,7 @@ int UtcDaliTextureUpload06(void)
   unsigned int width(64);
   unsigned int height(64);
   tet_infoline("Creating a Texure with an alpha channel");
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
 
   application.GetGlAbstraction().EnableTextureCallTrace(true);
 
@@ -623,7 +627,7 @@ int UtcDaliTextureUpload07(void)
     unsigned int width(64);
     unsigned int height(64);
     tet_infoline("Creating a floating point texture");
-    Texture texture = Texture::New(TextureType::TEXTURE_2D, FLOATING_POINT_PIXEL_FORMATS[index], width, height);
+    Texture texture = CreateTexture(TextureType::TEXTURE_2D, FLOATING_POINT_PIXEL_FORMATS[index], width, height);
 
     application.GetGlAbstraction().EnableTextureCallTrace(true);
 
@@ -661,6 +665,58 @@ int UtcDaliTextureUpload07(void)
   END_TEST;
 }
 
+int UtcDaliTextureUploadPixelFormats(void)
+{
+  TestApplication application;
+  application.GetGlAbstraction().EnableTextureCallTrace(true);
+
+  //Create the texture
+  unsigned int width(64);
+  unsigned int height(64);
+
+  std::vector<Pixel::Format> formats =
+    {
+      Pixel::A8,
+      Pixel::L8,
+      Pixel::LA88,
+      Pixel::RGB565,
+      Pixel::BGR565,
+      Pixel::RGBA4444,
+      Pixel::BGRA4444,
+      Pixel::RGBA5551,
+      Pixel::BGRA5551,
+      Pixel::RGB888,
+      Pixel::RGB8888,
+      Pixel::BGR8888,
+      Pixel::RGBA8888,
+      Pixel::BGRA8888,
+      Pixel::DEPTH_UNSIGNED_INT,
+      Pixel::DEPTH_FLOAT,
+      Pixel::DEPTH_STENCIL};
+
+  for(auto format : formats)
+  {
+    tet_infoline("Creating a Texure with an alpha channel");
+    Texture texture = CreateTexture(TextureType::TEXTURE_2D, format, width, height);
+
+    application.SendNotification();
+    application.Render();
+
+    TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
+
+    tet_infoline("TexImage2D should be called twice per texture");
+    DALI_TEST_EQUALS(callStack.CountMethod("TexImage2D"), 2, TEST_LOCATION);
+    {
+      std::stringstream out;
+      out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height;
+      DALI_TEST_CHECK(callStack.FindMethodAndParams("TexImage2D", out.str().c_str()));
+    }
+    callStack.Reset();
+  }
+
+  END_TEST;
+}
+
 int UtcDaliTextureUploadSmallerThanSize(void)
 {
   TestApplication application;
@@ -668,7 +724,7 @@ int UtcDaliTextureUploadSmallerThanSize(void)
   //Create the texture
   unsigned int width(64);
   unsigned int height(64);
-  Texture      texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture      texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
 
   application.GetGlAbstraction().EnableTextureCallTrace(true);
 
@@ -676,8 +732,11 @@ int UtcDaliTextureUploadSmallerThanSize(void)
   application.Render();
 
   TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
+  callStack.EnableLogging(true);
+  TraceCallStack& texParamCallStack = application.GetGlAbstraction().GetTexParameterTrace();
+  texParamCallStack.EnableLogging(true);
 
-  //TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu
+  tet_infoline("TexImage2D should be called with a null pointer to reserve storage for the texture in the gpu");
   {
     std::stringstream out;
     out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height;
@@ -696,7 +755,7 @@ int UtcDaliTextureUploadSmallerThanSize(void)
   application.SendNotification();
   application.Render();
 
-  //TexImage2D should be called to upload the data
+  //TexSubImage2D should be called to upload the data
   {
     std::stringstream out;
     out << GL_TEXTURE_2D << ", " << 0u << ", " << 0u << ", " << 0u << ", " << width / 2 << ", " << height / 2;
@@ -704,20 +763,20 @@ int UtcDaliTextureUploadSmallerThanSize(void)
     DALI_TEST_CHECK(callStack.FindMethodAndGetParameters("TexSubImage2D", params));
     DALI_TEST_EQUALS(out.str(), params, TEST_LOCATION);
   }
-
   END_TEST;
 }
 
 int UtcDaliTextureGenerateMipmaps(void)
 {
+#ifdef OLD_GRAPHICS_TEST
   TestApplication application;
   unsigned int    width(64);
   unsigned int    height(64);
 
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
   texture.GenerateMipmaps();
 
-  Texture textureCubemap = Texture::New(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height);
+  Texture textureCubemap = CreateTexture(TextureType::TEXTURE_CUBE, Pixel::RGBA8888, width, height);
   textureCubemap.GenerateMipmaps();
 
   application.GetGlAbstraction().EnableTextureCallTrace(true);
@@ -735,6 +794,9 @@ int UtcDaliTextureGenerateMipmaps(void)
     out << GL_TEXTURE_CUBE_MAP;
     DALI_TEST_CHECK(callStack.FindMethodAndParams("GenerateMipmap", out.str().c_str()));
   }
+#else
+  DALI_TEST_CHECK(1);
+#endif
 
   END_TEST;
 }
@@ -745,7 +807,7 @@ int UtcDaliTextureGetWidth(void)
   unsigned int    width(64);
   unsigned int    height(64);
 
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
   DALI_TEST_EQUALS(texture.GetWidth(), width, TEST_LOCATION);
   END_TEST;
 }
@@ -756,7 +818,7 @@ int UtcDaliTextureGetHeight(void)
   unsigned int    width(64);
   unsigned int    height(64);
 
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
   DALI_TEST_EQUALS(texture.GetHeight(), height, TEST_LOCATION);
 
   END_TEST;
@@ -770,7 +832,7 @@ int UtcDaliTextureContextLoss(void)
   //Create the texture
   unsigned int width(64);
   unsigned int height(64);
-  Texture      texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture      texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
   DALI_TEST_CHECK(texture);
 
   application.SendNotification();
@@ -836,8 +898,9 @@ int UtcDaliNativeImageTexture02(void)
 
     // Expect 2 attempts to create the texture - once when adding the texture
     // to the scene-graph, and again since that failed, during the Bind.
+    // The second one succeeds (TargetTexture only errors once)
     DALI_TEST_EQUALS(imageInterface->mExtensionCreateCalls, 2, TEST_LOCATION);
-    DALI_TEST_EQUALS(imageInterface->mExtensionDestroyCalls, 2, TEST_LOCATION);
+    DALI_TEST_EQUALS(imageInterface->mExtensionDestroyCalls, 1, TEST_LOCATION);
 
     UnparentAndReset(actor);
 
@@ -958,7 +1021,7 @@ int UtcDaliTextureCheckNativeN1(void)
   TestApplication application;
   unsigned int    width(64);
   unsigned int    height(64);
-  Texture         texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture         texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
 
   DALI_TEST_CHECK(texture);
   DALI_TEST_CHECK(!DevelTexture::IsNative(texture));
@@ -1046,7 +1109,7 @@ int UtcDaliTextureApplyFragShaderN2(void)
   TestApplication application;
   unsigned int    width(64);
   unsigned int    height(64);
-  Texture         texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture         texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
 
   const std::string baseFragShader =
     "varying mediump vec4 uColor;\n"
index 83cc3f85ad819f21bfb1e43775461e6ad56ebac2..f0f0cb9bfbdfe47f604a4bc79eadfa1b9a2d1323 100644 (file)
@@ -32,9 +32,20 @@ enum SetSampler
   DONT_SET_SAMPLER
 };
 
+Texture CreateTexture(TextureType::Type type, Pixel::Format format, int width, int height)
+{
+  Texture texture = Texture::New(type, format, width, height);
+
+  int       bufferSize = width * height * 2;
+  uint8_t*  buffer     = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+  PixelData pixelData  = PixelData::New(buffer, bufferSize, width, height, format, PixelData::FREE);
+  texture.Upload(pixelData, 0u, 0u, 0u, 0u, width, height);
+  return texture;
+}
+
 Actor CreateActor(SetSampler setSamplerOption)
 {
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
 
   Shader     shader     = CreateShader();
   TextureSet textureSet = CreateTextureSet();
@@ -93,7 +104,7 @@ int UtcDaliTextureSetCopyConstructor(void)
 {
   TestApplication application;
 
-  Texture    image      = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32);
+  Texture    image      = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32);
   TextureSet textureSet = TextureSet::New();
   textureSet.SetTexture(0u, image);
 
@@ -126,7 +137,7 @@ int UtcDaliTextureSetMoveConstructor(void)
   DALI_TEST_CHECK(textureSet);
   DALI_TEST_EQUALS(1, textureSet.GetBaseObject().ReferenceCount(), TEST_LOCATION);
 
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32);
   textureSet.SetTexture(0u, texture);
   DALI_TEST_EQUALS(textureSet.GetTexture(0u), texture, TEST_LOCATION);
 
@@ -147,7 +158,7 @@ int UtcDaliTextureSetMoveAssignment(void)
   DALI_TEST_CHECK(textureSet);
   DALI_TEST_EQUALS(1, textureSet.GetBaseObject().ReferenceCount(), TEST_LOCATION);
 
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 32, 32);
   textureSet.SetTexture(0u, texture);
   DALI_TEST_EQUALS(textureSet.GetTexture(0u), texture, TEST_LOCATION);
 
@@ -259,6 +270,7 @@ int UtcDaliTextureSetMultiple(void)
   TraceCallStack& texParameterTrace = gl.GetTexParameterTrace();
   texParameterTrace.Reset();
   texParameterTrace.Enable(true);
+  texParameterTrace.EnableLogging(true);
   application.SendNotification();
   application.Render();
 
@@ -271,7 +283,7 @@ int UtcDaliTextureSetMultiple(void)
   // Verify gl state
   // For each actor there are four calls to TexParameteri when the texture is first created
   // Texture minification and magnification filters are now different than default so
-  //there should have been two extra TexParameteri calls to set the new filter mode
+  // there should have been two extra TexParameteri calls to set the new filter mode
   DALI_TEST_EQUALS(texParameterTrace.CountMethod("TexParameteri"), 2 * 6, TEST_LOCATION);
 
   END_TEST;
@@ -281,7 +293,7 @@ int UtcDaliTextureSetSetSampler(void)
 {
   TestApplication application;
 
-  Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
 
   Shader     shader     = CreateShader();
   TextureSet textureSet = CreateTextureSet(image);
@@ -301,6 +313,7 @@ int UtcDaliTextureSetSetSampler(void)
 
   TraceCallStack& texParameterTrace = gl.GetTexParameterTrace();
   texParameterTrace.Reset();
+  texParameterTrace.EnableLogging(true);
   texParameterTrace.Enable(true);
   application.SendNotification();
   application.Render();
@@ -344,7 +357,7 @@ int UtcDaliTextureSetGetTexture(void)
   DALI_TEST_EQUALS(textureSet.GetTexture(1), Texture(), TEST_LOCATION);
   DALI_TEST_EQUALS(textureSet.GetTexture(2), Texture(), TEST_LOCATION);
 
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
   textureSet.SetTexture(0u, texture);
 
   DALI_TEST_EQUALS(textureSet.GetTexture(0), texture, TEST_LOCATION);
@@ -401,7 +414,7 @@ int UtcDaliTextureSetGetTextureCount0(void)
   TextureSet textureSet = CreateTextureSet();
   DALI_TEST_EQUALS(textureSet.GetTextureCount(), 0u, TEST_LOCATION);
 
-  Texture image = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture image = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
   textureSet.SetTexture(0u, image);
   DALI_TEST_EQUALS(textureSet.GetTextureCount(), 1u, TEST_LOCATION);
 
@@ -427,7 +440,7 @@ int UtcDaliTextureSetGetTextureCount1(void)
   TextureSet textureSet = CreateTextureSet();
   DALI_TEST_EQUALS(textureSet.GetTextureCount(), 0u, TEST_LOCATION);
 
-  Texture texture = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
   textureSet.SetTexture(0u, texture);
   DALI_TEST_EQUALS(textureSet.GetTextureCount(), 1u, TEST_LOCATION);
 
@@ -540,10 +553,10 @@ int UtcDaliTextureSetMultipleTextures(void)
   TextureSet textureSet = CreateTextureSet();
 
   // Set 2 textures
-  Texture texture1 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture texture1 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
   textureSet.SetTexture(0u, texture1);
 
-  Texture texture2 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  Texture texture2 = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
   textureSet.SetTexture(1u, texture2);
 
   Geometry geometry = CreateQuadGeometry();
index 511285f1005bea4df7481e1e32d966e71d1e63a8..518b3dbff87252e6ee1ba495f6081387bc885ffe 100644 (file)
@@ -352,7 +352,7 @@ IF( ENABLE_COVERAGE )
           -name libdali*.so* \)
           | grep -v TC | xargs rm -rf
           TARGET  ${DALI_CORE_PREFIX}distclean
-          VERBATIM
+VERBATIM
           )
 
   ENDIF( LCOV_BIN )
@@ -365,6 +365,10 @@ IF( ENABLE_LINK_TEST )
   SET( LINKER_TEST_SOURCES
     linker-test.cpp
     ${DALI_TEST_SUITE_DIR}/test-application.cpp
+    ${DALI_TEST_SUITE_DIR}/test-graphics-controller.cpp
+    ${DALI_TEST_SUITE_DIR}/test-graphics-sampler.cpp
+    ${DALI_TEST_SUITE_DIR}/test-graphics-texture.cpp
+    ${DALI_TEST_SUITE_DIR}/test-graphics-command-buffer.cpp
     ${DALI_TEST_SUITE_DIR}/test-platform-abstraction.cpp
     ${DALI_TEST_SUITE_DIR}/test-render-controller.cpp
     ${DALI_TEST_SUITE_DIR}/test-gl-abstraction.cpp
index 4fbfb4e00ae70fb5010a782d04466eac1ab5c26a..672e69cc57b0de6d035a3daa4de79ee9ae6c5376 100644 (file)
@@ -114,9 +114,10 @@ SET( internal_src_files
   ${internal_src_dir}/render/queue/render-queue.cpp
   ${internal_src_dir}/render/renderers/render-frame-buffer.cpp
   ${internal_src_dir}/render/renderers/render-geometry.cpp
-  ${internal_src_dir}/render/renderers/render-vertex-buffer.cpp
   ${internal_src_dir}/render/renderers/render-renderer.cpp
+  ${internal_src_dir}/render/renderers/render-sampler.cpp
   ${internal_src_dir}/render/renderers/render-texture.cpp
+  ${internal_src_dir}/render/renderers/render-vertex-buffer.cpp
   ${internal_src_dir}/render/shaders/program.cpp
   ${internal_src_dir}/render/shaders/program-controller.cpp
   ${internal_src_dir}/render/shaders/scene-graph-shader.cpp
index 445f9c7711804e178370e855e670dc920f1fb8ff..589c48fc0f13125b614a8479b6390227d2b047d5 100644 (file)
@@ -392,7 +392,7 @@ inline void RenderAlgorithms::ProcessRenderList(const RenderList&
                                                 const Matrix&                       projectionMatrix,
                                                 Integration::DepthBufferAvailable   depthBufferAvailable,
                                                 Integration::StencilBufferAvailable stencilBufferAvailable,
-                                                Vector<GLuint>&                     boundTextures,
+                                                Vector<Graphics::Texture*>&         boundTextures,
                                                 const RenderInstruction&            instruction,
                                                 const Rect<int>&                    rootClippingRect)
 {
@@ -506,7 +506,7 @@ void RenderAlgorithms::ProcessRenderInstruction(const RenderInstruction&
                                                 BufferIndex                         bufferIndex,
                                                 Integration::DepthBufferAvailable   depthBufferAvailable,
                                                 Integration::StencilBufferAvailable stencilBufferAvailable,
-                                                Vector<GLuint>&                     boundTextures,
+                                                Vector<Graphics::Texture*>&         boundTextures,
                                                 const Rect<int>&                    rootClippingRect)
 {
   DALI_PRINT_RENDER_INSTRUCTION(instruction, bufferIndex);
index 246314d2f903d2be923c13224d3b94645b9bb809..38c0828c119b25b5ecbc809f4dc63c4ab9ad7fe1 100644 (file)
@@ -62,7 +62,7 @@ public:
                                 BufferIndex                          bufferIndex,
                                 Integration::DepthBufferAvailable    depthBufferAvailable,
                                 Integration::StencilBufferAvailable  stencilBufferAvailable,
-                                Vector<GLuint>&                      boundTextures,
+                                Vector<Graphics::Texture*>&          boundTextures,
                                 const Rect<int>&                     rootClippingRect);
 
 private:
@@ -124,7 +124,7 @@ private:
                                 const Matrix&                                        projectionMatrix,
                                 Integration::DepthBufferAvailable                    depthBufferAvailable,
                                 Integration::StencilBufferAvailable                  stencilBufferAvailable,
-                                Vector<GLuint>&                                      boundTextures,
+                                Vector<Graphics::Texture*>&                          boundTextures,
                                 const Dali::Internal::SceneGraph::RenderInstruction& instruction, // in the case of reflection, things like CullFace need to be adjusted for reflection world
                                 const Rect<int>&                                     rootClippingRect);
 
index 32b6c8121eefaa28f3af8f45b6f5b047e970e09b..f7bdb21e99cd31be6f92a33fd01b9ec603e74426 100644 (file)
@@ -168,8 +168,8 @@ struct RenderManager::Impl
   Integration::PartialUpdateAvailable partialUpdateAvailable; ///< Whether the partial update is available
 
   std::unique_ptr<Dali::ThreadPool> threadPool;            ///< The thread pool
-  Vector<GLuint>                    boundTextures;         ///< The textures bound for rendering
-  Vector<GLuint>                    textureDependencyList; ///< The dependency list of binded textures
+  Vector<Graphics::Texture*>        boundTextures;         ///< The textures bound for rendering
+  Vector<Graphics::Texture*>        textureDependencyList; ///< The dependency list of binded textures
 };
 
 RenderManager* RenderManager::New(Graphics::Controller&               graphicsController,
@@ -217,7 +217,7 @@ void RenderManager::ContextDestroyed()
   //Inform textures
   for(auto&& texture : mImpl->textureContainer)
   {
-    texture->GlContextDestroyed();
+    texture->Destroy();
   }
 
   //Inform framebuffers
@@ -247,7 +247,7 @@ void RenderManager::SetShaderSaver(ShaderSaver& upstream)
 void RenderManager::AddRenderer(OwnerPointer<Render::Renderer>& renderer)
 {
   // Initialize the renderer as we are now in render thread
-  renderer->Initialize(mImpl->context);
+  renderer->Initialize(mImpl->context, mImpl->graphicsController);
 
   mImpl->rendererContainer.PushBack(renderer.Release());
 }
@@ -259,6 +259,7 @@ void RenderManager::RemoveRenderer(Render::Renderer* renderer)
 
 void RenderManager::AddSampler(OwnerPointer<Render::Sampler>& sampler)
 {
+  sampler->Initialize(mImpl->graphicsController);
   mImpl->samplerContainer.PushBack(sampler.Release());
 }
 
@@ -269,7 +270,7 @@ void RenderManager::RemoveSampler(Render::Sampler* sampler)
 
 void RenderManager::AddTexture(OwnerPointer<Render::Texture>& texture)
 {
-  texture->Initialize(mImpl->context);
+  texture->Initialize(mImpl->graphicsController);
   mImpl->textureContainer.PushBack(texture.Release());
 }
 
@@ -282,7 +283,7 @@ void RenderManager::RemoveTexture(Render::Texture* texture)
   {
     if(iter == texture)
     {
-      texture->Destroy(mImpl->context);
+      texture->Destroy();
       mImpl->textureContainer.Erase(&iter); // Texture found; now destroy it
       return;
     }
@@ -291,25 +292,25 @@ void RenderManager::RemoveTexture(Render::Texture* texture)
 
 void RenderManager::UploadTexture(Render::Texture* texture, PixelDataPtr pixelData, const Texture::UploadParams& params)
 {
-  texture->Upload(mImpl->context, pixelData, params);
+  texture->Upload(pixelData, params);
 }
 
 void RenderManager::GenerateMipmaps(Render::Texture* texture)
 {
-  texture->GenerateMipmaps(mImpl->context);
+  texture->GenerateMipmaps();
 }
 
 void RenderManager::SetFilterMode(Render::Sampler* sampler, uint32_t minFilterMode, uint32_t magFilterMode)
 {
-  sampler->mMinificationFilter  = static_cast<Dali::FilterMode::Type>(minFilterMode);
-  sampler->mMagnificationFilter = static_cast<Dali::FilterMode::Type>(magFilterMode);
+  sampler->SetFilterMode(static_cast<Dali::FilterMode::Type>(minFilterMode),
+                         static_cast<Dali::FilterMode::Type>(magFilterMode));
 }
 
 void RenderManager::SetWrapMode(Render::Sampler* sampler, uint32_t rWrapMode, uint32_t sWrapMode, uint32_t tWrapMode)
 {
-  sampler->mRWrapMode = static_cast<Dali::WrapMode::Type>(rWrapMode);
-  sampler->mSWrapMode = static_cast<Dali::WrapMode::Type>(sWrapMode);
-  sampler->mTWrapMode = static_cast<Dali::WrapMode::Type>(tWrapMode);
+  sampler->SetWrapMode(static_cast<Dali::WrapMode::Type>(rWrapMode),
+                       static_cast<Dali::WrapMode::Type>(sWrapMode),
+                       static_cast<Dali::WrapMode::Type>(tWrapMode));
 }
 
 void RenderManager::AddFrameBuffer(OwnerPointer<Render::FrameBuffer>& frameBuffer)
@@ -858,7 +859,7 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
       // For each offscreen buffer, update the dependency list with the new texture id used by this frame buffer.
       for(unsigned int i0 = 0, i1 = instruction.mFrameBuffer->GetColorAttachmentCount(); i0 < i1; ++i0)
       {
-        mImpl->textureDependencyList.PushBack(instruction.mFrameBuffer->GetTextureId(i0));
+        mImpl->textureDependencyList.PushBack(instruction.mFrameBuffer->GetTexture(i0));
       }
     }
     else
@@ -996,15 +997,15 @@ void RenderManager::RenderScene(Integration::RenderStatus& status, Integration::
     // Synchronise the FBO/Texture access when there are multiple contexts
     if(mImpl->currentContext->IsSurfacelessContextSupported())
     {
-      // Check whether any binded texture is in the dependency list
+      // Check whether any bound texture is in the dependency list
       bool textureFound = false;
 
       if(mImpl->boundTextures.Count() > 0u && mImpl->textureDependencyList.Count() > 0u)
       {
-        for(auto textureId : mImpl->textureDependencyList)
+        for(auto texture : mImpl->textureDependencyList)
         {
-          textureFound = std::find_if(mImpl->boundTextures.Begin(), mImpl->boundTextures.End(), [textureId](GLuint id) {
-                           return textureId == id;
+          textureFound = std::find_if(mImpl->boundTextures.Begin(), mImpl->boundTextures.End(), [texture](Graphics::Texture* graphicsTexture) {
+                           return texture == graphicsTexture;
                          }) != mImpl->boundTextures.End();
         }
       }
index 2203a7f587c1c64541bb591286ad774773a5c01f..733cbf44044d78a9fc8a6e016646ddc103b60756 100644 (file)
@@ -43,7 +43,7 @@ const GLenum COLOR_ATTACHMENTS[] =
 
 FrameBuffer::FrameBuffer(uint32_t width, uint32_t height, Mask attachments)
 : mId(0u),
-  mTextureId{0u},
+  mTextures{0u},
   mDepthBuffer(attachments & Dali::FrameBuffer::Attachment::DEPTH),
   mStencilBuffer(attachments & Dali::FrameBuffer::Attachment::STENCIL),
   mWidth(width),
@@ -97,14 +97,14 @@ void FrameBuffer::AttachColorTexture(Context& context, Render::Texture* texture,
 {
   context.BindFramebuffer(GL_FRAMEBUFFER, mId);
 
-  const GLuint textureId            = texture->GetId();
-  mTextureId[mColorAttachmentCount] = textureId;
+  mTextures[mColorAttachmentCount] = texture->GetGraphicsObject();
+  GLuint textureId                 = 0; //@todo Temp
 
   // Create a color attachment.
   const GLenum iAttachment = COLOR_ATTACHMENTS[mColorAttachmentCount];
   if(texture->GetType() == TextureType::TEXTURE_2D)
   {
-    context.FramebufferTexture2D(GL_FRAMEBUFFER, iAttachment, texture->GetTarget(), textureId, mipmapLevel);
+    context.FramebufferTexture2D(GL_FRAMEBUFFER, iAttachment, GL_TEXTURE_2D, textureId, mipmapLevel);
   }
   else
   {
@@ -122,10 +122,13 @@ void FrameBuffer::AttachDepthTexture(Context& context, Render::Texture* texture,
 {
   context.BindFramebuffer(GL_FRAMEBUFFER, mId);
 
+  //@todo Temp
+  GLuint textureId = 0;
+
   // Create a depth attachment.
   if(texture->GetType() == TextureType::TEXTURE_2D)
   {
-    context.FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture->GetId(), mipmapLevel);
+    context.FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureId, mipmapLevel);
   }
 
   context.BindFramebuffer(GL_FRAMEBUFFER, 0);
@@ -135,10 +138,13 @@ void FrameBuffer::AttachDepthStencilTexture(Context& context, Render::Texture* t
 {
   context.BindFramebuffer(GL_FRAMEBUFFER, mId);
 
+  //@todo temp
+  GLuint textureId = 0;
+
   // Create a depth/stencil attachment.
   if(texture->GetType() == TextureType::TEXTURE_2D)
   {
-    context.FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture->GetId(), mipmapLevel);
+    context.FramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, textureId, mipmapLevel);
   }
 
   context.BindFramebuffer(GL_FRAMEBUFFER, 0);
index 13a0fc0c0abe7981bc747f011599f72eb7a2ba7d..0483760d88101767858ef623eacb68c6843779c5 100644 (file)
@@ -118,12 +118,12 @@ public:
   }
 
   /**
-   * @brief Get the id (OpenGL handle) of the texture bound to this frame buffer as color attachment @a index.
-   * @return The texture id.
+   * @brief Get the texture bound to this frame buffer as color attachment @a index.
+   * @return The texture.
    */
-  GLuint GetTextureId(uint8_t index)
+  Graphics::Texture* GetTexture(uint8_t index)
   {
-    return mTextureId[index];
+    return mTextures[index];
   };
 
 private:
@@ -138,13 +138,13 @@ private:
   FrameBuffer& operator=(const FrameBuffer& rhs) = delete;
 
 private:
-  GLuint   mId;
-  GLuint   mTextureId[Dali::DevelFrameBuffer::MAX_COLOR_ATTACHMENTS];
-  GLuint   mDepthBuffer;
-  GLuint   mStencilBuffer;
-  uint32_t mWidth;
-  uint32_t mHeight;
-  uint8_t  mColorAttachmentCount;
+  GLuint             mId;
+  Graphics::Texture* mTextures[Dali::DevelFrameBuffer::MAX_COLOR_ATTACHMENTS];
+  GLuint             mDepthBuffer;
+  GLuint             mStencilBuffer;
+  uint32_t           mWidth;
+  uint32_t           mHeight;
+  uint8_t            mColorAttachmentCount;
 };
 
 } // namespace Render
index cea62ab54414d01940df84e89ae22a1f7ea57497..4be7532e37733247b0f23fc08387867079c27e70 100644 (file)
@@ -154,9 +154,10 @@ Renderer::Renderer(SceneGraph::RenderDataProvider* dataProvider,
   mBlendingOptions.SetBlendColor(blendColor);
 }
 
-void Renderer::Initialize(Context& context)
+void Renderer::Initialize(Context& context, Graphics::Controller& graphicsController)
 {
-  mContext = &context;
+  mContext            = &context;
+  mGraphicsController = &graphicsController;
 }
 
 Renderer::~Renderer() = default;
@@ -363,7 +364,7 @@ void Renderer::SetUniformFromProperty(BufferIndex bufferIndex, Program& program,
   }
 }
 
-bool Renderer::BindTextures(Context& context, Program& program, Vector<GLuint>& boundTextures)
+bool Renderer::BindTextures(Context& context, Program& program, Graphics::CommandBuffer& commandBuffer, Vector<Graphics::Texture*>& boundTextures)
 {
   uint32_t textureUnit = 0;
   bool     result      = true;
@@ -371,20 +372,33 @@ bool Renderer::BindTextures(Context& context, Program& program, Vector<GLuint>&
   GLint                          uniformLocation(-1);
   std::vector<Render::Sampler*>& samplers(mRenderDataProvider->GetSamplers());
   std::vector<Render::Texture*>& textures(mRenderDataProvider->GetTextures());
+
+  std::vector<Graphics::TextureBinding> textureBindings;
   for(uint32_t i = 0; i < static_cast<uint32_t>(textures.size()) && result; ++i) // not expecting more than uint32_t of textures
   {
     if(textures[i])
     {
-      result = textures[i]->Bind(context, textureUnit, samplers[i]);
-      boundTextures.PushBack(textures[i]->GetId());
-      if(result && program.GetSamplerUniformLocation(i, uniformLocation))
+      if(program.GetSamplerUniformLocation(i, uniformLocation))
       {
-        program.SetUniform1i(uniformLocation, textureUnit);
+        // if the sampler exists,
+        //   if it's default, delete the graphics object
+        //   otherwise re-initialize it if dirty
+
+        const Graphics::Sampler* graphicsSampler = (samplers[i] ? samplers[i]->GetGraphicsObject()
+                                                                : nullptr);
+
+        boundTextures.PushBack(textures[i]->GetGraphicsObject());
+        const Graphics::TextureBinding textureBinding{textures[i]->GetGraphicsObject(), graphicsSampler, textureUnit};
+        textureBindings.push_back(textureBinding);
+
+        program.SetUniform1i(uniformLocation, textureUnit); // Get through shader reflection
         ++textureUnit;
       }
     }
   }
 
+  commandBuffer.BindTextures(textureBindings);
+
   return result;
 }
 
@@ -559,7 +573,7 @@ void Renderer::Render(Context&                                             conte
                       const Matrix&                                        projectionMatrix,
                       const Vector3&                                       size,
                       bool                                                 blend,
-                      Vector<GLuint>&                                      boundTextures,
+                      Vector<Graphics::Texture*>&                          boundTextures,
                       const Dali::Internal::SceneGraph::RenderInstruction& instruction,
                       uint32_t                                             queueIndex)
 {
@@ -593,6 +607,14 @@ void Renderer::Render(Context&                                             conte
     return;
   }
 
+  // For now, create command buffer to perform only the texture / sample binding
+  // and submit it.
+  // Expect this call to glBindTextureForUnit, and glTexParameteri() for the sampler
+  Graphics::UniquePtr<Graphics::CommandBuffer> commandBuffer = mGraphicsController->CreateCommandBuffer(
+    Graphics::CommandBufferCreateInfo()
+      .SetLevel(Graphics::CommandBufferLevel::SECONDARY),
+    nullptr);
+
   //Set cull face  mode
   const Dali::Internal::SceneGraph::Camera* cam = instruction.GetCamera();
   if(cam->GetReflectionUsed())
@@ -625,10 +647,15 @@ void Renderer::Render(Context&                                             conte
   // Take the program into use so we can send uniforms to it
   program->Use();
 
-  if(DALI_LIKELY(BindTextures(context, *program, boundTextures)))
+  if(DALI_LIKELY(BindTextures(context, *program, *commandBuffer.get(), boundTextures)))
   {
     // Only set up and draw if we have textures and they are all valid
 
+    // @todo Move to render manager. For now, ensure textures are bound before drawing
+    Graphics::SubmitInfo submitInfo{{}, 0 | Graphics::SubmitFlagBits::FLUSH};
+    submitInfo.cmdBuffer.push_back(commandBuffer.get());
+    mGraphicsController->SubmitCommandBuffers(submitInfo);
+
     // set projection and view matrix if program has not yet received them yet this frame
     SetMatrices(*program, modelMatrix, viewMatrix, projectionMatrix, modelViewMatrix);
 
index d6668a13247707af8583bb4dcc28c415ea17d77a..f567e2a6b0323a194b29ef867781ab88cda1344e 100644 (file)
  */
 
 // INTERNAL INCLUDES
+#include <dali/public-api/math/matrix.h>
+#include <dali/public-api/math/vector4.h>
+#include <dali/public-api/rendering/texture-set.h>
+
+#include <dali/graphics-api/graphics-controller.h>
 #include <dali/integration-api/debug.h>
 #include <dali/internal/common/blending-options.h>
 #include <dali/internal/common/message.h>
@@ -28,9 +33,6 @@
 #include <dali/internal/render/gl-resources/gl-resource-owner.h>
 #include <dali/internal/render/renderers/render-geometry.h>
 #include <dali/internal/update/manager/render-instruction-processor.h>
-#include <dali/public-api/math/matrix.h>
-#include <dali/public-api/math/vector4.h>
-#include <dali/public-api/rendering/texture-set.h>
 
 namespace Dali
 {
@@ -164,9 +166,10 @@ public:
   /**
    * Second-phase construction.
    * This is called when the renderer is inside render thread
-   * @param[in] context Context used by the renderer
+   * @param[in] context Context used by the renderer (To be removed)
+   * @param[in] graphicsController The graphics controller to use
    */
-  void Initialize(Context& context);
+  void Initialize(Context& context, Graphics::Controller& graphicsController);
 
   /**
    * Destructor
@@ -371,7 +374,7 @@ public:
               const Matrix&                                        projectionMatrix,
               const Vector3&                                       size,
               bool                                                 blend,
-              Vector<GLuint>&                                      boundTextures,
+              Vector<Graphics::Texture*>&                          boundTextures,
               const Dali::Internal::SceneGraph::RenderInstruction& instruction,
               uint32_t                                             queueIndex);
 
@@ -438,9 +441,10 @@ private:
    * @param[in] boundTextures The textures bound for rendering
    * @return False if create or bind failed, true if success.
    */
-  bool BindTextures(Context& context, Program& program, Vector<GLuint>& boundTextures);
+  bool BindTextures(Context& context, Program& program, Graphics::CommandBuffer& commandBuffer, Vector<Graphics::Texture*>& boundTextures);
 
 private:
+  Graphics::Controller*                        mGraphicsController;
   OwnerPointer<SceneGraph::RenderDataProvider> mRenderDataProvider;
 
   Context*          mContext;
diff --git a/dali/internal/render/renderers/render-sampler.cpp b/dali/internal/render/renderers/render-sampler.cpp
new file mode 100644 (file)
index 0000000..632503d
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * 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/internal/render/renderers/render-sampler.h>
+
+namespace Dali
+{
+namespace Internal
+{
+namespace Render
+{
+Sampler::Sampler()
+: mMinificationFilter(FilterMode::DEFAULT),
+  mMagnificationFilter(FilterMode::DEFAULT),
+  mSWrapMode(WrapMode::DEFAULT),
+  mTWrapMode(WrapMode::DEFAULT),
+  mRWrapMode(WrapMode::DEFAULT)
+{
+}
+
+const Dali::Graphics::Sampler* Sampler::GetGraphicsObject()
+{
+  if(IsDefaultSampler())
+  {
+    mGraphicsSampler.reset();
+  }
+  else
+  {
+    CreateGraphicsObject();
+  }
+  mIsDirty = false;
+  return mGraphicsSampler.get();
+}
+
+void Sampler::DestroyGraphicsObjects()
+{
+  mGraphicsSampler.reset();
+}
+
+void Sampler::Initialize(Graphics::Controller& graphicsController)
+{
+  mGraphicsController = &graphicsController;
+  mGraphicsSampler.reset(nullptr);
+}
+
+Graphics::Sampler* Sampler::CreateGraphicsObject()
+{
+  if(!mGraphicsSampler || mIsDirty)
+  {
+    Graphics::SamplerFilter     minFilter  = GetGraphicsFilter(mMinificationFilter);
+    Graphics::SamplerFilter     magFilter  = GetGraphicsFilter(mMagnificationFilter);
+    Graphics::SamplerMipmapMode mipmapMode = GetGraphicsSamplerMipmapMode(mMinificationFilter);
+
+    if(mMinificationFilter == FilterMode::NONE)
+    {
+      minFilter  = Graphics::SamplerFilter::NEAREST;
+      mipmapMode = Graphics::SamplerMipmapMode::LINEAR;
+    }
+    if(mMagnificationFilter == FilterMode::NONE)
+    {
+      magFilter = Graphics::SamplerFilter::LINEAR;
+    }
+
+    mGraphicsSampler = mGraphicsController->CreateSampler(
+      Graphics::SamplerCreateInfo()
+        .SetMinFilter(minFilter)
+        .SetMagFilter(magFilter)
+        .SetAddressModeU(GetGraphicsSamplerAddressMode(mSWrapMode))
+        .SetAddressModeV(GetGraphicsSamplerAddressMode(mTWrapMode))
+        .SetAddressModeW(GetGraphicsSamplerAddressMode(mRWrapMode))
+        .SetMipMapMode(mipmapMode),
+      nullptr);
+  }
+  mIsDirty = false;
+  return mGraphicsSampler.get();
+}
+
+} // namespace Render
+
+} // namespace Internal
+
+} // namespace Dali
index 1c86d8bef4a34076758f34ba59f01b7c68a24a4e..21a461fb937441cea3062f57318a367bf9bdf5e0 100644 (file)
@@ -17,6 +17,7 @@
  * limitations under the License.
  */
 
+#include <dali/graphics-api/graphics-controller.h>
 #include <dali/public-api/actors/sampling.h>
 #include <dali/public-api/rendering/sampler.h>
 
@@ -26,6 +27,12 @@ namespace Internal
 {
 namespace Render
 {
+/**
+ * The sampler class holds the min/mag filter and texture wrap modes.
+ * It's graphics counterpart is only created when needed, and also
+ * only created when the filters and wrap modes are not default
+ * values.
+ */
 struct Sampler
 {
   using FilterMode = Dali::FilterMode::Type;
@@ -34,14 +41,7 @@ struct Sampler
   /**
    * Constructor
    */
-  Sampler()
-  : mMinificationFilter(FilterMode::DEFAULT),
-    mMagnificationFilter(FilterMode::DEFAULT),
-    mSWrapMode(WrapMode::DEFAULT),
-    mTWrapMode(WrapMode::DEFAULT),
-    mRWrapMode(WrapMode::DEFAULT)
-  {
-  }
+  Sampler();
 
   /**
    * Destructor
@@ -62,11 +62,123 @@ struct Sampler
     return !(*this == rhs);
   }
 
+  /**
+   * Returns Graphics API sampler object
+   * @return Pointer to API sampler or nullptr
+   */
+  const Dali::Graphics::Sampler* GetGraphicsObject();
+
+  void DestroyGraphicsObjects();
+
+  inline Graphics::SamplerAddressMode GetGraphicsSamplerAddressMode(WrapMode mode) const
+  {
+    switch(mode)
+    {
+      case WrapMode::REPEAT:
+        return Graphics::SamplerAddressMode::REPEAT;
+      case WrapMode::MIRRORED_REPEAT:
+        return Graphics::SamplerAddressMode::MIRRORED_REPEAT;
+      case WrapMode::CLAMP_TO_EDGE:
+        return Graphics::SamplerAddressMode::CLAMP_TO_EDGE;
+      case WrapMode::DEFAULT:
+        return Graphics::SamplerAddressMode::CLAMP_TO_EDGE;
+    }
+    return {};
+  }
+
+  inline Graphics::SamplerMipmapMode GetGraphicsSamplerMipmapMode(FilterMode mode) const
+  {
+    switch(mode)
+    {
+      case FilterMode::LINEAR_MIPMAP_LINEAR:
+        return Graphics::SamplerMipmapMode::LINEAR;
+      case FilterMode::NEAREST_MIPMAP_LINEAR:
+        return Graphics::SamplerMipmapMode::LINEAR;
+      case FilterMode::NEAREST_MIPMAP_NEAREST:
+        return Graphics::SamplerMipmapMode::NEAREST;
+      case FilterMode::LINEAR_MIPMAP_NEAREST:
+        return Graphics::SamplerMipmapMode::NEAREST;
+      default:
+        return Graphics::SamplerMipmapMode::NONE;
+    }
+    return {};
+  }
+
+  inline Graphics::SamplerFilter GetGraphicsFilter(FilterMode mode) const
+  {
+    switch(mode)
+    {
+      case FilterMode::LINEAR:
+      case FilterMode::LINEAR_MIPMAP_LINEAR:
+      case FilterMode::LINEAR_MIPMAP_NEAREST:
+        return Graphics::SamplerFilter::LINEAR;
+      case FilterMode::NEAREST:
+      case FilterMode::NEAREST_MIPMAP_LINEAR:
+      case FilterMode::NEAREST_MIPMAP_NEAREST:
+        return Graphics::SamplerFilter::NEAREST;
+      case FilterMode::DEFAULT:
+        return Graphics::SamplerFilter::LINEAR;
+      case FilterMode::NONE:
+        return Graphics::SamplerFilter::NEAREST;
+      default:
+        return {};
+    }
+    return {};
+  }
+
+  /**
+   * Sets the filter modes for an existing sampler
+   * @param[in] sampler The sampler
+   * @param[in] minFilterMode The filter to use under minification
+   * @param[in] magFilterMode The filter to use under magnification
+   */
+  inline void SetFilterMode(unsigned int minFilterMode, unsigned int magFilterMode)
+  {
+    mMinificationFilter  = static_cast<Dali::FilterMode::Type>(minFilterMode);
+    mMagnificationFilter = static_cast<Dali::FilterMode::Type>(magFilterMode);
+    mIsDirty             = true;
+  }
+
+  /**
+   * Sets the wrap mode for an existing sampler
+   * @param[in] sampler The sampler
+   * @param[in] rWrapMode Wrapping mode in z direction
+   * @param[in] sWrapMode Wrapping mode in x direction
+   * @param[in] tWrapMode Wrapping mode in y direction
+   */
+  inline void SetWrapMode(unsigned int rWrapMode, unsigned int sWrapMode, unsigned int tWrapMode)
+  {
+    mRWrapMode = static_cast<Dali::WrapMode::Type>(rWrapMode);
+    mSWrapMode = static_cast<Dali::WrapMode::Type>(sWrapMode);
+    mTWrapMode = static_cast<Dali::WrapMode::Type>(tWrapMode);
+    mIsDirty   = true;
+  }
+
+  /**
+   * Check if the sampler has default values
+   */
+  inline bool IsDefaultSampler()
+  {
+    return (mMagnificationFilter == FilterMode::DEFAULT &&
+            mMinificationFilter == FilterMode::DEFAULT &&
+            mSWrapMode == WrapMode::DEFAULT &&
+            mTWrapMode == WrapMode::DEFAULT &&
+            mRWrapMode == WrapMode::DEFAULT);
+  }
+
+  void Initialize(Graphics::Controller& graphicsController);
+
+  Graphics::Sampler* CreateGraphicsObject();
+
+  Graphics::Controller*                  mGraphicsController;
+  Graphics::UniquePtr<Graphics::Sampler> mGraphicsSampler;
+
   FilterMode mMinificationFilter : 4;  ///< The minify filter
   FilterMode mMagnificationFilter : 4; ///< The magnify filter
   WrapMode   mSWrapMode : 4;           ///< The horizontal wrap mode
   WrapMode   mTWrapMode : 4;           ///< The vertical wrap mode
   WrapMode   mRWrapMode : 4;           ///< The vertical wrap mode
+  bool       mIsDirty : 1;             ///< If parameters have been set thru API
 };
 
 } // namespace Render
index 83d2260a2e949bcbbd112e8153d69df753597073..2cfa49e1f531c209490406fcd455fa09ac0fbdc6 100644 (file)
@@ -30,919 +30,287 @@ namespace Render
 {
 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;
-
-/**
- * @brief Convert a FilterMode to its corresponding GL type.
- *
- * @param[in] filterMode The FilterMode type.
- * @param[in] daliDefault The filter mode to use if filterMode is DEFAULT.
- * @param[in] glDefault The filter mode to use if filterMode is NONE.
- * @return the equivalent GL filter mode.
- */
-GLint FilterModeToGL(FilterMode::Type filterMode, GLint daliDefault, GLint glDefault)
-{
-  switch(filterMode)
-  {
-    case FilterMode::NEAREST:
-    {
-      return GL_NEAREST;
-    }
-    case FilterMode::LINEAR:
-    {
-      return GL_LINEAR;
-    }
-    case FilterMode::NONE:
-    {
-      return glDefault;
-    }
-    case FilterMode::NEAREST_MIPMAP_NEAREST:
-    {
-      return GL_NEAREST_MIPMAP_NEAREST;
-    }
-    case FilterMode::LINEAR_MIPMAP_NEAREST:
-    {
-      return GL_LINEAR_MIPMAP_NEAREST;
-    }
-    case FilterMode::NEAREST_MIPMAP_LINEAR:
-    {
-      return GL_NEAREST_MIPMAP_LINEAR;
-    }
-    case FilterMode::LINEAR_MIPMAP_LINEAR:
-    {
-      return GL_LINEAR_MIPMAP_LINEAR;
-    }
-    case FilterMode::DEFAULT:
-    {
-      return daliDefault;
-    }
-  }
-
-  return daliDefault;
-}
-
-/**
- * @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 WrapModeToGL(WrapMode::Type wrapMode, GLint defaultWrapMode)
-{
-  switch(wrapMode)
-  {
-    case WrapMode::CLAMP_TO_EDGE:
-    {
-      return GL_CLAMP_TO_EDGE;
-    }
-    case WrapMode::REPEAT:
-    {
-      return GL_REPEAT;
-    }
-    case WrapMode::MIRRORED_REPEAT:
-    {
-      return GL_MIRRORED_REPEAT;
-    }
-    case WrapMode::DEFAULT:
-    {
-      return defaultWrapMode;
-    }
-  }
-
-  return defaultWrapMode;
-}
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gTextureFilter = Debug::Filter::New(Debug::Concise, false, "LOG_TEXTURE");
+#endif
 
 /**
- * @brief Retrives the GL format, GL internal format and pixel data type from a Pixel::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.
+ * Converts DALi pixel format to Graphics::Format
+ * @param format
+ * @return
  */
-void PixelFormatToGl(Pixel::Format pixelFormat, GLenum& glFormat, GLint& glInternalFormat, GLenum& pixelDataType)
+constexpr Graphics::Format ConvertPixelFormat(Pixel::Format format)
 {
-  // Compressed textures have no pixelDataType, so init to an invalid value:
-  pixelDataType = -1;
-
-  switch(pixelFormat)
+  switch(format)
   {
+    case Pixel::INVALID:
+      return Graphics::Format::UNDEFINED;
     case Pixel::A8:
-    {
-      pixelDataType = GL_UNSIGNED_BYTE;
-      glFormat      = GL_ALPHA;
-      break;
-    }
+      return Graphics::Format::R8_UNORM;
 
     case Pixel::L8:
-    {
-      pixelDataType = GL_UNSIGNED_BYTE;
-      glFormat      = GL_LUMINANCE;
-      break;
-    }
-
+      return Graphics::Format::L8;
     case Pixel::LA88:
-    {
-      pixelDataType = GL_UNSIGNED_BYTE;
-      glFormat      = GL_LUMINANCE_ALPHA;
-      break;
-    }
-
+      return Graphics::Format::L8A8;
     case Pixel::RGB565:
-    {
-      pixelDataType = GL_UNSIGNED_SHORT_5_6_5;
-      glFormat      = GL_RGB;
-      break;
-    }
-
+      return Graphics::Format::R5G6B5_UNORM_PACK16;
     case Pixel::BGR565:
-    {
-      DALI_LOG_ERROR("Pixel format BGR565 is not supported by GLES.\n");
-      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;
-    }
-
+      return Graphics::Format::B5G6R5_UNORM_PACK16;
     case Pixel::RGBA4444:
-    {
-      pixelDataType = GL_UNSIGNED_SHORT_4_4_4_4;
-      glFormat      = GL_RGBA;
-      break;
-    }
+      return Graphics::Format::R4G4B4A4_UNORM_PACK16;
 
     case Pixel::BGRA4444:
-    {
-      DALI_LOG_ERROR("Pixel format BGRA4444 is not supported by GLES.\n");
-      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;
-    }
-
+      return Graphics::Format::B4G4R4A4_UNORM_PACK16;
     case Pixel::RGBA5551:
-    {
-      pixelDataType = GL_UNSIGNED_SHORT_5_5_5_1;
-      glFormat      = GL_RGBA;
-      break;
-    }
-
+      return Graphics::Format::R5G5B5A1_UNORM_PACK16;
     case Pixel::BGRA5551:
-    {
-      DALI_LOG_ERROR("Pixel format BGRA5551 is not supported by GLES.\n");
-      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;
-    }
-
+      return Graphics::Format::B5G5R5A1_UNORM_PACK16;
     case Pixel::RGB888:
-    {
-      pixelDataType = GL_UNSIGNED_BYTE;
-      glFormat      = GL_RGB;
-      break;
-    }
-
+      return Graphics::Format::R8G8B8_UNORM;
     case Pixel::RGB8888:
-    {
-      pixelDataType = GL_UNSIGNED_BYTE;
-      glFormat      = GL_RGBA; // alpha is reserved but not used
-      break;
-    }
-
+      return Graphics::Format::R8G8B8A8_UNORM;
     case Pixel::BGR8888:
-    {
-      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;
-    }
-
+      return Graphics::Format::B8G8R8A8_UNORM;
     case Pixel::RGBA8888:
-    {
-      pixelDataType = GL_UNSIGNED_BYTE;
-      glFormat      = GL_RGBA;
-      break;
-    }
-
+      return Graphics::Format::R8G8B8A8_UNORM;
     case Pixel::BGRA8888:
-    {
-      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;
-    }
+      return Graphics::Format::B8G8R8A8_UNORM;
 
-    // GLES 2 extension compressed formats:
-    case Pixel::COMPRESSED_RGB8_ETC1:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB8_ETC1.\n");
-      glFormat = 0x8D64; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
-      break;
-    }
-    case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using non-standard GLES 2.0 extension compressed pixel format COMPRESSED_RGB_PVRTC_4BPPV1.\n");
-      glFormat = 0x8C00; ///! < Hardcoded so we can test before we move to GLES 3.0 or greater.
-      break;
-    }
+    case Pixel::DEPTH_UNSIGNED_INT:
+      return Graphics::Format::D16_UNORM;
+    case Pixel::DEPTH_FLOAT:
+      return Graphics::Format::D32_SFLOAT;
+    case Pixel::DEPTH_STENCIL:
+      return Graphics::Format::D24_UNORM_S8_UINT;
 
-    // GLES 3.0 standard compressed formats:
+    // EAC
     case Pixel::COMPRESSED_R11_EAC:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_R11_EAC.\n");
-      glFormat = GL_COMPRESSED_R11_EAC;
-      break;
-    }
+      return Graphics::Format::EAC_R11_UNORM_BLOCK;
     case Pixel::COMPRESSED_SIGNED_R11_EAC:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_R11_EAC.\n");
-      glFormat = GL_COMPRESSED_SIGNED_R11_EAC;
-      break;
-    }
+      return Graphics::Format::EAC_R11_SNORM_BLOCK;
     case Pixel::COMPRESSED_RG11_EAC:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RG11_EAC.\n");
-      glFormat = GL_COMPRESSED_RG11_EAC;
-      break;
-    }
+      return Graphics::Format::EAC_R11G11_UNORM_BLOCK;
     case Pixel::COMPRESSED_SIGNED_RG11_EAC:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SIGNED_RG11_EAC.\n");
-      glFormat = GL_COMPRESSED_SIGNED_RG11_EAC;
-      break;
-    }
+      return Graphics::Format::EAC_R11G11_SNORM_BLOCK;
+
+    // ETC
     case Pixel::COMPRESSED_RGB8_ETC2:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_ETC2.\n");
-      glFormat = GL_COMPRESSED_RGB8_ETC2;
-      break;
-    }
+      return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ETC2:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ETC2.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ETC2;
-      break;
-    }
+      return Graphics::Format::ETC2_R8G8B8_SRGB_BLOCK;
+
     case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n");
-      glFormat = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
-      break;
-    }
+      return Graphics::Format::ETC2_R8G8B8A1_UNORM_BLOCK; // no 'punchthrough' format
+
     case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2.\n");
-      glFormat = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
-      break;
-    }
+      return Graphics::Format::ETC2_R8G8B8A1_SRGB_BLOCK; // no 'punchthrough' format
+
     case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_RGBA8_ETC2_EAC.\n");
-      glFormat = GL_COMPRESSED_RGBA8_ETC2_EAC;
-      break;
-    }
+      return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; // doesn't seem to map onto any format
+
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.0 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ETC2_EAC.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
-      break;
-    }
+      return Graphics::Format::ETC2_R8G8B8A8_SRGB_BLOCK; // doesn't seem to map onto any format
+
+    case Pixel::COMPRESSED_RGB8_ETC1:
+      return Graphics::Format::ETC2_R8G8B8_UNORM_BLOCK; // doesn't seem to be supported at all
 
-    // GLES 3.1 extension compressed formats:
+    case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
+      return Graphics::Format::PVRTC1_4BPP_UNORM_BLOCK_IMG; // or SRGB?
+
+    // ASTC
     case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_4x4_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_4x4_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_4x4_UNORM_BLOCK; // or SRGB?
     case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x4_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_5x4_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_5x4_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_5x5_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_5x5_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_5x5_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x5_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_6x5_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_6x5_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_6x6_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_6x6_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_6x6_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x5_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_8x5_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_8x5_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x6_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_8x6_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_8x6_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_8x8_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_8x8_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_8x8_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x5_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_10x5_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_10x5_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x6_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_10x6_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_10x6_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x8_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_10x8_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_10x8_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_10x10_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_10x10_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_10x10_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x10_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_12x10_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_12x10_UNORM_BLOCK;
     case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_RGBA_ASTC_12x12_KHR.\n");
-      glFormat = GL_COMPRESSED_RGBA_ASTC_12x12_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_12x12_UNORM_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR;
-      break;
-    }
+
+      return Graphics::Format::ASTC_4x4_SRGB_BLOCK; // not type with alpha, but likely to use SRGB
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_5x4_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_5x5_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_6x5_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_6x6_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_8x5_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_8x6_UNORM_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_8x8_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_10x5_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_10x6_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_10x8_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_10x10_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR;
-      break;
-    }
+      return Graphics::Format::ASTC_12x10_SRGB_BLOCK;
     case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
-    {
-      DALI_LOG_INFO(Debug::Filter::gImage, Debug::Verbose, "Using GLES 3.1 standard compressed pixel format COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR.\n");
-      glFormat = GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR;
-      break;
-    }
-
-    // GLES 3.0 floating point formats.
+      return Graphics::Format::ASTC_12x12_SRGB_BLOCK;
     case Pixel::RGB16F:
-    {
-      glFormat      = GL_RGB;
-      pixelDataType = GL_HALF_FLOAT;
-      break;
-    }
+      return Graphics::Format::R16G16B16_SFLOAT;
     case Pixel::RGB32F:
-    {
-      glFormat      = GL_RGB;
-      pixelDataType = GL_FLOAT;
-      break;
-    }
-
-    // GLES 3.0 depth and stencil formats
-    case Pixel::DEPTH_UNSIGNED_INT:
-    {
-      glFormat      = GL_DEPTH_COMPONENT;
-      pixelDataType = GL_UNSIGNED_INT;
-      break;
-    }
-
-    case Pixel::DEPTH_FLOAT:
-    {
-      glFormat      = GL_DEPTH_COMPONENT;
-      pixelDataType = GL_FLOAT;
-      break;
-    }
-
-    case Pixel::DEPTH_STENCIL:
-    {
-      glFormat      = GL_DEPTH_STENCIL;
-      pixelDataType = GL_UNSIGNED_INT_24_8;
-      break;
-    }
-
-    case Pixel::INVALID:
-    {
-      DALI_LOG_ERROR("Invalid pixel format for bitmap\n");
-      glFormat = 0;
-      break;
-    }
-  }
-
-  switch(pixelFormat)
-  {
-    case Pixel::RGB16F:
-    case Pixel::RGB32F: // FALL THROUGH
-    {
-      glInternalFormat = GL_R11F_G11F_B10F;
-      break;
-    }
-    case Pixel::DEPTH_FLOAT:
-    {
-      glInternalFormat = GL_DEPTH_COMPONENT32F;
-      break;
-    }
-    case Pixel::DEPTH_STENCIL:
-    {
-      glInternalFormat = GL_DEPTH24_STENCIL8;
-      break;
-    }
-    default:
-    {
-      glInternalFormat = glFormat;
-    }
+      return Graphics::Format::R32G32B32_SFLOAT;
   }
+  return Graphics::Format::UNDEFINED;
 }
 
-/**
- * @brief Whether specified pixel format is compressed.
- *
- * @param [in] pixelformat Pixel format
- * @return true if format is compressed, false otherwise
- */
-bool IsCompressedFormat(Pixel::Format pixelFormat)
+constexpr Graphics::TextureType ConvertType(Texture::Type type)
 {
-  switch(pixelFormat)
+  switch(type)
   {
-    case Pixel::L8:
-    case Pixel::A8:
-    case Pixel::LA88:
-    case Pixel::RGB565:
-    case Pixel::RGBA4444:
-    case Pixel::RGBA5551:
-    case Pixel::BGR565:
-    case Pixel::BGRA4444:
-    case Pixel::BGRA5551:
-    case Pixel::RGB888:
-    case Pixel::RGB8888:
-    case Pixel::BGR8888:
-    case Pixel::RGBA8888:
-    case Pixel::BGRA8888:
-    case Pixel::RGB16F:
-    case Pixel::RGB32F:
-    case Pixel::DEPTH_UNSIGNED_INT:
-    case Pixel::DEPTH_FLOAT:
-    case Pixel::DEPTH_STENCIL:
-    case Pixel::INVALID:
-    {
-      return false;
-    }
-
-    case Pixel::COMPRESSED_R11_EAC:
-    case Pixel::COMPRESSED_SIGNED_R11_EAC:
-    case Pixel::COMPRESSED_RG11_EAC:
-    case Pixel::COMPRESSED_SIGNED_RG11_EAC:
-    case Pixel::COMPRESSED_RGB8_ETC2:
-    case Pixel::COMPRESSED_SRGB8_ETC2:
-    case Pixel::COMPRESSED_RGB8_ETC1:
-    case Pixel::COMPRESSED_RGB_PVRTC_4BPPV1:
-    case Pixel::COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    case Pixel::COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-    case Pixel::COMPRESSED_RGBA8_ETC2_EAC:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-    case Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR:
-    case Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
-    case Pixel::COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
-    {
-      return true;
-    }
+    case TextureType::TEXTURE_2D:
+      return Graphics::TextureType::TEXTURE_2D;
+    case TextureType::TEXTURE_CUBE:
+      return Graphics::TextureType::TEXTURE_CUBEMAP;
   }
-
-  return false;
+  return Graphics::TextureType::TEXTURE_2D;
 }
 
 } //Unnamed namespace
 
 Texture::Texture(Type type, Pixel::Format format, ImageDimensions size)
-: mNativeImage(),
+: mGraphicsController(nullptr),
+  mGraphicsTexture(nullptr),
+  mNativeImage(),
   mSampler(),
-  mId(0),
-  mTarget((type == TextureType::TEXTURE_2D) ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP),
-  mGlInternalFormat(GL_RGB),
-  mGlFormat(GL_RGB),
-  mPixelDataType(GL_UNSIGNED_BYTE),
+  mPixelFormat(format),
   mWidth(size.GetWidth()),
   mHeight(size.GetHeight()),
   mMaxMipMapLevel(0),
   mType(type),
-  mHasAlpha(HasAlpha(format)),
-  mIsCompressed(IsCompressedFormat(format))
+  mHasAlpha(HasAlpha(format))
 {
-  PixelFormatToGl(format,
-                  mGlFormat,
-                  mGlInternalFormat,
-                  mPixelDataType);
 }
 
 Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
-: mNativeImage(nativeImageInterface),
+: mGraphicsController(nullptr),
+  mGraphicsTexture(nullptr),
+  mNativeImage(nativeImageInterface),
   mSampler(),
-  mId(0),
-  mTarget(GL_TEXTURE_2D),
-  mGlInternalFormat(GL_RGB),
-  mGlFormat(GL_RGB),
-  mPixelDataType(GL_UNSIGNED_BYTE),
+  mPixelFormat(Pixel::RGBA8888),
   mWidth(static_cast<uint16_t>(nativeImageInterface->GetWidth())),   // ignoring overflow, not happening in practice
   mHeight(static_cast<uint16_t>(nativeImageInterface->GetHeight())), // ignoring overflow, not happening in practice
   mMaxMipMapLevel(0),
   mType(TextureType::TEXTURE_2D),
-  mHasAlpha(nativeImageInterface->RequiresBlending()),
-  mIsCompressed(false)
+  mHasAlpha(nativeImageInterface->RequiresBlending())
 {
 }
 
 Texture::~Texture() = default;
 
-void Texture::Destroy(Context& context)
+void Texture::Initialize(Graphics::Controller& graphicsController)
 {
-  if(mId)
+  mGraphicsController = &graphicsController;
+  if(mNativeImage)
   {
-    context.DeleteTextures(1, &mId);
-
-    if(mNativeImage)
-    {
-      mNativeImage->DestroyResource();
-    }
+    Create(static_cast<uint32_t>(Graphics::TextureUsageFlagBits::SAMPLE));
   }
 }
 
-void Texture::GlContextDestroyed()
+void Texture::Destroy()
 {
-  mId = 0u;
+  mGraphicsTexture.reset();
 }
 
-void Texture::Initialize(Context& context)
+Graphics::Texture* Texture::GetGraphicsObject() const
 {
-  if(mNativeImage)
-  {
-    if(mNativeImage->CreateResource())
-    {
-      mTarget = mNativeImage->GetTextureTarget();
-
-      context.GenTextures(1, &mId);
-      context.BindTexture(mTarget, mId);
-      context.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data
-
-      //Apply default sampling parameters
-      context.TexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT);
-      context.TexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT);
-      context.TexParameteri(mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT);
-      context.TexParameteri(mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT);
-
-      // platform specific implementation decides on what GL extension to use
-      if(mNativeImage->TargetTexture() != 0u)
-      {
-        context.DeleteTextures(1, &mId);
-        mNativeImage->DestroyResource();
-        mId = 0u;
-      }
-    }
-  }
-  else
-  {
-    //Create the texture and reserve memory for the first mipmap level.
-    context.GenTextures(1, &mId);
-    context.BindTexture(mTarget, mId);
-    context.PixelStorei(GL_UNPACK_ALIGNMENT, 1); // We always use tightly packed data
-
-    //Apply default sampling parameters
-    context.TexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT);
-    context.TexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT);
-    context.TexParameteri(mTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT);
-    context.TexParameteri(mTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT);
-
-    if(mType == TextureType::TEXTURE_2D)
-    {
-      if(!mIsCompressed)
-      {
-        context.TexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, nullptr);
-      }
-      else
-      {
-        context.CompressedTexImage2D(GL_TEXTURE_2D, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, nullptr);
-      }
-    }
-    else if(mType == TextureType::TEXTURE_CUBE)
-    {
-      if(!mIsCompressed)
-      {
-        for(uint32_t i(0); i < 6; ++i)
-        {
-          context.TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, mGlFormat, mPixelDataType, nullptr);
-        }
-      }
-      else
-      {
-        for(uint32_t i(0); i < 6; ++i)
-        {
-          context.CompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, mGlInternalFormat, mWidth, mHeight, 0, 0, nullptr);
-        }
-      }
-      context.TexParameteri(mTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT);
-    }
-  }
+  DALI_LOG_INFO(gTextureFilter, Debug::General, "SC::Texture(%p)::GetGraphicsObject() = %p\n", this, mGraphicsTexture.get());
+
+  return mGraphicsTexture.get();
 }
 
-void Texture::Upload(Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params)
+void Texture::Create(Graphics::TextureUsageFlags usage)
 {
-  DALI_ASSERT_ALWAYS(mNativeImage == nullptr);
-
-  //Get pointer to the data of the PixelData object
-  uint8_t* buffer(pixelData->GetBuffer());
-
-  //This buffer is only used if manually converting from RGB to RGBA
-  std::vector<uint8_t> tempBuffer;
-
-  //Retrieves the pixel data element type, the gl format and gl internal format of the data contained in the PixelData object.
-  GLenum glFormat;
-  GLint  glInternalFormat;
-  GLenum pixelDataElementType;
-  PixelFormatToGl(pixelData->GetPixelFormat(), glFormat, glInternalFormat, pixelDataElementType);
-
-  //Get the maximum mipmap level to set GL_TEXTURE_MAX_LEVEL parameter in GLES3x because is not
-  //necessary to upload all the mipmap levels
-  mMaxMipMapLevel = (mMaxMipMapLevel > params.mipmap) ? mMaxMipMapLevel : params.mipmap;
-
-  const bool isSubImage = ((params.xOffset != 0) ||
-                           (params.yOffset != 0) ||
-                           (params.width != (mWidth / (1 << params.mipmap))) ||
-                           (params.height != (mHeight / (1 << params.mipmap))));
-
-  if(context.TextureRequiresConverting(glFormat, mGlFormat, isSubImage))
-  {
-    uint32_t dataSize = static_cast<uint32_t>(params.width) * params.height;
-    //reserve() does not allocate the memory on some systems so can crash if not populated using push_back
-    tempBuffer.resize(dataSize * 4u);
-    for(uint32_t i = 0u; i < dataSize; ++i)
-    {
-      tempBuffer[i * 4u]     = buffer[i * 3u];
-      tempBuffer[i * 4u + 1] = buffer[i * 3u + 1];
-      tempBuffer[i * 4u + 2] = buffer[i * 3u + 2];
-      tempBuffer[i * 4u + 3] = 0xFF;
-    }
-
-    buffer   = &tempBuffer[0];
-    glFormat = mGlFormat; // Set the glFormat to GL_RGBA
-  }
-
-  //Upload data to the texture
-
-  context.BindTexture(mTarget, mId);
-  GLenum target(mTarget);
-  if(mType == TextureType::TEXTURE_CUBE)
-  {
-    target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params.layer;
-  }
-
-  context.PixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
-  if(!isSubImage)
-  {
-    //Specifying the whole image for the mipmap. We cannot assume that storage for that mipmap has been created so we need to use TexImage2D
-    if(!mIsCompressed)
-    {
-      context.TexImage2D(target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, glFormat, pixelDataElementType, buffer);
-    }
-    else
-    {
-      context.CompressedTexImage2D(target, params.mipmap, mGlInternalFormat, params.width, params.height, 0, static_cast<GLsizei>(pixelData->GetBufferSize()), buffer);
-    }
-  }
-  else
-  {
-    //Specifying part of the image for the mipmap
-    if(!mIsCompressed)
-    {
-      context.TexSubImage2D(target, params.mipmap, params.xOffset, params.yOffset, params.width, params.height, glFormat, pixelDataElementType, buffer);
-    }
-    else
-    {
-      context.CompressedTexSubImage2D(target, params.mipmap, params.xOffset, params.yOffset, params.width, params.height, glFormat, static_cast<GLsizei>(pixelData->GetBufferSize()), buffer);
-    }
-  }
+  CreateWithData(usage, nullptr, 0u);
 }
 
-bool Texture::Bind(Context& context, uint32_t textureUnit, Render::Sampler* sampler)
+void Texture::CreateWithData(Graphics::TextureUsageFlags usage, uint8_t* data, uint32_t size)
 {
-  if(mNativeImage && mId == 0)
-  {
-    Initialize(context);
-  }
-
-  if(mId != 0)
-  {
-    context.BindTextureForUnit(static_cast<TextureUnit>(textureUnit), mTarget, mId);
-    ApplySampler(context, sampler);
-
-    if(mNativeImage)
-    {
-      mNativeImage->PrepareTexture();
-    }
-
-    return true;
-  }
-
-  return false;
+  auto createInfo = Graphics::TextureCreateInfo();
+  createInfo
+    .SetTextureType(ConvertType(mType))
+    .SetUsageFlags(usage)
+    .SetFormat(ConvertPixelFormat(mPixelFormat))
+    .SetSize({mWidth, mHeight})
+    .SetLayout(Graphics::TextureLayout::LINEAR)
+    .SetData(data)
+    .SetDataSize(size)
+    .SetNativeImage(mNativeImage)
+    .SetMipMapFlag(Graphics::TextureMipMapFlag::DISABLED);
+
+  mGraphicsTexture = mGraphicsController->CreateTexture(createInfo, std::move(mGraphicsTexture));
 }
 
-void Texture::ApplySampler(Context& context, Render::Sampler* sampler)
+void Texture::Upload(PixelDataPtr pixelData, const Internal::Texture::UploadParams& params)
 {
-  Render::Sampler oldSampler = mSampler;
-  mSampler                   = sampler ? *sampler : Sampler();
+  DALI_ASSERT_ALWAYS(mNativeImage == nullptr);
 
-  if(mSampler != oldSampler)
+  if(!mGraphicsTexture)
   {
-    GLint mode = FilterModeToGL(mSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT);
-    if(mode != FilterModeToGL(oldSampler.mMinificationFilter, DALI_MINIFY_DEFAULT, GL_MINIFY_DEFAULT))
-    {
-      context.TexParameteri(mTarget, GL_TEXTURE_MIN_FILTER, mode);
-    }
-
-    mode = FilterModeToGL(mSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT);
-    if(mode != FilterModeToGL(oldSampler.mMagnificationFilter, DALI_MAGNIFY_DEFAULT, GL_MAGNIFY_DEFAULT))
-    {
-      context.TexParameteri(mTarget, GL_TEXTURE_MAG_FILTER, mode);
-    }
-
-    mode = WrapModeToGL(mSampler.mSWrapMode, GL_WRAP_DEFAULT);
-    if(mode != WrapModeToGL(oldSampler.mSWrapMode, GL_WRAP_DEFAULT))
-    {
-      context.TexParameteri(mTarget, GL_TEXTURE_WRAP_S, mode);
-    }
-
-    mode = WrapModeToGL(mSampler.mTWrapMode, GL_WRAP_DEFAULT);
-    if(mode != WrapModeToGL(oldSampler.mTWrapMode, GL_WRAP_DEFAULT))
-    {
-      context.TexParameteri(mTarget, GL_TEXTURE_WRAP_T, mode);
-    }
-
-    if(mType == TextureType::TEXTURE_CUBE)
-    {
-      mode = WrapModeToGL(mSampler.mRWrapMode, GL_WRAP_DEFAULT);
-      if(mode != WrapModeToGL(oldSampler.mRWrapMode, GL_WRAP_DEFAULT))
-      {
-        context.TexParameteri(mTarget, GL_TEXTURE_WRAP_R, mode);
-      }
-    }
-
-    if(mMaxMipMapLevel)
-    {
-      context.TexParameteri(mTarget, GL_TEXTURE_MAX_LEVEL, mMaxMipMapLevel);
-    }
+    Create(static_cast<Graphics::TextureUsageFlags>(Graphics::TextureUsageFlagBits::SAMPLE));
   }
+
+  Graphics::TextureUpdateInfo info{};
+  info.dstTexture   = mGraphicsTexture.get();
+  info.dstOffset2D  = {params.xOffset, params.yOffset};
+  info.layer        = params.layer;
+  info.level        = params.mipmap;
+  info.srcReference = 0;
+  info.srcExtent2D  = {params.width, params.height};
+  info.srcOffset    = 0;
+  info.srcSize      = pixelData->GetBufferSize();
+
+  Graphics::TextureUpdateSourceInfo updateSourceInfo{};
+  updateSourceInfo.sourceType          = Graphics::TextureUpdateSourceInfo::Type::MEMORY;
+  updateSourceInfo.memorySource.memory = pixelData->GetBuffer();
+
+  mGraphicsController->UpdateTextures({info}, {updateSourceInfo});
 }
 
 bool Texture::HasAlphaChannel() const
 {
-  return mHasAlpha;
+  bool alpha = mHasAlpha;
+  if(mNativeImage)
+  {
+    alpha = mNativeImage->RequiresBlending();
+  }
+  return alpha;
 }
 
-void Texture::GenerateMipmaps(Context& context)
+void Texture::GenerateMipmaps()
 {
-  //GL_TEXTURE_MAX_LEVEL does not need to be set when mipmaps are generated by GL
   mMaxMipMapLevel = 0;
-  context.BindTexture(mTarget, mId);
-  context.GenerateMipmap(mTarget);
+  DALI_LOG_ERROR("FIXME: GRAPHICS");
+  //@todo Implement with Graphics API
 }
 
 } // namespace Render
index 63f20b46c63d3ba8bd4eaa847e334d31859f7d68..cbf0e2baa107290bbc311e82b689cbea85157584 100644 (file)
 #include <string>
 
 // INTERNAL INCLUDES
+#include <dali/public-api/images/image-operations.h> // Dali::ImageDimensions
+#include <dali/public-api/rendering/sampler.h>
+#include <dali/public-api/rendering/texture.h>
+
+#include <dali/graphics-api/graphics-controller.h>
+#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 <dali/internal/event/rendering/texture-impl.h>
 #include <dali/internal/render/gl-resources/context.h>
 #include <dali/internal/render/renderers/render-sampler.h>
-#include <dali/public-api/images/image-operations.h> // Dali::ImageDimensions
-#include <dali/public-api/rendering/sampler.h>
-#include <dali/public-api/rendering/texture.h>
 
 namespace Dali
 {
@@ -63,69 +68,58 @@ public:
   ~Texture();
 
   /**
-   * Creates the texture in the GPU.
-   * Creates the texture and reserves memory for the first mipmap level
-   * @param[in] context The GL context
+   * Stores the graphics controller for use when required.
+   *
+   * @param[in] graphicsController The graphics controller to use
    */
-  void Initialize(Context& context);
+  void Initialize(Graphics::Controller& graphicsController);
 
   /**
-   * Deletes the texture from the GPU
-   * @param[in] context The GL context
+   * Create the texture without a buffer
+   * @param[in] usage How texture will be used
+   */
+  void Create(Graphics::TextureUsageFlags usage);
+
+  /**
+   * Create a texture with a buffer if non-null
+   * @param[in] usage How texture will be used
+   * @param[in] buffer Buffer to copy
    */
-  void Destroy(Context& context);
+  void CreateWithData(Graphics::TextureUsageFlags usage, uint8_t* buffer, uint32_t bufferSize);
 
   /**
-   * Called by RenderManager to inform the texture that the context has been destroyed
+   * Deletes the texture from the GPU
    */
-  void GlContextDestroyed();
+  void Destroy();
 
   /**
    * Uploads data to the texture.
-   * @param[in] context The GL context
    * @param[in] pixelData A pixel data object
    * @param[in] params Upload parameters. See UploadParams
    */
-  void Upload(Context& context, PixelDataPtr pixelData, const Internal::Texture::UploadParams& params);
+  void Upload(PixelDataPtr pixelData, const Internal::Texture::UploadParams& params);
 
   /**
-   * Bind the texture to the given texture unit and applies the given sampler
-   * @param[in] context The GL context
-   * @param[in] textureUnit the texture unit
-   * @param[in] sampler The sampler to be used with the texture
-   * @return true if the bind succeeded, false otherwise
+   * Called when the texture is about to be used for drawing.
+   * Allows native textures to be set up appropriately.
    */
-  bool Bind(Context& context, uint32_t textureUnit, Render::Sampler* sampler);
+  void Prepare();
 
   /**
    * Auto generates mipmaps for the texture
-   * @param[in] context The GL context
    */
-  void GenerateMipmaps(Context& context);
+  void GenerateMipmaps();
 
   /**
-   * Retrieve wheter the texture has an alpha channel
+   * Retrieve whether the texture has an alpha channel
    * @return True if the texture has alpha channel, false otherwise
    */
   bool HasAlphaChannel() const;
 
   /**
-   * Get the id of the texture
-   * @return Id of the texture
+   * Get the graphics object associated with this texture
    */
-  GLuint GetId() const
-  {
-    return mId;
-  }
-
-  /**
-   * Get the target to which the texture is bound
-   * @return target to which the texture is bound
-   */
-  GLuint GetTarget() const
-  {
-    return mTarget;
-  }
+  Graphics::Texture* GetGraphicsObject() const;
 
   /**
    * Get the type of the texture
@@ -151,21 +145,21 @@ private:
    * @param[in] context The GL context
    * @param[in] sampler The sampler
    */
-  void ApplySampler(Context& context, Render::Sampler* sampler);
-
-  NativeImageInterfacePtr mNativeImage;      ///< Pointer to native image
-  Render::Sampler         mSampler;          ///< The current sampler state
-  GLuint                  mId;               ///< Id of the texture
-  GLuint                  mTarget;           ///< Specifies the target to which the texture is bound.
-  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
-  uint16_t                mWidth;            ///< Width of the texture
-  uint16_t                mHeight;           ///< Height of the texture
-  uint16_t                mMaxMipMapLevel;   ///< Maximum mipmap level
-  Type                    mType : 3;         ///< Type of the texture
-  bool                    mHasAlpha : 1;     ///< Whether the format has an alpha channel
-  bool                    mIsCompressed : 1; ///< Whether the format is compressed
+  void ApplySampler(Render::Sampler* sampler);
+
+private:
+  Graphics::Controller*                  mGraphicsController;
+  Graphics::UniquePtr<Graphics::Texture> mGraphicsTexture;
+
+  NativeImageInterfacePtr mNativeImage; ///< Pointer to native image
+  Render::Sampler         mSampler;     ///< The current sampler state
+
+  Pixel::Format mPixelFormat;    ///< Pixel format of the texture
+  uint16_t      mWidth;          ///< Width of the texture
+  uint16_t      mHeight;         ///< Height of the texture
+  uint16_t      mMaxMipMapLevel; ///< Maximum mipmap level
+  Type          mType : 3;       ///< Type of the texture
+  bool          mHasAlpha : 1;   ///< Whether the format has an alpha channel
 };
 
 } // namespace Render