Fix texture bound cache issue 78/244278/2
authorHeeyong Song <heeyong.song@samsung.com>
Wed, 16 Sep 2020 15:23:13 +0000 (00:23 +0900)
committerHeeyong Song <heeyong.song@samsung.com>
Thu, 17 Sep 2020 09:08:41 +0000 (18:08 +0900)
ActiveTexture should be called if mActiveTextureUnit is different.
We don't need to check it in BindTextureForUnit().

And the mBoundTextureId should store ids per target.

Change-Id: I30d93784577a2ce261ef047f2ec36c6adb766b0a

automated-tests/src/dali/utc-Dali-TextureSet.cpp
dali/internal/render/gl-resources/context.h

index 4e30f15..fa2112a 100644 (file)
@@ -531,3 +531,58 @@ int UtcDaliTextureSetGetTextureCountNegative(void)
   }
   END_TEST;
 }
+
+int UtcDaliTextureSetMultipleTextures(void)
+{
+  TestApplication application;
+
+  Shader     shader     = CreateShader();
+  TextureSet textureSet = CreateTextureSet();
+
+  // Set 2 textures
+  Texture texture1 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  textureSet.SetTexture(0u, texture1);
+
+  Texture texture2 = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, 64, 64);
+  textureSet.SetTexture(1u, texture2);
+
+  Geometry geometry = CreateQuadGeometry();
+  Renderer renderer = Renderer::New(geometry, shader);
+  renderer.SetTextures(textureSet);
+
+  Actor actor = Actor::New();
+  actor.AddRenderer(renderer);
+  actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+  actor.SetProperty(Actor::Property::SIZE, Vector2(400.0f, 400.0f));
+
+  application.GetScene().Add(actor);
+
+  application.SendNotification();
+  application.Render();
+
+  const std::vector<GLuint>& boundTextures0 = application.GetGlAbstraction().GetBoundTextures(GL_TEXTURE0);
+  DALI_TEST_CHECK(boundTextures0[boundTextures0.size() - 1] == 1u); // the latest one should be 0.
+
+  const std::vector<GLuint>& boundTextures1 = application.GetGlAbstraction().GetBoundTextures(GL_TEXTURE1);
+  size_t count = boundTextures1.size();
+  DALI_TEST_CHECK(boundTextures1[count - 1] == 2u); // the latest one should be 1.
+
+  // Create a new TextureSet
+  textureSet = CreateTextureSet();
+
+  // Set 1 texture
+  textureSet.SetTexture(0u, texture1);
+
+  renderer.SetTextures(textureSet);
+
+  application.SendNotification();
+  application.Render();
+
+  TestGlAbstraction& gl = application.GetGlAbstraction();
+  DALI_TEST_CHECK(gl.GetActiveTextureUnit() == GL_TEXTURE0);
+
+  DALI_TEST_CHECK(boundTextures0[boundTextures0.size() - 1] == 1u);
+  DALI_TEST_CHECK(boundTextures1.size() == count);  // The bound texture count of GL_TEXTURE1 should not be changed.
+
+  END_TEST;
+}
index 378ee31..2e5a0ee 100644 (file)
@@ -60,9 +60,10 @@ public:
    * Size of the VertexAttributeArray enables
    * GLES specification states that there's minimum of 8
    */
-  static const unsigned int MAX_ATTRIBUTE_CACHE_SIZE = 8;
+  static constexpr unsigned int MAX_ATTRIBUTE_CACHE_SIZE = 8;
 
-  static const unsigned int MAX_TEXTURE_UNITS = 8; // for GLES 2.0 8 is guaranteed, which is more than DALi uses anyways
+  static constexpr unsigned int MAX_TEXTURE_UNITS = 8; // for GLES 2.0 8 is guaranteed, which is more than DALi uses anyways
+  static constexpr unsigned int MAX_TEXTURE_TARGET = 3; // We support only GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP and GL_TEXTURE_EXTERNAL_OES now
 
   /**
    * Creates the Dali Context object for surface rendering only.
@@ -133,6 +134,9 @@ public:
     DALI_LOG_INFO(Debug::Filter::gRender, Debug::General, "GL %s = %s\n", stringName, reinterpret_cast< const char * >( GetString( stringId ) ) );
   }
 
+  /**
+   * Reset the cached buffer ids.
+   */
   void ResetBufferCache()
   {
     // reset the cached buffer id's
@@ -143,13 +147,47 @@ public:
     mBoundTransformFeedbackBufferId = 0;
   }
 
+  /**
+   * Reset the cached texture ids.
+   */
   void ResetTextureCache()
   {
     // reset the cached texture id's in case the driver re-uses them
     // when creating new textures
-    for( unsigned int i=0; i < MAX_TEXTURE_UNITS; ++i )
+    for(unsigned int i = 0; i < MAX_TEXTURE_UNITS; ++i)
     {
-       mBoundTextureId[ i ] = 0;
+      for(unsigned int j = 0; j < MAX_TEXTURE_TARGET; ++j)
+      {
+        mBoundTextureId[i][j] = 0;
+      }
+    }
+  }
+
+  /**
+   * Get an index of the cached texture list from the texture target.
+   * @param target The texture target
+   * @return The index of the cached texture list
+   */
+  static constexpr int16_t GetTextureIndexFromGlFormat(int target)
+  {
+    switch(target)
+    {
+      case GL_TEXTURE_2D:
+      {
+        return 0;
+      }
+      case GL_TEXTURE_CUBE_MAP:
+      {
+        return 1;
+      }
+      case GL_TEXTURE_EXTERNAL_OES:
+      {
+        return 2;
+      }
+      default:
+      {
+        return -1;
+      }
     }
   }
 
@@ -311,11 +349,8 @@ public:
    */
   void BindTextureForUnit( TextureUnit textureunit, int target, GLuint texture )
   {
-    if( mBoundTextureId[ textureunit ] != texture )
-    {
-      ActiveTexture( textureunit );
-      BindTexture( target, texture );
-    }
+    ActiveTexture(textureunit);
+    BindTexture(target, texture);
   }
 
   /**
@@ -323,12 +358,13 @@ public:
    */
   void BindTexture( int target, GLuint texture )
   {
-    if (mBoundTextureId[ mActiveTextureUnit ] != texture)
+    int16_t index = GetTextureIndexFromGlFormat(target);
+    if(index >= 0 && mBoundTextureId[ mActiveTextureUnit ][index] != texture)
     {
-      mBoundTextureId[ mActiveTextureUnit ] = texture;
+      mBoundTextureId[ mActiveTextureUnit ][index] = texture;
 
       LOG_GL("BindTexture target(%d) %d\n", target, texture);
-      CHECK_GL( mGlAbstraction, mGlAbstraction.BindTexture(target, texture) );
+      CHECK_GL(mGlAbstraction, mGlAbstraction.BindTexture(target, texture));
     }
   }
 
@@ -1789,7 +1825,7 @@ private: // Data
 
   // glBindTexture() state
   TextureUnit mActiveTextureUnit;
-  GLuint mBoundTextureId[ MAX_TEXTURE_UNITS ];  ///< The ID passed to glBindTexture()
+  GLuint mBoundTextureId[ MAX_TEXTURE_UNITS ][MAX_TEXTURE_TARGET];  ///< The ID passed to glBindTexture()
 
   // glBlendColor() state
   Vector4 mBlendColor; ///< Blend color