Home | History | Annotate | Download | only in libGLESv2
      1 #include "precompiled.h"
      2 //
      3 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 //
      7 
      8 // main.cpp: DLL entry point and management of thread-local data.
      9 
     10 #include "libGLESv2/main.h"
     11 
     12 #include "libGLESv2/Context.h"
     13 
     14 static DWORD currentTLS = TLS_OUT_OF_INDEXES;
     15 
     16 namespace gl
     17 {
     18 
     19 Current *AllocateCurrent()
     20 {
     21     Current *current = (Current*)LocalAlloc(LPTR, sizeof(Current));
     22 
     23     if (!current)
     24     {
     25         ERR("Could not allocate thread local storage.");
     26         return NULL;
     27     }
     28 
     29     ASSERT(currentTLS != TLS_OUT_OF_INDEXES);
     30     TlsSetValue(currentTLS, current);
     31 
     32     current->context = NULL;
     33     current->display = NULL;
     34 
     35     return current;
     36 }
     37 
     38 void DeallocateCurrent()
     39 {
     40     void *current = TlsGetValue(currentTLS);
     41 
     42     if (current)
     43     {
     44         LocalFree((HLOCAL)current);
     45     }
     46 }
     47 
     48 }
     49 
     50 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
     51 {
     52     switch (reason)
     53     {
     54       case DLL_PROCESS_ATTACH:
     55         {
     56             currentTLS = TlsAlloc();
     57 
     58             if (currentTLS == TLS_OUT_OF_INDEXES)
     59             {
     60                 return FALSE;
     61             }
     62         }
     63         // Fall throught to initialize index
     64       case DLL_THREAD_ATTACH:
     65         {
     66             gl::AllocateCurrent();
     67         }
     68         break;
     69       case DLL_THREAD_DETACH:
     70         {
     71             gl::DeallocateCurrent();
     72         }
     73         break;
     74       case DLL_PROCESS_DETACH:
     75         {
     76             gl::DeallocateCurrent();
     77             TlsFree(currentTLS);
     78         }
     79         break;
     80       default:
     81         break;
     82     }
     83 
     84     return TRUE;
     85 }
     86 
     87 namespace gl
     88 {
     89 
     90 Current *GetCurrentData()
     91 {
     92     Current *current = (Current*)TlsGetValue(currentTLS);
     93 
     94     // ANGLE issue 488: when the dll is loaded after thread initialization,
     95     // thread local storage (current) might not exist yet.
     96     return (current ? current : AllocateCurrent());
     97 }
     98 
     99 void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
    100 {
    101     Current *current = GetCurrentData();
    102 
    103     current->context = context;
    104     current->display = display;
    105 
    106     if (context && display && surface)
    107     {
    108         context->makeCurrent(surface);
    109     }
    110 }
    111 
    112 Context *getContext()
    113 {
    114     Current *current = GetCurrentData();
    115 
    116     return current->context;
    117 }
    118 
    119 Context *getNonLostContext()
    120 {
    121     Context *context = getContext();
    122 
    123     if (context)
    124     {
    125         if (context->isContextLost())
    126         {
    127             gl::error(GL_OUT_OF_MEMORY);
    128             return NULL;
    129         }
    130         else
    131         {
    132             return context;
    133         }
    134     }
    135     return NULL;
    136 }
    137 
    138 egl::Display *getDisplay()
    139 {
    140     Current *current = GetCurrentData();
    141 
    142     return current->display;
    143 }
    144 
    145 // Records an error code
    146 void error(GLenum errorCode)
    147 {
    148     gl::Context *context = glGetCurrentContext();
    149 
    150     if (context)
    151     {
    152         switch (errorCode)
    153         {
    154           case GL_INVALID_ENUM:
    155             context->recordInvalidEnum();
    156             TRACE("\t! Error generated: invalid enum\n");
    157             break;
    158           case GL_INVALID_VALUE:
    159             context->recordInvalidValue();
    160             TRACE("\t! Error generated: invalid value\n");
    161             break;
    162           case GL_INVALID_OPERATION:
    163             context->recordInvalidOperation();
    164             TRACE("\t! Error generated: invalid operation\n");
    165             break;
    166           case GL_OUT_OF_MEMORY:
    167             context->recordOutOfMemory();
    168             TRACE("\t! Error generated: out of memory\n");
    169             break;
    170           case GL_INVALID_FRAMEBUFFER_OPERATION:
    171             context->recordInvalidFramebufferOperation();
    172             TRACE("\t! Error generated: invalid framebuffer operation\n");
    173             break;
    174           default: UNREACHABLE();
    175         }
    176     }
    177 }
    178 
    179 }
    180 
    181