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 #include "common/tls.h"
     13 
     14 static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
     15 
     16 namespace egl
     17 {
     18 
     19 Current *AllocateCurrent()
     20 {
     21     ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
     22     if (currentTLS == TLS_OUT_OF_INDEXES)
     23     {
     24         return NULL;
     25     }
     26 
     27     Current *current = new Current();
     28     current->error = EGL_SUCCESS;
     29     current->API = EGL_OPENGL_ES_API;
     30     current->display = EGL_NO_DISPLAY;
     31     current->drawSurface = EGL_NO_SURFACE;
     32     current->readSurface = EGL_NO_SURFACE;
     33 
     34     if (!SetTLSValue(currentTLS, current))
     35     {
     36         ERR("Could not set thread local storage.");
     37         return NULL;
     38     }
     39 
     40     return current;
     41 }
     42 
     43 void DeallocateCurrent()
     44 {
     45     Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
     46     SafeDelete(current);
     47     SetTLSValue(currentTLS, NULL);
     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 = CreateTLSIndex();
     74             if (currentTLS == TLS_OUT_OF_INDEXES)
     75             {
     76                 return FALSE;
     77             }
     78         }
     79         // Fall through to initialize index
     80       case DLL_THREAD_ATTACH:
     81         {
     82             egl::AllocateCurrent();
     83         }
     84         break;
     85       case DLL_THREAD_DETACH:
     86         {
     87             egl::DeallocateCurrent();
     88         }
     89         break;
     90       case DLL_PROCESS_DETACH:
     91         {
     92             egl::DeallocateCurrent();
     93             DestroyTLSIndex(currentTLS);
     94         }
     95         break;
     96       default:
     97         break;
     98     }
     99 
    100     return TRUE;
    101 }
    102 
    103 namespace egl
    104 {
    105 
    106 Current *GetCurrentData()
    107 {
    108     Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
    109 
    110     // ANGLE issue 488: when the dll is loaded after thread initialization,
    111     // thread local storage (current) might not exist yet.
    112     return (current ? current : AllocateCurrent());
    113 }
    114 
    115 void setCurrentError(EGLint error)
    116 {
    117     Current *current = GetCurrentData();
    118 
    119     current->error = error;
    120 }
    121 
    122 EGLint getCurrentError()
    123 {
    124     Current *current = GetCurrentData();
    125 
    126     return current->error;
    127 }
    128 
    129 void setCurrentAPI(EGLenum API)
    130 {
    131     Current *current = GetCurrentData();
    132 
    133     current->API = API;
    134 }
    135 
    136 EGLenum getCurrentAPI()
    137 {
    138     Current *current = GetCurrentData();
    139 
    140     return current->API;
    141 }
    142 
    143 void setCurrentDisplay(EGLDisplay dpy)
    144 {
    145     Current *current = GetCurrentData();
    146 
    147     current->display = dpy;
    148 }
    149 
    150 EGLDisplay getCurrentDisplay()
    151 {
    152     Current *current = GetCurrentData();
    153 
    154     return current->display;
    155 }
    156 
    157 void setCurrentDrawSurface(EGLSurface surface)
    158 {
    159     Current *current = GetCurrentData();
    160 
    161     current->drawSurface = surface;
    162 }
    163 
    164 EGLSurface getCurrentDrawSurface()
    165 {
    166     Current *current = GetCurrentData();
    167 
    168     return current->drawSurface;
    169 }
    170 
    171 void setCurrentReadSurface(EGLSurface surface)
    172 {
    173     Current *current = GetCurrentData();
    174 
    175     current->readSurface = surface;
    176 }
    177 
    178 EGLSurface getCurrentReadSurface()
    179 {
    180     Current *current = GetCurrentData();
    181 
    182     return current->readSurface;
    183 }
    184 
    185 void error(EGLint errorCode)
    186 {
    187     egl::setCurrentError(errorCode);
    188 }
    189 
    190 }
    191