blob: a56b6bb6095a434388ab371a724b0eaefa17059a [file] [log] [blame]
// Copyright (c) 2010 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 "app/gfx/gl/gl_implementation.h"
#include <algorithm>
#include <string>
#include "app/app_switches.h"
#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/logging.h"
namespace gfx {
const char kGLImplementationDesktopName[] = "desktop";
const char kGLImplementationOSMesaName[] = "osmesa";
const char kGLImplementationEGLName[] = "egl";
const char kGLImplementationMockName[] = "mock";
namespace {
const struct {
const char* name;
GLImplementation implementation;
} kGLImplementationNamePairs[] = {
{ kGLImplementationDesktopName, kGLImplementationDesktopGL },
{ kGLImplementationOSMesaName, kGLImplementationOSMesaGL },
{ kGLImplementationEGLName, kGLImplementationEGLGLES2 },
{ kGLImplementationMockName, kGLImplementationMockGL }
};
typedef std::vector<base::NativeLibrary> LibraryArray;
GLImplementation g_gl_implementation = kGLImplementationNone;
LibraryArray* g_libraries;
GLGetProcAddressProc g_get_proc_address;
void CleanupNativeLibraries(void* unused) {
if (g_libraries) {
for (LibraryArray::iterator it = g_libraries->begin();
it != g_libraries->end(); ++it) {
base::UnloadNativeLibrary(*it);
}
delete g_libraries;
g_libraries = NULL;
}
}
}
GLImplementation GetNamedGLImplementation(const std::string& name) {
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
if (name == kGLImplementationNamePairs[i].name)
return kGLImplementationNamePairs[i].implementation;
}
return kGLImplementationNone;
}
const char* GetGLImplementationName(GLImplementation implementation) {
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kGLImplementationNamePairs); ++i) {
if (implementation == kGLImplementationNamePairs[i].implementation)
return kGLImplementationNamePairs[i].name;
}
return "unknown";
}
bool InitializeRequestedGLBindings(
const GLImplementation* allowed_implementations_begin,
const GLImplementation* allowed_implementations_end,
GLImplementation default_implementation) {
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kUseGL)) {
std::string requested_implementation_name =
CommandLine::ForCurrentProcess()->GetSwitchValueASCII(switches::kUseGL);
GLImplementation requested_implementation =
GetNamedGLImplementation(requested_implementation_name);
if (std::find(allowed_implementations_begin,
allowed_implementations_end,
requested_implementation) == allowed_implementations_end) {
LOG(ERROR) << "Requested GL implementation is not available.";
return false;
}
InitializeGLBindings(requested_implementation);
} else {
InitializeGLBindings(default_implementation);
}
if (GetGLImplementation() == kGLImplementationNone) {
LOG(ERROR) << "Could not initialize GL.";
return false;
} else {
LOG(INFO) << "Using "
<< GetGLImplementationName(GetGLImplementation())
<< " GL implementation.";
return true;
}
}
void SetGLImplementation(GLImplementation implementation) {
g_gl_implementation = implementation;
}
GLImplementation GetGLImplementation() {
return g_gl_implementation;
}
void AddGLNativeLibrary(base::NativeLibrary library) {
DCHECK(library);
if (!g_libraries) {
g_libraries = new LibraryArray;
base::AtExitManager::RegisterCallback(CleanupNativeLibraries, NULL);
}
g_libraries->push_back(library);
}
void SetGLGetProcAddressProc(GLGetProcAddressProc proc) {
DCHECK(proc);
g_get_proc_address = proc;
}
void* GetGLProcAddress(const char* name) {
DCHECK(g_gl_implementation != kGLImplementationNone);
if (g_libraries) {
for (size_t i = 0; i < g_libraries->size(); ++i) {
void* proc = base::GetFunctionPointerFromNativeLibrary((*g_libraries)[i],
name);
if (proc)
return proc;
}
}
if (g_get_proc_address) {
void* proc = g_get_proc_address(name);
if (proc)
return proc;
}
return NULL;
}
} // namespace gfx