]> git.sesse.net Git - casparcg/blob - core/mixer/gpu/fence.cpp
41e2d4cb10578c4b4cce6564bb492dbd81aa2b25
[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 #include <gl/glew.h>\r
10 \r
11 namespace caspar { namespace core {\r
12 \r
13 struct fence::implementation\r
14 {\r
15         GLsync sync_;\r
16 \r
17         implementation() : sync_(0){}\r
18         ~implementation(){glDeleteSync(sync_);}\r
19                 \r
20         void set()\r
21         {\r
22                 glDeleteSync(sync_);\r
23                 sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);\r
24         }\r
25 \r
26         bool ready() const\r
27         {\r
28                 if(!sync_)\r
29                         return true;\r
30 \r
31                 GLsizei length = 0;\r
32                 int values[] = {0};\r
33 \r
34                 GL(glGetSynciv(sync_, GL_SYNC_STATUS, 1, &length, values));\r
35 \r
36                 return values[0] == GL_SIGNALED;\r
37         }\r
38 \r
39         void wait(ogl_device& ogl)\r
40         {       \r
41                 int delay = 0;\r
42                 if(!ogl.invoke([this]{return ready();}, high_priority))\r
43                 {\r
44                         while(!ogl.invoke([this]{return ready();}, normal_priority) && delay < 20)\r
45                         {\r
46                                 delay += 2;\r
47                                 Sleep(2);\r
48                         }\r
49                 }\r
50 \r
51                 if(delay > 0)\r
52                         CASPAR_LOG(debug) << L"[fence] Performance warning. GPU was not ready during requested host read-back. Delayed by atleast: " << delay << L" ms.";\r
53         }\r
54 };\r
55         \r
56 fence::fence() \r
57 {\r
58         static bool log_flag = false;\r
59 \r
60         if(GLEW_ARB_sync)\r
61                 impl_.reset(new implementation());\r
62         else if(!log_flag)\r
63         {\r
64                 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
65                 log_flag = true;\r
66         }\r
67 }\r
68 \r
69 void fence::set() \r
70 {\r
71         if(impl_)\r
72                 impl_->set();\r
73 }\r
74 \r
75 bool fence::ready() const \r
76 {\r
77         return impl_ ? impl_->ready() : true;\r
78 }\r
79 \r
80 void fence::wait(ogl_device& ogl)\r
81 {\r
82         if(impl_)\r
83                 impl_->wait(ogl);\r
84 }\r
85 \r
86 }}