blob: 3bad24ee4d6623b03468360810e5bd975fbe9b3a [file] [log] [blame]
[email protected]b9363b22010-06-09 22:06:151// Copyright (c) 2010 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 <dlfcn.h>
[email protected]0bec8e22010-06-21 22:20:026#include <vector>
[email protected]b9363b22010-06-09 22:06:157
[email protected]0bec8e22010-06-21 22:20:028#include "base/at_exit.h"
[email protected]b9363b22010-06-09 22:06:159#include "base/logging.h"
10#include "app/gfx/gl/gl_bindings.h"
11#include "app/gfx/gl/gl_context_stub.h"
12#include "app/gfx/gl/gl_implementation.h"
13
14namespace gfx {
15namespace {
16typedef void* (*GetProcAddressProc)(const char* name);
17
18GLImplementation g_gl_implementation = kGLImplementationNone;
[email protected]0bec8e22010-06-21 22:20:0219typedef std::vector<void*> PointerArray;
20PointerArray* g_shared_libraries = NULL;
[email protected]b9363b22010-06-09 22:06:1521GetProcAddressProc g_get_proc_address;
[email protected]0bec8e22010-06-21 22:20:0222
23// TODO(piman): it should be Desktop GL marshalling from double to float. Today
24// on native GLES, we do float->double->float.
25void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) {
26 glClearDepthf(static_cast<GLclampf>(depth));
27}
28
29void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near,
30 GLclampd z_far) {
31 glDepthRangef(static_cast<GLclampf>(z_near), static_cast<GLclampf>(z_far));
32}
33
34void CleanupSharedLibraries(void* unused) {
35 if (g_shared_libraries) {
36 for (PointerArray::iterator it = g_shared_libraries->begin();
37 it != g_shared_libraries->end(); ++it) {
38 dlclose(*it);
39 }
40 delete g_shared_libraries;
41 g_shared_libraries = NULL;
42 }
43}
44
[email protected]b9363b22010-06-09 22:06:1545} // namespace anonymous
46
47bool InitializeGLBindings(GLImplementation implementation) {
48 // Prevent reinitialization with a different implementation. Once the gpu
49 // unit tests have initialized with kGLImplementationMock, we don't want to
50 // later switch to another GL implementation.
51 if (g_gl_implementation != kGLImplementationNone)
52 return true;
53
[email protected]0bec8e22010-06-21 22:20:0254 if (!g_shared_libraries) {
55 g_shared_libraries = new PointerArray();
56 base::AtExitManager::RegisterCallback(CleanupSharedLibraries, NULL);
57 }
58
59 void* shared_library = NULL;
60
[email protected]b9363b22010-06-09 22:06:1561 switch (implementation) {
62 case kGLImplementationDesktopGL:
[email protected]0bec8e22010-06-21 22:20:0263 DLOG(INFO) << "Initializing Desktop GL";
64 shared_library = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
65 if (!shared_library) {
66 DLOG(ERROR) << "Failed to load libGL.so.1";
[email protected]b9363b22010-06-09 22:06:1567 return false;
[email protected]0bec8e22010-06-21 22:20:0268 }
69
70 g_shared_libraries->push_back(shared_library);
[email protected]b9363b22010-06-09 22:06:1571
72 g_gl_implementation = kGLImplementationDesktopGL;
73
74 g_get_proc_address = reinterpret_cast<GetProcAddressProc>(
[email protected]0bec8e22010-06-21 22:20:0275 dlsym(shared_library, "glXGetProcAddress"));
[email protected]b9363b22010-06-09 22:06:1576 CHECK(g_get_proc_address);
77
78 InitializeGLBindingsGL();
79 InitializeGLBindingsGLX();
80 break;
81
[email protected]0bec8e22010-06-21 22:20:0282 case kGLImplementationEGLGLES2:
83 DLOG(INFO) << "Initializing EGL";
84 shared_library = dlopen("libEGL.so", RTLD_LAZY | RTLD_LOCAL);
85 if (!shared_library) {
86 DLOG(ERROR) << "Failed to load libEGL.so";
87 return false;
88 }
89
90 g_gl_implementation = kGLImplementationEGLGLES2;
91
92 g_get_proc_address = reinterpret_cast<GetProcAddressProc>(
93 dlsym(shared_library, "eglGetProcAddress"));
94 DCHECK(g_get_proc_address);
95
96 g_shared_libraries->push_back(shared_library);
97
98 shared_library = dlopen("libGLESv2.so", RTLD_LAZY | RTLD_LOCAL);
99 if (!shared_library) {
100 DLOG(ERROR) << "Failed to load libGLESv2.so";
101 g_shared_libraries->clear();
102 return false;
103 }
104
105 DCHECK(shared_library);
106
107 g_shared_libraries->push_back(shared_library);
108
109 InitializeGLBindingsGL();
110 InitializeGLBindingsEGL();
111
112 // These two functions take single precision float rather than double
113 // precision float parameters in GLES.
114 ::gfx::g_glClearDepth = MarshalClearDepthToClearDepthf;
115 ::gfx::g_glDepthRange = MarshalDepthRangeToDepthRangef;
116 break;
117
[email protected]b9363b22010-06-09 22:06:15118 case kGLImplementationMockGL:
119 g_get_proc_address = GetMockGLProcAddress;
120 g_gl_implementation = kGLImplementationMockGL;
121 InitializeGLBindingsGL();
122 break;
123
124 default:
125 return false;
126 }
127
128
129 return true;
130}
131
132GLImplementation GetGLImplementation() {
133 return g_gl_implementation;
134}
135
136void* GetGLProcAddress(const char* name) {
137 DCHECK(g_gl_implementation != kGLImplementationNone);
138
139 if (g_get_proc_address) {
140 void* proc = g_get_proc_address(name);
141 if (proc)
142 return proc;
143 }
144
[email protected]0bec8e22010-06-21 22:20:02145 if (g_shared_libraries) {
146 for (PointerArray::iterator it = g_shared_libraries->begin();
147 it != g_shared_libraries->end(); ++it) {
148 void* proc = dlsym(*it, name);
149 if (proc)
150 return proc;
151 }
[email protected]b9363b22010-06-09 22:06:15152 }
153
154 return NULL;
155}
156
157} // namespace gfx