зеркало из https://github.com/mozilla/gecko-dev.git
Bug 732865 - Clean up the GLContext* classes. r=bgirard,joe
This commit is contained in:
Родитель
98b0d12882
Коммит
96d0e2fd38
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче