// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/base_paths.h" #include "base/command_line.h" #include "base/file_path.h" #include "base/logging.h" #include "base/native_library.h" #include "base/path_service.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_egl_api_implementation.h" #include "ui/gl/gl_gl_api_implementation.h" #include "ui/gl/gl_implementation.h" #include "ui/gl/gl_osmesa_api_implementation.h" namespace gfx { namespace { void GL_BINDING_CALL MarshalClearDepthToClearDepthf(GLclampd depth) { glClearDepthf(static_cast(depth)); } void GL_BINDING_CALL MarshalDepthRangeToDepthRangef(GLclampd z_near, GLclampd z_far) { glDepthRangef(static_cast(z_near), static_cast(z_far)); } base::NativeLibrary LoadLibrary(const FilePath& filename) { std::string error; base::NativeLibrary library = base::LoadNativeLibrary(filename, &error); if (!library) { DVLOG(1) << "Failed to load " << filename.MaybeAsASCII() << ": " << error; return NULL; } return library; } base::NativeLibrary LoadLibrary(const char* filename) { return LoadLibrary(FilePath(filename)); } } // namespace void GetAllowedGLImplementations(std::vector* impls) { impls->push_back(kGLImplementationEGLGLES2); } bool InitializeGLBindings(GLImplementation implementation) { // Prevent reinitialization with a different implementation. Once the gpu // unit tests have initialized with kGLImplementationMock, we don't want to // later switch to another GL implementation. if (GetGLImplementation() != kGLImplementationNone) return true; switch (implementation) { case kGLImplementationEGLGLES2: { base::NativeLibrary gles_library = LoadLibrary("libGLESv2.so"); if (!gles_library) return false; base::NativeLibrary egl_library = LoadLibrary("libEGL.so"); if (!egl_library) { base::UnloadNativeLibrary(gles_library); return false; } GLGetProcAddressProc get_proc_address = reinterpret_cast( base::GetFunctionPointerFromNativeLibrary( egl_library, "eglGetProcAddress")); if (!get_proc_address) { LOG(ERROR) << "eglGetProcAddress not found."; base::UnloadNativeLibrary(egl_library); base::UnloadNativeLibrary(gles_library); return false; } SetGLGetProcAddressProc(get_proc_address); AddGLNativeLibrary(egl_library); AddGLNativeLibrary(gles_library); SetGLImplementation(kGLImplementationEGLGLES2); InitializeGLBindingsGL(); InitializeGLBindingsEGL(); // These two functions take single precision float rather than double // precision float parameters in GLES. ::gfx::g_driver_gl.fn.glClearDepthFn = MarshalClearDepthToClearDepthf; ::gfx::g_driver_gl.fn.glDepthRangeFn = MarshalDepthRangeToDepthRangef; break; } case kGLImplementationMockGL: { SetGLGetProcAddressProc(GetMockGLProcAddress); SetGLImplementation(kGLImplementationMockGL); InitializeGLBindingsGL(); break; } default: NOTIMPLEMENTED() << "InitializeGLBindings on Android"; return false; } return true; } bool InitializeGLExtensionBindings(GLImplementation implementation, GLContext* context) { switch (implementation) { case kGLImplementationEGLGLES2: InitializeGLExtensionBindingsGL(context); InitializeGLExtensionBindingsEGL(context); break; case kGLImplementationMockGL: InitializeGLExtensionBindingsGL(context); break; default: return false; } return true; } void InitializeDebugGLBindings() { } void ClearGLBindings() { ClearGLBindingsEGL(); ClearGLBindingsGL(); SetGLImplementation(kGLImplementationNone); UnloadGLNativeLibraries(); } } // namespace gfx