[TTVD] Use GPU workaround to disable parallel copy 86/313986/2
authorJakub Gajownik <j.gajownik2@samsung.com>
Mon, 1 Jul 2024 10:28:41 +0000 (12:28 +0200)
committerj.gajownik2 <j.gajownik2@samsung.com>
Wed, 3 Jul 2024 16:41:46 +0000 (18:41 +0200)
Before this CL, parallel access to single buffer was behind
static compile-time check of platform version. It works for
UWE, but behavior for OSU is invalid. Instead, after this
patch version checking is done in runtime.

Bug: https://jira-eu.sec.samsung.net/browse/VDGAME-517
Change-Id: I2900545ee39310a5c9b7021f45ef5892affd7278
Signed-off-by: Jakub Gajownik <j.gajownik2@samsung.com>
gpu/config/gpu_driver_bug_list.json
gpu/config/gpu_workaround_list.txt
media/filters/tizen/ttvd_decoded_frame.cc
media/filters/tizen/ttvd_decoded_frame.h
media/filters/tizen/ttvd_video_decoder_impl.cc

index d2b3873c755a49a78a1f7a1609cff43171e80df8..0a946007e26b6a5cea983353b2a6925745e70a4f 100644 (file)
       "features": [
         "ttvd_disable_faster_decoder_selection"
       ]
+    },
+    {
+      "id": 412,
+      "description": "Old Tizen TV platform might crash (SIGBUS) due to parallel access to single mapped buffer",
+      "machine_model_version": {
+        "op": "<=",
+        "value": "21"
+      },
+      "features": [
+        "ttvd_disable_buffer_parallel_copy"
+      ]
     }
   ]
 }
index 96614eee5db1138f9d578e31bd0398762c3fa87f..ffc73fa5be239ca6869e542fe40ea48f6e4754af 100644 (file)
@@ -125,6 +125,7 @@ rotation_180_degrees_workaround
 round_down_uniform_bind_buffer_range_size
 ttvd_force_first_frame_rendering
 ttvd_force_frames_rendering
+ttvd_disable_buffer_parallel_copy
 ttvd_disable_faster_decoder_selection
 scalarize_vec_and_mat_constructor_args
 set_zero_level_before_generating_mipmap
index f29be4c3b0696248b39aea274400d717cd0c8645..b7ce66ce5ed7df9e63b291943393589a639cbdaf 100644 (file)
@@ -31,10 +31,11 @@ void TTvdDecodedFrame::CreateAsync(
     base::OnceCallback<void(scoped_refptr<TTvdDecodedFrame>)> result_cb,
     base::RepeatingCallback<void(base::WeakPtr<TTvdDecodedFrame>,
                                  OverlayRenderCb)> render_cb,
-    base::RepeatingCallback<void(scoped_refptr<TTvdDecodedFrame>)> release_cb) {
+    base::RepeatingCallback<void(scoped_refptr<TTvdDecodedFrame>)> release_cb,
+    const gpu::GpuDriverBugWorkarounds* workarounds) {
   scoped_refptr<TTvdDecodedFrame> result(new TTvdDecodedFrame(
       coded_size, natural_size, std::move(command_buffer_helper),
-      std::move(gpu_task_runner), std::move(release_cb)));
+      std::move(gpu_task_runner), std::move(release_cb), workarounds));
   TTvdDecodedFrame* raw_result = result.get();
   raw_result->InitializeGpuPart(
       allocate_memory, plane_collection,
@@ -47,13 +48,15 @@ TTvdDecodedFrame::TTvdDecodedFrame(
     gfx::Size natural_size,
     scoped_refptr<CommandBufferHelper> command_buffer_helper,
     scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
-    base::RepeatingCallback<void(scoped_refptr<TTvdDecodedFrame>)> release_cb)
+    base::RepeatingCallback<void(scoped_refptr<TTvdDecodedFrame>)> release_cb,
+    const gpu::GpuDriverBugWorkarounds* workarounds)
     : natural_size_(natural_size),
       picture_size_(coded_size),
       decoded_size_(coded_size),
       command_buffer_helper_(std::move(command_buffer_helper)),
       gpu_task_runner_(std::move(gpu_task_runner)),
-      release_cb_(std::move(release_cb)) {
+      release_cb_(std::move(release_cb)),
+      workarounds_(workarounds) {
   weak_this_ = weak_factory_.GetWeakPtr();
 }
 
@@ -210,25 +213,25 @@ void TTvdDecodedFrame::CopyDataFrom(const NV12Data& nv12_data) {
   }
 
   TRACE_EVENT0("gpu", "TTvdDecodedFrame.Copy");
-#if TIZEN_VERSION_AT_LEAST(6, 5, 0)
-  if (!CopyFrameDataParallel(nv12_data, pixmap_.get(), picture_size_)) {
-    TIZEN_MEDIA_LOG(ERROR) << "Error while copying frame data";
-  }
-#else
-  // When writing into the same buffer in parallel from different threads,
-  // like it's possible in |CopyFrameDataParallel| method, there were some
-  // weird crashes (SIGBUS). It always occured from side thread that tries
-  // to copy data.
-  // Now we won't be using heavy parallelization, possibly splitting single
-  // plane into multiple copying task. However, copying large video frame might
-  // be slow, so instead stick with processing each plane separately to speed up
-  // this task.
-  // TODO(VDGAME-485) There should be area to optimize it, possible with
-  //                  mapping with offset or even get rid of this issue.
-  if (!CopyNv12FramePlanesParallel(nv12_data, pixmap_.get(), picture_size_)) {
-    TIZEN_MEDIA_LOG(ERROR) << "Error while copying frame data";
+  if (workarounds_->ttvd_disable_buffer_parallel_copy) {
+    // When writing into the same buffer in parallel from different threads,
+    // like it's possible in |CopyFrameDataParallel| method, there were some
+    // weird crashes (SIGBUS). It always occured from side thread that tries
+    // to copy data.
+    // Now we won't be using heavy parallelization, possibly splitting single
+    // plane into multiple copying task. However, copying large video frame
+    // might be slow, so instead stick with processing each plane separately
+    // to speed up this task.
+    // TODO(VDGAME-485) There should be area to optimize it, possible with
+    //                  mapping with offset or even get rid of this issue.
+    if (!CopyNv12FramePlanesParallel(nv12_data, pixmap_.get(), picture_size_)) {
+      TIZEN_MEDIA_LOG(ERROR) << "Error while copying frame data";
+    }
+  } else {
+    if (!CopyFrameDataParallel(nv12_data, pixmap_.get(), picture_size_)) {
+      TIZEN_MEDIA_LOG(ERROR) << "Error while copying frame data";
+    }
   }
-#endif  // TIZEN_VERSION_AT_LEAST(6, 5, 0)
 }
 
 void TTvdDecodedFrame::ClearLazyData() {
index 824fab9b3069f8e792bb9cdb5836981ee932dba4..ef1f969293e18a93afdbf48dcb8a9afa2b58ac75 100644 (file)
@@ -17,6 +17,7 @@
 #include "base/unguessable_token.h"
 #include "command_buffer/common/mailbox.h"
 #include "command_buffer/common/sync_token.h"
+#include "gpu/config/gpu_driver_bug_workarounds.h"
 #include "gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h"
 #include "gpu/ipc/service/shared_image_stub.h"
 #include "media/base/video_frame.h"
@@ -43,8 +44,8 @@ class TTvdDecodedFrame : public base::RefCountedThreadSafe<TTvdDecodedFrame> {
       base::OnceCallback<void(scoped_refptr<TTvdDecodedFrame>)> result_cb,
       base::RepeatingCallback<void(base::WeakPtr<TTvdDecodedFrame>,
                                    OverlayRenderCb)> render_cb,
-      base::RepeatingCallback<void(scoped_refptr<TTvdDecodedFrame>)>
-          release_cb);
+      base::RepeatingCallback<void(scoped_refptr<TTvdDecodedFrame>)> release_cb,
+      const gpu::GpuDriverBugWorkarounds* workarounds);
   ~TTvdDecodedFrame();
 
   scoped_refptr<VideoFrame> CreateVideoFrame(base::TimeDelta timestamp);
@@ -83,8 +84,8 @@ class TTvdDecodedFrame : public base::RefCountedThreadSafe<TTvdDecodedFrame> {
       gfx::Size natural_size,
       scoped_refptr<CommandBufferHelper> command_buffer_helper,
       scoped_refptr<base::SingleThreadTaskRunner> gpu_task_runner,
-      base::RepeatingCallback<void(scoped_refptr<TTvdDecodedFrame>)>
-          release_cb);
+      base::RepeatingCallback<void(scoped_refptr<TTvdDecodedFrame>)> release_cb,
+      const gpu::GpuDriverBugWorkarounds* workarounds);
 
   void VideoFrameDestroyed(const gpu::SyncToken& sync_token);
 
@@ -142,6 +143,8 @@ class TTvdDecodedFrame : public base::RefCountedThreadSafe<TTvdDecodedFrame> {
   std::unique_ptr<TTvdDecodedFrameOnGpu> frame_on_gpu_;
   base::RepeatingCallback<void(scoped_refptr<TTvdDecodedFrame>)> release_cb_;
 
+  const gpu::GpuDriverBugWorkarounds* workarounds_;
+
   base::WeakPtr<TTvdDecodedFrame> weak_this_;
   base::WeakPtrFactory<TTvdDecodedFrame> weak_factory_{this};
 };
index 5d59237087945d43fc80c05e5073387060e5d7f0..63904ccd2b235153ddff779ddf5492fa4c1131d7 100644 (file)
@@ -1204,7 +1204,8 @@ scoped_refptr<TTvdDecodedFrame> TTvdVideoDecoderImpl::CreateTTvdDecodedFrame() {
       base::BindRepeating(&TTvdVideoDecoderImpl::RenderToOverlay,
                           weak_factory_.GetWeakPtr()),
       base::BindRepeating(&TTvdVideoDecoderImpl::ReleasePicture,
-                          weak_factory_.GetWeakPtr()));
+                          weak_factory_.GetWeakPtr()),
+      &workarounds_);
   event.Wait();
   TIZEN_MEDIA_LOG(VERBOSE) << "Decoding results: " << decoding_results_.size()
                            << ", pool size: "
@@ -1354,7 +1355,8 @@ void TTvdVideoDecoderImpl::CreateLazyTTvdDecodedFrame() {
       base::BindRepeating(&TTvdVideoDecoderImpl::RenderToOverlay,
                           weak_factory_.GetWeakPtr()),
       base::BindRepeating(&TTvdVideoDecoderImpl::ReleasePicture,
-                          weak_factory_.GetWeakPtr()));
+                          weak_factory_.GetWeakPtr()),
+      &workarounds_);
 }
 
 void TTvdVideoDecoderImpl::OnTTvdDecodedFrame(