scons: Add support for GLES.
[mesa.git] / src / gallium / state_trackers / wgl / stw_device.c
index 7785aba46775b9c910503dc4ac8dd64f01dd84d3..4ece4e4979abb3ed4a6cadeb45aab87915653ee0 100644 (file)
 
 #include <windows.h>
 
-#include "glapi/glthread.h"
+#include "glapi/glapi.h"
 #include "util/u_debug.h"
 #include "util/u_math.h"
+#include "util/u_memory.h"
 #include "pipe/p_screen.h"
-#include "state_tracker/st_public.h"
-
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_texture.h"
-#endif
 
 #include "stw_device.h"
 #include "stw_winsys.h"
 #include "stw_icd.h"
 #include "stw_tls.h"
 #include "stw_framebuffer.h"
+#include "stw_st.h"
 
-#ifdef WIN32_THREADS
 extern _glthread_Mutex OneTimeLock;
-extern void FreeAllTSD(void);
-#endif
 
 
 struct stw_device *stw_dev = NULL;
 
-
-/**
- * XXX: Dispatch pipe_screen::flush_front_buffer to our 
- * stw_winsys::flush_front_buffer.
- */
-static void 
-stw_flush_frontbuffer(struct pipe_screen *screen,
-                     struct pipe_surface *surface,
-                     void *context_private )
+static int
+stw_get_param(struct st_manager *smapi,
+              enum st_manager_param param)
 {
-   HDC hdc = (HDC)context_private;
-   struct stw_framebuffer *fb;
-   
-   fb = stw_framebuffer_from_hdc( hdc );
-   if (!fb) {
-      /* fb can be NULL if window was destroyed already */
-      return;
-   }
-
-   stw_framebuffer_present_locked(hdc, fb, surface);
+   return 0;
 }
 
-
 boolean
 stw_init(const struct stw_winsys *stw_winsys)
 {
@@ -97,9 +74,12 @@ stw_init(const struct stw_winsys *stw_winsys)
    
    stw_dev->stw_winsys = stw_winsys;
 
-#ifdef WIN32_THREADS
    _glthread_INIT_MUTEX(OneTimeLock);
-#endif
+
+   stw_dev->stapi = stw_st_create_api();
+   stw_dev->smapi = CALLOC_STRUCT(st_manager);
+   if (!stw_dev->stapi || !stw_dev->smapi)
+      goto error1;
 
    screen = stw_winsys->create_screen();
    if(!screen)
@@ -108,15 +88,14 @@ stw_init(const struct stw_winsys *stw_winsys)
    if(stw_winsys->get_adapter_luid)
       stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid);
 
-#ifdef DEBUG
-   stw_dev->screen = trace_screen_create(screen);
-   stw_dev->trace_running = stw_dev->screen != screen ? TRUE : FALSE;
-#else
+   stw_dev->smapi->screen = screen;
+   stw_dev->smapi->get_param = stw_get_param;
    stw_dev->screen = screen;
-#endif
-   
-   stw_dev->screen->flush_frontbuffer = &stw_flush_frontbuffer;
-   
+
+   stw_dev->max_2d_levels =
+         screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+   stw_dev->max_2d_length = 1 << (stw_dev->max_2d_levels - 1);
+
    pipe_mutex_init( stw_dev->ctx_mutex );
    pipe_mutex_init( stw_dev->fb_mutex );
 
@@ -130,6 +109,11 @@ stw_init(const struct stw_winsys *stw_winsys)
    return TRUE;
 
 error1:
+   if (stw_dev->smapi)
+      FREE(stw_dev->smapi);
+   if (stw_dev->stapi)
+      stw_dev->stapi->destroy(stw_dev->stapi);
+
    stw_dev = NULL;
    return FALSE;
 }
@@ -152,35 +136,43 @@ stw_cleanup_thread(void)
 void
 stw_cleanup(void)
 {
-   unsigned i;
+   DHGLRC dhglrc;
 
    debug_printf("%s\n", __FUNCTION__);
 
    if (!stw_dev)
       return;
    
+   /*
+    * Abort cleanup if there are still active contexts. In some situations
+    * this DLL may be unloaded before the DLL that is using GL contexts is.
+    */
    pipe_mutex_lock( stw_dev->ctx_mutex );
-   {
-      /* Ensure all contexts are destroyed */
-      i = handle_table_get_first_handle(stw_dev->ctx_table);
-      while (i) {
-         DrvDeleteContext(i);
-         i = handle_table_get_next_handle(stw_dev->ctx_table, i);
-      }
-      handle_table_destroy(stw_dev->ctx_table);
-   }
+   dhglrc = handle_table_get_first_handle(stw_dev->ctx_table);
    pipe_mutex_unlock( stw_dev->ctx_mutex );
+   if (dhglrc) {
+      debug_printf("%s: contexts still active -- cleanup aborted\n", __FUNCTION__);
+      stw_dev = NULL;
+      return;
+   }
+
+   handle_table_destroy(stw_dev->ctx_table);
 
    stw_framebuffer_cleanup();
    
    pipe_mutex_destroy( stw_dev->fb_mutex );
    pipe_mutex_destroy( stw_dev->ctx_mutex );
    
+   FREE(stw_dev->smapi);
+   stw_dev->stapi->destroy(stw_dev->stapi);
+
    stw_dev->screen->destroy(stw_dev->screen);
 
-#ifdef WIN32_THREADS
    _glthread_DESTROY_MUTEX(OneTimeLock);
-   FreeAllTSD();
+
+   /* glapi is statically linked: we can call the local destroy function. */
+#ifdef _GLAPI_NO_EXPORTS
+   _glapi_destroy_multithread();
 #endif
 
 #ifdef DEBUG