Home | History | Annotate | Download | only in libEGL
      1 //
      2 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // main.cpp: DLL entry point and management of thread-local data.
      8 
      9 #include "libEGL/main.h"
     10 
     11 #include "common/debug.h"
     12 
     13 static DWORD currentTLS = TLS_OUT_OF_INDEXES;
     14 
     15 namespace egl
     16 {
     17 
     18 Current *AllocateCurrent()
     19 {
     20     Current *current = (egl::Current*)LocalAlloc(LPTR, sizeof(egl::Current));
     21 
     22     if (!current)
     23     {
     24         ERR("Could not allocate thread local storage.");
     25         return NULL;
     26     }
     27 
     28     ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
     29     TlsSetValue(currentTLS, current);
     30 
     31     current->error = EGL_SUCCESS;
     32     current->API = EGL_OPENGL_ES_API;
     33     current->display = EGL_NO_DISPLAY;
     34     current->drawSurface = EGL_NO_SURFACE;
     35     current->readSurface = EGL_NO_SURFACE;
     36 
     37     return current;
     38 }
     39 
     40 void DeallocateCurrent()
     41 {
     42     void *current = TlsGetValue(currentTLS);
     43 
     44     if (current)
     45     {
     46         LocalFree((HLOCAL)current);
     47     }
     48 }
     49 
     50 }
     51 
     52 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
     53 {
     54     switch (reason)
     55     {
     56       case DLL_PROCESS_ATTACH:
     57         {
     58 #if defined(ANGLE_ENABLE_TRACE)
     59             FILE *debug = fopen(TRACE_OUTPUT_FILE, "rt");
     60 
     61             if (debug)
     62             {
     63                 fclose(debug);
     64                 debug = fopen(TRACE_OUTPUT_FILE, "wt");   // Erase
     65 
     66                 if (debug)
     67                 {
     68                     fclose(debug);
     69                 }
     70             }
     71 #endif
     72 
     73             currentTLS = TlsAlloc();
     74 
     75             if (currentTLS == TLS_OUT_OF_INDEXES)
     76             {
     77                 return FALSE;
     78             }
     79         }
     80         // Fall throught to initialize index
     81       case DLL_THREAD_ATTACH:
     82         {
     83             egl::AllocateCurrent();
     84         }
     85         break;
     86       case DLL_THREAD_DETACH:
     87         {
     88             egl::DeallocateCurrent();
     89         }
     90         break;
     91       case DLL_PROCESS_DETACH:
     92         {
     93             egl::DeallocateCurrent();
     94             TlsFree(currentTLS);
     95         }
     96         break;
     97       default:
     98         break;
     99     }
    100 
    101     return TRUE;
    102 }
    103 
    104 namespace egl
    105 {
    106 
    107 Current *GetCurrentData()
    108 {
    109     Current *current = (Current*)TlsGetValue(currentTLS);
    110 
    111     // ANGLE issue 488: when the dll is loaded after thread initialization,
    112     // thread local storage (current) might not exist yet.
    113     return (current ? current : AllocateCurrent());
    114 }
    115 
    116 void setCurrentError(EGLint error)
    117 {
    118     Current *current = GetCurrentData();
    119 
    120     current->error = error;
    121 }
    122 
    123 EGLint getCurrentError()
    124 {
    125     Current *current = GetCurrentData();
    126 
    127     return current->error;
    128 }
    129 
    130 void setCurrentAPI(EGLenum API)
    131 {
    132     Current *current = GetCurrentData();
    133 
    134     current->API = API;
    135 }
    136 
    137 EGLenum getCurrentAPI()
    138 {
    139     Current *current = GetCurrentData();
    140 
    141     return current->API;
    142 }
    143 
    144 void setCurrentDisplay(EGLDisplay dpy)
    145 {
    146     Current *current = GetCurrentData();
    147 
    148     current->display = dpy;
    149 }
    150 
    151 EGLDisplay getCurrentDisplay()
    152 {
    153     Current *current = GetCurrentData();
    154 
    155     return current->display;
    156 }
    157 
    158 void setCurrentDrawSurface(EGLSurface surface)
    159 {
    160     Current *current = GetCurrentData();
    161 
    162     current->drawSurface = surface;
    163 }
    164 
    165 EGLSurface getCurrentDrawSurface()
    166 {
    167     Current *current = GetCurrentData();
    168 
    169     return current->drawSurface;
    170 }
    171 
    172 void setCurrentReadSurface(EGLSurface surface)
    173 {
    174     Current *current = GetCurrentData();
    175 
    176     current->readSurface = surface;
    177 }
    178 
    179 EGLSurface getCurrentReadSurface()
    180 {
    181     Current *current = GetCurrentData();
    182 
    183     return current->readSurface;
    184 }
    185 
    186 void error(EGLint errorCode)
    187 {
    188     egl::setCurrentError(errorCode);
    189 }
    190 
    191 }
    192