Home | History | Annotate | Download | only in gl
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/gl/gl_implementation.h"
      6 
      7 #include <algorithm>
      8 #include <string>
      9 
     10 #include "base/at_exit.h"
     11 #include "base/command_line.h"
     12 #include "base/logging.h"
     13 #include "ui/gl/gl_bindings.h"
     14 
     15 namespace gfx {
     16 
     17 namespace {
     18 
     19 const struct {
     20   const char* name;
     21   GLImplementation implementation;
     22 } kGLImplementationNamePairs[] = {
     23   { kGLImplementationDesktopName, kGLImplementationDesktopGL },
     24   { kGLImplementationOSMesaName, kGLImplementationOSMesaGL },
     25 #if defined(OS_MACOSX)
     26   { kGLImplementationAppleName, kGLImplementationAppleGL },
     27 #endif
     28   { kGLImplementationEGLName, kGLImplementationEGLGLES2 },
     29   { kGLImplementationMockName, kGLImplementationMockGL }
     30 };
     31 
     32 typedef std::vector<base::NativeLibrary> LibraryArray;
     33 
     34 GLImplementation g_gl_implementation = kGLImplementationNone;
     35 LibraryArray* g_libraries;
     36 GLGetProcAddressProc g_get_proc_address;
     37 
     38 void CleanupNativeLibraries(void* unused) {
     39   if (g_libraries) {
     40     for (LibraryArray::iterator it = g_libraries->begin();
     41          it != g_libraries->end(); ++it) {
     42       base::UnloadNativeLibrary(*it);
     43     }
     44     delete g_libraries;
     45     g_libraries = NULL;
     46   }
     47 }
     48 
     49 bool ExportsCoreFunctionsFromGetProcAddress(GLImplementation implementation) {
     50   switch (GetGLImplementation()) {
     51     case kGLImplementationDesktopGL:
     52     case kGLImplementationOSMesaGL:
     53     case kGLImplementationAppleGL:
     54     case kGLImplementationMockGL:
     55       return true;
     56     case kGLImplementationEGLGLES2:
     57       return false;
     58     default:
     59       NOTREACHED();
     60       return true;
     61   }
     62 }
     63 
     64 }
     65 
     66 base::ThreadLocalPointer<GLApi>* g_current_gl_context_tls = NULL;
     67 OSMESAApi* g_current_osmesa_context;
     68 
     69 #if defined(OS_WIN)
     70 
     71 EGLApi* g_current_egl_context;
     72 WGLApi* g_current_wgl_context;
     73 
     74 #elif defined(USE_X11)
     75 
     76 EGLApi* g_current_egl_context;
     77 GLXApi* g_current_glx_context;
     78 
     79 #elif defined(USE_OZONE)
     80 
     81 EGLApi* g_current_egl_context;
     82 
     83 #elif defined(OS_ANDROID)
     84 
     85 EGLApi* g_current_egl_context;
     86 
     87 #endif
     88 
     89 GLImplementation GetNamedGLImplementation(const std::string& name) {
     90   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
     91     if (name == kGLImplementationNamePairs[i].name)
     92       return kGLImplementationNamePairs[i].implementation;
     93   }
     94 
     95   return kGLImplementationNone;
     96 }
     97 
     98 const char* GetGLImplementationName(GLImplementation implementation) {
     99   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
    100     if (implementation == kGLImplementationNamePairs[i].implementation)
    101       return kGLImplementationNamePairs[i].name;
    102   }
    103 
    104   return "unknown";
    105 }
    106 
    107 void SetGLImplementation(GLImplementation implementation) {
    108   g_gl_implementation = implementation;
    109 }
    110 
    111 GLImplementation GetGLImplementation() {
    112   return g_gl_implementation;
    113 }
    114 
    115 bool HasDesktopGLFeatures() {
    116   return kGLImplementationDesktopGL == g_gl_implementation ||
    117          kGLImplementationOSMesaGL == g_gl_implementation ||
    118          kGLImplementationAppleGL == g_gl_implementation;
    119 }
    120 
    121 void AddGLNativeLibrary(base::NativeLibrary library) {
    122   DCHECK(library);
    123 
    124   if (!g_libraries) {
    125     g_libraries = new LibraryArray;
    126     base::AtExitManager::RegisterCallback(CleanupNativeLibraries, NULL);
    127   }
    128 
    129   g_libraries->push_back(library);
    130 }
    131 
    132 void UnloadGLNativeLibraries() {
    133   CleanupNativeLibraries(NULL);
    134 }
    135 
    136 void SetGLGetProcAddressProc(GLGetProcAddressProc proc) {
    137   DCHECK(proc);
    138   g_get_proc_address = proc;
    139 }
    140 
    141 void* GetGLCoreProcAddress(const char* name) {
    142   DCHECK(g_gl_implementation != kGLImplementationNone);
    143 
    144   if (g_libraries) {
    145     for (size_t i = 0; i < g_libraries->size(); ++i) {
    146       void* proc = base::GetFunctionPointerFromNativeLibrary((*g_libraries)[i],
    147                                                              name);
    148       if (proc)
    149         return proc;
    150     }
    151   }
    152   if (ExportsCoreFunctionsFromGetProcAddress(g_gl_implementation) &&
    153       g_get_proc_address) {
    154     void* proc = g_get_proc_address(name);
    155     if (proc)
    156       return proc;
    157   }
    158 
    159   return NULL;
    160 }
    161 
    162 void* GetGLProcAddress(const char* name) {
    163   DCHECK(g_gl_implementation != kGLImplementationNone);
    164 
    165   void* proc = GetGLCoreProcAddress(name);
    166   if (!proc && g_get_proc_address) {
    167     proc = g_get_proc_address(name);
    168     if (proc)
    169       return proc;
    170   }
    171 
    172   return proc;
    173 }
    174 
    175 }  // namespace gfx
    176