r878: This is Cinelerra 2.1.
[cinelerra_cv/ct.git] / guicast / bcsynchronous.h
blob9dab5165bdc960e043fa2ef555643b198b4ec072
1 #ifndef BCSYNCHRONOUS_H
2 #define BCSYNCHRONOUS_H
4 #include "arraylist.h"
5 #include "bcpbuffer.inc"
6 #include "bcpixmap.inc"
7 #include "bctexture.inc"
8 #include "bcwindowbase.inc"
9 #include "condition.inc"
10 #include "mutex.inc"
11 #include "thread.h"
12 #include "vframe.inc"
14 #if defined(HAVE_CONFIG_H)
15 #include "config.h"
16 #endif
19 #ifdef HAVE_GL
20 #include <GL/gl.h>
21 #include <GL/glx.h>
22 #endif
24 #include <X11/Xlib.h>
26 // This takes requests and runs all OpenGL calls in the main thread.
27 // Past experience showed OpenGL couldn't be run from multiple threads
28 // reliably even if MakeCurrent was used and only 1 thread at a time did
29 // anything.
31 // Also manages texture memory. Textures are not deleted until the gl_context
32 // is deleted, so they have to be reused as much as possible.
33 // Must be run as the main loop of the application. Other threads must
34 // call into it to dispatch commands.
36 // In addition to synchronous operations, it handles global OpenGL variables.
38 // Users should create a subclass of the command and thread components to
39 // add specific commands.
43 class TextureID
45 public:
46 TextureID(int window_id, int id, int w, int h, int components);
47 int window_id;
48 int id;
49 int w;
50 int h;
51 int components;
52 BC_WindowBase *window;
53 int in_use;
56 class ShaderID
58 public:
59 ShaderID(int window_id, unsigned int handle, char *source);
60 ~ShaderID();
62 // Should really use an MD5 to compare sources but this is easiest.
63 char *source;
64 int window_id;
65 unsigned int handle;
68 class PBufferID
70 public:
71 PBufferID() {};
72 #ifdef HAVE_GL
73 PBufferID(int window_id,
74 GLXPbuffer pbuffer,
75 GLXContext gl_context,
76 int w,
77 int h);
78 GLXPbuffer pbuffer;
79 GLXContext gl_context;
80 int window_id;
81 int w;
82 int h;
83 int in_use;
84 #endif
87 class BC_SynchronousCommand
89 public:
90 BC_SynchronousCommand();
91 ~BC_SynchronousCommand();
93 virtual void copy_from(BC_SynchronousCommand *command);
95 Condition *command_done;
96 int result;
97 int command;
99 // Commands
100 enum
102 NONE,
103 QUIT,
104 // Used by garbage collector
105 DELETE_WINDOW,
106 DELETE_PIXMAP,
107 // subclasses create new commands starting with this enumeration
108 LAST_COMMAND
111 int colormodel;
112 BC_WindowBase *window;
113 VFrame *frame;
115 VFrame *frame_return;
117 int id;
118 int w;
119 int h;
121 // For garbage collection
122 int window_id;
123 Display *display;
124 Window win;
125 #ifdef HAVE_GL
126 GLXContext gl_context;
127 GLXPixmap gl_pixmap;
128 #endif
132 class BC_Synchronous : public Thread
134 public:
135 BC_Synchronous();
136 virtual ~BC_Synchronous();
138 friend class BC_WindowBase;
139 friend class VFrame;
140 friend class BC_PBuffer;
141 friend class BC_Pixmap;
142 friend class BC_Texture;
144 // Called by another thread
145 // Quits the loop
146 void quit();
147 // Must be called after constructor to create inherited objects.
148 void create_objects();
149 void start();
150 void run();
152 virtual BC_SynchronousCommand* new_command();
153 // Handle extra commands not part of the base class.
154 // Contains a switch statement starting with LAST_COMMAND
155 virtual void handle_command(BC_SynchronousCommand *command);
158 // OpenGL texture removal doesn't work. Need to store the ID's of all the deleted
159 // textures in this stack and reuse them. Also since OpenGL needs synchronous
160 // commands, be sure this is always called synchronously.
161 // Called when a texture is created to associate it with the current window.
162 // Must be called inside synchronous loop.
163 void put_texture(int id, int w, int h, int components);
164 // Search for existing texture matching the parameters and not in use
165 // and return it. If -1 is returned, a new texture must be created.
166 // Must be called inside synchronous loop.
167 // If someone proves OpenGL can delete texture memory, this function can be
168 // forced to always return -1.
169 int get_texture(int w, int h, int components);
170 // Release a texture for use by the get_texture call.
171 // Can be called outside synchronous loop.
172 void release_texture(int window_id, int id);
174 // Get the shader by window_id and source comparison if it exists.
175 // Not run in OpenGL thread because it has its own lock.
176 // Sets *got_it to 1 on success.
177 unsigned int get_shader(char *source, int *got_it);
178 // Add a new shader program by title if it doesn't exist.
179 // Doesn't check if it already exists.
180 void put_shader(unsigned int handle, char *source);
181 void dump_shader(unsigned int handle);
184 #ifdef HAVE_GL
185 // Push a pbuffer when it's created.
186 // Must be called inside synchronous loop.
187 void put_pbuffer(int w,
188 int h,
189 GLXPbuffer pbuffer,
190 GLXContext gl_context);
191 // Get the PBuffer by window_id and dimensions if it exists.
192 // Must be called inside synchronous loop.
193 GLXPbuffer get_pbuffer(int w,
194 int h,
195 int *window_id,
196 GLXContext *gl_context);
197 // Release a pbuffer for use by get_pbuffer.
198 void release_pbuffer(int window_id, GLXPbuffer pbuffer);
200 // Schedule GL pixmap for deletion by the garbage collector.
201 // Pixmaps don't wait until until the window is deleted but they must be
202 // deleted before the window is deleted to have the display connection.
203 void delete_pixmap(BC_WindowBase *window,
204 GLXPixmap pixmap,
205 GLXContext context);
206 #endif
210 // Called by ~BC_WindowBase to delete OpenGL objects related to the window.
211 // This function returns immediately instead of waiting for the synchronous
212 // part to finish.
213 void delete_window(BC_WindowBase *window);
216 int send_command(BC_SynchronousCommand *command);
217 void send_garbage(BC_SynchronousCommand *command);
220 // Get the window currently bound to the context.
221 BC_WindowBase* get_window();
223 private:
224 void handle_command_base(BC_SynchronousCommand *command);
226 // Execute commands which can't be executed until the caller returns.
227 void handle_garbage();
229 // Release OpenGL objects related to the window id.
230 // Called from the garbage collector only
231 void delete_window_sync(BC_SynchronousCommand *command);
232 void delete_pixmap_sync(BC_SynchronousCommand *command);
234 Condition *next_command;
235 Mutex *command_lock;
237 // Must be locked in order of current_window->lock_window, table_lock
238 // or just table_lock.
239 Mutex *table_lock;
241 // This quits the program when it's 1.
242 int done;
243 // Command stack
244 ArrayList<BC_SynchronousCommand*> commands;
245 int is_running;
246 // The window the opengl context is currently bound to.
247 // Set by BC_WindowBase::enable_opengl.
248 BC_WindowBase *current_window;
250 ArrayList<ShaderID*> shader_ids;
251 ArrayList<TextureID*> texture_ids;
252 ArrayList<PBufferID*> pbuffer_ids;
253 // Commands which can't be executed until the caller returns.
254 ArrayList<BC_SynchronousCommand*> garbage;
256 // When the context is bound to a pbuffer, this
257 // signals glCopyTexSubImage2D to use the front buffer.
258 int is_pbuffer;
264 #endif