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 "base/base_paths.h"
      6 #include "base/files/file_path.h"
      7 #include "base/logging.h"
      8 #include "base/mac/foundation_util.h"
      9 #include "base/native_library.h"
     10 #include "base/path_service.h"
     11 #include "base/threading/thread_restrictions.h"
     12 #include "ui/gl/gl_bindings.h"
     13 #include "ui/gl/gl_context_stub_with_extensions.h"
     14 #include "ui/gl/gl_gl_api_implementation.h"
     15 #include "ui/gl/gl_implementation.h"
     16 #include "ui/gl/gl_osmesa_api_implementation.h"
     17 
     18 namespace gfx {
     19 namespace {
     20 const char kOpenGLFrameworkPath[] =
     21     "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL";
     22 }  // namespace
     23 
     24 void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
     25   impls->push_back(kGLImplementationDesktopGL);
     26   impls->push_back(kGLImplementationAppleGL);
     27   impls->push_back(kGLImplementationOSMesaGL);
     28 }
     29 
     30 bool InitializeStaticGLBindings(GLImplementation implementation) {
     31   // Prevent reinitialization with a different implementation. Once the gpu
     32   // unit tests have initialized with kGLImplementationMock, we don't want to
     33   // later switch to another GL implementation.
     34   DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
     35 
     36   // Allow the main thread or another to initialize these bindings
     37   // after instituting restrictions on I/O. Going forward they will
     38   // likely be used in the browser process on most platforms. The
     39   // one-time initialization cost is small, between 2 and 5 ms.
     40   base::ThreadRestrictions::ScopedAllowIO allow_io;
     41 
     42   switch (implementation) {
     43     case kGLImplementationOSMesaGL: {
     44       // osmesa.so is located in the build directory. This code path is only
     45       // valid in a developer build environment.
     46       base::FilePath exe_path;
     47       if (!PathService::Get(base::FILE_EXE, &exe_path)) {
     48         LOG(ERROR) << "PathService::Get failed.";
     49         return false;
     50       }
     51       base::FilePath bundle_path = base::mac::GetAppBundlePath(exe_path);
     52       // Some unit test targets depend on osmesa but aren't built as app
     53       // bundles. In that case, the .so is next to the executable.
     54       if (bundle_path.empty())
     55         bundle_path = exe_path;
     56       base::FilePath build_dir_path = bundle_path.DirName();
     57       base::FilePath osmesa_path = build_dir_path.Append("osmesa.so");
     58 
     59       // When using OSMesa, just use OSMesaGetProcAddress to find entry points.
     60       base::NativeLibrary library = base::LoadNativeLibrary(osmesa_path, NULL);
     61       if (!library) {
     62         LOG(ERROR) << "osmesa.so not found at " << osmesa_path.value();
     63         return false;
     64       }
     65 
     66       GLGetProcAddressProc get_proc_address =
     67           reinterpret_cast<GLGetProcAddressProc>(
     68               base::GetFunctionPointerFromNativeLibrary(
     69                   library, "OSMesaGetProcAddress"));
     70       if (!get_proc_address) {
     71         LOG(ERROR) << "OSMesaGetProcAddress not found.";
     72         base::UnloadNativeLibrary(library);
     73         return false;
     74       }
     75 
     76       SetGLGetProcAddressProc(get_proc_address);
     77       AddGLNativeLibrary(library);
     78       SetGLImplementation(kGLImplementationOSMesaGL);
     79 
     80       InitializeStaticGLBindingsGL();
     81       InitializeStaticGLBindingsOSMESA();
     82       break;
     83     }
     84     case kGLImplementationDesktopGL:
     85     case kGLImplementationAppleGL: {
     86       base::NativeLibrary library = base::LoadNativeLibrary(
     87           base::FilePath(kOpenGLFrameworkPath), NULL);
     88       if (!library) {
     89         LOG(ERROR) << "OpenGL framework not found";
     90         return false;
     91       }
     92 
     93       AddGLNativeLibrary(library);
     94       SetGLImplementation(implementation);
     95 
     96       InitializeStaticGLBindingsGL();
     97       break;
     98     }
     99     case kGLImplementationMockGL: {
    100       SetGLImplementation(kGLImplementationMockGL);
    101       InitializeStaticGLBindingsGL();
    102       break;
    103     }
    104     default:
    105       return false;
    106   }
    107 
    108   return true;
    109 }
    110 
    111 bool InitializeDynamicGLBindings(GLImplementation implementation,
    112     GLContext* context) {
    113   switch (implementation) {
    114     case kGLImplementationOSMesaGL:
    115       InitializeDynamicGLBindingsGL(context);
    116       InitializeDynamicGLBindingsOSMESA(context);
    117       break;
    118     case kGLImplementationDesktopGL:
    119     case kGLImplementationAppleGL:
    120       InitializeDynamicGLBindingsGL(context);
    121       break;
    122     case kGLImplementationMockGL:
    123       if (!context) {
    124         scoped_refptr<GLContextStubWithExtensions> mock_context(
    125             new GLContextStubWithExtensions());
    126         mock_context->SetGLVersionString("3.0");
    127         InitializeDynamicGLBindingsGL(mock_context.get());
    128       } else
    129         InitializeDynamicGLBindingsGL(context);
    130       break;
    131     default:
    132       return false;
    133   }
    134 
    135   return true;
    136 }
    137 
    138 void InitializeDebugGLBindings() {
    139   InitializeDebugGLBindingsGL();
    140   InitializeDebugGLBindingsOSMESA();
    141 }
    142 
    143 void ClearGLBindings() {
    144   ClearGLBindingsGL();
    145   ClearGLBindingsOSMESA();
    146   SetGLImplementation(kGLImplementationNone);
    147 
    148   UnloadGLNativeLibraries();
    149 }
    150 
    151 bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
    152   return false;
    153 }
    154 
    155 }  // namespace gfx
    156