synthetic-stream-gl.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2017 Intel Corporation. All Rights Reserved.
3 
4 #include "core/video.h"
5 #include "synthetic-stream-gl.h"
6 #include "option.h"
7 #include "opengl3.h"
8 
9 #include <GLFW/glfw3.h>
10 
11 #ifndef NOMINMAX
12 #define NOMINMAX
13 #endif // NOMINMAX
14 
15 #include <glad/glad.h>
16 
17 #include <iostream>
18 #include <future>
19 
20 namespace librealsense
21 {
22  namespace gl
23  {
26  { TEXTYPE_BGR, RS2_FORMAT_BGR8, 3, GL_BGR, GL_BGR, GL_UNSIGNED_BYTE },
27  { TEXTYPE_RGBA, RS2_FORMAT_RGBA8, 4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE },
28  { TEXTYPE_BGRA, RS2_FORMAT_BGRA8, 4, GL_BGRA, GL_BGRA, GL_UNSIGNED_BYTE },
29  { TEXTYPE_UINT8, RS2_FORMAT_Y8, 1, GL_RGB, GL_LUMINANCE, GL_UNSIGNED_BYTE },
30  { TEXTYPE_UINT16, RS2_FORMAT_Z16, 2, GL_RG8, GL_RG, GL_UNSIGNED_BYTE },
32  { TEXTYPE_UV, RS2_FORMAT_ANY, 8, GL_RGB16F, GL_RG, GL_FLOAT },
34  };
35 
37  {
38  for (int i = 0; i < TEXTYPE_COUNT; i++)
39  if (texture_formats[i].type == type) return texture_formats[i];
40  throw std::runtime_error("Selected RealSense format cannot be converted to GL format!");
41  }
42 
44  {
45  for (int i = 0; i < TEXTYPE_COUNT; i++)
46  if (texture_formats[i].format == type) return texture_formats[i];
47  throw std::runtime_error("Selected RealSense format cannot be converted to GL format!");
48  }
49 
51  {
52  if (!initialized)
53  {
54  initialize();
55  initialized = true;
56  }
57  }
58 
60 
62  {
63  return std::this_thread::get_id() == _rendering_thread;
64  }
65 
67  {
68  _data.register_gpu_object(obj);
69  }
70 
72  {
73  _data.unregister_gpu_object(obj);
74  }
75 
77  {
78  std::lock_guard<std::mutex> lock(_data.mutex);
79 
81  LOG_INFO("Initializing rendering, GLSL=" << use_glsl);
82 
83  for (auto&& obj : _data.objs)
84  {
85  obj->update_gpu_resources(use_glsl);
86  }
87  _data.active = true;
88  _data.use_glsl = use_glsl;
89 
90  LOG_INFO(" " << _data.objs.size() << " GPU objects initialized");
91 
92  _rendering_thread = std::this_thread::get_id();
93  }
94 
96  {
97  std::lock_guard<std::mutex> lock(_data.mutex);
98  LOG_INFO("Shutting down rendering");
99  for (auto&& obj : _data.objs)
100  {
101  obj->update_gpu_resources(false);
102  }
103  _data.active = false;
104  LOG_INFO(" " << _data.objs.size() << " GPU objects cleaned-up");
105  }
106 
108  {
109  static rendering_lane instance;
110  return instance;
111  }
112 
114  {
115  static processing_lane instance;
116  return instance;
117  }
118 
120  {
121  _data.register_gpu_object(obj);
122  }
123 
125  {
126  _data.unregister_gpu_object(obj);
127  }
128 
129  void processing_lane::init(GLFWwindow* share_with, glfw_binding binding, bool use_glsl)
130  {
131  std::lock_guard<std::mutex> lock(_data.mutex);
132 
133  LOG_INFO("Initializing processing, GLSL=" << use_glsl);
134 
135  _data.active = true;
136  _data.use_glsl = use_glsl;
137 
138  _ctx = std::make_shared<context>(share_with, binding);
139  auto session = _ctx->begin_session();
140 
141  for (auto&& obj : _data.objs)
142  {
143  ((gpu_processing_object*)obj)->set_context(_ctx);
144  obj->update_gpu_resources(use_glsl);
145  }
146 
147  LOG_INFO(" " << _data.objs.size() << " GPU objects initialized");
148  }
149 
151  {
152  std::lock_guard<std::mutex> lock(_data.mutex);
153 
154  LOG_INFO("Shutting down processing");
155 
156  _data.active = false;
157  auto session = _ctx->begin_session();
158 
159  for (auto&& obj : _data.objs)
160  {
161  ((gpu_processing_object*)obj)->set_context({});
162  obj->update_gpu_resources(false);
163  }
164 
165  LOG_INFO(" " << _data.objs.size() << " GPU objects cleaned-up");
166 
167  _ctx.reset();
168  }
169 
171  {
172  if (backup_content)
173  {
174  backup = std::unique_ptr<uint8_t[]>(new uint8_t[get_frame_size()]);
175  fetch_frame(backup.get());
176  }
177  for (int i = 0; i < MAX_TEXTURES; i++)
178  {
179  if (textures[i])
180  {
181  glDeleteTextures(1, &textures[i]);
182  textures[i] = 0;
183  }
184  }
185  }
186 
188  {
189  backup_content = false;
190  perform_gl_action([&](){
192  }, []{});
193  }
194 
196  {
197  backup.reset();
198  }
199 
200  gpu_section::operator bool()
201  {
202  bool res = false;
203  for (int i = 0; i < MAX_TEXTURES; i++)
204  if (loaded[i]) res = true;
205  return res;
206  }
207 
209  {
210  for (int i = 0; i < MAX_TEXTURES; i++)
211  {
212  textures[i] = 0;
213  loaded[i] = false;
214  }
215 
216  }
217 
219  {
220  ensure_init();
221  for (int i = 0; i < MAX_TEXTURES; i++)
222  {
223  loaded[i] = false;
224  }
225  }
226 
228  {
229  for (int i = 0; i < MAX_TEXTURES; i++)
230  {
231  loaded[i] = false;
232  }
233  }
234 
236  {
237  ensure_init();
238 
239  auto existing_tex = textures[id];
240  if (existing_tex)
241  *tex = existing_tex;
242  else
243  {
244  glGenTextures(1, tex);
245  textures[id] = *tex;
246  }
247  loaded[id] = true;
248  types[id] = type;
249  }
250 
252  {
253  this->width = width; this->height = height; this->preloaded = preloaded;
254  }
255 
257  {
258  if (loaded[id])
259  {
260  *tex = textures[id];
261  return true;
262  }
263  return false;
264  }
265 
267  {
268  int res = 0;
269  for (int i = 0; i < MAX_TEXTURES; i++)
270  if (textures[i] && loaded[i])
271  {
272  res += width * height * gl_format_mapping(types[i]).size;
273  }
274  return res;
275  }
276 
278  {
279  if (preloaded) return;
280 
281  ensure_init();
282 
283  bool need_to_fetch = false;
284  for (int i = 0; i < MAX_TEXTURES; i++)
285  if (loaded[i]) need_to_fetch = true;
286 
287  if (need_to_fetch)
288  {
289  perform_gl_action([&]{
290  auto ptr = (uint8_t*)to;
291 
292  for (int i = 0; i < MAX_TEXTURES; i++)
293  if (textures[i] && loaded[i])
294  {
295  auto& vis = get_texture_visualizer();
296  //rs2::visualizer_2d vis;
297  rs2::fbo fbo(width, height);
298  uint32_t res;
299  glGenTextures(1, &res);
301 
302  auto textype = gl_format_mapping(types[i]);
303  if (textype.size)
304  glTexImage2D(GL_TEXTURE_2D, 0, textype.internal_format,
305  width, height, 0, textype.gl_format, textype.data_type, nullptr);
306 
308 
309  fbo.bind();
310  glViewport(0, 0, width, height);
311  glClearColor(0, 0, 0, 1);
313  vis.draw_texture(textures[i]);
315 
316  if (textype.size)
317  {
318  glReadPixels(0, 0, width, height, textype.gl_format, textype.data_type, ptr);
319  ptr += width * height * textype.size;
320  }
321 
322  glDeleteTextures(1, &res);
323 
324  fbo.unbind();
325 
326  preloaded = true;
327  }
328  }, [&]{
329  memcpy(to, backup.get(), get_frame_size());
330  });
331  }
332  }
333 
334  context::context(GLFWwindow* share_with, glfw_binding binding) : _binding(binding)
335  {
336  if (binding.glfwInit) binding.glfwInit();
337 
338  binding.glfwWindowHint(GLFW_VISIBLE, 0);
339  _ctx = binding.glfwCreateWindow(640, 480, "Offscreen Context", NULL, share_with);
340  if (!_ctx)
341  {
342  throw std::runtime_error("Could not initialize offscreen context!");
343  }
344 
345  auto curr = binding.glfwGetCurrentContext();
346  binding.glfwMakeContextCurrent(_ctx);
347 
348  if (glShaderSource == nullptr)
349  {
351  }
352 
353  binding.glfwSwapInterval(0);
354 
355  _vis = std::make_shared<rs2::visualizer_2d>();
356 
357  binding.glfwMakeContextCurrent(curr);
358  }
359 
360  std::shared_ptr<void> context::begin_session()
361  {
362  auto curr = _binding.glfwGetCurrentContext();
363  if (curr == _ctx) return nullptr;
364 
365  _lock.lock();
366 
368  auto me = shared_from_this();
369  return std::shared_ptr<void>(nullptr, [curr, me](void*){
370  me->_binding.glfwMakeContextCurrent(curr);
371  me->_lock.unlock();
372  });
373  }
374 
376  {
377  _vis.reset();
379  }
380  }
381 }
static const textual_icon lock
Definition: model-views.h:218
#define GL_RG8
glfwCreateWindowFun glfwCreateWindow
void init(GLFWwindow *share_with, glfw_binding binding, bool use_glsl)
void unregister_gpu_object(gpu_processing_object *obj)
glfwMakeContextCurrentFun glfwMakeContextCurrent
#define glFramebufferTexture2D
The header of the GLFW 3 API.
#define GL_TEXTURE_2D
glfwDestroyWindowFun glfwDestroyWindow
glfwGetProcAddressFun glfwGetProcAddress
#define GL_RGBA
void *(* GLADloadproc)(const char *name)
std::unique_ptr< uint8_t[]> backup
#define GL_UNSIGNED_BYTE
bool get_id(DEVINST devinst, std::string *p_out_str)
void output_texture(int id, uint32_t *tex, texture_type type)
void unregister_gpu_object(gpu_rendering_object *obj)
#define GL_RGB16F
#define GL_BGRA
texture_mapping & rs_format_to_gl_format(rs2_format type)
#define GL_BGR
#define glReadBuffer
#define MAX_TEXTURES
unsigned char uint8_t
Definition: stdint.h:78
GLhandleARB obj
Definition: glext.h:4157
#define glTexImage2D
glfwInitFun glfwInit
#define GL_LUMINANCE
GLenum GLuint id
void bind()
Definition: opengl3.cpp:635
std::shared_ptr< rs2::visualizer_2d > _vis
#define glGenTextures
GLsizei GLenum GLenum * types
#define GL_FLOAT
#define GL_COLOR_BUFFER_BIT
static std::thread::id _rendering_thread
unsigned int uint32_t
Definition: stdint.h:80
#define glClear
GLint GLsizei GLsizei height
GLint GLint GLsizei GLint GLenum format
#define GL_R16F
void set_size(uint32_t width, uint32_t height, bool preloaded=false)
void unbind()
Definition: opengl3.cpp:647
rs2_format
A stream&#39;s format identifies how binary data is encoded within a frame.
Definition: rs_sensor.h:59
#define glShaderSource
std::recursive_mutex _lock
std::shared_ptr< void > begin_session()
#define GL_RG
#define glViewport
GLAPI int gladLoadGLLoader(GLADloadproc)
Definition: glad/glad.c:1697
glfwSwapIntervalFun glfwSwapInterval
texture_mapping & gl_format_mapping(texture_type type)
#define glDeleteTextures
LOG_INFO("Log message using LOG_INFO()")
#define GL_RED
const GLuint * textures
GLenum type
void register_gpu_object(gpu_processing_object *obj)
#define glBindTexture
static rendering_lane & instance()
void perform_gl_action(T action, S fallback)
void init(glfw_binding binding, bool use_glsl)
#define GLFW_VISIBLE
Window visibility window hint and attribute.
Definition: glfw3.h:780
#define glClearColor
glfwGetCurrentContextFun glfwGetCurrentContext
void register_gpu_object(gpu_rendering_object *obj)
static processing_lane & instance()
#define NULL
Definition: tinycthread.c:47
#define GL_COLOR_ATTACHMENT0
int i
GLuint res
Definition: glext.h:8856
#define GL_RGB
glfwWindowHintFun glfwWindowHint
#define glReadPixels
bool input_texture(int id, uint32_t *tex)
context(GLFWwindow *share_with, glfw_binding binding)
struct GLFWwindow GLFWwindow
#define GL_FRAMEBUFFER
GLint GLsizei width
texture_mapping texture_formats[TEXTYPE_COUNT]


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:50:11