Bug 732865 - Clean up the GLContext* classes. r=bgirard,joe

This commit is contained in:
George Wright 2012-03-16 14:30:09 -04:00
Родитель 98b0d12882
Коммит 96d0e2fd38
12 изменённых файлов: 1058 добавлений и 916 удалений

Просмотреть файл

@ -110,94 +110,6 @@ static const char *sExtensionNames[] = {
NULL
};
bool
LibrarySymbolLoader::OpenLibrary(const char *library)
{
PRLibSpec lspec;
lspec.type = PR_LibSpec_Pathname;
lspec.value.pathname = library;
mLibrary = PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
if (!mLibrary)
return false;
return true;
}
bool
LibrarySymbolLoader::LoadSymbols(SymLoadStruct *firstStruct, bool tryplatform, const char *prefix)
{
return LoadSymbols(mLibrary, firstStruct, tryplatform ? mLookupFunc : nsnull, prefix);
}
PRFuncPtr
LibrarySymbolLoader::LookupSymbol(PRLibrary *lib,
const char *sym,
PlatformLookupFunction lookupFunction)
{
PRFuncPtr res = 0;
// try finding it in the library directly, if we have one
if (lib) {
res = PR_FindFunctionSymbol(lib, sym);
}
// then try looking it up via the lookup symbol
if (!res && lookupFunction) {
res = lookupFunction(sym);
}
// finally just try finding it in the process
if (!res) {
PRLibrary *leakedLibRef;
res = PR_FindFunctionSymbolAndLibrary(sym, &leakedLibRef);
}
return res;
}
bool
LibrarySymbolLoader::LoadSymbols(PRLibrary *lib,
SymLoadStruct *firstStruct,
PlatformLookupFunction lookupFunction,
const char *prefix)
{
char sbuf[MAX_SYMBOL_LENGTH * 2];
int failCount = 0;
SymLoadStruct *ss = firstStruct;
while (ss->symPointer) {
*ss->symPointer = 0;
for (int i = 0; i < MAX_SYMBOL_NAMES; i++) {
if (ss->symNames[i] == nsnull)
break;
const char *s = ss->symNames[i];
if (prefix && *prefix != 0) {
strcpy(sbuf, prefix);
strcat(sbuf, ss->symNames[i]);
s = sbuf;
}
PRFuncPtr p = LookupSymbol(lib, s, lookupFunction);
if (p) {
*ss->symPointer = p;
break;
}
}
if (*ss->symPointer == 0) {
fprintf (stderr, "Can't find symbol '%s'\n", ss->symNames[0]);
failCount++;
}
ss++;
}
return failCount == 0 ? true : false;
}
/*
* XXX - we should really know the ARB/EXT variants of these
* instead of only handling the symbol if it's exposed directly.

Просмотреть файл

@ -54,6 +54,7 @@
#endif
#include "GLDefs.h"
#include "GLLibraryLoader.h"
#include "gfxASurface.h"
#include "gfxImageSurface.h"
#include "gfxContext.h"
@ -84,46 +85,6 @@ namespace mozilla {
namespace gl {
class GLContext;
class LibrarySymbolLoader
{
public:
bool OpenLibrary(const char *library);
typedef PRFuncPtr (GLAPIENTRY * PlatformLookupFunction) (const char *);
enum {
MAX_SYMBOL_NAMES = 5,
MAX_SYMBOL_LENGTH = 128
};
typedef struct {
PRFuncPtr *symPointer;
const char *symNames[MAX_SYMBOL_NAMES];
} SymLoadStruct;
bool LoadSymbols(SymLoadStruct *firstStruct,
bool tryplatform = false,
const char *prefix = nsnull);
/*
* Static version of the functions in this class
*/
static PRFuncPtr LookupSymbol(PRLibrary *lib,
const char *symname,
PlatformLookupFunction lookupFunction = nsnull);
static bool LoadSymbols(PRLibrary *lib,
SymLoadStruct *firstStruct,
PlatformLookupFunction lookupFunction = nsnull,
const char *prefix = nsnull);
protected:
LibrarySymbolLoader() {
mLibrary = nsnull;
mLookupFunc = nsnull;
}
PRLibrary *mLibrary;
PlatformLookupFunction mLookupFunc;
};
enum ShaderProgramType {
RGBALayerProgramType,
@ -534,7 +495,7 @@ struct THEBES_API ContextFormat
};
class GLContext
: public LibrarySymbolLoader
: public GLLibraryLoader
{
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLContext)
public:

Просмотреть файл

@ -70,42 +70,23 @@
#include "AndroidBridge.h"
#endif
#include <android/log.h>
// We only need to explicitly dlopen egltrace
// on android as we can use LD_PRELOAD or other tricks
// on other platforms. We look for it in /data/local
// as that's writeable by all users
#define APITRACE_LIB "/data/local/egltrace.so"
#endif
#define EGL_LIB "libEGL.so"
#define GLES2_LIB "libGLESv2.so"
#define EGL_LIB1 "libEGL.so.1"
#define GLES2_LIB2 "libGLESv2.so.2"
typedef void *EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(XP_WIN)
#include "nsILocalFile.h"
#define GLES2_LIB "libGLESv2.dll"
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
typedef HWND EGLNativeWindowType;
#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
#define EGL_LIB "libEGL.dll"
#define GLES2_LIB "libGLESv2.dll"
// a little helper
class AutoDestroyHWND {
public:
@ -156,6 +137,7 @@ public:
#include "gfxImageSurface.h"
#include "gfxPlatform.h"
#include "GLContextProvider.h"
#include "GLLibraryEGL.h"
#include "nsDebug.h"
#include "nsThreadUtils.h"
#include "EGLUtils.h"
@ -177,28 +159,7 @@ extern nsIntRect gScreenBounds;
namespace mozilla {
namespace gl {
typedef int EGLint;
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void *EGLConfig;
typedef void *EGLContext;
typedef void *EGLDisplay;
typedef void *EGLSurface;
typedef void *EGLClientBuffer;
typedef void *EGLCastToRelevantPtr;
typedef void *EGLImageKHR;
typedef void *GLeglImageOES;
#ifdef MOZ_WIDGET_QT
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)QX11Info::display())
#else
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
#endif
#define EGL_NO_CONTEXT ((EGLContext)0)
#define EGL_NO_DISPLAY ((EGLDisplay)0)
#define EGL_NO_SURFACE ((EGLSurface)0)
#define EGL_DISPLAY() sEGLLibrary.Display()
static GLLibraryEGL sEGLLibrary;
#define ADD_ATTR_2(_array, _k, _v) do { \
(_array).AppendElement(_k); \
@ -236,38 +197,6 @@ static EGLint gContextAttribsRobustness[] = {
LOCAL_EGL_NONE
};
static PRLibrary* LoadApitraceLibrary()
{
static PRLibrary* sApitraceLibrary = NULL;
if (sApitraceLibrary)
return sApitraceLibrary;
#if defined(ANDROID)
nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");
if (logFile.IsEmpty()) {
logFile = "firefox.trace";
}
// The firefox process can't write to /data/local, but it can write
// to $GRE_HOME/
nsCAutoString logPath;
logPath.AppendPrintf("%s/%s", getenv("GRE_HOME"), logFile.get());
// apitrace uses the TRACE_FILE environment variable to determine where
// to log trace output to
printf_stderr("Logging GL tracing output to %s", logPath.get());
setenv("TRACE_FILE", logPath.get(), false);
printf_stderr("Attempting load of %s\n", APITRACE_LIB);
sApitraceLibrary = PR_LoadLibrary(APITRACE_LIB);
#endif
return sApitraceLibrary;
}
static int
next_power_of_two(int v)
{
@ -293,684 +222,6 @@ is_power_of_two(int v)
return (v & (v-1)) == 0;
}
#ifdef DEBUG
#undef BEFORE_GL_CALL
#undef AFTER_GL_CALL
#define BEFORE_GL_CALL do { \
BeforeGLCall(MOZ_FUNCTION_NAME); \
} while (0)
#define AFTER_GL_CALL do { \
AfterGLCall(MOZ_FUNCTION_NAME); \
} while (0)
static void BeforeGLCall(const char* glFunction)
{
if (GLContext::DebugMode()) {
if (GLContext::DebugMode() & GLContext::DebugTrace)
printf_stderr("[egl] > %s\n", glFunction);
}
}
static void AfterGLCall(const char* glFunction)
{
if (GLContext::DebugMode() & GLContext::DebugTrace) {
printf_stderr("[egl] < %s\n", glFunction);
}
}
// We rely on the fact that GLContext.h #defines BEFORE_GL_CALL and
// AFTER_GL_CALL to nothing if !defined(DEBUG).
#endif
static class EGLLibrary
{
public:
EGLLibrary()
: mInitialized(false),
mEGLLibrary(nsnull),
mHasRobustness(false)
{
mIsANGLE = false;
mHave_EGL_KHR_image_base = false;
mHave_EGL_KHR_image_pixmap = false;
mHave_EGL_KHR_gl_texture_2D_image = false;
mHave_EGL_KHR_lock_surface = false;
mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle = false;
}
struct {
typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void *display_id);
pfnGetDisplay fGetDisplay;
typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint);
pfnGetCurrentSurface fGetCurrentSurface;
typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void);
pfnGetCurrentContext fGetCurrentContext;
typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
pfnMakeCurrent fMakeCurrent;
typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
pfnDestroyContext fDestroyContext;
typedef EGLContext (GLAPIENTRY * pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
pfnCreateContext fCreateContext;
typedef EGLBoolean (GLAPIENTRY * pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface);
pfnDestroySurface fDestroySurface;
typedef EGLSurface (GLAPIENTRY * pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
pfnCreateWindowSurface fCreateWindowSurface;
typedef EGLSurface (GLAPIENTRY * pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
pfnCreatePbufferSurface fCreatePbufferSurface;
typedef EGLSurface (GLAPIENTRY * pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
pfnCreatePixmapSurface fCreatePixmapSurface;
typedef EGLBoolean (GLAPIENTRY * pfnBindAPI)(EGLenum api);
pfnBindAPI fBindAPI;
typedef EGLBoolean (GLAPIENTRY * pfnInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
pfnInitialize fInitialize;
typedef EGLBoolean (GLAPIENTRY * pfnChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
pfnChooseConfig fChooseConfig;
typedef EGLint (GLAPIENTRY * pfnGetError)(void);
pfnGetError fGetError;
typedef EGLBoolean (GLAPIENTRY * pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
pfnGetConfigAttrib fGetConfigAttrib;
typedef EGLBoolean (GLAPIENTRY * pfnGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
pfnGetConfigs fGetConfigs;
typedef EGLBoolean (GLAPIENTRY * pfnWaitNative)(EGLint engine);
pfnWaitNative fWaitNative;
typedef EGLCastToRelevantPtr (GLAPIENTRY * pfnGetProcAddress)(const char *procname);
pfnGetProcAddress fGetProcAddress;
typedef EGLBoolean (GLAPIENTRY * pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
pfnSwapBuffers fSwapBuffers;
typedef EGLBoolean (GLAPIENTRY * pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
EGLNativePixmapType target);
pfnCopyBuffers fCopyBuffers;
typedef const GLubyte* (GLAPIENTRY * pfnQueryString)(EGLDisplay, EGLint name);
pfnQueryString fQueryString;
typedef EGLBoolean (GLAPIENTRY * pfnQueryContext)(EGLDisplay dpy, EGLContext ctx,
EGLint attribute, EGLint *value);
pfnQueryContext fQueryContext;
typedef EGLBoolean (GLAPIENTRY * pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
pfnBindTexImage fBindTexImage;
typedef EGLBoolean (GLAPIENTRY * pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
pfnReleaseTexImage fReleaseTexImage;
typedef EGLImageKHR (GLAPIENTRY * pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
pfnCreateImageKHR fCreateImageKHR;
typedef EGLBoolean (GLAPIENTRY * pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
pfnDestroyImageKHR fDestroyImageKHR;
#ifdef MOZ_WIDGET_GONK
typedef EGLBoolean (GLAPIENTRY * pfnSetSwapRectangleANDROID)(EGLDisplay dpy, EGLSurface surface, EGLint left, EGLint top, EGLint width, EGLint height);
pfnSetSwapRectangleANDROID fSetSwapRectangleANDROID;
#endif
// New extension which allow us to lock texture and get raw image pointer
typedef EGLBoolean (GLAPIENTRY * pfnLockSurfaceKHR)(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
pfnLockSurfaceKHR fLockSurfaceKHR;
typedef EGLBoolean (GLAPIENTRY * pfnUnlockSurfaceKHR)(EGLDisplay dpy, EGLSurface surface);
pfnUnlockSurfaceKHR fUnlockSurfaceKHR;
typedef EGLBoolean (GLAPIENTRY * pfnQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
pfnQuerySurface fQuerySurface;
typedef EGLBoolean (GLAPIENTRY * pfnQuerySurfacePointerANGLE)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
pfnQuerySurfacePointerANGLE fQuerySurfacePointerANGLE;
// This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
// Lets keep it here for now.
typedef void (GLAPIENTRY * pfnImageTargetTexture2DOES)(GLenum target, GLeglImageOES image);
pfnImageTargetTexture2DOES fImageTargetTexture2DOES;
} mSymbols;
EGLDisplay fGetDisplay(void* display_id)
{
BEFORE_GL_CALL;
EGLDisplay disp = mSymbols.fGetDisplay(display_id);
AFTER_GL_CALL;
return disp;
}
EGLSurface fGetCurrentSurface(EGLint id)
{
BEFORE_GL_CALL;
EGLSurface surf = mSymbols.fGetCurrentSurface(id);
AFTER_GL_CALL;
return surf;
}
EGLContext fGetCurrentContext()
{
BEFORE_GL_CALL;
EGLContext context = mSymbols.fGetCurrentContext();
AFTER_GL_CALL;
return context;
}
EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fMakeCurrent(dpy, draw, read, ctx);
AFTER_GL_CALL;
return b;
}
EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fDestroyContext(dpy, ctx);
AFTER_GL_CALL;
return b;
}
EGLContext fCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLContext ctx = mSymbols.fCreateContext(dpy, config, share_context, attrib_list);
AFTER_GL_CALL;
return ctx;
}
EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fDestroySurface(dpy, surface);
AFTER_GL_CALL;
return b;
}
EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLSurface surf = mSymbols.fCreateWindowSurface(dpy, config, win, attrib_list);
AFTER_GL_CALL;
return surf;
}
EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLSurface surf = mSymbols.fCreatePbufferSurface(dpy, config, attrib_list);
AFTER_GL_CALL;
return surf;
}
EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLSurface surf = mSymbols.fCreatePixmapSurface(dpy, config, pixmap, attrib_list);
AFTER_GL_CALL;
return surf;
}
EGLBoolean fBindAPI(EGLenum api)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fBindAPI(api);
AFTER_GL_CALL;
return b;
}
EGLBoolean fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fInitialize(dpy, major, minor);
AFTER_GL_CALL;
return b;
}
EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fChooseConfig(dpy, attrib_list, configs, config_size, num_config);
AFTER_GL_CALL;
return b;
}
EGLint fGetError()
{
BEFORE_GL_CALL;
EGLint i = mSymbols.fGetError();
AFTER_GL_CALL;
return i;
}
EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fGetConfigAttrib(dpy, config, attribute, value);
AFTER_GL_CALL;
return b;
}
EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fGetConfigs(dpy, configs, config_size, num_config);
AFTER_GL_CALL;
return b;
}
EGLBoolean fWaitNative(EGLint engine)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fWaitNative(engine);
AFTER_GL_CALL;
return b;
}
EGLCastToRelevantPtr fGetProcAddress(const char *procname)
{
BEFORE_GL_CALL;
EGLCastToRelevantPtr p = mSymbols.fGetProcAddress(procname);
AFTER_GL_CALL;
return p;
}
EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fSwapBuffers(dpy, surface);
AFTER_GL_CALL;
return b;
}
EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fCopyBuffers(dpy, surface, target);
AFTER_GL_CALL;
return b;
}
const GLubyte* fQueryString(EGLDisplay dpy, EGLint name)
{
BEFORE_GL_CALL;
const GLubyte* b = mSymbols.fQueryString(dpy, name);
AFTER_GL_CALL;
return b;
}
EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fQueryContext(dpy, ctx, attribute, value);
AFTER_GL_CALL;
return b;
}
EGLBoolean fBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fBindTexImage(dpy, surface, buffer);
AFTER_GL_CALL;
return b;
}
EGLBoolean fReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fReleaseTexImage(dpy, surface, buffer);
AFTER_GL_CALL;
return b;
}
EGLImageKHR fCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLImageKHR i = mSymbols.fCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
AFTER_GL_CALL;
return i;
}
EGLBoolean fDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fDestroyImageKHR(dpy, image);
AFTER_GL_CALL;
return b;
}
#ifdef MOZ_WIDGET_GONK
EGLBoolean fSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface surface, EGLint left, EGLint top, EGLint width, EGLint height)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fSetSwapRectangleANDROID(dpy, surface, left, top, width, height);
AFTER_GL_CALL;
return b;
}
#endif
// New extension which allow us to lock texture and get raw image pointer
EGLBoolean fLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fLockSurfaceKHR(dpy, surface, attrib_list);
AFTER_GL_CALL;
return b;
}
EGLBoolean fUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fUnlockSurfaceKHR(dpy, surface);
AFTER_GL_CALL;
return b;
}
EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fQuerySurface(dpy, surface, attribute, value);
AFTER_GL_CALL;
return b;
}
EGLBoolean fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fQuerySurfacePointerANGLE(dpy, surface, attribute, value);
AFTER_GL_CALL;
return b;
}
// This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
// Lets keep it here for now.
void fImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
{
BEFORE_GL_CALL;
mSymbols.fImageTargetTexture2DOES(target, image);
AFTER_GL_CALL;
}
bool EnsureInitialized()
{
if (mInitialized) {
return true;
}
mozilla::ScopedGfxFeatureReporter reporter("EGL");
#ifdef XP_WIN
// Allow for explicitly specifying the location of libEGL.dll and
// libGLESv2.dll.
do {
nsCOMPtr<nsILocalFile> eglFile, glesv2File;
nsresult rv = Preferences::GetComplex("gfx.angle.egl.path",
NS_GET_IID(nsILocalFile),
getter_AddRefs(eglFile));
if (NS_FAILED(rv) || !eglFile)
break;
nsCAutoString s;
// note that we have to load the libs in this order, because libEGL.dll
// depends on libGLESv2.dll, but is not/may not be in our search path.
nsCOMPtr<nsIFile> f;
eglFile->Clone(getter_AddRefs(f));
glesv2File = do_QueryInterface(f);
if (!glesv2File)
break;
glesv2File->Append(NS_LITERAL_STRING("libGLESv2.dll"));
PRLibrary *glesv2lib = nsnull; // this will be leaked on purpose
glesv2File->Load(&glesv2lib);
if (!glesv2lib)
break;
eglFile->Append(NS_LITERAL_STRING("libEGL.dll"));
eglFile->Load(&mEGLLibrary);
} while (false);
#endif
if (!mEGLLibrary) {
mEGLLibrary = LoadApitraceLibrary();
if (!mEGLLibrary) {
printf_stderr("Attempting load of %s\n", EGL_LIB);
mEGLLibrary = PR_LoadLibrary(EGL_LIB);
#if defined(XP_UNIX)
if (!mEGLLibrary) {
mEGLLibrary = PR_LoadLibrary(EGL_LIB1);
}
#endif
}
}
if (!mEGLLibrary) {
NS_WARNING("Couldn't load EGL LIB.");
return false;
}
#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, NULL } }
LibrarySymbolLoader::SymLoadStruct earlySymbols[] = {
SYMBOL(GetDisplay),
SYMBOL(GetCurrentSurface),
SYMBOL(GetCurrentContext),
SYMBOL(MakeCurrent),
SYMBOL(DestroyContext),
SYMBOL(CreateContext),
SYMBOL(DestroySurface),
SYMBOL(CreateWindowSurface),
SYMBOL(CreatePbufferSurface),
SYMBOL(CreatePixmapSurface),
SYMBOL(BindAPI),
SYMBOL(Initialize),
SYMBOL(ChooseConfig),
SYMBOL(GetError),
SYMBOL(GetConfigs),
SYMBOL(GetConfigAttrib),
SYMBOL(WaitNative),
SYMBOL(GetProcAddress),
SYMBOL(SwapBuffers),
SYMBOL(CopyBuffers),
SYMBOL(QueryString),
SYMBOL(QueryContext),
SYMBOL(BindTexImage),
SYMBOL(ReleaseTexImage),
SYMBOL(QuerySurface),
#ifdef MOZ_WIDGET_GONK
SYMBOL(SetSwapRectangleANDROID),
#endif
{ NULL, { NULL } }
};
if (!LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
NS_WARNING("Couldn't find required entry points in EGL library (early init)");
return false;
}
#if defined(MOZ_X11) && defined(MOZ_EGL_XRENDER_COMPOSITE)
mEGLDisplay = fGetDisplay((EGLNativeDisplayType) gdk_x11_get_default_xdisplay());
#else
mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
#endif
if (!fInitialize(mEGLDisplay, NULL, NULL))
return false;
const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
mIsANGLE = true;
}
const char *extensions = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
if (!extensions)
extensions = "";
printf_stderr("Extensions: %s 0x%02x\n", extensions, extensions[0]);
printf_stderr("Extensions length: %d\n", strlen(extensions));
// note the extra space -- this ugliness tries to match
// EGL_KHR_image in the middle of the string, or right at the
// end. It's a prefix for other extensions, so we have to do
// this...
bool hasKHRImage = false;
if (strstr(extensions, "EGL_KHR_image ") ||
(strlen(extensions) >= strlen("EGL_KHR_image") &&
strcmp(extensions+(strlen(extensions)-strlen("EGL_KHR_image")), "EGL_KHR_image")))
{
hasKHRImage = true;
}
if (strstr(extensions, "EGL_KHR_image_base")) {
mHave_EGL_KHR_image_base = true;
}
if (strstr(extensions, "EGL_KHR_image_pixmap")) {
mHave_EGL_KHR_image_pixmap = true;
}
if (strstr(extensions, "EGL_KHR_gl_texture_2D_image")) {
mHave_EGL_KHR_gl_texture_2D_image = true;
}
if (strstr(extensions, "EGL_KHR_lock_surface")) {
mHave_EGL_KHR_lock_surface = true;
}
if (hasKHRImage) {
LibrarySymbolLoader::SymLoadStruct khrSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fCreateImageKHR, { "eglCreateImageKHR", NULL } },
{ (PRFuncPtr*) &mSymbols.fDestroyImageKHR, { "eglDestroyImageKHR", NULL } },
{ (PRFuncPtr*) &mSymbols.fImageTargetTexture2DOES, { "glEGLImageTargetTexture2DOES", NULL } },
{ NULL, { NULL } }
};
LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &khrSymbols[0],
(LibrarySymbolLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
}
if (mHave_EGL_KHR_lock_surface) {
LibrarySymbolLoader::SymLoadStruct lockSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fLockSurfaceKHR, { "eglLockSurfaceKHR", NULL } },
{ (PRFuncPtr*) &mSymbols.fUnlockSurfaceKHR, { "eglUnlockSurfaceKHR", NULL } },
{ NULL, { NULL } }
};
LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &lockSymbols[0],
(LibrarySymbolLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
if (!mSymbols.fLockSurfaceKHR) {
mHave_EGL_KHR_lock_surface = false;
}
}
if (!mSymbols.fCreateImageKHR) {
mHave_EGL_KHR_image_base = false;
mHave_EGL_KHR_image_pixmap = false;
mHave_EGL_KHR_gl_texture_2D_image = false;
}
if (!mSymbols.fImageTargetTexture2DOES) {
mHave_EGL_KHR_gl_texture_2D_image = false;
}
if (strstr(extensions, "EGL_ANGLE_surface_d3d_texture_2d_share_handle")) {
LibrarySymbolLoader::SymLoadStruct d3dSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", NULL } },
{ NULL, { NULL } }
};
LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &d3dSymbols[0],
(LibrarySymbolLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
if (mSymbols.fQuerySurfacePointerANGLE) {
mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle = true;
}
}
if (strstr(extensions, "EGL_EXT_create_context_robustness")) {
mHasRobustness = true;
}
mInitialized = true;
reporter.SetSuccessful();
return true;
}
EGLDisplay Display() {
return mEGLDisplay;
}
bool IsANGLE() {
return mIsANGLE;
}
bool HasKHRImageBase() {
return mHave_EGL_KHR_image_base;
}
bool HasKHRImagePixmap() {
return mHave_EGL_KHR_image_pixmap;
}
bool HasKHRImageTexture2D() {
return mHave_EGL_KHR_gl_texture_2D_image;
}
bool HasKHRLockSurface() {
return mHave_EGL_KHR_lock_surface;
}
bool HasANGLESurfaceD3DTexture2DShareHandle() {
return mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
}
bool HasRobustness() {
return mHasRobustness;
}
void
DumpEGLConfig(EGLConfig cfg)
{
int attrval;
int err;
#define ATTR(_x) do { \
fGetConfigAttrib(mEGLDisplay, cfg, LOCAL_EGL_##_x, &attrval); \
if ((err = fGetError()) != 0x3000) { \
printf_stderr(" %s: ERROR (0x%04x)\n", #_x, err); \
} else { \
printf_stderr(" %s: %d (0x%04x)\n", #_x, attrval, attrval); \
} \
} while(0)
printf_stderr("EGL Config: %d [%p]\n", (int)(intptr_t)cfg, cfg);
ATTR(BUFFER_SIZE);
ATTR(ALPHA_SIZE);
ATTR(BLUE_SIZE);
ATTR(GREEN_SIZE);
ATTR(RED_SIZE);
ATTR(DEPTH_SIZE);
ATTR(STENCIL_SIZE);
ATTR(CONFIG_CAVEAT);
ATTR(CONFIG_ID);
ATTR(LEVEL);
ATTR(MAX_PBUFFER_HEIGHT);
ATTR(MAX_PBUFFER_PIXELS);
ATTR(MAX_PBUFFER_WIDTH);
ATTR(NATIVE_RENDERABLE);
ATTR(NATIVE_VISUAL_ID);
ATTR(NATIVE_VISUAL_TYPE);
ATTR(PRESERVED_RESOURCES);
ATTR(SAMPLES);
ATTR(SAMPLE_BUFFERS);
ATTR(SURFACE_TYPE);
ATTR(TRANSPARENT_TYPE);
ATTR(TRANSPARENT_RED_VALUE);
ATTR(TRANSPARENT_GREEN_VALUE);
ATTR(TRANSPARENT_BLUE_VALUE);
ATTR(BIND_TO_TEXTURE_RGB);
ATTR(BIND_TO_TEXTURE_RGBA);
ATTR(MIN_SWAP_INTERVAL);
ATTR(MAX_SWAP_INTERVAL);
ATTR(LUMINANCE_SIZE);
ATTR(ALPHA_MASK_SIZE);
ATTR(COLOR_BUFFER_TYPE);
ATTR(RENDERABLE_TYPE);
ATTR(CONFORMANT);
#undef ATTR
}
void DumpEGLConfigs() {
int nc = 0;
fGetConfigs(mEGLDisplay, NULL, 0, &nc);
EGLConfig *ec = new EGLConfig[nc];
fGetConfigs(mEGLDisplay, ec, nc, &nc);
for (int i = 0; i < nc; ++i) {
printf_stderr ("========= EGL Config %d ========\n", i);
DumpEGLConfig(ec[i]);
}
delete [] ec;
}
private:
bool mInitialized;
PRLibrary *mEGLLibrary;
EGLDisplay mEGLDisplay;
bool mIsANGLE;
bool mHasRobustness;
bool mHave_EGL_KHR_image_base;
bool mHave_EGL_KHR_image_pixmap;
bool mHave_EGL_KHR_gl_texture_2D_image;
bool mHave_EGL_KHR_lock_surface;
bool mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
} sEGLLibrary;
class GLContextEGL : public GLContext
{
friend class TextureImageEGL;

Просмотреть файл

@ -51,6 +51,7 @@
#include "prenv.h"
#include "GLContextProvider.h"
#include "GLLibraryLoader.h"
#include "nsDebug.h"
#include "nsIWidget.h"
#include "GLXLibrary.h"
@ -120,7 +121,7 @@ GLXLibrary::EnsureInitialized()
mDebug = true;
}
LibrarySymbolLoader::SymLoadStruct symbols[] = {
GLLibraryLoader::SymLoadStruct symbols[] = {
/* functions that were in GLX 1.0 */
{ (PRFuncPtr*) &xDestroyContextInternal, { "glXDestroyContext", NULL } },
{ (PRFuncPtr*) &xMakeCurrentInternal, { "glXMakeCurrent", NULL } },
@ -136,7 +137,7 @@ GLXLibrary::EnsureInitialized()
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct symbols13[] = {
GLLibraryLoader::SymLoadStruct symbols13[] = {
/* functions introduced in GLX 1.3 */
{ (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfig", NULL } },
{ (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttrib", NULL } },
@ -150,7 +151,7 @@ GLXLibrary::EnsureInitialized()
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct symbols13_ext[] = {
GLLibraryLoader::SymLoadStruct symbols13_ext[] = {
/* extension equivalents for functions introduced in GLX 1.3 */
// GLX_SGIX_fbconfig extension
{ (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfigSGIX", NULL } },
@ -164,31 +165,31 @@ GLXLibrary::EnsureInitialized()
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct symbols14[] = {
GLLibraryLoader::SymLoadStruct symbols14[] = {
/* functions introduced in GLX 1.4 */
{ (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddress", NULL } },
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct symbols14_ext[] = {
GLLibraryLoader::SymLoadStruct symbols14_ext[] = {
/* extension equivalents for functions introduced in GLX 1.4 */
// GLX_ARB_get_proc_address extension
{ (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddressARB", NULL } },
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct symbols_texturefrompixmap[] = {
GLLibraryLoader::SymLoadStruct symbols_texturefrompixmap[] = {
{ (PRFuncPtr*) &xBindTexImageInternal, { "glXBindTexImageEXT", NULL } },
{ (PRFuncPtr*) &xReleaseTexImageInternal, { "glXReleaseTexImageEXT", NULL } },
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct symbols_robustness[] = {
GLLibraryLoader::SymLoadStruct symbols_robustness[] = {
{ (PRFuncPtr*) &xCreateContextAttribsInternal, { "glXCreateContextAttribsARB", NULL } },
{ NULL, { NULL } }
};
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
NS_WARNING("Couldn't find required entry point in OpenGL shared library");
return false;
}
@ -215,7 +216,7 @@ GLXLibrary::EnsureInitialized()
extensionsStr = xQueryExtensionsString(display, screen);
LibrarySymbolLoader::SymLoadStruct *sym13;
GLLibraryLoader::SymLoadStruct *sym13;
if (!GLXVersionCheck(1, 3)) {
// Even if we don't have 1.3, we might have equivalent extensions
// (as on the Intel X server).
@ -226,12 +227,12 @@ GLXLibrary::EnsureInitialized()
} else {
sym13 = symbols13;
}
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, sym13)) {
if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym13)) {
NS_WARNING("Couldn't find required entry point in OpenGL shared library");
return false;
}
LibrarySymbolLoader::SymLoadStruct *sym14;
GLLibraryLoader::SymLoadStruct *sym14;
if (!GLXVersionCheck(1, 4)) {
// Even if we don't have 1.4, we might have equivalent extensions
// (as on the Intel X server).
@ -242,14 +243,14 @@ GLXLibrary::EnsureInitialized()
} else {
sym14 = symbols14;
}
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, sym14)) {
if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym14)) {
NS_WARNING("Couldn't find required entry point in OpenGL shared library");
return false;
}
if (HasExtension(extensionsStr, "GLX_EXT_texture_from_pixmap") &&
LibrarySymbolLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap,
(LibrarySymbolLoader::PlatformLookupFunction)&xGetProcAddress))
GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap,
(GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress))
{
mHasTextureFromPixmap = true;
} else {
@ -257,7 +258,7 @@ GLXLibrary::EnsureInitialized()
}
if (HasExtension(extensionsStr, "GLX_ARB_create_context_robustness") &&
LibrarySymbolLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) {
GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) {
mHasRobustness = true;
}

Просмотреть файл

@ -37,6 +37,7 @@
#include "GLContextProvider.h"
#include "GLContext.h"
#include "GLLibraryLoader.h"
#include "nsDebug.h"
#include "nsString.h"
#include "nsIWidget.h"
@ -118,7 +119,7 @@ OSMesaLibrary::EnsureInitialized()
return false;
}
LibrarySymbolLoader::SymLoadStruct symbols[] = {
GLLibraryLoader::SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &fCreateContextExt, { "OSMesaCreateContextExt", NULL } },
{ (PRFuncPtr*) &fMakeCurrent, { "OSMesaMakeCurrent", NULL } },
{ (PRFuncPtr*) &fPixelStore, { "OSMesaPixelStore", NULL } },
@ -129,7 +130,7 @@ OSMesaLibrary::EnsureInitialized()
{ NULL, { NULL } }
};
if (!LibrarySymbolLoader::LoadSymbols(mOSMesaLibrary, &symbols[0])) {
if (!GLLibraryLoader::LoadSymbols(mOSMesaLibrary, &symbols[0])) {
LogMessage("Couldn't find required entry points in OSMesa libary");
return false;
}

Просмотреть файл

@ -36,6 +36,7 @@
#include "GLContextProvider.h"
#include "GLContext.h"
#include "GLLibraryLoader.h"
#include "nsDebug.h"
#include "nsIWidget.h"
#include "WGLLibrary.h"
@ -147,7 +148,7 @@ WGLLibrary::EnsureInitialized()
gUseDoubleBufferedWindows = PR_GetEnv("MOZ_WGL_DB") != nsnull;
LibrarySymbolLoader::SymLoadStruct earlySymbols[] = {
GLLibraryLoader::SymLoadStruct earlySymbols[] = {
{ (PRFuncPtr*) &fCreateContext, { "wglCreateContext", NULL } },
{ (PRFuncPtr*) &fMakeCurrent, { "wglMakeCurrent", NULL } },
{ (PRFuncPtr*) &fGetProcAddress, { "wglGetProcAddress", NULL } },
@ -158,7 +159,7 @@ WGLLibrary::EnsureInitialized()
{ NULL, { NULL } }
};
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &earlySymbols[0])) {
if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &earlySymbols[0])) {
NS_WARNING("Couldn't find required entry points in OpenGL DLL (early init)");
return false;
}
@ -183,7 +184,7 @@ WGLLibrary::EnsureInitialized()
// Now we can grab all the other symbols that we couldn't without having
// a context current.
LibrarySymbolLoader::SymLoadStruct pbufferSymbols[] = {
GLLibraryLoader::SymLoadStruct pbufferSymbols[] = {
{ (PRFuncPtr*) &fCreatePbuffer, { "wglCreatePbufferARB", "wglCreatePbufferEXT", NULL } },
{ (PRFuncPtr*) &fDestroyPbuffer, { "wglDestroyPbufferARB", "wglDestroyPbufferEXT", NULL } },
{ (PRFuncPtr*) &fGetPbufferDC, { "wglGetPbufferDCARB", "wglGetPbufferDCEXT", NULL } },
@ -192,42 +193,42 @@ WGLLibrary::EnsureInitialized()
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct pixFmtSymbols[] = {
GLLibraryLoader::SymLoadStruct pixFmtSymbols[] = {
{ (PRFuncPtr*) &fChoosePixelFormat, { "wglChoosePixelFormatARB", "wglChoosePixelFormatEXT", NULL } },
{ (PRFuncPtr*) &fGetPixelFormatAttribiv, { "wglGetPixelFormatAttribivARB", "wglGetPixelFormatAttribivEXT", NULL } },
{ NULL, { NULL } }
};
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &pbufferSymbols[0],
(LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress))
if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pbufferSymbols[0],
(GLLibraryLoader::PlatformLookupFunction)fGetProcAddress))
{
// this isn't an error, just means that pbuffers aren't supported
fCreatePbuffer = nsnull;
}
if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &pixFmtSymbols[0],
(LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress))
if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pixFmtSymbols[0],
(GLLibraryLoader::PlatformLookupFunction)fGetProcAddress))
{
// this isn't an error, just means that we don't have the pixel format extension
fChoosePixelFormat = nsnull;
}
LibrarySymbolLoader::SymLoadStruct extensionsSymbols[] = {
GLLibraryLoader::SymLoadStruct extensionsSymbols[] = {
{ (PRFuncPtr *) &fGetExtensionsString, { "wglGetExtensionsStringARB", NULL} },
{ NULL, { NULL } }
};
LibrarySymbolLoader::SymLoadStruct robustnessSymbols[] = {
GLLibraryLoader::SymLoadStruct robustnessSymbols[] = {
{ (PRFuncPtr *) &fCreateContextAttribs, { "wglCreateContextAttribsARB", NULL} },
{ NULL, { NULL } }
};
if (LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &extensionsSymbols[0],
(LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress)) {
if (GLLibraryLoader::LoadSymbols(mOGLLibrary, &extensionsSymbols[0],
(GLLibraryLoader::PlatformLookupFunction)fGetProcAddress)) {
const char *wglExts = fGetExtensionsString(gSharedWindowDC);
if (wglExts && HasExtension(wglExts, "WGL_ARB_create_context")) {
LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &robustnessSymbols[0],
(LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress);
GLLibraryLoader::LoadSymbols(mOGLLibrary, &robustnessSymbols[0],
(GLLibraryLoader::PlatformLookupFunction)fGetProcAddress);
if (HasExtension(wglExts, "WGL_ARB_create_context_robustness")) {
mHasRobustness = true;
}

Просмотреть файл

@ -70,6 +70,8 @@ typedef ptrdiff_t GLsizeiptr;
typedef ptrdiff_t GLintptr;
#endif
#endif /* #if !defined(__gltypes_h_) && !defined(__gl_h_) */
#ifndef GLAPIENTRY
# ifdef WIN32
# define GLAPIENTRY APIENTRY
@ -80,8 +82,6 @@ typedef ptrdiff_t GLintptr;
# endif
#endif
#endif /* #if !defined(__gltypes_h_) && !defined(__gl_h_) */
#define LOCAL_GL_VERSION_1_1 1
#define LOCAL_GL_ACCUM 0x0100
#define LOCAL_GL_LOAD 0x0101

371
gfx/gl/GLLibraryEGL.cpp Normal file
Просмотреть файл

@ -0,0 +1,371 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GLLibraryEGL.h"
#include "gfxCrashReporterUtils.h"
#include "mozilla/Preferences.h"
// We only need to explicitly dlopen egltrace
// on android as we can use LD_PRELOAD or other tricks
// on other platforms. We look for it in /data/local
// as that's writeable by all users
#define APITRACE_LIB "/data/local/egltrace.so"
#define EGL_LIB "libEGL.so"
#define EGL_LIB1 "libEGL.so.1"
#if defined(XP_WIN)
#define EGL_LIB "libEGL.dll"
#endif
namespace mozilla {
namespace gl {
#ifdef DEBUG
#undef BEFORE_GL_CALL
#undef AFTER_GL_CALL
#define BEFORE_GL_CALL do { \
BeforeGLCall(MOZ_FUNCTION_NAME); \
} while (0)
#define AFTER_GL_CALL do { \
AfterGLCall(MOZ_FUNCTION_NAME); \
} while (0)
static void BeforeGLCall(const char* glFunction)
{
if (GLContext::DebugMode()) {
if (GLContext::DebugMode() & GLContext::DebugTrace)
printf_stderr("[egl] > %s\n", glFunction);
}
}
static void AfterGLCall(const char* glFunction)
{
if (GLContext::DebugMode() & GLContext::DebugTrace) {
printf_stderr("[egl] < %s\n", glFunction);
}
}
// We rely on the fact that GLContext.h #defines BEFORE_GL_CALL and
// AFTER_GL_CALL to nothing if !defined(DEBUG).
#endif
static PRLibrary* LoadApitraceLibrary()
{
static PRLibrary* sApitraceLibrary = NULL;
if (sApitraceLibrary)
return sApitraceLibrary;
#if defined(ANDROID)
nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");
if (logFile.IsEmpty()) {
logFile = "firefox.trace";
}
// The firefox process can't write to /data/local, but it can write
// to $GRE_HOME/
nsCAutoString logPath;
logPath.AppendPrintf("%s/%s", getenv("GRE_HOME"), logFile.get());
// apitrace uses the TRACE_FILE environment variable to determine where
// to log trace output to
printf_stderr("Logging GL tracing output to %s", logPath.get());
setenv("TRACE_FILE", logPath.get(), false);
printf_stderr("Attempting load of %s\n", APITRACE_LIB);
sApitraceLibrary = PR_LoadLibrary(APITRACE_LIB);
#endif
return sApitraceLibrary;
}
bool
GLLibraryEGL::EnsureInitialized()
{
if (mInitialized) {
return true;
}
mozilla::ScopedGfxFeatureReporter reporter("EGL");
#ifdef XP_WIN
// Allow for explicitly specifying the location of libEGL.dll and
// libGLESv2.dll.
do {
nsCOMPtr<nsILocalFile> eglFile, glesv2File;
nsresult rv = Preferences::GetComplex("gfx.angle.egl.path",
NS_GET_IID(nsILocalFile),
getter_AddRefs(eglFile));
if (NS_FAILED(rv) || !eglFile)
break;
nsCAutoString s;
// note that we have to load the libs in this order, because libEGL.dll
// depends on libGLESv2.dll, but is not/may not be in our search path.
nsCOMPtr<nsIFile> f;
eglFile->Clone(getter_AddRefs(f));
glesv2File = do_QueryInterface(f);
if (!glesv2File)
break;
glesv2File->Append(NS_LITERAL_STRING("libGLESv2.dll"));
PRLibrary *glesv2lib = nsnull; // this will be leaked on purpose
glesv2File->Load(&glesv2lib);
if (!glesv2lib)
break;
eglFile->Append(NS_LITERAL_STRING("libEGL.dll"));
eglFile->Load(&mEGLLibrary);
} while (false);
#endif
if (!mEGLLibrary) {
mEGLLibrary = LoadApitraceLibrary();
if (!mEGLLibrary) {
printf_stderr("Attempting load of %s\n", EGL_LIB);
mEGLLibrary = PR_LoadLibrary(EGL_LIB);
#if defined(XP_UNIX)
if (!mEGLLibrary) {
mEGLLibrary = PR_LoadLibrary(EGL_LIB1);
}
#endif
}
}
if (!mEGLLibrary) {
NS_WARNING("Couldn't load EGL LIB.");
return false;
}
#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, NULL } }
GLLibraryLoader::SymLoadStruct earlySymbols[] = {
SYMBOL(GetDisplay),
SYMBOL(GetCurrentSurface),
SYMBOL(GetCurrentContext),
SYMBOL(MakeCurrent),
SYMBOL(DestroyContext),
SYMBOL(CreateContext),
SYMBOL(DestroySurface),
SYMBOL(CreateWindowSurface),
SYMBOL(CreatePbufferSurface),
SYMBOL(CreatePixmapSurface),
SYMBOL(BindAPI),
SYMBOL(Initialize),
SYMBOL(ChooseConfig),
SYMBOL(GetError),
SYMBOL(GetConfigs),
SYMBOL(GetConfigAttrib),
SYMBOL(WaitNative),
SYMBOL(GetProcAddress),
SYMBOL(SwapBuffers),
SYMBOL(CopyBuffers),
SYMBOL(QueryString),
SYMBOL(QueryContext),
SYMBOL(BindTexImage),
SYMBOL(ReleaseTexImage),
SYMBOL(QuerySurface),
#ifdef MOZ_WIDGET_GONK
SYMBOL(SetSwapRectangleANDROID),
#endif
{ NULL, { NULL } }
};
if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
NS_WARNING("Couldn't find required entry points in EGL library (early init)");
return false;
}
#if defined(MOZ_X11) && defined(MOZ_EGL_XRENDER_COMPOSITE)
mEGLDisplay = fGetDisplay((EGLNativeDisplayType) gdk_x11_get_default_xdisplay());
#else
mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
#endif
if (!fInitialize(mEGLDisplay, NULL, NULL))
return false;
const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
mIsANGLE = true;
}
const char *extensions = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
if (!extensions)
extensions = "";
printf_stderr("Extensions: %s 0x%02x\n", extensions, extensions[0]);
printf_stderr("Extensions length: %d\n", strlen(extensions));
// note the extra space -- this ugliness tries to match
// EGL_KHR_image in the middle of the string, or right at the
// end. It's a prefix for other extensions, so we have to do
// this...
bool hasKHRImage = false;
if (strstr(extensions, "EGL_KHR_image ") ||
(strlen(extensions) >= strlen("EGL_KHR_image") &&
strcmp(extensions+(strlen(extensions)-strlen("EGL_KHR_image")), "EGL_KHR_image")))
{
hasKHRImage = true;
}
if (strstr(extensions, "EGL_KHR_image_base")) {
mHave_EGL_KHR_image_base = true;
}
if (strstr(extensions, "EGL_KHR_image_pixmap")) {
mHave_EGL_KHR_image_pixmap = true;
}
if (strstr(extensions, "EGL_KHR_gl_texture_2D_image")) {
mHave_EGL_KHR_gl_texture_2D_image = true;
}
if (strstr(extensions, "EGL_KHR_lock_surface")) {
mHave_EGL_KHR_lock_surface = true;
}
if (hasKHRImage) {
GLLibraryLoader::SymLoadStruct khrSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fCreateImageKHR, { "eglCreateImageKHR", NULL } },
{ (PRFuncPtr*) &mSymbols.fDestroyImageKHR, { "eglDestroyImageKHR", NULL } },
{ (PRFuncPtr*) &mSymbols.fImageTargetTexture2DOES, { "glEGLImageTargetTexture2DOES", NULL } },
{ NULL, { NULL } }
};
GLLibraryLoader::LoadSymbols(mEGLLibrary, &khrSymbols[0],
(GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
}
if (mHave_EGL_KHR_lock_surface) {
GLLibraryLoader::SymLoadStruct lockSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fLockSurfaceKHR, { "eglLockSurfaceKHR", NULL } },
{ (PRFuncPtr*) &mSymbols.fUnlockSurfaceKHR, { "eglUnlockSurfaceKHR", NULL } },
{ NULL, { NULL } }
};
GLLibraryLoader::LoadSymbols(mEGLLibrary, &lockSymbols[0],
(GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
if (!mSymbols.fLockSurfaceKHR) {
mHave_EGL_KHR_lock_surface = false;
}
}
if (!mSymbols.fCreateImageKHR) {
mHave_EGL_KHR_image_base = false;
mHave_EGL_KHR_image_pixmap = false;
mHave_EGL_KHR_gl_texture_2D_image = false;
}
if (!mSymbols.fImageTargetTexture2DOES) {
mHave_EGL_KHR_gl_texture_2D_image = false;
}
if (strstr(extensions, "EGL_ANGLE_surface_d3d_texture_2d_share_handle")) {
GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
{ (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", NULL } },
{ NULL, { NULL } }
};
GLLibraryLoader::LoadSymbols(mEGLLibrary, &d3dSymbols[0],
(GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
if (mSymbols.fQuerySurfacePointerANGLE) {
mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle = true;
}
}
if (strstr(extensions, "EGL_EXT_create_context_robustness")) {
mHasRobustness = true;
}
mInitialized = true;
reporter.SetSuccessful();
return true;
}
void
GLLibraryEGL::DumpEGLConfig(EGLConfig cfg)
{
int attrval;
int err;
#define ATTR(_x) do { \
fGetConfigAttrib(mEGLDisplay, cfg, LOCAL_EGL_##_x, &attrval); \
if ((err = fGetError()) != 0x3000) { \
printf_stderr(" %s: ERROR (0x%04x)\n", #_x, err); \
} else { \
printf_stderr(" %s: %d (0x%04x)\n", #_x, attrval, attrval); \
} \
} while(0)
printf_stderr("EGL Config: %d [%p]\n", (int)(intptr_t)cfg, cfg);
ATTR(BUFFER_SIZE);
ATTR(ALPHA_SIZE);
ATTR(BLUE_SIZE);
ATTR(GREEN_SIZE);
ATTR(RED_SIZE);
ATTR(DEPTH_SIZE);
ATTR(STENCIL_SIZE);
ATTR(CONFIG_CAVEAT);
ATTR(CONFIG_ID);
ATTR(LEVEL);
ATTR(MAX_PBUFFER_HEIGHT);
ATTR(MAX_PBUFFER_PIXELS);
ATTR(MAX_PBUFFER_WIDTH);
ATTR(NATIVE_RENDERABLE);
ATTR(NATIVE_VISUAL_ID);
ATTR(NATIVE_VISUAL_TYPE);
ATTR(PRESERVED_RESOURCES);
ATTR(SAMPLES);
ATTR(SAMPLE_BUFFERS);
ATTR(SURFACE_TYPE);
ATTR(TRANSPARENT_TYPE);
ATTR(TRANSPARENT_RED_VALUE);
ATTR(TRANSPARENT_GREEN_VALUE);
ATTR(TRANSPARENT_BLUE_VALUE);
ATTR(BIND_TO_TEXTURE_RGB);
ATTR(BIND_TO_TEXTURE_RGBA);
ATTR(MIN_SWAP_INTERVAL);
ATTR(MAX_SWAP_INTERVAL);
ATTR(LUMINANCE_SIZE);
ATTR(ALPHA_MASK_SIZE);
ATTR(COLOR_BUFFER_TYPE);
ATTR(RENDERABLE_TYPE);
ATTR(CONFORMANT);
#undef ATTR
}
void
GLLibraryEGL::DumpEGLConfigs()
{
int nc = 0;
fGetConfigs(mEGLDisplay, NULL, 0, &nc);
EGLConfig *ec = new EGLConfig[nc];
fGetConfigs(mEGLDisplay, ec, nc, &nc);
for (int i = 0; i < nc; ++i) {
printf_stderr ("========= EGL Config %d ========\n", i);
DumpEGLConfig(ec[i]);
}
delete [] ec;
}
} /* namespace gl */
} /* namespace mozilla */

470
gfx/gl/GLLibraryEGL.h Normal file
Просмотреть файл

@ -0,0 +1,470 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GLLIBRARYEGL_H_
#define GLLIBRARYEGL_H_
#include "GLContext.h"
#include "GLLibraryLoader.h"
#include "nsILocalFile.h"
typedef int EGLint;
typedef unsigned int EGLBoolean;
typedef unsigned int EGLenum;
typedef void *EGLConfig;
typedef void *EGLContext;
typedef void *EGLDisplay;
typedef void *EGLSurface;
typedef void *EGLClientBuffer;
typedef void *EGLCastToRelevantPtr;
typedef void *EGLImageKHR;
typedef void *GLeglImageOES;
#ifdef ANDROID
typedef void *EGLNativeDisplayType;
typedef void *EGLNativePixmapType;
typedef void *EGLNativeWindowType;
#elif defined(XP_WIN)
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
typedef HDC EGLNativeDisplayType;
typedef HBITMAP EGLNativePixmapType;
typedef HWND EGLNativeWindowType;
#define GET_NATIVE_WINDOW(aWidget) ((EGLNativeWindowType)aWidget->GetNativeData(NS_NATIVE_WINDOW))
#endif
#ifdef MOZ_WIDGET_QT
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)QX11Info::display())
#else
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
#endif
#define EGL_NO_CONTEXT ((EGLContext)0)
#define EGL_NO_DISPLAY ((EGLDisplay)0)
#define EGL_NO_SURFACE ((EGLSurface)0)
#define EGL_DISPLAY() sEGLLibrary.Display()
namespace mozilla {
namespace gl {
class GLLibraryEGL
{
public:
GLLibraryEGL()
: mInitialized(false),
mEGLLibrary(nsnull),
mHasRobustness(false),
mIsANGLE(false),
mHave_EGL_KHR_image_base(false),
mHave_EGL_KHR_image_pixmap(false),
mHave_EGL_KHR_gl_texture_2D_image(false),
mHave_EGL_KHR_lock_surface(false),
mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle(false)
{
}
EGLDisplay fGetDisplay(void* display_id)
{
BEFORE_GL_CALL;
EGLDisplay disp = mSymbols.fGetDisplay(display_id);
AFTER_GL_CALL;
return disp;
}
EGLSurface fGetCurrentSurface(EGLint id)
{
BEFORE_GL_CALL;
EGLSurface surf = mSymbols.fGetCurrentSurface(id);
AFTER_GL_CALL;
return surf;
}
EGLContext fGetCurrentContext()
{
BEFORE_GL_CALL;
EGLContext context = mSymbols.fGetCurrentContext();
AFTER_GL_CALL;
return context;
}
EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fMakeCurrent(dpy, draw, read, ctx);
AFTER_GL_CALL;
return b;
}
EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fDestroyContext(dpy, ctx);
AFTER_GL_CALL;
return b;
}
EGLContext fCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLContext ctx = mSymbols.fCreateContext(dpy, config, share_context, attrib_list);
AFTER_GL_CALL;
return ctx;
}
EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fDestroySurface(dpy, surface);
AFTER_GL_CALL;
return b;
}
EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLSurface surf = mSymbols.fCreateWindowSurface(dpy, config, win, attrib_list);
AFTER_GL_CALL;
return surf;
}
EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLSurface surf = mSymbols.fCreatePbufferSurface(dpy, config, attrib_list);
AFTER_GL_CALL;
return surf;
}
EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLSurface surf = mSymbols.fCreatePixmapSurface(dpy, config, pixmap, attrib_list);
AFTER_GL_CALL;
return surf;
}
EGLBoolean fBindAPI(EGLenum api)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fBindAPI(api);
AFTER_GL_CALL;
return b;
}
EGLBoolean fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fInitialize(dpy, major, minor);
AFTER_GL_CALL;
return b;
}
EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fChooseConfig(dpy, attrib_list, configs, config_size, num_config);
AFTER_GL_CALL;
return b;
}
EGLint fGetError()
{
BEFORE_GL_CALL;
EGLint i = mSymbols.fGetError();
AFTER_GL_CALL;
return i;
}
EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fGetConfigAttrib(dpy, config, attribute, value);
AFTER_GL_CALL;
return b;
}
EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fGetConfigs(dpy, configs, config_size, num_config);
AFTER_GL_CALL;
return b;
}
EGLBoolean fWaitNative(EGLint engine)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fWaitNative(engine);
AFTER_GL_CALL;
return b;
}
EGLCastToRelevantPtr fGetProcAddress(const char *procname)
{
BEFORE_GL_CALL;
EGLCastToRelevantPtr p = mSymbols.fGetProcAddress(procname);
AFTER_GL_CALL;
return p;
}
EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fSwapBuffers(dpy, surface);
AFTER_GL_CALL;
return b;
}
EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fCopyBuffers(dpy, surface, target);
AFTER_GL_CALL;
return b;
}
const GLubyte* fQueryString(EGLDisplay dpy, EGLint name)
{
BEFORE_GL_CALL;
const GLubyte* b = mSymbols.fQueryString(dpy, name);
AFTER_GL_CALL;
return b;
}
EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fQueryContext(dpy, ctx, attribute, value);
AFTER_GL_CALL;
return b;
}
EGLBoolean fBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fBindTexImage(dpy, surface, buffer);
AFTER_GL_CALL;
return b;
}
EGLBoolean fReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fReleaseTexImage(dpy, surface, buffer);
AFTER_GL_CALL;
return b;
}
EGLImageKHR fCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLImageKHR i = mSymbols.fCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
AFTER_GL_CALL;
return i;
}
EGLBoolean fDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fDestroyImageKHR(dpy, image);
AFTER_GL_CALL;
return b;
}
#ifdef MOZ_WIDGET_GONK
EGLBoolean fSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface surface, EGLint left, EGLint top, EGLint width, EGLint height)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fSetSwapRectangleANDROID(dpy, surface, left, top, width, height);
AFTER_GL_CALL;
return b;
}
#endif
// New extension which allow us to lock texture and get raw image pointer
EGLBoolean fLockSurfaceKHR(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fLockSurfaceKHR(dpy, surface, attrib_list);
AFTER_GL_CALL;
return b;
}
EGLBoolean fUnlockSurfaceKHR(EGLDisplay dpy, EGLSurface surface)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fUnlockSurfaceKHR(dpy, surface);
AFTER_GL_CALL;
return b;
}
EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fQuerySurface(dpy, surface, attribute, value);
AFTER_GL_CALL;
return b;
}
EGLBoolean fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
{
BEFORE_GL_CALL;
EGLBoolean b = mSymbols.fQuerySurfacePointerANGLE(dpy, surface, attribute, value);
AFTER_GL_CALL;
return b;
}
// This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
// Lets keep it here for now.
void fImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
{
BEFORE_GL_CALL;
mSymbols.fImageTargetTexture2DOES(target, image);
AFTER_GL_CALL;
}
EGLDisplay Display() {
return mEGLDisplay;
}
bool IsANGLE() {
return mIsANGLE;
}
bool HasKHRImageBase() {
return mHave_EGL_KHR_image_base;
}
bool HasKHRImagePixmap() {
return mHave_EGL_KHR_image_pixmap;
}
bool HasKHRImageTexture2D() {
return mHave_EGL_KHR_gl_texture_2D_image;
}
bool HasKHRLockSurface() {
return mHave_EGL_KHR_lock_surface;
}
bool HasANGLESurfaceD3DTexture2DShareHandle() {
return mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
}
bool HasRobustness() {
return mHasRobustness;
}
bool EnsureInitialized();
void DumpEGLConfig(EGLConfig cfg);
void DumpEGLConfigs();
struct {
typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void *display_id);
pfnGetDisplay fGetDisplay;
typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint);
pfnGetCurrentSurface fGetCurrentSurface;
typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void);
pfnGetCurrentContext fGetCurrentContext;
typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
pfnMakeCurrent fMakeCurrent;
typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx);
pfnDestroyContext fDestroyContext;
typedef EGLContext (GLAPIENTRY * pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
pfnCreateContext fCreateContext;
typedef EGLBoolean (GLAPIENTRY * pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface);
pfnDestroySurface fDestroySurface;
typedef EGLSurface (GLAPIENTRY * pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
pfnCreateWindowSurface fCreateWindowSurface;
typedef EGLSurface (GLAPIENTRY * pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
pfnCreatePbufferSurface fCreatePbufferSurface;
typedef EGLSurface (GLAPIENTRY * pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
pfnCreatePixmapSurface fCreatePixmapSurface;
typedef EGLBoolean (GLAPIENTRY * pfnBindAPI)(EGLenum api);
pfnBindAPI fBindAPI;
typedef EGLBoolean (GLAPIENTRY * pfnInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor);
pfnInitialize fInitialize;
typedef EGLBoolean (GLAPIENTRY * pfnChooseConfig)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
pfnChooseConfig fChooseConfig;
typedef EGLint (GLAPIENTRY * pfnGetError)(void);
pfnGetError fGetError;
typedef EGLBoolean (GLAPIENTRY * pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
pfnGetConfigAttrib fGetConfigAttrib;
typedef EGLBoolean (GLAPIENTRY * pfnGetConfigs)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
pfnGetConfigs fGetConfigs;
typedef EGLBoolean (GLAPIENTRY * pfnWaitNative)(EGLint engine);
pfnWaitNative fWaitNative;
typedef EGLCastToRelevantPtr (GLAPIENTRY * pfnGetProcAddress)(const char *procname);
pfnGetProcAddress fGetProcAddress;
typedef EGLBoolean (GLAPIENTRY * pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
pfnSwapBuffers fSwapBuffers;
typedef EGLBoolean (GLAPIENTRY * pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
EGLNativePixmapType target);
pfnCopyBuffers fCopyBuffers;
typedef const GLubyte* (GLAPIENTRY * pfnQueryString)(EGLDisplay, EGLint name);
pfnQueryString fQueryString;
typedef EGLBoolean (GLAPIENTRY * pfnQueryContext)(EGLDisplay dpy, EGLContext ctx,
EGLint attribute, EGLint *value);
pfnQueryContext fQueryContext;
typedef EGLBoolean (GLAPIENTRY * pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
pfnBindTexImage fBindTexImage;
typedef EGLBoolean (GLAPIENTRY * pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
pfnReleaseTexImage fReleaseTexImage;
typedef EGLImageKHR (GLAPIENTRY * pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
pfnCreateImageKHR fCreateImageKHR;
typedef EGLBoolean (GLAPIENTRY * pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
pfnDestroyImageKHR fDestroyImageKHR;
#ifdef MOZ_WIDGET_GONK
typedef EGLBoolean (GLAPIENTRY * pfnSetSwapRectangleANDROID)(EGLDisplay dpy, EGLSurface surface, EGLint left, EGLint top, EGLint width, EGLint height);
pfnSetSwapRectangleANDROID fSetSwapRectangleANDROID;
#endif
// New extension which allow us to lock texture and get raw image pointer
typedef EGLBoolean (GLAPIENTRY * pfnLockSurfaceKHR)(EGLDisplay dpy, EGLSurface surface, const EGLint *attrib_list);
pfnLockSurfaceKHR fLockSurfaceKHR;
typedef EGLBoolean (GLAPIENTRY * pfnUnlockSurfaceKHR)(EGLDisplay dpy, EGLSurface surface);
pfnUnlockSurfaceKHR fUnlockSurfaceKHR;
typedef EGLBoolean (GLAPIENTRY * pfnQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
pfnQuerySurface fQuerySurface;
typedef EGLBoolean (GLAPIENTRY * pfnQuerySurfacePointerANGLE)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value);
pfnQuerySurfacePointerANGLE fQuerySurfacePointerANGLE;
// This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
// Lets keep it here for now.
typedef void (GLAPIENTRY * pfnImageTargetTexture2DOES)(GLenum target, GLeglImageOES image);
pfnImageTargetTexture2DOES fImageTargetTexture2DOES;
} mSymbols;
private:
bool mInitialized;
PRLibrary* mEGLLibrary;
EGLDisplay mEGLDisplay;
bool mIsANGLE;
bool mHasRobustness;
bool mHave_EGL_KHR_image_base;
bool mHave_EGL_KHR_image_pixmap;
bool mHave_EGL_KHR_gl_texture_2D_image;
bool mHave_EGL_KHR_lock_surface;
bool mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle;
};
} /* namespace gl */
} /* namespace mozilla */
#endif /* GLLIBRARYEGL_H_ */

100
gfx/gl/GLLibraryLoader.cpp Normal file
Просмотреть файл

@ -0,0 +1,100 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GLLibraryLoader.h"
namespace mozilla {
namespace gl {
bool
GLLibraryLoader::OpenLibrary(const char *library)
{
PRLibSpec lspec;
lspec.type = PR_LibSpec_Pathname;
lspec.value.pathname = library;
mLibrary = PR_LoadLibraryWithFlags(lspec, PR_LD_LAZY | PR_LD_LOCAL);
if (!mLibrary)
return false;
return true;
}
bool
GLLibraryLoader::LoadSymbols(SymLoadStruct *firstStruct, bool tryplatform, const char *prefix)
{
return LoadSymbols(mLibrary, firstStruct, tryplatform ? mLookupFunc : nsnull, prefix);
}
PRFuncPtr
GLLibraryLoader::LookupSymbol(PRLibrary *lib,
const char *sym,
PlatformLookupFunction lookupFunction)
{
PRFuncPtr res = 0;
// try finding it in the library directly, if we have one
if (lib) {
res = PR_FindFunctionSymbol(lib, sym);
}
// then try looking it up via the lookup symbol
if (!res && lookupFunction) {
res = lookupFunction(sym);
}
// finally just try finding it in the process
if (!res) {
PRLibrary *leakedLibRef;
res = PR_FindFunctionSymbolAndLibrary(sym, &leakedLibRef);
}
return res;
}
bool
GLLibraryLoader::LoadSymbols(PRLibrary *lib,
SymLoadStruct *firstStruct,
PlatformLookupFunction lookupFunction,
const char *prefix)
{
char sbuf[MAX_SYMBOL_LENGTH * 2];
int failCount = 0;
SymLoadStruct *ss = firstStruct;
while (ss->symPointer) {
*ss->symPointer = 0;
for (int i = 0; i < MAX_SYMBOL_NAMES; i++) {
if (ss->symNames[i] == nsnull)
break;
const char *s = ss->symNames[i];
if (prefix && *prefix != 0) {
strcpy(sbuf, prefix);
strcat(sbuf, ss->symNames[i]);
s = sbuf;
}
PRFuncPtr p = LookupSymbol(lib, s, lookupFunction);
if (p) {
*ss->symPointer = p;
break;
}
}
if (*ss->symPointer == 0) {
fprintf (stderr, "Can't find symbol '%s'\n", ss->symNames[0]);
failCount++;
}
ss++;
}
return failCount == 0 ? true : false;
}
} /* namespace gl */
} /* namespace mozilla */

66
gfx/gl/GLLibraryLoader.h Normal file
Просмотреть файл

@ -0,0 +1,66 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GLLIBRARYLOADER_H_
#define GLLIBRARYLOADER_H_
#include <stdio.h>
#ifdef WIN32
#include <windows.h>
#endif
#include "GLDefs.h"
#include "mozilla/Util.h"
#include "nscore.h"
#include "prlink.h"
namespace mozilla {
namespace gl {
class GLLibraryLoader
{
public:
bool OpenLibrary(const char *library);
typedef PRFuncPtr (GLAPIENTRY * PlatformLookupFunction) (const char *);
enum {
MAX_SYMBOL_NAMES = 5,
MAX_SYMBOL_LENGTH = 128
};
typedef struct {
PRFuncPtr *symPointer;
const char *symNames[MAX_SYMBOL_NAMES];
} SymLoadStruct;
bool LoadSymbols(SymLoadStruct *firstStruct,
bool tryplatform = false,
const char *prefix = nsnull);
/*
* Static version of the functions in this class
*/
static PRFuncPtr LookupSymbol(PRLibrary *lib,
const char *symname,
PlatformLookupFunction lookupFunction = nsnull);
static bool LoadSymbols(PRLibrary *lib,
SymLoadStruct *firstStruct,
PlatformLookupFunction lookupFunction = nsnull,
const char *prefix = nsnull);
protected:
GLLibraryLoader() {
mLibrary = nsnull;
mLookupFunc = nsnull;
}
PRLibrary *mLibrary;
PlatformLookupFunction mLookupFunc;
};
} /* namespace gl */
} /* namespace mozilla */
#endif /* GLLIBRARYLOADER_H_ */

Просмотреть файл

@ -51,6 +51,7 @@ EXPORTS = \
GLContextSymbols.h \
GLContextProvider.h \
GLContextProviderImpl.h \
GLLibraryLoader.h \
EGLUtils.h \
ForceDiscreteGPUHelperCGL.h \
$(NULL)
@ -70,6 +71,7 @@ endif
CPPSRCS = \
GLContext.cpp \
GLLibraryLoader.cpp \
GLContextProviderOSMesa.cpp \
$(NULL)
@ -118,9 +120,15 @@ else
CPPSRCS += GLContextProvider$(GL_PROVIDER).cpp
endif
ifeq ($(GL_PROVIDER),EGL)
CPPSRCS += GLLibraryEGL.cpp
endif
# Win32 is a special snowflake, for ANGLE
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
CPPSRCS += GLContextProviderEGL.cpp
CPPSRCS += \
GLContextProviderEGL.cpp \
GLLibraryEGL.cpp
endif
ifdef MOZ_JAVA_COMPOSITOR