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     // We do not call base::UnloadNativeLibrary() for these libraries as
     41     // unloading libGL without closing X display is not allowed. See
     42     // crbug.com/250813 for details.
     43     delete g_libraries;
     44     g_libraries = NULL;
     45   }
     46 }
     47 
     48 bool ExportsCoreFunctionsFromGetProcAddress(GLImplementation implementation) {
     49   switch (GetGLImplementation()) {
     50     case kGLImplementationDesktopGL:
     51     case kGLImplementationOSMesaGL:
     52     case kGLImplementationAppleGL:
     53     case kGLImplementationMockGL:
     54       return true;
     55     case kGLImplementationEGLGLES2:
     56       return false;
     57     default:
     58       NOTREACHED();
     59       return true;
     60   }
     61 }
     62 
     63 }
     64 
     65 base::ThreadLocalPointer<GLApi>* g_current_gl_context_tls = NULL;
     66 OSMESAApi* g_current_osmesa_context;
     67 
     68 #if defined(OS_WIN)
     69 
     70 EGLApi* g_current_egl_context;
     71 WGLApi* g_current_wgl_context;
     72 
     73 #elif defined(USE_X11)
     74 
     75 EGLApi* g_current_egl_context;
     76 GLXApi* g_current_glx_context;
     77 
     78 #elif defined(USE_OZONE)
     79 
     80 EGLApi* g_current_egl_context;
     81 
     82 #elif defined(OS_ANDROID)
     83 
     84 EGLApi* g_current_egl_context;
     85 
     86 #endif
     87 
     88 GLImplementation GetNamedGLImplementation(const std::string& name) {
     89   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
     90     if (name == kGLImplementationNamePairs[i].name)
     91       return kGLImplementationNamePairs[i].implementation;
     92   }
     93 
     94   return kGLImplementationNone;
     95 }
     96 
     97 const char* GetGLImplementationName(GLImplementation implementation) {
     98   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
     99     if (implementation == kGLImplementationNamePairs[i].implementation)
    100       return kGLImplementationNamePairs[i].name;
    101   }
    102 
    103   return "unknown";
    104 }
    105 
    106 void SetGLImplementation(GLImplementation implementation) {
    107   g_gl_implementation = implementation;
    108 }
    109 
    110 GLImplementation GetGLImplementation() {
    111   return g_gl_implementation;
    112 }
    113 
    114 bool HasDesktopGLFeatures() {
    115   return kGLImplementationDesktopGL == g_gl_implementation ||
    116          kGLImplementationOSMesaGL == g_gl_implementation ||
    117          kGLImplementationAppleGL == g_gl_implementation;
    118 }
    119 
    120 void AddGLNativeLibrary(base::NativeLibrary library) {
    121   DCHECK(library);
    122 
    123   if (!g_libraries) {
    124     g_libraries = new LibraryArray;
    125     base::AtExitManager::RegisterCallback(CleanupNativeLibraries, NULL);
    126   }
    127 
    128   g_libraries->push_back(library);
    129 }
    130 
    131 void UnloadGLNativeLibraries() {
    132   CleanupNativeLibraries(NULL);
    133 }
    134 
    135 void SetGLGetProcAddressProc(GLGetProcAddressProc proc) {
    136   DCHECK(proc);
    137   g_get_proc_address = proc;
    138 }
    139 
    140 void* GetGLCoreProcAddress(const char* name) {
    141   DCHECK(g_gl_implementation != kGLImplementationNone);
    142 
    143   if (g_libraries) {
    144     for (size_t i = 0; i < g_libraries->size(); ++i) {
    145       void* proc = base::GetFunctionPointerFromNativeLibrary((*g_libraries)[i],
    146                                                              name);
    147       if (proc)
    148         return proc;
    149     }
    150   }
    151   if (ExportsCoreFunctionsFromGetProcAddress(g_gl_implementation) &&
    152       g_get_proc_address) {
    153     void* proc = g_get_proc_address(name);
    154     if (proc)
    155       return proc;
    156   }
    157 
    158   return NULL;
    159 }
    160 
    161 void* GetGLProcAddress(const char* name) {
    162   DCHECK(g_gl_implementation != kGLImplementationNone);
    163 
    164   void* proc = GetGLCoreProcAddress(name);
    165   if (!proc && g_get_proc_address) {
    166     proc = g_get_proc_address(name);
    167     if (proc)
    168       return proc;
    169   }
    170 
    171   return proc;
    172 }
    173 
    174 }  // namespace gfx
    175