From: sunghyun kim Date: Thu, 19 Aug 2021 13:35:27 +0000 (+0900) Subject: Delete buffer after the resource of nativeImage is destroyed X-Git-Tag: submit/tizen/20211117.081222^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=31f17452feabc1faa2456db27955e139863a5b5a;p=platform%2Fcore%2Fuifw%2Fwidget-viewer-dali.git Delete buffer after the resource of nativeImage is destroyed Previously WidgetView deleted the previous buffer when updating the next buffer. But in this struct, the buffers in use may be cleared if the rendering is fast. Thus, To resolve these problems, it has been modified to erase the buffer using WidgetBuffer and EventCallback. Change-Id: I4e00bed378a98d735a06830ef2b77c6aefe4a4a7 --- diff --git a/widget_viewer_dali/internal/widget_view/widget_view_impl.cpp b/widget_viewer_dali/internal/widget_view/widget_view_impl.cpp index 166cb96..d165adf 100644 --- a/widget_viewer_dali/internal/widget_view/widget_view_impl.cpp +++ b/widget_viewer_dali/internal/widget_view/widget_view_impl.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #ifdef ECORE_WL2 #include @@ -177,6 +178,32 @@ static void OnSurfaceRemoved( const char *appid, const char *instance_id, const } // unnamed namespace + +WidgetBuffer::WidgetBuffer(wl_buffer* buffer, Dali::WidgetView::Internal::WidgetView& widgetview, Dali::NativeImageSourcePtr source) +: mBuffer(buffer), + mWidgetView(widgetview), + mImageSource(source) +{ +} + +WidgetBuffer::~WidgetBuffer() +{ + if(mImageSource) + { + Dali::DevelNativeImageSource::SetResourceDestructionCallback(*mImageSource,NULL); + } +} + +void WidgetBuffer::OnResourceDestruction() +{ + mWidgetView.DeleteBuffer(mBuffer, this); +} + +wl_buffer* WidgetBuffer::GetBuffer() const +{ + return mBuffer; +} + Dali::WidgetView::WidgetView WidgetView::New( const std::string& widgetId, const std::string& contentInfo, int width, int height, float updatePeriod ) { // Create the implementation, temporarily owned on stack @@ -1129,6 +1156,11 @@ void WidgetView::UpdateImageSource( tbm_surface_h source ) 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)); } bool WidgetView::OnTouch( Dali::Actor actor, const Dali::TouchEvent& event ) @@ -1210,6 +1242,28 @@ bool WidgetView::OnKeyEvent( const Dali::KeyEvent& event ) return false; } +void WidgetView::DeleteBuffer(wl_buffer* buffer, WidgetBuffer* widgetBuffer) +{ + bool findBuffer = false; + auto bufferInstance = std::find_if( mBufferContainer.begin(), + mBufferContainer.end(), + [widgetBuffer]( std::unique_ptr& instanceBuffer) + { return (instanceBuffer->GetBuffer() == widgetBuffer->GetBuffer()); } ); + if(bufferInstance != mBufferContainer.end()) + { + mBufferContainer.erase(bufferInstance); + findBuffer = true; + } + + if( findBuffer && mWatcherHandle != NULL ) + { + if( mRemoteSurface != NULL && buffer != NULL && tizen_remote_surface_get_version( mRemoteSurface ) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION ) + { + screen_connector_toolkit_dispose_buffer( mWatcherHandle , buffer ); + } + } +} + Vector3 WidgetView::GetNaturalSize() { Vector3 size; @@ -1255,9 +1309,16 @@ void WidgetView::CloseRemoteSurface() { if( mWatcherHandle != NULL ) { - if( mRemoteSurface != NULL && mBuffer != NULL && tizen_remote_surface_get_version( mRemoteSurface ) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION ) + if( mBufferContainer.size() ) { - screen_connector_toolkit_dispose_buffer( mWatcherHandle , mBuffer ); + for( std::vector>::iterator iter = mBufferContainer.begin(), endIter = mBufferContainer.end(); iter != endIter; ++iter ) + { + if( mRemoteSurface != NULL && (*iter)->GetBuffer() != NULL && tizen_remote_surface_get_version( mRemoteSurface ) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION ) + { + screen_connector_toolkit_dispose_buffer( mWatcherHandle , (*iter)->GetBuffer() ); + } + } + mBufferContainer.clear(); mBuffer = NULL; } @@ -1620,22 +1681,10 @@ void WidgetView::UpdateBuffer( struct tizen_remote_surface *surface, struct wl_b DALI_LOG_ERROR("tbm surface is NULL"); return; } - UpdateImageSource( tbmSurface ); - if( mBuffer != NULL && tizen_remote_surface_get_version( surface ) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION ) - { - if( mWatcherHandle != NULL ) - { - screen_connector_toolkit_dispose_buffer( mWatcherHandle , mBuffer ); - } - else - { - DALI_LOG_ERROR("WidgetView can't dispose buffer because mWatcherHandle is invalid. "); - } - } - - mRemoteSurface = surface; mBuffer = buffer; + UpdateImageSource( tbmSurface ); + mRemoteSurface = surface; } bool WidgetView::LaunchWidget() diff --git a/widget_viewer_dali/internal/widget_view/widget_view_impl.h b/widget_viewer_dali/internal/widget_view/widget_view_impl.h index 831618b..f952641 100644 --- a/widget_viewer_dali/internal/widget_view/widget_view_impl.h +++ b/widget_viewer_dali/internal/widget_view/widget_view_impl.h @@ -23,7 +23,6 @@ // EXTERNAL INCLUDES #include -#include #include #include #include @@ -31,6 +30,7 @@ #include #include #include +#include #include #include @@ -43,6 +43,49 @@ namespace WidgetView namespace Internal { +/** + * @brief WidgetBuffer is a class for managing resource the widget's buffer + */ +class WidgetBuffer +{ +public: + + /** + * @brief Construct a new Widget Buffer object + * + */ + WidgetBuffer( wl_buffer* buffer, Dali::WidgetView::Internal::WidgetView& widgetview, Dali::NativeImageSourcePtr source); + + /** + * @brief Destroy the Widget Buffer object + * + */ + virtual ~WidgetBuffer(); + + /** + * @brief Get the wayland buffer + * + * @return wl_buffer* + */ + wl_buffer* GetBuffer() const; + + /** + * @brief Callback for ResourceDestruction + * + */ + void OnResourceDestruction(); + + WidgetBuffer( const WidgetBuffer& ); + + WidgetBuffer& operator= ( const WidgetBuffer& ); + +private: + + wl_buffer* mBuffer; + Dali::WidgetView::Internal::WidgetView& mWidgetView; + Dali::NativeImageSourcePtr mImageSource; +}; + class WidgetView : public Toolkit::Internal::Control { public: @@ -205,6 +248,14 @@ public: // Internal API */ void UpdateImageSource( tbm_surface_h source ); + /** + * @brief Delete a buffer and its resource. + * + * @param buffer the wayland buffer + * @param widgetBuffer a pointer of widgetbuffer + */ + void DeleteBuffer(wl_buffer* buffer, WidgetBuffer* widgetBuffer); + /** * @brief Callback for touch event */ @@ -459,13 +510,13 @@ private: screen_connector_toolkit_h mWatcherHandle; ///< Handle for screen connector tizen_remote_surface* mRemoteSurface; ///< RemoteSurface for controlling events and visibillity wl_buffer* mBuffer; ///< Buffer for screen_connector. WidgetView need to release previous buffer + std::vector> mBufferContainer; bool mCreated; ///< Check whether widget instance is created or not bool mResizeRequired; ///< Check whether widget instance need to resize. bool mPaused; ///< Check whether widget is paused or not bool mPausedManually; ///< Check whether widget is paused or not by application bool mWindowVisible; ///< Check whether window is visible or not bool mPreviewEnable; ///< Check whether preview is enable or not - Dali::Property::Map mEffectPropertyMap; ///< Shader for effect // Notification for property change confirmation