4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #ifndef BCSYNCHRONOUS_H
23 #define BCSYNCHRONOUS_H
25 #include "arraylist.h"
26 #include "bcpbuffer.inc"
27 #include "bcpixmap.inc"
28 #include "bctexture.inc"
29 #include "bcwindowbase.inc"
30 #include "condition.inc"
35 #if defined(HAVE_CONFIG_H)
46 // This takes requests and runs all OpenGL calls in the main thread.
47 // Past experience showed OpenGL couldn't be run from multiple threads
48 // reliably even if MakeCurrent was used and only 1 thread at a time did
51 // Also manages texture memory. Textures are not deleted until the glx_context
52 // is deleted, so they have to be reused as much as possible.
53 // Must be run as the main loop of the application. Other threads must
54 // call into it to dispatch commands.
56 // In addition to synchronous operations, it handles global OpenGL variables.
58 // Users should create a subclass of the command and thread components to
59 // add specific commands.
66 TextureID(int window_id, int id, int w, int h, int components);
72 BC_WindowBase *window;
79 ShaderID(int window_id, unsigned int handle, char *source);
82 // Should really use an MD5 to compare sources but this is easiest.
93 PBufferID(int window_id,
94 GLXPbuffer glx_pbuffer, GLXContext glx_context,
96 GLXPbuffer glx_pbuffer;
97 GLXContext glx_context;
104 class BC_SynchronousCommand
107 BC_SynchronousCommand();
108 virtual ~BC_SynchronousCommand();
110 virtual void copy_from(BC_SynchronousCommand *command);
112 Condition *command_done;
121 // Used by garbage collector
125 // subclasses create new commands starting with this enumeration
130 BC_WindowBase *window;
133 VFrame *frame_return;
138 // For garbage collection
143 GLXContext glx_context;
144 GLXPixmap glx_pixmap;
149 class BC_Synchronous : public Thread
153 virtual ~BC_Synchronous();
155 friend class BC_WindowBase;
157 friend class BC_PBuffer;
158 friend class BC_Pixmap;
159 friend class BC_Texture;
162 // Must be called after constructor to create inherited objects.
163 void create_objects();
167 virtual BC_SynchronousCommand* new_command();
168 // Handle extra commands not part of the base class.
169 // Contains a switch statement starting with LAST_COMMAND
170 virtual void handle_command(BC_SynchronousCommand *command);
173 // OpenGL texture removal doesn't work. Need to store the ID's of all the deleted
174 // textures in this stack and reuse them. Also since OpenGL needs synchronous
175 // commands, be sure this is always called synchronously.
176 // Called when a texture is created to associate it with the current window.
177 // Must be called inside synchronous loop.
178 void put_texture(int id, int w, int h, int components);
179 // Search for existing texture matching the parameters and not in use
180 // and return it. If -1 is returned, a new texture must be created.
181 // Must be called inside synchronous loop.
182 // If someone proves OpenGL can delete texture memory, this function can be
183 // forced to always return -1.
184 int get_texture(int w, int h, int components);
185 // Release a texture for use by the get_texture call.
186 // Can be called outside synchronous loop.
187 void release_texture(int window_id, int id);
189 // Get the shader by window_id and source comparison if it exists.
190 // Not run in OpenGL thread because it has its own lock.
191 // Sets *got_it to 1 on success.
192 unsigned int get_shader(char *source, int *got_it);
193 // Add a new shader program by title if it doesn't exist.
194 // Doesn't check if it already exists.
195 void put_shader(unsigned int handle, char *source);
196 void dump_shader(unsigned int handle);
200 // Push a pbuffer when it's created.
201 // Must be called inside synchronous loop.
202 void put_pbuffer(int w, int h,
203 GLXPbuffer glx_pbuffer,
204 GLXContext glx_context);
205 // Get the PBuffer by window_id and dimensions if it exists.
206 // Must be called inside synchronous loop.
207 GLXPbuffer get_pbuffer(int w, int h, GLXContext *glx_context);
208 // Release a pbuffer for use by get_pbuffer.
209 void release_pbuffer(int window_id, GLXPbuffer pbuffer);
211 // Schedule GL pixmap for deletion by the garbage collector.
212 // Pixmaps don't wait until until the window is deleted but they must be
213 // deleted before the window is deleted to have the display connection.
214 void delete_pixmap(BC_WindowBase *window,
221 // Called by ~BC_WindowBase to delete OpenGL objects related to the window.
222 // This function returns immediately instead of waiting for the synchronous
224 void delete_window(BC_WindowBase *window);
225 void delete_display(BC_WindowBase *window);
227 long send_command(BC_SynchronousCommand *command);
228 void send_garbage(BC_SynchronousCommand *command);
230 void delete_pixmap_sync(BC_SynchronousCommand *command);
231 void delete_window_sync(BC_SynchronousCommand *command);
232 void delete_display_sync(BC_SynchronousCommand *command);
234 // Get the window currently bound to the context.
235 BC_WindowBase* get_window();
238 void handle_command_base(BC_SynchronousCommand *command);
241 void sync_lock(const char *cp=0);
244 void get_display_sync(Display *display, const char *cp);
246 Condition *next_command;
249 // Must be locked in order of current_window->lock_window, table_lock
250 // or just table_lock.
253 // This quits the program when it's 1.
256 ArrayList<BC_SynchronousCommand*> commands;
258 // The window the opengl context is currently bound to.
259 // Set by BC_WindowBase::enable_opengl.
260 BC_WindowBase *current_window;
262 ArrayList<ShaderID*> shader_ids;
263 ArrayList<TextureID*> texture_ids;
264 ArrayList<PBufferID*> pbuffer_ids;
266 // When the context is bound to a pbuffer, this
267 // signals glCopyTexSubImage2D to use the front buffer.