Release tbm surface on block state 80/231680/4
authorDaehyeon Jung <darrenh.jung@samsung.com>
Thu, 23 Apr 2020 10:14:51 +0000 (19:14 +0900)
committerDaehyeon Jung <darrenh.jung@samsung.com>
Fri, 24 Apr 2020 10:45:06 +0000 (19:45 +0900)
Change-Id: I9ac996016fbc7dc69029c4e88fbdff40e807b7c0
Signed-off-by: Daehyeon Jung <darrenh.jung@samsung.com>
screen_connector_remote_surface/handle.h
screen_connector_remote_surface/remote_surface.cc
screen_connector_remote_surface_evas/remote_surface_mixed.cc
screen_connector_remote_surface_evas/remote_surface_mixed_internal.h
screen_connector_remote_surface_evas/remote_surface_watcher.cc
screen_connector_remote_surface_evas/remote_surface_watcher_implementation.h
screen_connector_remote_surface_evas/watcher_image.cc
screen_connector_remote_surface_evas/watcher_image_internal.h

index 535e8f95643da73ee8254b676a5b5d023169b981..f129713b719f1559dd73f112277197e88d74b679 100644 (file)
@@ -71,6 +71,16 @@ class EXPORT_API WlSurface : public Handle<struct wl_surface*> {
   virtual ~WlSurface() { }
 };
 
+class EXPORT_API TbmSurface : public Handle<tbm_surface_h> {
+ public:
+  TbmSurface(tbm_surface_h raw, bool owner) :
+      Handle<tbm_surface_h>(raw, owner) { }
+
+  virtual ~TbmSurface() {
+    tbm_surface_internal_unref(GetRaw());
+  }
+};
+
 }  // namespace screen_connector
 
 #endif  // SCREEN_CONNECTOR_REMOTE_SURFACE_HANDLE_H_
index d24ab9cef9c25b0f75d016d97843ee568ca6f73f..113b57f0e2ab839d31a1dec11be03fd3a78c459b 100644 (file)
@@ -290,6 +290,7 @@ void RemoteSurface::SetChangedEventFilter(ChangedEventFilter filter) {
 }
 
 void RemoteSurface::SetBlock(bool is_block) {
+  LOGD("SetBlock %s:%d", GetAppId().c_str(), is_block);
   impl_->block_ = is_block;
 }
 
index 37642c85bd8b4e3cbc57b15446813255b2450dac..7e043731b5ff5099ae0adbed50824f3e79334ab7 100644 (file)
@@ -95,6 +95,7 @@ void RemoteSurfaceMixed::OnBufferChanged(int type,
 }
 
 void RemoteSurfaceMixed::ForceToUpdateWatcher() {
+  LOGD("ForceToUpdate %s:%s", GetAppId().c_str(), GetInstId().c_str());
   if (!is_file_) {
     if (img_tbm_.get() == nullptr) {
       LOGE("tbm surface is not ready");
@@ -110,6 +111,14 @@ void RemoteSurfaceMixed::ForceToUpdateWatcher() {
   }
 }
 
+void RemoteSurfaceMixed::ReleaseBuffer() {
+  if (img_tbm_.get() != nullptr) {
+    LOGD("tbm surface release buffer %s:%s", GetAppId().c_str(),
+        GetInstId().c_str());
+    img_tbm_->ReleaseWlBuffer();
+  }
+}
+
 void RemoteSurfaceMixed::SetChangedEventFilter(
     RemoteSurface::ChangedEventFilter filter) {
   RemoteSurface::SetChangedEventFilter(filter);
index d8edad3c6f7f815ded0162c47e4f12d183d0c0fc..de1f2f924b44c72568d79e29d64297550f2fd868 100644 (file)
@@ -45,6 +45,7 @@ class RemoteSurfaceMixed : public RemoteSurface {
   void OnBufferChanged(int type, std::shared_ptr<WlBuffer> tbm, int fd,
                        uint32_t size, uint32_t time) override;
   void ForceToUpdateWatcher();
+  void ReleaseBuffer();
 
  private:
   IWatcherEvent* listener_;
index 5ed735577c00ebb4f4308897f05314968c148d29..194def5e964ef45868b931218643e28a9e2e7f66 100644 (file)
@@ -103,6 +103,16 @@ void RemoteSurfaceWatcher::Impl::UpdateFocusedSurface() {
   }
 }
 
+void RemoteSurfaceWatcher::Impl::ReleaseFocusedSurfaceBuffer() {
+  if (focused_only_) {
+    for (auto& i : surfaces_) {
+      if (i->GetInstId() == focused_inst_id_) {
+          i->ReleaseBuffer();
+      }
+    }
+  }
+}
+
 void RemoteSurfaceWatcher::Impl::OnAppFocused(const std::string& app_id,
                                               const std::string& inst_id,
                                               const int pid,
@@ -152,6 +162,8 @@ void RemoteSurfaceWatcher::SetChangedEventFilter(
   for (auto& i : impl_->surfaces_) {
     i->SetChangedEventFilter(filter);
   }
+
+
 }
 
 int RemoteSurfaceWatcher::SetRemoteRender() {
@@ -164,6 +176,9 @@ int RemoteSurfaceWatcher::SetRemoteRender() {
 int RemoteSurfaceWatcher::SetBlock(bool enable) {
   impl_->block_update_ = enable;
   impl_->UpdateFocusedSurface();
+  if (enable)
+    impl_->ReleaseFocusedSurfaceBuffer();
+
   return 0;
 }
 
index f271f5a27e3bedd695392778bd33dc4b30c741dd..e68fe87d8b91ebfdd1937741ff304de107331990 100644 (file)
@@ -49,6 +49,7 @@ class RemoteSurfaceWatcher::Impl : AulHandle::IEventListener {
       std::shared_ptr<EvasObject> viewer_win,
       bool focused_only, bool mock = false);
   void UpdateFocusedSurface();
+  void ReleaseFocusedSurfaceBuffer();
 
  private:
   friend class RemoteSurfaceWatcher;
index 91935937a8275fe188b0b6f3a8aec05460f87c5b..866d56beac4ed514315a41e778fdc327cae1fd38 100644 (file)
 
 #include "screen_connector_remote_surface_evas/watcher_image_internal.h"
 
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "SC_RS_WI"
+
 #define SC_TOOLKIT_HANDLE_TAG "SC_TOOLKIT_HANDLE_TAG"
 
 namespace screen_connector {
@@ -54,7 +59,71 @@ void WatcherImage::UpdateTbm(std::shared_ptr<WlBuffer> tbm) {
 void WatcherImage::ClearTbm() {
      /* set null to previous object for the tbm type */
     evas_object_image_native_surface_set(GetRaw(), NULL);
-    prev_buf_.reset();
+    if (prev_buf_.get() != nullptr) {
+      prev_buf_.reset();
+    } else {
+      prev_surf_.reset();
+    }
+}
+
+void WatcherImage::ReleaseWlBuffer() {
+  if (prev_buf_.get() == nullptr)
+    return;
+
+  LOGD("ReleaseWlBuffer() start");
+
+  Evas_Native_Surface* ns;
+  tbm_surface_h surface;
+  int ret;
+  tbm_surface_info_s info = {0, };
+  tbm_surface_info_s info2;
+  void* source_data;
+
+  ns = evas_object_image_native_surface_get(GetRaw());
+  if (ns == nullptr) // image_ is file
+    return;
+
+  surface = (tbm_surface_h)ns->data.tbm.buffer;
+  if (surface == nullptr)
+    return;
+
+  ret = tbm_surface_map(surface, TBM_SURF_OPTION_READ, &info);
+  if (ret != TBM_SURFACE_ERROR_NONE)
+    return;
+
+  source_data = info.planes[0].ptr;
+  if (source_data == nullptr) {
+    tbm_surface_unmap(surface);
+    return;
+  }
+
+  prev_surf_.reset(new TbmSurface(tbm_surface_create(info.width, info.height, info.format), true));
+  if (prev_surf_.get() == nullptr) {
+    tbm_surface_unmap(surface);
+    return;
+  }
+
+  ret = tbm_surface_map(prev_surf_.get()->GetRaw(), TBM_SURF_OPTION_WRITE, &info2);
+  if (ret != TBM_SURFACE_ERROR_NONE) {
+    tbm_surface_unmap(surface);
+    return;
+  }
+
+  memset(info2.planes[0].ptr, 0, info2.planes[0].size);
+  memcpy(info2.planes[0].ptr, source_data, info.planes[0].size);
+
+  Evas_Native_Surface ns2;
+  memset(&ns2, 0, sizeof(Evas_Native_Surface));
+  ns2.version = EVAS_NATIVE_SURFACE_VERSION;
+  ns2.type = EVAS_NATIVE_SURFACE_TBM;
+  ns2.data.tbm.buffer = prev_surf_.get()->GetRaw();
+  evas_object_image_native_surface_set(GetRaw(), &ns2);
+
+  tbm_surface_unmap(surface);
+  tbm_surface_unmap(prev_surf_.get()->GetRaw());
+  prev_buf_.reset();
+
+  LOGD("ReleaseWlBuffer() end");
 }
 
 void WatcherImage::UpdateFile(int fd, uint32_t size) {
index 31fb4f31a4534a56016822ab918184436db921dd..a1d8bf0c7980db1f4f23f14399a935096d58bbe1 100644 (file)
@@ -33,10 +33,12 @@ class WatcherImage : public EvasObject {
 
   void UpdateTbm(std::shared_ptr<WlBuffer> tbm);
   void ClearTbm();
+  void ReleaseWlBuffer();
   void UpdateFile(int fd, uint32_t size);
 
  private:
   std::shared_ptr<WlBuffer> prev_buf_;
+  std::unique_ptr<TbmSurface> prev_surf_;
 };
 
 }  // namespace screen_connector