stw_device.c revision f724036f0045bd28f323af3666c43b3ef03b6886
1/************************************************************************** 2 * 3 * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28#include <windows.h> 29 30#include "glapi/glthread.h" 31#include "util/u_debug.h" 32#include "pipe/p_screen.h" 33#include "state_tracker/st_public.h" 34 35#ifdef DEBUG 36#include "trace/tr_screen.h" 37#include "trace/tr_texture.h" 38#endif 39 40#include "stw_device.h" 41#include "stw_winsys.h" 42#include "stw_pixelformat.h" 43#include "stw_public.h" 44#include "stw_tls.h" 45#include "stw_framebuffer.h" 46 47#ifdef WIN32_THREADS 48extern _glthread_Mutex OneTimeLock; 49extern void FreeAllTSD(void); 50#endif 51 52 53struct stw_device *stw_dev = NULL; 54 55 56/** 57 * XXX: Dispatch pipe_screen::flush_front_buffer to our 58 * stw_winsys::flush_front_buffer. 59 */ 60static void 61stw_flush_frontbuffer(struct pipe_screen *screen, 62 struct pipe_surface *surface, 63 void *context_private ) 64{ 65 const struct stw_winsys *stw_winsys = stw_dev->stw_winsys; 66 HDC hdc = (HDC)context_private; 67 struct stw_framebuffer *fb; 68 69 fb = stw_framebuffer_from_hdc( hdc ); 70 /* fb can be NULL if window was destroyed already */ 71 if (fb) { 72#if DEBUG 73 { 74 struct pipe_surface *surface2; 75 76 if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_FRONT_LEFT, &surface2 )) 77 assert(0); 78 else 79 assert(surface2 == surface); 80 } 81#endif 82 83#ifdef DEBUG 84 if(stw_dev->trace_running) { 85 screen = trace_screen(screen)->screen; 86 surface = trace_surface(surface)->surface; 87 } 88#endif 89 } 90 91 stw_winsys->flush_frontbuffer(screen, surface, hdc); 92 93 if(fb) { 94 stw_framebuffer_update(fb); 95 stw_framebuffer_release(fb); 96 } 97} 98 99 100boolean 101stw_init(const struct stw_winsys *stw_winsys) 102{ 103 static struct stw_device stw_dev_storage; 104 struct pipe_screen *screen; 105 106 debug_printf("%s\n", __FUNCTION__); 107 108 assert(!stw_dev); 109 110 stw_tls_init(); 111 112 stw_dev = &stw_dev_storage; 113 memset(stw_dev, 0, sizeof(*stw_dev)); 114 115#ifdef DEBUG 116 stw_dev->memdbg_no = debug_memory_begin(); 117#endif 118 119 stw_dev->stw_winsys = stw_winsys; 120 121#ifdef WIN32_THREADS 122 _glthread_INIT_MUTEX(OneTimeLock); 123#endif 124 125 screen = stw_winsys->create_screen(); 126 if(!screen) 127 goto error1; 128 129#ifdef DEBUG 130 stw_dev->screen = trace_screen_create(screen); 131 stw_dev->trace_running = stw_dev->screen != screen ? TRUE : FALSE; 132#else 133 stw_dev->screen = screen; 134#endif 135 136 stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer; 137 138 pipe_mutex_init( stw_dev->ctx_mutex ); 139 pipe_mutex_init( stw_dev->fb_mutex ); 140 141 stw_dev->ctx_table = handle_table_create(); 142 if (!stw_dev->ctx_table) { 143 goto error1; 144 } 145 146 stw_pixelformat_init(); 147 148 return TRUE; 149 150error1: 151 stw_dev = NULL; 152 return FALSE; 153} 154 155 156boolean 157stw_init_thread(void) 158{ 159 return stw_tls_init_thread(); 160} 161 162 163void 164stw_cleanup_thread(void) 165{ 166 stw_tls_cleanup_thread(); 167} 168 169 170void 171stw_cleanup(void) 172{ 173 unsigned i; 174 175 debug_printf("%s\n", __FUNCTION__); 176 177 if (!stw_dev) 178 return; 179 180 pipe_mutex_lock( stw_dev->ctx_mutex ); 181 { 182 /* Ensure all contexts are destroyed */ 183 i = handle_table_get_first_handle(stw_dev->ctx_table); 184 while (i) { 185 stw_delete_context(i); 186 i = handle_table_get_next_handle(stw_dev->ctx_table, i); 187 } 188 handle_table_destroy(stw_dev->ctx_table); 189 } 190 pipe_mutex_unlock( stw_dev->ctx_mutex ); 191 192 stw_framebuffer_cleanup(); 193 194 pipe_mutex_destroy( stw_dev->fb_mutex ); 195 pipe_mutex_destroy( stw_dev->ctx_mutex ); 196 197 stw_dev->screen->destroy(stw_dev->screen); 198 199#ifdef WIN32_THREADS 200 _glthread_DESTROY_MUTEX(OneTimeLock); 201 FreeAllTSD(); 202#endif 203 204#ifdef DEBUG 205 debug_memory_end(stw_dev->memdbg_no); 206#endif 207 208 stw_tls_cleanup(); 209 210 stw_dev = NULL; 211} 212 213 214struct stw_context * 215stw_lookup_context_locked( UINT_PTR dhglrc ) 216{ 217 if (dhglrc == 0) 218 return NULL; 219 220 if (stw_dev == NULL) 221 return NULL; 222 223 return (struct stw_context *) handle_table_get(stw_dev->ctx_table, dhglrc); 224} 225 226