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"
42 // This takes requests and runs all OpenGL calls in the main thread.
43 // Past experience showed OpenGL couldn't be run from multiple threads
44 // reliably even if MakeCurrent was used and only 1 thread at a time did
47 // Also manages texture memory. Textures are not deleted until the glx_context
48 // is deleted, so they have to be reused as much as possible.
49 // Must be run as the main loop of the application. Other threads must
50 // call into it to dispatch commands.
52 // In addition to synchronous operations, it handles global OpenGL variables.
54 // Users should create a subclass of the command and thread components to
55 // add specific commands.
62 TextureID(int window_id, int id, int w, int h, int components);
68 BC_WindowBase *window;
75 ShaderID(int window_id, unsigned int handle, char *source);
78 // Should really use an MD5 to compare sources but this is easiest.
89 PBufferID(int window_id,
90 GLXPbuffer glx_pbuffer, GLXContext glx_context,
92 GLXPbuffer glx_pbuffer;
93 GLXContext glx_context;
100 class BC_SynchronousCommand
103 BC_SynchronousCommand();
104 virtual ~BC_SynchronousCommand();
106 virtual void copy_from(BC_SynchronousCommand *command);
108 Condition *command_done;
117 // Used by garbage collector
121 // subclasses create new commands starting with this enumeration
126 BC_WindowBase *window;
129 VFrame *frame_return;
134 // For garbage collection
139 GLXContext glx_context;
140 GLXPixmap glx_pixmap;
145 class BC_Synchronous : public Thread
149 virtual ~BC_Synchronous();
151 friend class BC_WindowBase;
153 friend class BC_PBuffer;
154 friend class BC_Pixmap;
155 friend class BC_Texture;
158 // Must be called after constructor to create inherited objects.
159 void create_objects();
163 virtual BC_SynchronousCommand* new_command();
164 // Handle extra commands not part of the base class.
165 // Contains a switch statement starting with LAST_COMMAND
166 virtual void handle_command(BC_SynchronousCommand *command);
169 // OpenGL texture removal doesn't work. Need to store the ID's of all the deleted
170 // textures in this stack and reuse them. Also since OpenGL needs synchronous
171 // commands, be sure this is always called synchronously.
172 // Called when a texture is created to associate it with the current window.
173 // Must be called inside synchronous loop.
174 void put_texture(int id, int w, int h, int components);
175 // Search for existing texture matching the parameters and not in use
176 // and return it. If -1 is returned, a new texture must be created.
177 // Must be called inside synchronous loop.
178 // If someone proves OpenGL can delete texture memory, this function can be
179 // forced to always return -1.
180 int get_texture(int w, int h, int components);
181 // Release a texture for use by the get_texture call.
182 // Can be called outside synchronous loop.
183 void release_texture(int window_id, int id);
185 // Get the shader by window_id and source comparison if it exists.
186 // Not run in OpenGL thread because it has its own lock.
187 // Sets *got_it to 1 on success.
188 unsigned int get_shader(char *source, int *got_it);
189 // Add a new shader program by title if it doesn't exist.
190 // Doesn't check if it already exists.
191 void put_shader(unsigned int handle, char *source);
192 void dump_shader(unsigned int handle);
196 // Push a pbuffer when it's created.
197 // Must be called inside synchronous loop.
198 void put_pbuffer(int w, int h,
199 GLXPbuffer glx_pbuffer,
200 GLXContext glx_context);
201 // Get the PBuffer by window_id and dimensions if it exists.
202 // Must be called inside synchronous loop.
203 GLXPbuffer get_pbuffer(int w, int h, GLXContext *glx_context);
204 // Release a pbuffer for use by get_pbuffer.
205 void release_pbuffer(int window_id, GLXPbuffer pbuffer);
207 // Schedule GL pixmap for deletion by the garbage collector.
208 // Pixmaps don't wait until until the window is deleted but they must be
209 // deleted before the window is deleted to have the display connection.
210 void delete_pixmap(BC_WindowBase *window,
217 // Called by ~BC_WindowBase to delete OpenGL objects related to the window.
218 // This function returns immediately instead of waiting for the synchronous
220 void delete_window(BC_WindowBase *window);
221 void delete_display(BC_WindowBase *window);
223 long send_command(BC_SynchronousCommand *command);
224 void send_garbage(BC_SynchronousCommand *command);
226 void delete_pixmap_sync(BC_SynchronousCommand *command);
227 void delete_window_sync(BC_SynchronousCommand *command);
228 void delete_display_sync(BC_SynchronousCommand *command);
230 // Get the window currently bound to the context.
231 BC_WindowBase* get_window();
234 void handle_command_base(BC_SynchronousCommand *command);
237 void sync_lock(const char *cp=0);
240 void get_display_sync(Display *display, const char *cp);
242 Condition *next_command;
245 // Must be locked in order of current_window->lock_window, table_lock
246 // or just table_lock.
249 // This quits the program when it's 1.
252 ArrayList<BC_SynchronousCommand*> commands;
254 // The window the opengl context is currently bound to.
255 // Set by BC_WindowBase::enable_opengl.
256 BC_WindowBase *current_window;
258 ArrayList<ShaderID*> shader_ids;
259 ArrayList<TextureID*> texture_ids;
260 ArrayList<PBufferID*> pbuffer_ids;
262 // When the context is bound to a pbuffer, this
263 // signals glCopyTexSubImage2D to use the front buffer.