зеркало из https://github.com/mozilla/pjs.git
Bug 571832 - Provide CreateForNativePixmapSurface API. r=vladimir.
--HG-- extra : rebase_source : 0f7214266a6bf449620d6b46fd14bc6978b621ee
This commit is contained in:
Родитель
4ea0ddc817
Коммит
f90e8bf405
|
@ -165,6 +165,14 @@ public:
|
|||
*/
|
||||
virtual PRBool SwapBuffers() { return PR_FALSE; }
|
||||
|
||||
/**
|
||||
* Defines a two-dimensional texture image for context target surface
|
||||
*/
|
||||
virtual PRBool BindTexImage() { return PR_FALSE; }
|
||||
/*
|
||||
* Releases a color buffer that is being used as a texture
|
||||
*/
|
||||
virtual PRBool ReleaseTexImage() { return PR_FALSE; }
|
||||
protected:
|
||||
|
||||
PRBool mInitialized;
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsAutoPtr.h"
|
||||
|
||||
class nsIWidget;
|
||||
class gfxASurface;
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
@ -119,6 +120,15 @@ public:
|
|||
* @return Context to use for this window
|
||||
*/
|
||||
already_AddRefed<GLContext> CreateForWindow(nsIWidget *aWidget);
|
||||
|
||||
/**
|
||||
* Try to create a GL context from native surface for arbitrary gfxASurface
|
||||
* If surface not compatible this will return NULL
|
||||
*
|
||||
* @param aSurface surface to create a context for
|
||||
* @return Context to use for this surface
|
||||
*/
|
||||
already_AddRefed<GLContext> CreateForNativePixmapSurface(gfxASurface *aSurface);
|
||||
};
|
||||
|
||||
/** Same as GLContextProvider but for off-screen Mesa rendering */
|
||||
|
@ -146,6 +156,15 @@ public:
|
|||
* @return Context to use for this window
|
||||
*/
|
||||
static already_AddRefed<GLContext> CreateForWindow(nsIWidget *aWidget);
|
||||
|
||||
/**
|
||||
* Try to create a GL context from native surface for arbitrary gfxASurface
|
||||
* If surface not compatible this will return NULL
|
||||
*
|
||||
* @param aSurface surface to create a context for
|
||||
* @return Context to use for this surface
|
||||
*/
|
||||
static already_AddRefed<GLContext> CreateForNativePixmapSurface(gfxASurface *aSurface);
|
||||
};
|
||||
|
||||
extern GLContextProvider THEBES_API sGLContextProvider;
|
||||
|
|
|
@ -3168,6 +3168,12 @@ typedef ptrdiff_t GLintptr;
|
|||
#define LOCAL_EGL_MULTISAMPLE_RESOLVE 0x3099
|
||||
#define LOCAL_EGL_CONTEXT_CLIENT_TYPE 0x3097
|
||||
#define LOCAL_EGL_CONTEXT_CLIENT_VERSION 0x3098
|
||||
#define LOCAL_EGL_BACK_BUFFER 0x3084
|
||||
#define LOCAL_EGL_TEXTURE_RGB 0x305D
|
||||
#define LOCAL_EGL_TEXTURE_RGBA 0x305E
|
||||
#define LOCAL_EGL_TEXTURE_2D 0x305F
|
||||
#define LOCAL_EGL_NATIVE_PIXMAP_KHR 0x30B0
|
||||
#define LOCAL_EGL_IMAGE_PRESERVED_KHR 0x30D2
|
||||
#define LOCAL_EGL_FALSE 0
|
||||
#define LOCAL_EGL_TRUE 1
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "OpenGL/OpenGL.h"
|
||||
#include <OpenGL/gl.h>
|
||||
#include <AppKit/NSOpenGL.h>
|
||||
#include "gfxASurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
@ -250,5 +251,11 @@ GLContextProvider::CreatePBuffer(const gfxIntSize &aSize,
|
|||
return glContext.forget().get();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProvider::CreateForNativePixmapSurface(gfxASurface *aSurface)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxXlibSurface.h"
|
||||
typedef Display *EGLNativeDisplayType;
|
||||
typedef Pixmap EGLNativePixmapType;
|
||||
typedef Window EGLNativeWindowType;
|
||||
|
@ -96,6 +98,8 @@ typedef void *EGLDisplay;
|
|||
typedef void *EGLSurface;
|
||||
typedef void *EGLClientBuffer;
|
||||
typedef void *EGLCastToRelevantPtr;
|
||||
typedef void *EGLImageKHR;
|
||||
typedef void *GLeglImageOES;
|
||||
|
||||
#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
|
||||
#define EGL_NO_CONTEXT ((EGLContext)0)
|
||||
|
@ -104,6 +108,7 @@ typedef void *EGLCastToRelevantPtr;
|
|||
|
||||
GLContextProvider sGLContextProvider;
|
||||
|
||||
|
||||
static class EGLLibrary
|
||||
{
|
||||
public:
|
||||
|
@ -143,6 +148,20 @@ public:
|
|||
pfnWaitNative fWaitNative;
|
||||
typedef EGLCastToRelevantPtr (*pfnGetProcAddress)(const char *procname);
|
||||
pfnGetProcAddress fGetProcAddress;
|
||||
typedef const GLubyte* (*pfnQueryString)(EGLDisplay, EGLint name);
|
||||
pfnQueryString fQueryString;
|
||||
typedef EGLBoolean (*pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
|
||||
pfnBindTexImage fBindTexImage;
|
||||
typedef EGLBoolean (*pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer);
|
||||
pfnReleaseTexImage fReleaseTexImage;
|
||||
typedef EGLImageKHR (*pfnCreateImageKHR)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list);
|
||||
pfnCreateImageKHR fCreateImageKHR;
|
||||
typedef EGLBoolean (*pfnDestroyImageKHR)(EGLDisplay dpy, EGLImageKHR image);
|
||||
pfnDestroyImageKHR fDestroyImageKHR;
|
||||
// This is EGL specific GL ext symbol "glEGLImageTargetTexture2DOES"
|
||||
// Lets keep it here for now.
|
||||
typedef void (*pfnImageTargetTexture2DOES)(GLenum target, GLeglImageOES image);
|
||||
pfnImageTargetTexture2DOES fImageTargetTexture2DOES;
|
||||
|
||||
PRBool EnsureInitialized()
|
||||
{
|
||||
|
@ -178,6 +197,9 @@ public:
|
|||
SYMBOL(GetConfigAttrib),
|
||||
SYMBOL(WaitNative),
|
||||
SYMBOL(GetProcAddress),
|
||||
SYMBOL(QueryString),
|
||||
SYMBOL(BindTexImage),
|
||||
SYMBOL(ReleaseTexImage),
|
||||
{ NULL, { NULL } }
|
||||
};
|
||||
|
||||
|
@ -186,6 +208,20 @@ public:
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
LibrarySymbolLoader::SymLoadStruct khrSymbols[] = {
|
||||
{ (PRFuncPtr*) &fCreateImageKHR, { "eglCreateImageKHR", NULL } },
|
||||
{ (PRFuncPtr*) &fDestroyImageKHR, { "eglDestroyImageKHR", NULL } },
|
||||
{ (PRFuncPtr*) &fImageTargetTexture2DOES, { "glEGLImageTargetTexture2DOES", NULL } },
|
||||
{ NULL, { NULL } }
|
||||
};
|
||||
|
||||
if (!LibrarySymbolLoader::LoadSymbols(mEGLLibrary, &khrSymbols[0],
|
||||
(LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress))
|
||||
{
|
||||
// just means that EGL_image_* isn't supported
|
||||
fCreateImageKHR = nsnull;
|
||||
}
|
||||
|
||||
mInitialized = PR_TRUE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -200,10 +236,13 @@ class GLContextEGL : public GLContext
|
|||
public:
|
||||
GLContextEGL(EGLDisplay aDisplay, EGLConfig aConfig,
|
||||
EGLSurface aSurface, EGLContext aContext,
|
||||
void *aGLWidget = nsnull)
|
||||
void *aGLWidget = nsnull,
|
||||
gfxASurface *aASurface = nsnull)
|
||||
: mDisplay(aDisplay), mConfig(aConfig)
|
||||
, mSurface(aSurface), mContext(aContext)
|
||||
, mGLWidget(aGLWidget)
|
||||
, mASurface(aASurface)
|
||||
, mBound(PR_FALSE)
|
||||
{}
|
||||
|
||||
~GLContextEGL()
|
||||
|
@ -229,6 +268,45 @@ public:
|
|||
return InitWithPrefix("gl", PR_TRUE);
|
||||
}
|
||||
|
||||
PRBool BindTexImage()
|
||||
{
|
||||
if (mBound)
|
||||
if (!ReleaseTexImage())
|
||||
return PR_FALSE;
|
||||
|
||||
if (mSurface) {
|
||||
EGLBoolean success;
|
||||
success = sEGLLibrary.fBindTexImage(mDisplay, (EGLSurface)mSurface,
|
||||
LOCAL_EGL_BACK_BUFFER);
|
||||
if (success == LOCAL_EGL_FALSE)
|
||||
return PR_FALSE;
|
||||
} else
|
||||
return PR_FALSE;
|
||||
|
||||
mBound = PR_TRUE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool ReleaseTexImage()
|
||||
{
|
||||
if (!mBound)
|
||||
return PR_TRUE;
|
||||
|
||||
if (!mDisplay)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mSurface) {
|
||||
EGLBoolean success;
|
||||
success = sEGLLibrary.fReleaseTexImage(mDisplay, (EGLSurface)mSurface, LOCAL_EGL_BACK_BUFFER);
|
||||
if (success == LOCAL_EGL_FALSE)
|
||||
return PR_FALSE;
|
||||
} else
|
||||
return PR_FALSE;
|
||||
|
||||
mBound = PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool MakeCurrent()
|
||||
{
|
||||
PRBool succeeded = PR_TRUE;
|
||||
|
@ -278,6 +356,8 @@ private:
|
|||
EGLSurface mSurface;
|
||||
EGLContext mContext;
|
||||
void *mGLWidget;
|
||||
nsRefPtr <gfxASurface> mASurface;
|
||||
PRBool mBound;
|
||||
};
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
|
@ -448,6 +528,102 @@ GLContextProvider::CreatePBuffer(const gfxIntSize &aSize, const ContextFormat &a
|
|||
return glContext.forget().get();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProvider::CreateForNativePixmapSurface(gfxASurface *aSurface)
|
||||
{
|
||||
EGLDisplay display = nsnull;
|
||||
EGLSurface surface = nsnull;
|
||||
EGLContext context = nsnull;
|
||||
|
||||
if (!sEGLLibrary.EnsureInitialized())
|
||||
return nsnull;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
if (aSurface->GetType() != gfxASurface::SurfaceTypeXlib) {
|
||||
// Not implemented
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
gfxXlibSurface *xsurface = static_cast<gfxXlibSurface*>(aSurface);
|
||||
|
||||
display = sEGLLibrary.fGetDisplay((EGLNativeDisplayType)xsurface->XDisplay());
|
||||
if (!display)
|
||||
return nsnull;
|
||||
|
||||
if (!sEGLLibrary.fInitialize(display, NULL, NULL))
|
||||
return nsnull;
|
||||
|
||||
EGLConfig configs[32];
|
||||
int numConfigs = 32;
|
||||
|
||||
EGLint pixmap_config[] = {
|
||||
LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PIXMAP_BIT,
|
||||
LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
|
||||
LOCAL_EGL_DEPTH_SIZE, 0,
|
||||
LOCAL_EGL_BIND_TO_TEXTURE_RGB, LOCAL_EGL_TRUE,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
EGLint pixmap_config_rgb[] = {
|
||||
LOCAL_EGL_TEXTURE_TARGET, LOCAL_EGL_TEXTURE_2D,
|
||||
LOCAL_EGL_TEXTURE_FORMAT, LOCAL_EGL_TEXTURE_RGB,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
EGLint pixmap_config_rgba[] = {
|
||||
LOCAL_EGL_TEXTURE_TARGET, LOCAL_EGL_TEXTURE_2D,
|
||||
LOCAL_EGL_TEXTURE_FORMAT, LOCAL_EGL_TEXTURE_RGBA,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
if (!sEGLLibrary.fChooseConfig(display, pixmap_config,
|
||||
configs, numConfigs, &numConfigs))
|
||||
return nsnull;
|
||||
|
||||
if (numConfigs == 0)
|
||||
return nsnull;
|
||||
|
||||
PRBool opaque =
|
||||
aSurface->GetContentType() == gfxASurface::CONTENT_COLOR;
|
||||
int i = 0;
|
||||
for (i = 0; i < numConfigs; ++i) {
|
||||
if (opaque)
|
||||
surface = sEGLLibrary.fCreatePixmapSurface(display, configs[i],
|
||||
xsurface->XDrawable(),
|
||||
pixmap_config_rgb);
|
||||
else
|
||||
surface = sEGLLibrary.fCreatePixmapSurface(display, configs[i],
|
||||
xsurface->XDrawable(),
|
||||
pixmap_config_rgba);
|
||||
|
||||
if (surface != EGL_NO_SURFACE)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (aCreateContext) {
|
||||
EGLint cxattribs[] = {
|
||||
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
LOCAL_EGL_NONE
|
||||
};
|
||||
|
||||
context = sEGLLibrary.fCreateContext(display, configs[i], 0, cxattribs);
|
||||
if (!context) {
|
||||
sEGLLibrary.fDestroySurface(display, surface);
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<GLContextEGL> glContext =
|
||||
new GLContextEGL(display, configs[i], surface, context, NULL, aSurface);
|
||||
|
||||
return glContext.forget().get();
|
||||
#else
|
||||
// Not implemented
|
||||
return nsnull;
|
||||
#endif
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "nsDebug.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "GLXLibrary.h"
|
||||
#include "gfxASurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
@ -431,5 +432,11 @@ GLContextProvider::CreatePBuffer(const gfxIntSize &aSize, const ContextFormat& a
|
|||
return glContext.forget().get();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProvider::CreateForNativePixmapSurface(gfxASurface *aSurface)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
|
|
@ -46,6 +46,12 @@ GLContextProvider::CreateForWindow(nsIWidget*)
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProvider::CreateForNativePixmapSurface(gfxASurface *aSurface)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProvider::CreatePBuffer(const gfxIntSize &, const ContextFormat &)
|
||||
{
|
||||
|
|
|
@ -251,6 +251,12 @@ GLContextProviderOSMesa::CreateForWindow(nsIWidget *aWidget)
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderOSMesa::CreateForNativePixmapSurface(gfxASurface *aSurface)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProviderOSMesa::CreatePBuffer(const gfxIntSize &aSize, const ContextFormat& aFormat)
|
||||
{
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "nsDebug.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "WGLLibrary.h"
|
||||
#include "gfxASurface.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
|
@ -411,5 +412,11 @@ GLContextProvider::CreatePBuffer(const gfxIntSize& aSize, const ContextFormat& a
|
|||
return glContext.forget().get();
|
||||
}
|
||||
|
||||
already_AddRefed<GLContext>
|
||||
GLContextProvider::CreateForNativePixmapSurface(gfxASurface *aSurface)
|
||||
{
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
} /* namespace gl */
|
||||
} /* namespace mozilla */
|
||||
|
|
Загрузка…
Ссылка в новой задаче