Adding wrap modes to texture binding 00/254500/3
authorDavid Steele <david.steele@samsung.com>
Wed, 3 Mar 2021 12:58:11 +0000 (12:58 +0000)
committerDavid Steele <david.steele@samsung.com>
Fri, 5 Mar 2021 14:14:55 +0000 (14:14 +0000)
Change-Id: I1f22405a5c14bc8d2dd42f3bbf53c468c5bd11fd

automated-tests/src/dali-adaptor/dali-test-suite-utils/test-gl-abstraction.h
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-trace-call-stack.cpp
automated-tests/src/dali-adaptor/dali-test-suite-utils/test-trace-call-stack.h
automated-tests/src/dali-graphics/CMakeLists.txt
automated-tests/src/dali-graphics/utc-Dali-GraphicsSampler.cpp [new file with mode: 0644]
dali/internal/graphics/gles-impl/egl-graphics-controller.cpp
dali/internal/graphics/gles-impl/egl-graphics-controller.h
dali/internal/graphics/gles-impl/gles-graphics-texture.cpp
dali/internal/graphics/gles-impl/gles-graphics-types.h

index 18fbbf1..1d93731 100644 (file)
@@ -1181,16 +1181,10 @@ public:
     out << std::hex << target << ", " << pname << ", " << param;
     std::string params = out.str();
 
-    out.str("");
-    out << std::hex << target;
     TraceCallStack::NamedParams 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();
+    namedParams["target"] << std::hex << target;
+    namedParams["pname"] << std::hex << pname;
+    namedParams["param"] << param;
     mTexParameterTrace.PushCall("TexParameteri", params, namedParams);
   }
 
index 1a0ab3a..7f2de63 100644 (file)
@@ -16,9 +16,9 @@
  */
 
 #include "test-trace-call-stack.h"
-
 #include <iostream>
 #include <sstream>
+#include "dali-test-suite-utils.h"
 
 namespace Dali
 {
@@ -255,6 +255,45 @@ int TraceCallStack::FindIndexFromMethodAndParams(std::string method, const Trace
   return index;
 }
 
+const TraceCallStack::NamedParams* TraceCallStack::FindLastMatch(std::string method, const TraceCallStack::NamedParams& params) const
+{
+  int index = -1;
+
+  if(mCallStack.size() > 0)
+  {
+    for(index = static_cast<int>(mCallStack.size() - 1); index >= 0; --index)
+    {
+      if(0 == mCallStack[index].method.compare(method))
+      {
+        // Test each of the passed in parameters:
+        bool match = true;
+
+        for(auto iter = params.mParams.begin(); iter != params.mParams.end(); ++iter)
+        {
+          auto        paramIter = mCallStack[index].namedParams.find(iter->parameterName);
+          std::string value     = paramIter->value.str();
+          std::string iValue    = iter->value.str();
+
+          if(paramIter == mCallStack[index].namedParams.end() || value.compare(iValue))
+          {
+            match = false;
+            break;
+          }
+        }
+        if(match == true)
+        {
+          break;
+        }
+      }
+    }
+  }
+  if(index >= 0)
+  {
+    return &mCallStack[index].namedParams;
+  }
+  return nullptr;
+}
+
 /**
  * Test if the given method and parameters are at a given index in the stack
  * @param[in] index Index in the call stack
@@ -274,4 +313,17 @@ void TraceCallStack::Reset()
   mCallStack.clear();
 }
 
+bool TraceCallStack::NamedParams::NameValue::operator==(int match) const
+{
+  std::ostringstream matchStr;
+  matchStr << match;
+  std::string valueStr = value.str();
+  bool        retval   = !valueStr.compare(matchStr.str());
+  if(!retval)
+  {
+    tet_printf("Comparing parameter \"%s\": %s with %s failed\n", parameterName.c_str(), value.str().c_str(), matchStr.str().c_str());
+  }
+  return retval;
+}
+
 } // namespace Dali
index b7d9e46..7631630 100644 (file)
@@ -73,6 +73,8 @@ public:
       {
         return !parameterName.compare(rhs.parameterName) && !value.str().compare(rhs.value.str());
       }
+
+      bool operator==(int match) const;
     };
 
     auto find(const std::string& param) const
@@ -238,6 +240,14 @@ public:
   int FindIndexFromMethodAndParams(std::string method, const NamedParams& params) const;
 
   /**
+   * Search for the most recent occurrence of the method with the given (partial) parameters.
+   * @param[in] method The name of the method
+   * @param[in] params A map of named parameter values to match
+   * @return The full named parameters of the matching call.
+   */
+  const NamedParams* FindLastMatch(std::string method, const TraceCallStack::NamedParams& params) const;
+
+  /**
    * Test if the given method and parameters are at a given index in the stack
    * @param[in] index Index in the call stack
    * @param[in] method Name of method to test
@@ -267,7 +277,7 @@ public:
     return traceStream.str();
   }
 
-private:
+public:
   bool        mTraceActive{false}; ///< True if the trace is active
   bool        mLogging{false};     ///< True if the trace is logged to stdout
   std::string mPrefix;
index be6702c..5ac7e09 100644 (file)
@@ -5,6 +5,7 @@ SET(RPM_NAME "core-${PKG_NAME}-tests")
 
 SET(CAPI_LIB "dali-graphics")
 SET(TC_SOURCES
+    utc-Dali-GraphicsSampler.cpp
     utc-Dali-GraphicsGeometry.cpp
     utc-Dali-GraphicsNativeImage.cpp
 )
diff --git a/automated-tests/src/dali-graphics/utc-Dali-GraphicsSampler.cpp b/automated-tests/src/dali-graphics/utc-Dali-GraphicsSampler.cpp
new file mode 100644 (file)
index 0000000..8f1994e
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * 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-test-suite-utils.h>
+#include <dali/dali.h>
+
+#include <dali/internal/graphics/gles-impl/egl-graphics-controller.h>
+#include <test-actor-utils.h>
+#include <test-graphics-application.h>
+#include <test-graphics-sampler.h>
+
+using namespace Dali;
+
+void utc_dali_sampler_startup(void)
+{
+  test_return_value = TET_UNDEF;
+}
+void utc_dali_sampler_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 UtcDaliGraphicsSamplerDefault(void)
+{
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliSampler01 - check defaults");
+
+  Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
+  Actor   actor   = CreateRenderableActor(texture, "myVertShaderSource", "myFragShaderSource");
+  app.GetScene().Add(actor);
+
+  auto& gl           = app.GetGlAbstraction();
+  auto& glParamTrace = gl.GetTexParameterTrace();
+  glParamTrace.Enable(true);
+  glParamTrace.EnableLogging(true);
+
+  app.SendNotification();
+  app.Render(16); // The above actor will get rendered and drawn once.
+
+  TraceCallStack::NamedParams minFilter;
+  minFilter["pname"] << std::hex << GL_TEXTURE_MIN_FILTER;
+  std::ostringstream LINEAR;
+  LINEAR << GL_LINEAR;
+  std::ostringstream CLAMP_TO_EDGE;
+  CLAMP_TO_EDGE << GL_CLAMP_TO_EDGE;
+
+  auto params = glParamTrace.FindLastMatch("TexParameteri", minFilter);
+  DALI_TEST_CHECK(params != nullptr);
+  auto iter = params->find("param");
+  DALI_TEST_EQUALS(iter->value.str(), LINEAR.str(), TEST_LOCATION);
+
+  TraceCallStack::NamedParams magFilter;
+  magFilter["pname"] << std::hex << GL_TEXTURE_MAG_FILTER;
+  params = glParamTrace.FindLastMatch("TexParameteri", magFilter);
+  DALI_TEST_CHECK(params != nullptr);
+  iter = params->find("param");
+  DALI_TEST_EQUALS(iter->value.str(), LINEAR.str(), TEST_LOCATION);
+
+  TraceCallStack::NamedParams wrapS;
+  wrapS["pname"] << std::hex << GL_TEXTURE_WRAP_S;
+  params = glParamTrace.FindLastMatch("TexParameteri", wrapS);
+  DALI_TEST_CHECK(params != nullptr);
+  iter = params->find("param");
+  DALI_TEST_EQUALS(iter->value.str(), CLAMP_TO_EDGE.str(), TEST_LOCATION);
+
+  TraceCallStack::NamedParams wrapT;
+  wrapT["pname"] << std::hex << GL_TEXTURE_WRAP_T;
+  params = glParamTrace.FindLastMatch("TexParameteri", wrapT);
+  DALI_TEST_CHECK(params != nullptr);
+  iter = params->find("param");
+  DALI_TEST_EQUALS(iter->value.str(), CLAMP_TO_EDGE.str(), TEST_LOCATION);
+
+  END_TEST;
+}
+
+int UtcDaliGraphicsSamplerAllSet(void)
+{
+  TestGraphicsApplication app;
+  tet_infoline("UtcDaliSampler01 - check defaults");
+
+  Texture    texture    = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, 16u, 16u);
+  Actor      actor      = CreateRenderableActor(texture, "myVertShaderSource", "myFragShaderSource");
+  TextureSet textureSet = actor.GetRendererAt(0u).GetTextures();
+
+  Sampler sampler = Sampler::New();
+  sampler.SetFilterMode(FilterMode::LINEAR_MIPMAP_NEAREST, FilterMode::NEAREST);
+  sampler.SetWrapMode(WrapMode::REPEAT, WrapMode::MIRRORED_REPEAT);
+  textureSet.SetSampler(0, sampler);
+
+  app.GetScene().Add(actor);
+
+  auto& gl           = app.GetGlAbstraction();
+  auto& glParamTrace = gl.GetTexParameterTrace();
+  glParamTrace.Enable(true);
+  glParamTrace.EnableLogging(true);
+
+  app.SendNotification();
+  app.Render(16); // The above actor will get rendered and drawn once.
+
+  TraceCallStack::NamedParams minFilter;
+  minFilter["pname"] << std::hex << GL_TEXTURE_MIN_FILTER;
+
+  auto params = glParamTrace.FindLastMatch("TexParameteri", minFilter);
+  DALI_TEST_CHECK(params != nullptr);
+  auto iter = params->find("param");
+  DALI_TEST_CHECK(*iter == GL_LINEAR_MIPMAP_NEAREST);
+
+  TraceCallStack::NamedParams magFilter;
+  magFilter["pname"] << std::hex << GL_TEXTURE_MAG_FILTER;
+  params = glParamTrace.FindLastMatch("TexParameteri", magFilter);
+  DALI_TEST_CHECK(params != nullptr);
+  iter = params->find("param");
+  DALI_TEST_CHECK(*iter == GL_NEAREST);
+
+  TraceCallStack::NamedParams wrapS;
+  wrapS["pname"] << std::hex << GL_TEXTURE_WRAP_S;
+  params = glParamTrace.FindLastMatch("TexParameteri", wrapS);
+  DALI_TEST_CHECK(params != nullptr);
+  iter = params->find("param");
+  DALI_TEST_CHECK(*iter == GL_REPEAT);
+
+  TraceCallStack::NamedParams wrapT;
+  wrapT["pname"] << std::hex << GL_TEXTURE_WRAP_T;
+  params = glParamTrace.FindLastMatch("TexParameteri", wrapT);
+  DALI_TEST_CHECK(params != nullptr);
+  iter = params->find("param");
+  DALI_TEST_CHECK(*iter == GL_MIRRORED_REPEAT);
+
+  sampler.SetFilterMode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::LINEAR);
+  sampler.SetWrapMode(WrapMode::CLAMP_TO_EDGE, WrapMode::DEFAULT);
+
+  glParamTrace.Reset();
+  app.SendNotification();
+  app.Render(16); // The above actor will get rendered and drawn once.
+
+  END_TEST;
+}
index 1ad0798..979c5be 100644 (file)
@@ -183,6 +183,11 @@ Graphics::UniquePtr<Shader> EglGraphicsController::CreateShader(const ShaderCrea
   return NewObject<GLES::Shader>(shaderCreateInfo, *this, std::move(oldShader));
 }
 
+Graphics::UniquePtr<Sampler> EglGraphicsController::CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler)
+{
+  return NewObject<GLES::Sampler>(samplerCreateInfo, *this, std::move(oldSampler));
+}
+
 const Graphics::Reflection& EglGraphicsController::GetProgramReflection(const Graphics::Program& program)
 {
   return static_cast<const Graphics::GLES::Program*>(&program)->GetReflection();
index 70f6d8c..6e90c03 100644 (file)
@@ -28,6 +28,7 @@
 #include "gles-graphics-pipeline-cache.h"
 #include "gles-graphics-pipeline.h"
 #include "gles-graphics-reflection.h"
+#include "gles-graphics-sampler.h"
 #include "gles-graphics-texture.h"
 
 namespace Dali
@@ -208,10 +209,7 @@ public:
   /**
    * @copydoc Dali::Graphics::CreateSampler()
    */
-  Graphics::UniquePtr<Sampler> CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler) override
-  {
-    return nullptr;
-  }
+  Graphics::UniquePtr<Sampler> CreateSampler(const SamplerCreateInfo& samplerCreateInfo, Graphics::UniquePtr<Sampler>&& oldSampler) override;
 
   /**
    * @copydoc Dali::Graphics::CreateRenderTarget()
index 54689a7..442583f 100644 (file)
@@ -26,6 +26,7 @@
 
 // INTERNAL INCLUDES
 #include "egl-graphics-controller.h"
+#include "gles-graphics-sampler.h"
 #include "gles-graphics-types.h"
 
 namespace
@@ -190,10 +191,32 @@ void Texture::Bind(const TextureBinding& binding) const
   gl->BindTexture(mGlTarget, mTextureId);
 
   // For GLES2 if there is a sampler set in the binding
-  //if(binding.sampler)
-  //{
-
-  //}
+  if(binding.sampler)
+  {
+    // Non-default.
+    auto*       sampler           = static_cast<const GLES::Sampler*>(binding.sampler);
+    const auto& samplerCreateInfo = sampler->GetCreateInfo();
+
+    gl->TexParameteri(mGlTarget, GL_TEXTURE_MIN_FILTER, GLSamplerFilterAndMipMapMode(samplerCreateInfo.minFilter, samplerCreateInfo.mipMapMode).glFilter);
+    gl->TexParameteri(mGlTarget, GL_TEXTURE_MAG_FILTER, GLSamplerFilter(samplerCreateInfo.magFilter).glFilter);
+    gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_S, GLAddressMode(samplerCreateInfo.addressModeU).texParameter);
+    gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_T, GLAddressMode(samplerCreateInfo.addressModeV).texParameter);
+    if(mGlTarget == GL_TEXTURE_CUBE_MAP)
+    {
+      gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_R, GLAddressMode(samplerCreateInfo.addressModeW).texParameter);
+    }
+  }
+  else
+  {
+    gl->TexParameteri(mGlTarget, GL_TEXTURE_MIN_FILTER, DALI_MINIFY_DEFAULT);
+    gl->TexParameteri(mGlTarget, GL_TEXTURE_MAG_FILTER, DALI_MAGNIFY_DEFAULT);
+    gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_S, GL_WRAP_DEFAULT);
+    gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_T, GL_WRAP_DEFAULT);
+    if(mGlTarget == GL_TEXTURE_CUBE_MAP)
+    {
+      gl->TexParameteri(mGlTarget, GL_TEXTURE_WRAP_R, GL_WRAP_DEFAULT);
+    }
+  }
 }
 
 void Texture::Prepare()
index 360045f..46946c8 100644 (file)
@@ -1029,11 +1029,31 @@ struct GLTextureFormatType
   uint32_t type{0};
 };
 
+struct GLSamplerFilter
+{
+  constexpr explicit GLSamplerFilter(Graphics::SamplerFilter filter)
+  {
+    switch(filter)
+    {
+      case Graphics::SamplerFilter::NEAREST:
+      {
+        glFilter = GL_NEAREST;
+        break;
+      }
+      case Graphics::SamplerFilter::LINEAR:
+      {
+        glFilter = GL_LINEAR;
+        break;
+      }
+    }
+  }
+  uint32_t glFilter{0};
+};
+
 struct GLSamplerFilterAndMipMapMode
 {
-  GLSamplerFilterAndMipMapMode() = default;
-  GLSamplerFilterAndMipMapMode(Graphics::SamplerFilter     filter,
-                               Graphics::SamplerMipmapMode mipMapMode)
+  constexpr explicit GLSamplerFilterAndMipMapMode(Graphics::SamplerFilter     filter,
+                                                  Graphics::SamplerMipmapMode mipMapMode)
   {
     switch(filter)
     {
@@ -1057,7 +1077,9 @@ struct GLSamplerFilterAndMipMapMode
             break;
           }
         }
+        break;
       }
+
       case Graphics::SamplerFilter::LINEAR:
       {
         switch(mipMapMode)
@@ -1189,6 +1211,42 @@ struct GLTextureTarget
   GLenum target{GL_TEXTURE_2D};
 };
 
+struct GLAddressMode
+{
+  constexpr explicit GLAddressMode(Graphics::SamplerAddressMode graphicsAddressMode)
+  {
+    switch(graphicsAddressMode)
+    {
+      case Graphics::SamplerAddressMode::REPEAT:
+      {
+        texParameter = GL_REPEAT;
+        break;
+      }
+      case Graphics::SamplerAddressMode::MIRRORED_REPEAT:
+      {
+        texParameter = GL_MIRRORED_REPEAT;
+        break;
+      }
+      case Graphics::SamplerAddressMode::CLAMP_TO_EDGE:
+      {
+        texParameter = GL_CLAMP_TO_EDGE;
+        break;
+      }
+      case Graphics::SamplerAddressMode::CLAMP_TO_BORDER:
+      {
+        texParameter = GL_CLAMP_TO_EDGE;
+        break;
+      }
+      case Graphics::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE:
+      {
+        texParameter = GL_CLAMP_TO_EDGE;
+        break;
+      }
+    }
+  }
+  GLenum texParameter{GL_CLAMP_TO_EDGE};
+};
+
 /**
  * @brief Descriptor of single buffer binding within
  * command buffer.