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 14static DWORD currentTLS = TLS_OUT_OF_INDEXES; 15 16namespace gl 17{ 18 19Current *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 38void DeallocateCurrent() 39{ 40 void *current = TlsGetValue(currentTLS); 41 42 if (current) 43 { 44 LocalFree((HLOCAL)current); 45 } 46} 47 48} 49 50extern "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 87namespace gl 88{ 89 90Current *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 99void 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 112Context *getContext() 113{ 114 Current *current = GetCurrentData(); 115 116 return current->context; 117} 118 119Context *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 138egl::Display *getDisplay() 139{ 140 Current *current = GetCurrentData(); 141 142 return current->display; 143} 144 145// Records an error code 146void 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