Refactoring WidgetView for apply cornerRadius in WidgetView 78/323578/5 accepted/tizen_unified accepted/tizen_unified_x accepted/tizen/unified/20250515.075557 accepted/tizen/unified/20250610.081833 accepted/tizen/unified/20250611.121137 accepted/tizen/unified/x/20250515.094158 accepted/tizen/unified/x/20250610.082555 accepted/tizen/unified/x/20250611.211744
authorsunghyun kim <scholb.kim@samsung.com>
Wed, 30 Apr 2025 04:36:06 +0000 (13:36 +0900)
committersunghyun kim <scholb.kim@samsung.com>
Tue, 13 May 2025 05:21:02 +0000 (14:21 +0900)
This patch fetches WidgetView CornerRadius-related functionality from Tizen 7.0 to Tizen 10.0.
with this patch, the CornerRadius feature is available for both WidgetView and preview images.

the details of the patch are as follows.
- Apply CornerRadius to WidgetView(483a8569571b9de8f7cf46d8de5889d130ff0d01)
- Fix bug after applying cornerRadius(91f97edb70043fea02b2301f665d832c96c9bccd)
- Fix svace issue in cornerRadius(4bfb1eba63aa4b93985ad8bab21b450b0a2d1f76)
- Enable premultiply using CornerRadius (5f58a6e30525857212b7d7b29450c05f37a26e7e)
- Apply cornerRadius in preview(b83423334bf3fdbced594b5cd6703db12fb59c70)
- Call widget_instance_resize() only when the size is changed(ec308f28f466b1de1c19af907b158cfe79b39086)

Change-Id: I37249bfa598e78a26497af68ff1bd5de03f73863

widget_viewer_dali/internal/widget_view/widget_view_impl.cpp
widget_viewer_dali/internal/widget_view/widget_view_impl.h

index bb4ca1805f7e524ed952c337d4b6f453ad5f37c9..6bebe64fd24d3665be382b7dfb2a83aa9752b41b 100644 (file)
 #include <dali/public-api/render-tasks/render-task.h>
 #include <dali/public-api/actors/camera-actor.h>
 #include <dali-toolkit/public-api/visuals/visual-properties.h>
+#include <dali-toolkit/public-api/image-loader/image.h>
+#include <dali-toolkit/public-api/image-loader/image-url.h>
+#include <dali-toolkit/public-api/visuals/image-visual-properties.h>
 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
 #include <dali-toolkit/devel-api/controls/control-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
+#include <dali-toolkit/devel-api/visuals/visual-actions-devel.h>
 #include <dali/integration-api/debug.h>
 #include <dali/devel-api/adaptor-framework/event-thread-callback.h>
 #include <string.h>
@@ -296,7 +301,6 @@ bool WidgetView::InitializeWidgets()
     return false;
   }
 
-  SetPreviewImage();
   return true;
 }
 
@@ -325,46 +329,57 @@ bool WidgetView::SetUpdatePeriod()
 
 void WidgetView::SetPreviewImage()
 {
-  auto self = Self();
-  char* previewPath = NULL;
-  std::string previewImage;
-  widget_size_type_e sizeType;
+  if(mPreviewImageMap.Empty())
+  {
+    auto self = Self();
+    char* previewPath = NULL;
+    std::string previewImage;
+    widget_size_type_e sizeType;
 
-  // Preview image
-  widget_service_get_size_type( mWidgetWidth, mWidgetHeight, &sizeType );
+    // Preview image
+    widget_service_get_size_type( mWidgetWidth, mWidgetHeight, &sizeType );
+
+    previewPath = widget_service_get_preview_image_path( mWidgetId.c_str(), sizeType );
+    if( previewPath )
+    {
+      previewImage = previewPath;
+      free( previewPath );
+    }
+    else
+    {
+      previewImage = WIDGET_VIEW_RESOURCE_DEFAULT_IMG;
+    }
 
-  previewPath = widget_service_get_preview_image_path( mWidgetId.c_str(), sizeType );
-  if( previewPath )
+    mPreviewImageMap.Insert(Dali::Toolkit::Visual::Property::TYPE, Dali::Toolkit::Visual::IMAGE);
+    mPreviewImageMap.Insert(Dali::Toolkit::ImageVisual::Property::URL, previewImage);
+
+    DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::SetPreviewImage: preview image path = %s [%p]\n", previewImage.c_str(), this );
+  }
+
+  // Create WidgetVisual for WidgetView
+  Toolkit::Visual::Base widgetVisual = Toolkit::VisualFactory::Get().CreateVisual(mPreviewImageMap);
+  if(widgetVisual)
   {
-    previewImage = previewPath;
-    free( previewPath );
+    Dali::Toolkit::DevelControl::RegisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID, widgetVisual);
+    Dali::Toolkit::DevelControl::EnableCornerPropertiesOverridden(*this, widgetVisual, true);
   }
   else
   {
-    previewImage = WIDGET_VIEW_RESOURCE_DEFAULT_IMG;
+    Dali::Toolkit::DevelControl::UnregisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID);
   }
+}
 
-  DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::SetPreviewImage: preview image path = %s [%p]\n", previewImage.c_str(), this );
-
+void WidgetView::InitializeLayout()
+{
+  auto self = Self();
   mPreviewActor = Dali::Actor::New();
   mPreviewActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
   mPreviewActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
   mPreviewActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
-
-  mPreviewImage = Toolkit::ImageView::New( previewImage );
-  mPreviewImage.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
-  mPreviewImage.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
-  mPreviewImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
-
   self.SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
   self.SetProperty( Actor::Property::SIZE, Vector2(mWidgetWidth, mWidgetHeight));
-
   self.Add( mPreviewActor );
-  mPreviewActor.Add( mPreviewImage );
-}
 
-void WidgetView::InitializeLayout()
-{
   mStateTextActor = Dali::Actor::New();
   mStateTextActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
   mStateTextActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
@@ -396,6 +411,7 @@ void WidgetView::InitializeLayout()
   mStateTextActor.Add( mRetryText );
   mRetryText.SetProperty( Actor::Property::VISIBLE, false );
 
+  SetPreviewImage();
 }
 
 void WidgetView::InitializeEvents()
@@ -606,10 +622,14 @@ bool WidgetView::CancelTouchEvent()
 
 void WidgetView::EnablePreview( bool visible )
 {
-  if( mPreviewImage && IsPreviewEnable() != visible )
+  if( IsPreviewEnable() != visible )
   {
     mPreviewEnable = visible;
-    mPreviewImage.SetProperty( Actor::Property::VISIBLE, visible );
+    if(visible)
+    {
+      SetPreviewImage();
+    }
+    Dali::Toolkit::DevelControl::EnableVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID, visible);
   }
 }
 
@@ -694,22 +714,28 @@ bool WidgetView::IsKeepWidgetSize()
 
 void WidgetView::CreateWidgetRenderer()
 {
-  Dali::Any source;
-  mImageSource = Dali::NativeImageSource::New( source );
-  Dali::Texture texture = Dali::Texture::New( *mImageSource );
+  // If we use EffectMap, use the existing custom shader and render method rather than visual
+  if(!mEffectPropertyMap.Empty())
+  {
+    // We don't need WidgetVisual anymore, so we can delete it.
+    Dali::Toolkit::DevelControl::UnregisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID);
 
-  Dali::Geometry geometry = CreateQuadGeometry();
-  Dali::Shader shader = CreateShader();
-  mRenderer = Dali::Renderer::New( geometry, shader );
+    Dali::Any source;
+    mImageSource = Dali::NativeImageSource::New( source );
+    Dali::Texture texture = Dali::Texture::New( *mImageSource );
+    Dali::Geometry geometry = CreateQuadGeometry();
+    Dali::Shader shader = CreateShader();
+    mRenderer = Dali::Renderer::New( geometry, shader );
 
-  Dali::TextureSet textureSet = Dali::TextureSet::New();
-  textureSet.SetTexture( 0u, texture );
-  mRenderer.SetTextures( textureSet );
+    Dali::TextureSet textureSet = Dali::TextureSet::New();
+    textureSet.SetTexture( 0u, texture );
+    mRenderer.SetTextures( textureSet );
 
-  //EFL app should be pre multiplied image.
-  mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true );
+    //EFL app should be pre multiplied image.
+    mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true );
 
-  Self().AddRenderer( mRenderer );
+    Self().AddRenderer( mRenderer );
+  }
 
   // Disable preview and text
   ShowLoadingState( false );
@@ -728,17 +754,18 @@ void WidgetView::RemoveWidgetRenderer()
 {
   if(mIsReadyToRender)
   {
-    if( mRenderer )
+    if(mRenderer)
     {
       Self().RemoveRenderer( mRenderer );
+      mRenderer.Reset();
+    }
 
-      ShowRetryState( true );
+    ShowRetryState( true );
 
-      Dali::WidgetView::WidgetView handle( GetOwner() );
-      mWidgetDeletedSignal.Emit( handle );
+    Dali::WidgetView::WidgetView handle( GetOwner() );
+    mWidgetDeletedSignal.Emit( handle );
 
-      mIsReadyToRender = false;
-    }
+    mIsReadyToRender = false;
   }
 
   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::RemoveWidgetRenderer: Widget image is removed. [%p]\n", this );
@@ -1269,20 +1296,48 @@ bool WidgetView::IsReadyToRender()
 
 void WidgetView::UpdateImageSource( tbm_surface_h source )
 {
+  Toolkit::Visual::Base widgetVisual = Dali::Toolkit::DevelControl::GetVisual(*this,  Dali::WidgetView::WidgetView::Property::WIDGET_ID);
+  if(widgetVisual && mImageSource)
+  {
+    Any nativeSource(source);
+    mImageSource->SetSource(nativeSource);
+    Dali::Stage::GetCurrent().KeepRendering(0.0f);
+    return;
+  }
+
   mImageSource = Dali::NativeImageSource::New( source );
-  Dali::Texture texture = Dali::Texture::New( *mImageSource );
 
   if( mRenderer )
   {
+    Dali::Texture texture = Dali::Texture::New( *mImageSource );
     Dali::TextureSet textureSet = mRenderer.GetTextures();
     textureSet.SetTexture( 0u, texture );
     mRenderer.SetProperty( Renderer::Property::BLEND_PRE_MULTIPLIED_ALPHA, true );
+
+    // Register a callback using WidgetBuffer class
+    auto widgetBuffer = new WidgetBuffer(mBuffer,*this,mImageSource);
+    Dali::DevelNativeImageSource::SetResourceDestructionCallback(*mImageSource, new EventThreadCallback(MakeCallback(widgetBuffer, &WidgetBuffer::OnResourceDestruction)));
+    mBufferContainer.push_back(std::unique_ptr<WidgetBuffer>(widgetBuffer));
   }
+  else
+  {
+    // Create WidgetVisual for new tbm surface
+    Dali::Toolkit::ImageUrl nativeImageUrl = Dali::Toolkit::Image::GenerateUrl(mImageSource, true);
 
-  // Register a callback using WidgetBuffer class
-  auto widgetBuffer = new WidgetBuffer(mBuffer,*this,mImageSource);
-  Dali::DevelNativeImageSource::SetResourceDestructionCallback(*mImageSource, new EventThreadCallback(MakeCallback(widgetBuffer, &WidgetBuffer::OnResourceDestruction)));
-  mBufferContainer.push_back(std::unique_ptr<WidgetBuffer>(widgetBuffer));
+    Property::Map propertyMap;
+    propertyMap.Insert(Dali::Toolkit::Visual::Property::TYPE, Dali::Toolkit::Visual::IMAGE);
+    propertyMap.Insert(Dali::Toolkit::ImageVisual::Property::URL, nativeImageUrl.GetUrl());
+    Dali::Toolkit::Visual::Base widgetVisual= Toolkit::VisualFactory::Get().CreateVisual(propertyMap);
+    if(widgetVisual)
+    {
+      Dali::Toolkit::DevelControl::RegisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID, widgetVisual);
+      Dali::Toolkit::DevelControl::EnableCornerPropertiesOverridden(*this, widgetVisual, true);
+    }
+    else
+    {
+      Dali::Toolkit::DevelControl::UnregisterVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID);
+    }
+  }
 }
 
 bool WidgetView::OnTouch( Dali::Actor actor, const Dali::TouchEvent& event )
@@ -1446,7 +1501,7 @@ void WidgetView::CloseRemoteSurface()
 {
   if( mWatcherHandle != NULL )
   {
-    if( mBufferContainer.size() )
+    if( mBufferContainer.size() > 0 )
     {
       for( std::vector<std::unique_ptr<WidgetBuffer>>::iterator iter = mBufferContainer.begin(), endIter = mBufferContainer.end(); iter != endIter; ++iter )
       {
@@ -1456,9 +1511,21 @@ void WidgetView::CloseRemoteSurface()
         }
       }
       mBufferContainer.clear();
-      mBuffer = NULL;
+    }
+    else
+    {
+      // delete previous buffer. this is widget visual case
+      if(mBuffer)
+      {
+        if( mRemoteSurface != NULL && mBuffer != NULL && tizen_remote_surface_get_version( mRemoteSurface ) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION )
+        {
+          screen_connector_toolkit_dispose_buffer( mWatcherHandle , mBuffer );
+        }
+      }
     }
 
+    mBuffer = NULL;
+
     screen_connector_toolkit_remove( mWatcherHandle );
     mWatcherHandle = NULL;
     mRemoteSurface = NULL;
@@ -1468,9 +1535,13 @@ void WidgetView::CloseRemoteSurface()
 
 void WidgetView::ShowLoadingState( bool show )
 {
-  if( mPreviewImage && IsPreviewEnable() )
+  if( IsPreviewEnable() )
   {
-    mPreviewImage.SetProperty( Actor::Property::VISIBLE, show );
+    if(show)
+    {
+      SetPreviewImage();
+    }
+    Dali::Toolkit::DevelControl::EnableVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID, show);
   }
 
   if( mLoadingText && IsLoadingTextVisible() )
@@ -1483,9 +1554,9 @@ void WidgetView::ShowLoadingState( bool show )
 
 void WidgetView::ShowRetryState( bool show )
 {
-  if( mPreviewImage && IsPreviewEnable() )
+  if( IsPreviewEnable() )
   {
-    mPreviewImage.SetProperty( Actor::Property::VISIBLE, false );
+    Dali::Toolkit::DevelControl::EnableVisual(*this, Dali::WidgetView::WidgetView::Property::WIDGET_ID, false);
   }
 
   if( mRetryText && IsRetryTextVisible() )
@@ -1827,6 +1898,16 @@ void WidgetView::UpdateBuffer( struct tizen_remote_surface *surface, struct wl_b
     return;
   }
 
+  // WidgetVisual can't use buffer container because of flickering issue
+  // To Avoid it, we dispose mBuffer before get a new buffer
+  if( mWatcherHandle != NULL && mBufferContainer.size() == 0)
+  {
+    if( mRemoteSurface != NULL && mBuffer != NULL && tizen_remote_surface_get_version( mRemoteSurface ) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION )
+    {
+      screen_connector_toolkit_dispose_buffer( mWatcherHandle , mBuffer );
+    }
+  }
+
   mBuffer = buffer;
   UpdateImageSource( tbmSurface );
   mRemoteSurface = surface;
@@ -1870,7 +1951,12 @@ void WidgetView::ResizeWidget(int width, int height)
     // in this case, we just save the size and do resize when instance is created.
     if( mCreated )
     {
-      widget_instance_resize(mInstanceId.c_str(), width, height);
+      if( (mWidgetWidth !=  width) || (mWidgetHeight != height))
+      {
+        widget_instance_resize(mInstanceId.c_str(), width, height);
+        mWidgetWidth = width;
+        mWidgetHeight = height;
+      }
     }
     else
     {
@@ -1881,7 +1967,7 @@ void WidgetView::ResizeWidget(int width, int height)
   }
   else
   {
-     DALI_LOG_RELEASE_INFO("widget instance is not resized(%dx%d), because KEEP_WIDGET_SIZE is true \n", width, height);
+     DALI_LOG_RELEASE_INFO("widget instance is not resized(%dx%d), because KEEP_WIDGET_SIZE is true \n", mWidgetWidth, mWidgetHeight);
   }
 }
 
index f2663bcbcd8c32432ebc633ebaf0329f448986f7..57846af6374fbf7aeeb6bcd7f954534a7738360a 100644 (file)
@@ -568,7 +568,6 @@ private:
   int mPid;
   float mUpdatePeriod;
 
-  Toolkit::ImageView mPreviewImage;          ///< Preview image
   Toolkit::TextLabel mLoadingText;           ///< Loading text
   Toolkit::TextLabel mRetryText;             ///< Retry text
   Dali::Actor mPreviewActor;                 ///< Preview Actor
@@ -592,6 +591,7 @@ private:
   bool mKeepWidgetSize;                      ///< Check whether widget instance keep it's size or not
   bool mIsReadyToRender;                     ///< Check whether widget is ready to render or not
   Dali::Property::Map mEffectPropertyMap;    ///< Shader for effect
+  Dali::Property::Map mPreviewImageMap;      ///< Property map for preview image
 
   // Notification for property change confirmation
   Dali::PropertyNotification mPositionUpdateNotification;