Bug 571832 - Provide CreateForNativePixmapSurface API. r=vladimir.

--HG--
extra : rebase_source : 0f7214266a6bf449620d6b46fd14bc6978b621ee
This commit is contained in:
Oleg Romashin 2010-06-23 05:24:31 -04:00
Родитель 4ea0ddc817
Коммит f90e8bf405
9 изменённых файлов: 243 добавлений и 1 удалений

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

@ -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 */