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/command_line.h"
7#include "base/files/file_path.h"
8#include "base/logging.h"
9#include "base/native_library.h"
10#include "base/path_service.h"
11#include "ui/gl/gl_bindings.h"
12#include "ui/gl/gl_context_stub_with_extensions.h"
13#include "ui/gl/gl_egl_api_implementation.h"
14#include "ui/gl/gl_gl_api_implementation.h"
15#include "ui/gl/gl_implementation.h"
16#include "ui/gl/gl_implementation_osmesa.h"
17#include "ui/gl/gl_osmesa_api_implementation.h"
18
19namespace gfx {
20
21namespace {
22
23void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
24  glClearDepthf(static_cast<GLclampf>(depth));
25}
26
27void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
28                                                    GLclampd z_far) {
29  glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
30}
31
32}  // namespace
33
34void GetAllowedGLImplementations(std::vector<GLImplementation>* impls) {
35  impls->push_back(kGLImplementationEGLGLES2);
36  impls->push_back(kGLImplementationOSMesaGL);
37}
38
39bool InitializeStaticGLBindings(GLImplementation implementation) {
40  // Prevent reinitialization with a different implementation. Once the gpu
41  // unit tests have initialized with kGLImplementationMock, we don't want to
42  // later switch to another GL implementation.
43  DCHECK_EQ(kGLImplementationNone, GetGLImplementation());
44
45  switch (implementation) {
46    case kGLImplementationEGLGLES2: {
47      base::NativeLibrary gles_library =
48          LoadLibraryAndPrintError("libGLESv2.so");
49      if (!gles_library)
50        return false;
51      base::NativeLibrary egl_library = LoadLibraryAndPrintError("libEGL.so");
52      if (!egl_library) {
53        base::UnloadNativeLibrary(gles_library);
54        return false;
55      }
56
57      GLGetProcAddressProc get_proc_address =
58          reinterpret_cast<GLGetProcAddressProc>(
59              base::GetFunctionPointerFromNativeLibrary(
60                  egl_library, "eglGetProcAddress"));
61      if (!get_proc_address) {
62        LOG(ERROR) << "eglGetProcAddress not found.";
63        base::UnloadNativeLibrary(egl_library);
64        base::UnloadNativeLibrary(gles_library);
65        return false;
66      }
67
68      SetGLGetProcAddressProc(get_proc_address);
69      AddGLNativeLibrary(egl_library);
70      AddGLNativeLibrary(gles_library);
71      SetGLImplementation(kGLImplementationEGLGLES2);
72
73      InitializeStaticGLBindingsGL();
74      InitializeStaticGLBindingsEGL();
75
76      // These two functions take single precision float rather than double
77      // precision float parameters in GLES.
78      ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf;
79      ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef;
80      break;
81    }
82    case kGLImplementationOSMesaGL:
83      InitializeStaticGLBindingsOSMesaGL();
84      break;
85    case kGLImplementationMockGL: {
86      SetGLImplementation(kGLImplementationMockGL);
87      InitializeStaticGLBindingsGL();
88      break;
89    }
90    default:
91      NOTIMPLEMENTED() << "InitializeStaticGLBindings on Android";
92      return false;
93  }
94
95  return true;
96}
97
98bool InitializeDynamicGLBindings(GLImplementation implementation,
99                                 GLContext* context) {
100  switch (implementation) {
101    case kGLImplementationEGLGLES2:
102      InitializeDynamicGLBindingsGL(context);
103      InitializeDynamicGLBindingsEGL(context);
104      break;
105    case kGLImplementationOSMesaGL:
106      InitializeDynamicGLBindingsGL(context);
107      InitializeDynamicGLBindingsOSMESA(context);
108      break;
109    case kGLImplementationMockGL:
110      if (!context) {
111        scoped_refptr<GLContextStubWithExtensions> mock_context(
112            new GLContextStubWithExtensions());
113        mock_context->SetGLVersionString("opengl es 3.0");
114        InitializeDynamicGLBindingsGL(mock_context.get());
115      } else
116        InitializeDynamicGLBindingsGL(context);
117      break;
118    default:
119      NOTREACHED() << "InitializeDynamicGLBindings on Android";
120      return false;
121  }
122
123  return true;
124}
125
126void InitializeDebugGLBindings() {
127  InitializeDebugGLBindingsEGL();
128  InitializeDebugGLBindingsGL();
129  InitializeDebugGLBindingsOSMESA();
130}
131
132void ClearGLBindings() {
133  ClearGLBindingsEGL();
134  ClearGLBindingsGL();
135  ClearGLBindingsOSMESA();
136  SetGLImplementation(kGLImplementationNone);
137
138  UnloadGLNativeLibraries();
139}
140
141bool GetGLWindowSystemBindingInfo(GLWindowSystemBindingInfo* info) {
142  switch (GetGLImplementation()) {
143    case kGLImplementationEGLGLES2:
144      return GetGLWindowSystemBindingInfoEGL(info);
145    default:
146      return false;
147  }
148  return false;
149}
150
151}  // namespace gfx
152