Home | History | Annotate | Download | only in libGLESv2
      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 "libGLESv2/main.h"
     10 #include "libGLESv2/Context.h"
     11 
     12 #include "common/tls.h"
     13 
     14 static TLSIndex currentTLS = TLS_OUT_OF_INDEXES;
     15 
     16 namespace gl
     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->context = NULL;
     29     current->display = NULL;
     30 
     31     if (!SetTLSValue(currentTLS, current))
     32     {
     33         ERR("Could not set thread local storage.");
     34         return NULL;
     35     }
     36 
     37     return current;
     38 }
     39 
     40 void DeallocateCurrent()
     41 {
     42     Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
     43     SafeDelete(current);
     44     SetTLSValue(currentTLS, NULL);
     45 }
     46 
     47 }
     48 
     49 extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
     50 {
     51     switch (reason)
     52     {
     53       case DLL_PROCESS_ATTACH:
     54         {
     55             currentTLS = CreateTLSIndex();
     56             if (currentTLS == TLS_OUT_OF_INDEXES)
     57             {
     58                 return FALSE;
     59             }
     60         }
     61         // Fall through to initialize index
     62       case DLL_THREAD_ATTACH:
     63         {
     64             gl::AllocateCurrent();
     65         }
     66         break;
     67       case DLL_THREAD_DETACH:
     68         {
     69             gl::DeallocateCurrent();
     70         }
     71         break;
     72       case DLL_PROCESS_DETACH:
     73         {
     74             gl::DeallocateCurrent();
     75             DestroyTLSIndex(currentTLS);
     76         }
     77         break;
     78       default:
     79         break;
     80     }
     81 
     82     return TRUE;
     83 }
     84 
     85 namespace gl
     86 {
     87 
     88 Current *GetCurrentData()
     89 {
     90     Current *current = reinterpret_cast<Current*>(GetTLSValue(currentTLS));
     91 
     92     // ANGLE issue 488: when the dll is loaded after thread initialization,
     93     // thread local storage (current) might not exist yet.
     94     return (current ? current : AllocateCurrent());
     95 }
     96 
     97 void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface)
     98 {
     99     Current *current = GetCurrentData();
    100 
    101     current->context = context;
    102     current->display = display;
    103 
    104     if (context && display && surface)
    105     {
    106         context->makeCurrent(surface);
    107     }
    108 }
    109 
    110 Context *getContext()
    111 {
    112     Current *current = GetCurrentData();
    113 
    114     return current->context;
    115 }
    116 
    117 Context *getNonLostContext()
    118 {
    119     Context *context = getContext();
    120 
    121     if (context)
    122     {
    123         if (context->isContextLost())
    124         {
    125             gl::error(GL_OUT_OF_MEMORY);
    126             return NULL;
    127         }
    128         else
    129         {
    130             return context;
    131         }
    132     }
    133     return NULL;
    134 }
    135 
    136 egl::Display *getDisplay()
    137 {
    138     Current *current = GetCurrentData();
    139 
    140     return current->display;
    141 }
    142 
    143 // Records an error code
    144 void error(GLenum errorCode)
    145 {
    146     gl::Context *context = glGetCurrentContext();
    147     context->recordError(Error(errorCode));
    148 
    149     switch (errorCode)
    150     {
    151       case GL_INVALID_ENUM:
    152         TRACE("\t! Error generated: invalid enum\n");
    153         break;
    154       case GL_INVALID_VALUE:
    155         TRACE("\t! Error generated: invalid value\n");
    156         break;
    157       case GL_INVALID_OPERATION:
    158         TRACE("\t! Error generated: invalid operation\n");
    159         break;
    160       case GL_OUT_OF_MEMORY:
    161         TRACE("\t! Error generated: out of memory\n");
    162         break;
    163       case GL_INVALID_FRAMEBUFFER_OPERATION:
    164         TRACE("\t! Error generated: invalid framebuffer operation\n");
    165         break;
    166       default: UNREACHABLE();
    167     }
    168 }
    169 
    170 }
    171 
    172