]> git.sesse.net Git - casparcg/blob - core/mixer/gpu/fence.cpp
2.0. Refactoring.
[casparcg] / core / mixer / gpu / fence.cpp
1 #include "../../StdAfx.h"\r
2 \r
3 #include "fence.h"\r
4 \r
5 #include "ogl_device.h"\r
6 \r
7 #include <common/gl/gl_check.h>\r
8 \r
9 namespace caspar { namespace core {\r
10 \r
11 struct fence::implementation\r
12 {\r
13         GLsync sync_;\r
14 \r
15         implementation() : sync_(0){}\r
16         ~implementation(){glDeleteSync(sync_);}\r
17                 \r
18         void set()\r
19         {\r
20                 glDeleteSync(sync_);\r
21                 sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);\r
22         }\r
23 \r
24         bool ready() const\r
25         {\r
26                 if(!sync_)\r
27                         return true;\r
28 \r
29                 GLsizei length = 0;\r
30                 int values[] = {0};\r
31 \r
32                 GL(glGetSynciv(sync_, GL_SYNC_STATUS, 1, &length, values));\r
33 \r
34                 return values[0] == GL_SIGNALED;\r
35         }\r
36 \r
37         void wait(ogl_device& ogl)\r
38         {       \r
39                 int delay = 0;\r
40                 if(!ogl.invoke([this]{return ready();}, high_priority))\r
41                 {\r
42                         while(!ogl.invoke([this]{return ready();}, normal_priority))\r
43                         {\r
44                                 delay += 3;\r
45                                 Sleep(3);\r
46                         }\r
47                 }\r
48 \r
49                 if(delay > 0)\r
50                         CASPAR_LOG(warning) << L"[fence] Performance warning. GPU was not ready during requested host read-back. Delayed by atleast: " << delay << L" ms.";\r
51         }\r
52 };\r
53         \r
54 fence::fence() \r
55 {\r
56         if(GLEW_ARB_sync)\r
57                 impl_.reset(new implementation());\r
58         else\r
59                 CASPAR_LOG(warning) << "[fence] GL_SYNC not supported, running without fences. This might cause performance degradation when running multiple channels and short buffer depth.";\r
60 \r
61 }\r
62 \r
63 void fence::set() \r
64 {\r
65         if(impl_)\r
66                 impl_->set();\r
67 }\r
68 \r
69 bool fence::ready() const \r
70 {\r
71         return impl_ ? impl_->ready() : true;\r
72 }\r
73 \r
74 void fence::wait(ogl_device& ogl)\r
75 {\r
76         if(impl_)\r
77                 impl_->wait(ogl);\r
78 }\r
79 \r
80 }}