1 // Copyright 2009-2020 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 #pragma once
5 
6 #include <thread>
7 // ospray
8 #include "common/Future.h"
9 #include "fb/FrameBuffer.h"
10 
11 namespace ospray {
12 namespace mpi {
13 
14 /* An asynchronous render task which runs on a thread independent
15  * of the tasking system's thread pool
16  */
17 struct ThreadedRenderTask : public Future
18 {
19   ThreadedRenderTask(FrameBuffer *, std::function<float()> fcn);
20   ~ThreadedRenderTask() override;
21 
22   bool isFinished(OSPSyncEvent event = OSP_TASK_FINISHED) override;
23 
24   void wait(OSPSyncEvent event) override;
25   void cancel() override;
26   float getProgress() override;
27 
28   float getTaskDuration() override;
29 
30  private:
31   Ref<FrameBuffer> fb;
32   std::atomic<float> taskDuration{0.f};
33   std::atomic<bool> finished;
34   std::thread thread;
35 };
36 
37 // Inlined definitions //////////////////////////////////////////////////////
38 
ThreadedRenderTask(FrameBuffer * _fb,std::function<float ()> fcn)39 inline ThreadedRenderTask::ThreadedRenderTask(
40     FrameBuffer *_fb, std::function<float()> fcn)
41     : fb(_fb), finished(false)
42 {
43   thread = std::thread([this, fcn]() {
44     taskDuration = fcn();
45     finished = true;
46   });
47 }
48 
~ThreadedRenderTask()49 inline ThreadedRenderTask::~ThreadedRenderTask()
50 {
51   if (thread.joinable()) {
52     thread.join();
53   }
54 }
55 
isFinished(OSPSyncEvent event)56 inline bool ThreadedRenderTask::isFinished(OSPSyncEvent event)
57 {
58   return finished == true || fb->getLatestCompleteEvent() >= event;
59 }
60 
wait(OSPSyncEvent event)61 inline void ThreadedRenderTask::wait(OSPSyncEvent event)
62 {
63   if (event == OSP_TASK_FINISHED) {
64     while (!finished) {
65       std::this_thread::yield();
66     }
67   } else
68     fb->waitForEvent(event);
69 }
70 
cancel()71 inline void ThreadedRenderTask::cancel()
72 {
73   fb->cancelFrame();
74 }
75 
getProgress()76 inline float ThreadedRenderTask::getProgress()
77 {
78   return fb->getCurrentProgress();
79 }
80 
getTaskDuration()81 inline float ThreadedRenderTask::getTaskDuration()
82 {
83     return taskDuration.load();
84 }
85 
86 } // namespace mpi
87 } // namespace ospray
88