зеркало из https://github.com/mozilla/pjs.git
Bug 659832 - Make WebGL working on Maemo r=joe
This commit is contained in:
Родитель
148539b780
Коммит
ea114fe9c9
|
@ -194,7 +194,7 @@ EGLConfig
|
||||||
CreateConfig();
|
CreateConfig();
|
||||||
#ifdef MOZ_X11
|
#ifdef MOZ_X11
|
||||||
static EGLConfig
|
static EGLConfig
|
||||||
CreateEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig = nsnull);
|
CreateEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig = nsnull, EGLenum aDepth = 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -609,6 +609,47 @@ class GLContextEGL : public GLContext
|
||||||
{
|
{
|
||||||
friend class TextureImageEGL;
|
friend class TextureImageEGL;
|
||||||
|
|
||||||
|
static already_AddRefed<GLContextEGL>
|
||||||
|
CreateGLContext(const ContextFormat& format,
|
||||||
|
EGLSurface surface,
|
||||||
|
EGLConfig config,
|
||||||
|
GLContextEGL *shareContext,
|
||||||
|
PRBool aIsOffscreen = PR_FALSE)
|
||||||
|
{
|
||||||
|
EGLContext context;
|
||||||
|
static EGLint cxattribs[] = {
|
||||||
|
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||||
|
LOCAL_EGL_NONE
|
||||||
|
};
|
||||||
|
|
||||||
|
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
|
||||||
|
config,
|
||||||
|
shareContext ? shareContext->mContext : EGL_NO_CONTEXT,
|
||||||
|
cxattribs);
|
||||||
|
if (!context) {
|
||||||
|
if (shareContext) {
|
||||||
|
shareContext = nsnull;
|
||||||
|
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
|
||||||
|
config,
|
||||||
|
EGL_NO_CONTEXT,
|
||||||
|
cxattribs);
|
||||||
|
if (!context) {
|
||||||
|
NS_WARNING("Failed to create EGLContext!");
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<GLContextEGL> glContext =
|
||||||
|
new GLContextEGL(format, shareContext, config,
|
||||||
|
surface, context, aIsOffscreen);
|
||||||
|
|
||||||
|
if (!glContext->Init())
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
return glContext.forget();
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLContextEGL(const ContextFormat& aFormat,
|
GLContextEGL(const ContextFormat& aFormat,
|
||||||
GLContext *aShareContext,
|
GLContext *aShareContext,
|
||||||
|
@ -813,7 +854,8 @@ public:
|
||||||
|
|
||||||
static already_AddRefed<GLContextEGL>
|
static already_AddRefed<GLContextEGL>
|
||||||
CreateEGLPixmapOffscreenContext(const gfxIntSize& aSize,
|
CreateEGLPixmapOffscreenContext(const gfxIntSize& aSize,
|
||||||
const ContextFormat& aFormat);
|
const ContextFormat& aFormat,
|
||||||
|
PRBool aShare);
|
||||||
|
|
||||||
static already_AddRefed<GLContextEGL>
|
static already_AddRefed<GLContextEGL>
|
||||||
CreateEGLPBufferOffscreenContext(const gfxIntSize& aSize,
|
CreateEGLPBufferOffscreenContext(const gfxIntSize& aSize,
|
||||||
|
@ -982,6 +1024,42 @@ GLContextEGL::ResizeOffscreen(const gfxIntSize& aNewSize)
|
||||||
return PR_TRUE;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MOZ_X11
|
||||||
|
if (gUseBackingSurface && mThebesSurface) {
|
||||||
|
if (aNewSize == mThebesSurface->GetSize()) {
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLNativePixmapType pixmap = 0;
|
||||||
|
nsRefPtr<gfxXlibSurface> xsurface =
|
||||||
|
gfxXlibSurface::Create(DefaultScreenOfDisplay(DefaultXDisplay()),
|
||||||
|
gfxXlibSurface::FindRenderFormat(DefaultXDisplay(),
|
||||||
|
gfxASurface::ImageFormatRGB24),
|
||||||
|
aNewSize);
|
||||||
|
// Make sure that pixmap created and ready for GL rendering
|
||||||
|
XSync(DefaultXDisplay(), False);
|
||||||
|
|
||||||
|
if (xsurface->CairoStatus() != 0) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
pixmap = xsurface->XDrawable();
|
||||||
|
if (!pixmap) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLSurface surface;
|
||||||
|
EGLConfig config = 0;
|
||||||
|
int depth = gfxUtils::ImageFormatToDepth(gfxPlatform::GetPlatform()->GetOffscreenFormat());
|
||||||
|
surface = CreateEGLSurfaceForXSurface(xsurface, &config, depth);
|
||||||
|
if (!config) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
mThebesSurface = xsurface;
|
||||||
|
|
||||||
|
return PR_TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return ResizeOffscreenFBO(aNewSize);
|
return ResizeOffscreenFBO(aNewSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1572,7 +1650,9 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
|
||||||
new GLContextEGL(ContextFormat(DepthToGLFormat(viewport->depth())),
|
new GLContextEGL(ContextFormat(DepthToGLFormat(viewport->depth())),
|
||||||
NULL,
|
NULL,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
sEGLLibrary.fGetCurrentContext());
|
sEGLLibrary.fGetCurrentContext(),
|
||||||
|
PR_FALSE);
|
||||||
|
|
||||||
if (!glContext->Init())
|
if (!glContext->Init())
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
|
@ -1717,36 +1797,18 @@ GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLint cxattribs[] = {
|
|
||||||
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
|
||||||
LOCAL_EGL_NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
GLContextEGL *shareContext = GetGlobalContextEGL();
|
GLContextEGL *shareContext = GetGlobalContextEGL();
|
||||||
|
|
||||||
TRY_AGAIN_NO_SHARING:
|
nsRefPtr<GLContextEGL> glContext =
|
||||||
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
|
GLContextEGL::CreateGLContext(ContextFormat(ContextFormat::BasicRGB24),
|
||||||
|
surface,
|
||||||
config,
|
config,
|
||||||
shareContext ? shareContext->mContext : EGL_NO_CONTEXT,
|
|
||||||
cxattribs);
|
|
||||||
if (!context) {
|
|
||||||
if (shareContext) {
|
|
||||||
NS_WARNING("CreateForWindow -- couldn't share, trying again");
|
|
||||||
shareContext = nsnull;
|
|
||||||
goto TRY_AGAIN_NO_SHARING;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_WARNING("CreateForWindow -- no context, giving up");
|
|
||||||
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<GLContextEGL> glContext = new GLContextEGL(ContextFormat(ContextFormat::BasicRGB24),
|
|
||||||
shareContext,
|
shareContext,
|
||||||
config, surface, context);
|
PR_FALSE);
|
||||||
|
|
||||||
if (!glContext->Init())
|
if (!glContext) {
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(XP_WIN) || defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
|
#if defined(XP_WIN) || defined(ANDROID) || defined(MOZ_PLATFORM_MAEMO)
|
||||||
glContext->SetIsDoubleBuffered(PR_TRUE);
|
glContext->SetIsDoubleBuffered(PR_TRUE);
|
||||||
|
@ -1909,7 +1971,7 @@ TRY_ATTRIBS_AGAIN:
|
||||||
|
|
||||||
#ifdef MOZ_X11
|
#ifdef MOZ_X11
|
||||||
EGLSurface
|
EGLSurface
|
||||||
CreateEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig)
|
CreateEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig, EGLenum aDepth)
|
||||||
{
|
{
|
||||||
gfxXlibSurface* xsurface = static_cast<gfxXlibSurface*>(aSurface);
|
gfxXlibSurface* xsurface = static_cast<gfxXlibSurface*>(aSurface);
|
||||||
PRBool opaque =
|
PRBool opaque =
|
||||||
|
@ -1948,7 +2010,7 @@ CreateEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig)
|
||||||
static EGLint pixmap_config[] = {
|
static EGLint pixmap_config[] = {
|
||||||
LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PIXMAP_BIT,
|
LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PIXMAP_BIT,
|
||||||
LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
|
LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
|
||||||
LOCAL_EGL_DEPTH_SIZE, 0,
|
LOCAL_EGL_DEPTH_SIZE, aDepth,
|
||||||
LOCAL_EGL_BIND_TO_TEXTURE_RGB, LOCAL_EGL_TRUE,
|
LOCAL_EGL_BIND_TO_TEXTURE_RGB, LOCAL_EGL_TRUE,
|
||||||
LOCAL_EGL_NONE
|
LOCAL_EGL_NONE
|
||||||
};
|
};
|
||||||
|
@ -1956,7 +2018,7 @@ CreateEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig)
|
||||||
static EGLint pixmap_lock_config[] = {
|
static EGLint pixmap_lock_config[] = {
|
||||||
LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PIXMAP_BIT | LOCAL_EGL_LOCK_SURFACE_BIT_KHR,
|
LOCAL_EGL_SURFACE_TYPE, LOCAL_EGL_PIXMAP_BIT | LOCAL_EGL_LOCK_SURFACE_BIT_KHR,
|
||||||
LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
|
LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
|
||||||
LOCAL_EGL_DEPTH_SIZE, 0,
|
LOCAL_EGL_DEPTH_SIZE, aDepth,
|
||||||
LOCAL_EGL_BIND_TO_TEXTURE_RGB, LOCAL_EGL_TRUE,
|
LOCAL_EGL_BIND_TO_TEXTURE_RGB, LOCAL_EGL_TRUE,
|
||||||
LOCAL_EGL_NONE
|
LOCAL_EGL_NONE
|
||||||
};
|
};
|
||||||
|
@ -1998,18 +2060,9 @@ CreateEGLSurfaceForXSurface(gfxASurface* aSurface, EGLConfig* aConfig)
|
||||||
|
|
||||||
already_AddRefed<GLContextEGL>
|
already_AddRefed<GLContextEGL>
|
||||||
GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& aSize,
|
GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& aSize,
|
||||||
const ContextFormat& aFormat)
|
const ContextFormat& aFormat,
|
||||||
|
PRBool aShare)
|
||||||
{
|
{
|
||||||
// XXX -- write me.
|
|
||||||
// This needs to find a FBConfig/Visual that matches aFormat, and allocate
|
|
||||||
// a gfxXlibSurface of the appropriat format, and then create a context
|
|
||||||
// for it.
|
|
||||||
//
|
|
||||||
// The code below is almost correct, except it doesn't do the format-FBConfig
|
|
||||||
// matching, instead just creating a random gfxXlibSurface. The code below just
|
|
||||||
// uses context sharing and a FBO target, when instead it should avoid context
|
|
||||||
// sharing if some form of texture-from-pixmap functionality is available.
|
|
||||||
|
|
||||||
gfxASurface *thebesSurface = nsnull;
|
gfxASurface *thebesSurface = nsnull;
|
||||||
EGLNativePixmapType pixmap = 0;
|
EGLNativePixmapType pixmap = 0;
|
||||||
|
|
||||||
|
@ -2018,7 +2071,7 @@ GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& aSize,
|
||||||
gfxXlibSurface::Create(DefaultScreenOfDisplay(DefaultXDisplay()),
|
gfxXlibSurface::Create(DefaultScreenOfDisplay(DefaultXDisplay()),
|
||||||
gfxXlibSurface::FindRenderFormat(DefaultXDisplay(),
|
gfxXlibSurface::FindRenderFormat(DefaultXDisplay(),
|
||||||
gfxASurface::ImageFormatRGB24),
|
gfxASurface::ImageFormatRGB24),
|
||||||
gfxIntSize(16, 16));
|
gUseBackingSurface ? aSize : gfxIntSize(16, 16));
|
||||||
|
|
||||||
// XSync required after gfxXlibSurface::Create, otherwise EGL will fail with BadDrawable error
|
// XSync required after gfxXlibSurface::Create, otherwise EGL will fail with BadDrawable error
|
||||||
XSync(DefaultXDisplay(), False);
|
XSync(DefaultXDisplay(), False);
|
||||||
|
@ -2037,41 +2090,22 @@ GLContextEGL::CreateEGLPixmapOffscreenContext(const gfxIntSize& aSize,
|
||||||
EGLConfig config = 0;
|
EGLConfig config = 0;
|
||||||
|
|
||||||
#ifdef MOZ_X11
|
#ifdef MOZ_X11
|
||||||
surface = CreateEGLSurfaceForXSurface(thebesSurface, &config);
|
int depth = gfxUtils::ImageFormatToDepth(gfxPlatform::GetPlatform()->GetOffscreenFormat());
|
||||||
|
surface = CreateEGLSurfaceForXSurface(thebesSurface, &config, gUseBackingSurface ? depth : 0);
|
||||||
#endif
|
#endif
|
||||||
if (!config) {
|
if (!config) {
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLint cxattribs[] = {
|
GLContextEGL *shareContext = aShare ? GetGlobalContextEGL() : nsnull;
|
||||||
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
|
||||||
LOCAL_EGL_NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
GLContextEGL *shareContext = GetGlobalContextEGL();
|
nsRefPtr<GLContextEGL> glContext =
|
||||||
if (!shareContext) {
|
GLContextEGL::CreateGLContext(aFormat,
|
||||||
// we depend on context sharing currently
|
surface,
|
||||||
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
EGLContext context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
|
|
||||||
config,
|
config,
|
||||||
shareContext->Context(),
|
shareContext,
|
||||||
cxattribs);
|
|
||||||
if (!context) {
|
|
||||||
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<GLContextEGL> glContext = new GLContextEGL(aFormat, shareContext,
|
|
||||||
config, surface, context,
|
|
||||||
PR_TRUE);
|
PR_TRUE);
|
||||||
|
|
||||||
if (!glContext->Init() ||
|
|
||||||
!glContext->ResizeOffscreenFBO(aSize))
|
|
||||||
return nsnull;
|
|
||||||
|
|
||||||
glContext->HoldSurface(thebesSurface);
|
glContext->HoldSurface(thebesSurface);
|
||||||
|
|
||||||
return glContext.forget();
|
return glContext.forget();
|
||||||
|
@ -2092,7 +2126,23 @@ GLContextProviderEGL::CreateOffscreen(const gfxIntSize& aSize,
|
||||||
#if defined(ANDROID) || defined(XP_WIN)
|
#if defined(ANDROID) || defined(XP_WIN)
|
||||||
return GLContextEGL::CreateEGLPBufferOffscreenContext(aSize, aFormat);
|
return GLContextEGL::CreateEGLPBufferOffscreenContext(aSize, aFormat);
|
||||||
#elif defined(MOZ_X11)
|
#elif defined(MOZ_X11)
|
||||||
return GLContextEGL::CreateEGLPixmapOffscreenContext(aSize, aFormat);
|
nsRefPtr<GLContextEGL> glContext =
|
||||||
|
GLContextEGL::CreateEGLPixmapOffscreenContext(aSize, aFormat, PR_TRUE);
|
||||||
|
|
||||||
|
if (!glContext) {
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
if (!glContext->GetSharedContext()) {
|
||||||
|
// no point in returning anything if sharing failed, we can't
|
||||||
|
// render from this
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
if (!gUseBackingSurface && !glContext->ResizeOffscreenFBO(aSize)) {
|
||||||
|
// we weren't able to create the initial
|
||||||
|
// offscreen FBO, so this is dead
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
return glContext.forget();
|
||||||
#else
|
#else
|
||||||
return nsnull;
|
return nsnull;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2137,23 +2187,13 @@ GLContextProviderEGL::CreateForNativePixmapSurface(gfxASurface* aSurface)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLint cxattribs[] = {
|
GLContextEGL *shareContext = GetGlobalContextEGL();
|
||||||
LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
|
gfxXlibSurface* xsurface = static_cast<gfxXlibSurface*>(aSurface);
|
||||||
LOCAL_EGL_NONE
|
|
||||||
};
|
|
||||||
|
|
||||||
context = sEGLLibrary.fCreateContext(EGL_DISPLAY(),
|
|
||||||
config,
|
|
||||||
EGL_NO_SURFACE,
|
|
||||||
cxattribs);
|
|
||||||
if (!context) {
|
|
||||||
sEGLLibrary.fDestroySurface(EGL_DISPLAY(), surface);
|
|
||||||
return nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsRefPtr<GLContextEGL> glContext =
|
nsRefPtr<GLContextEGL> glContext =
|
||||||
new GLContextEGL(ContextFormat(ContentTypeToGLFormat(aSurface->GetContentType())),
|
GLContextEGL::CreateGLContext(DepthToGLFormat(xsurface->XRenderFormat()->depth),
|
||||||
nsnull, config, surface, context, PR_FALSE);
|
surface, config, shareContext, PR_FALSE);
|
||||||
|
|
||||||
glContext->HoldSurface(aSurface);
|
glContext->HoldSurface(aSurface);
|
||||||
|
|
||||||
return glContext.forget().get();
|
return glContext.forget().get();
|
||||||
|
@ -2174,7 +2214,10 @@ GLContextProviderEGL::GetGlobalContext()
|
||||||
static bool triedToCreateContext = false;
|
static bool triedToCreateContext = false;
|
||||||
if (!triedToCreateContext && !gGlobalContext) {
|
if (!triedToCreateContext && !gGlobalContext) {
|
||||||
triedToCreateContext = true;
|
triedToCreateContext = true;
|
||||||
gGlobalContext = CreateOffscreen(gfxIntSize(16, 16));
|
gGlobalContext =
|
||||||
|
GLContextEGL::CreateEGLPixmapOffscreenContext(gfxIntSize(16, 16),
|
||||||
|
ContextFormat(ContextFormat::BasicRGB24),
|
||||||
|
PR_FALSE);
|
||||||
if (gGlobalContext)
|
if (gGlobalContext)
|
||||||
gGlobalContext->SetIsGlobalSharedContext(PR_TRUE);
|
gGlobalContext->SetIsGlobalSharedContext(PR_TRUE);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче