[Tizen] Fix partial update issue when change texture 67/293867/2 accepted/tizen/7.0/unified/20230623.162702 accepted/tizen/7.0/unified/20230719.171756 accepted/tizen/7.0/unified/20230811.173917
authorHeeyong Song <heeyong.song@samsung.com>
Mon, 29 Mar 2021 09:07:20 +0000 (18:07 +0900)
committerEunki, Hong <eunkiki.hong@samsung.com>
Wed, 7 Jun 2023 08:02:23 +0000 (17:02 +0900)
Uploading texture or changing texture were not detected.

Change-Id: I390b4ee8c26167a2daa9ab3dc25acb47ae6ceeb7

automated-tests/src/dali/utc-Dali-Texture.cpp
dali/internal/render/renderers/render-renderer.cpp
dali/internal/render/renderers/render-texture.cpp
dali/internal/render/renderers/render-texture.h
dali/internal/update/rendering/scene-graph-texture-set.cpp

index b16d10b..4a2126f 100644 (file)
@@ -1319,3 +1319,169 @@ int UtcDaliTextureGetPixelFormat(void)
 
   END_TEST;
 }
+
+int utcDaliTexturePartialUpdate01(void)
+{
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  tet_infoline("Check the damaged rect with partial update and texture change");
+
+  const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+  std::vector<Rect<int>> damagedRects;
+  Rect<int>              clippingRect;
+
+  Geometry geometry = CreateQuadGeometry();
+  Shader   shader   = Shader::New("vertexSrc", "fragmentSrc");
+  Renderer renderer = Renderer::New(geometry, shader);
+
+  unsigned int width(4);
+  unsigned int height(4);
+  Texture      texture    = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  TextureSet   textureSet = TextureSet::New();
+  textureSet.SetTexture(0u, texture);
+  renderer.SetTextures(textureSet);
+
+  Actor actor = Actor::New();
+  actor.AddRenderer(renderer);
+
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  application.GetScene().Add(actor);
+
+  damagedRects.clear();
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  // Aligned by 16
+  clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Ensure the damaged rect is empty
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+  // Upload texture
+  unsigned int   bufferSize(width * height * 4);
+  unsigned char* buffer    = reinterpret_cast<unsigned char*>(malloc(bufferSize));
+  PixelData      pixelData = PixelData::New(buffer, bufferSize, width, height, Pixel::RGBA8888, PixelData::FREE);
+  texture.Upload(pixelData);
+
+  damagedRects.clear();
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  // Aligned by 16
+  clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  END_TEST;
+}
+
+int utcDaliTexturePartialUpdate02(void)
+{
+  TestApplication application(
+    TestApplication::DEFAULT_SURFACE_WIDTH,
+    TestApplication::DEFAULT_SURFACE_HEIGHT,
+    TestApplication::DEFAULT_HORIZONTAL_DPI,
+    TestApplication::DEFAULT_VERTICAL_DPI,
+    true,
+    true);
+
+  tet_infoline("Check the damaged rect with partial update and texture change");
+
+  const TestGlAbstraction::ScissorParams& glScissorParams(application.GetGlAbstraction().GetScissorParams());
+
+  std::vector<Rect<int>> damagedRects;
+  Rect<int>              clippingRect;
+
+  Geometry geometry = CreateQuadGeometry();
+  Shader   shader   = Shader::New("vertexSrc", "fragmentSrc");
+  Renderer renderer = Renderer::New(geometry, shader);
+
+  unsigned int width(4);
+  unsigned int height(4);
+  Texture      texture1   = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  Texture      texture2   = Texture::New(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+  TextureSet   textureSet = TextureSet::New();
+  textureSet.SetTexture(0u, texture1);
+  renderer.SetTextures(textureSet);
+
+  Actor actor = Actor::New();
+  actor.AddRenderer(renderer);
+
+  actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+  actor.SetProperty(Actor::Property::POSITION, Vector3(16.0f, 16.0f, 0.0f));
+  actor.SetProperty(Actor::Property::SIZE, Vector3(16.0f, 16.0f, 0.0f));
+  application.GetScene().Add(actor);
+
+  damagedRects.clear();
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  // Aligned by 16
+  clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  damagedRects.clear();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+
+  // Ensure the damaged rect is empty
+  DALI_TEST_EQUALS(damagedRects.size(), 0, TEST_LOCATION);
+
+  // Set another texture
+  textureSet.SetTexture(0u, texture2);
+
+  damagedRects.clear();
+  application.SendNotification();
+  application.PreRenderWithPartialUpdate(TestApplication::RENDER_FRAME_INTERVAL, nullptr, damagedRects);
+  DALI_TEST_EQUALS(damagedRects.size(), 1, TEST_LOCATION);
+
+  // Aligned by 16
+  clippingRect = Rect<int>(16, 768, 32, 32); // in screen coordinates, includes 3 last frames updates
+  DALI_TEST_EQUALS<Rect<int>>(clippingRect, damagedRects[0], TEST_LOCATION);
+  application.RenderWithPartialUpdate(damagedRects, clippingRect);
+  DALI_TEST_EQUALS(clippingRect.x, glScissorParams.x, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.y, glScissorParams.y, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.width, glScissorParams.width, TEST_LOCATION);
+  DALI_TEST_EQUALS(clippingRect.height, glScissorParams.height, TEST_LOCATION);
+
+  END_TEST;
+}
index f347198..d4d327c 100644 (file)
@@ -905,7 +905,7 @@ bool Renderer::Updated(BufferIndex bufferIndex, const SceneGraph::NodeDataProvid
     for(auto iter = textures->Begin(), end = textures->End(); iter < end; ++iter)
     {
       auto texture = *iter;
-      if(texture && texture->IsNativeImage())
+      if(texture && texture->Updated())
       {
         return true;
       }
index f2bc5a3..8662303 100644 (file)
@@ -214,7 +214,8 @@ Texture::Texture(Type type, Pixel::Format format, ImageDimensions size)
   mWidth(size.GetWidth()),
   mHeight(size.GetHeight()),
   mType(type),
-  mHasAlpha(HasAlpha(format))
+  mHasAlpha(HasAlpha(format)),
+  mUpdated(true)
 {
 }
 
@@ -227,7 +228,8 @@ Texture::Texture(NativeImageInterfacePtr nativeImageInterface)
   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
   mType(TextureType::TEXTURE_2D),
-  mHasAlpha(nativeImageInterface->RequiresBlending())
+  mHasAlpha(nativeImageInterface->RequiresBlending()),
+  mUpdated(true)
 {
 }
 
@@ -345,6 +347,8 @@ void Texture::Upload(PixelDataPtr pixelData, const Internal::Texture::UploadPara
   updateSourceInfo.memorySource.memory = pixelData->GetBuffer();
 
   mGraphicsController->UpdateTextures({info}, {updateSourceInfo});
+
+  SetUpdated(true);
 }
 
 bool Texture::HasAlphaChannel() const
index a3945d8..285a535 100644 (file)
@@ -130,6 +130,28 @@ public:
   {
     return static_cast<bool>(mNativeImage);
   }
+  /**
+   * Set the updated flag.
+   * @param[in] updated The updated flag
+   */
+  void SetUpdated(bool updated)
+  {
+    mUpdated = updated;
+  }
+
+  /**
+   * Check if the texture is updated
+   * @return True if the texture is updated
+   */
+  [[nodiscard]] bool Updated()
+  {
+    if(mUpdated || IsNativeImage())
+    {
+      mUpdated = false; ///< 2023-06-07 tizen_7.0 branch only logic
+      return true;
+    }
+    return false;
+  }
 
 private:
   /**
@@ -150,6 +172,7 @@ private:
   uint16_t      mHeight;       ///< Height of the texture
   Type          mType : 3;     ///< Type of the texture
   bool          mHasAlpha : 1; ///< Whether the format has an alpha channel
+  bool          mUpdated : 1;  ///< Whether the texture is updated
 };
 
 } // namespace Render
index 0fa96f0..1d57e7d 100644 (file)
@@ -68,6 +68,11 @@ void TextureSet::SetSampler(uint32_t index, Render::Sampler* sampler)
   }
 
   mSamplers[index] = sampler;
+
+  if(index < static_cast<uint32_t>(mTextures.Size()) && mTextures[index])
+  {
+    mTextures[index]->SetUpdated(true);
+  }
 }
 
 void TextureSet::SetTexture(uint32_t index, Render::Texture* texture)
@@ -99,6 +104,7 @@ void TextureSet::SetTexture(uint32_t index, Render::Texture* texture)
   if(texture)
   {
     mHasAlpha |= texture->HasAlphaChannel();
+    texture->SetUpdated(true);
   }
 }