Bug 994856 - Add support for Gecko rendering via GLScreenBuffer into external GL Context. r=bjacob,jgilbert

This commit is contained in:
Tatiana Meshkova 2014-04-15 07:57:26 -07:00
parent ef52c3bbf9
commit 0dbaa9d653
11 changed files with 116 additions and 12 deletions

View File

@ -2523,6 +2523,8 @@ public:
return MakeCurrentImpl(aForce);
}
virtual bool Init() = 0;
virtual bool SetupLookupFunction() = 0;
virtual void ReleaseSurface() {}

View File

@ -42,7 +42,7 @@ public:
return static_cast<GLContextCGL*>(gl);
}
bool Init();
bool Init() MOZ_OVERRIDE;
NSOpenGLContext* GetNSOpenGLContext() const { return mContext; }
CGLContextObj GetCGLContext() const;

View File

@ -46,7 +46,7 @@ public:
return static_cast<GLContextEGL*>(gl);
}
bool Init();
bool Init() MOZ_OVERRIDE;
virtual bool IsDoubleBuffered() const MOZ_OVERRIDE {
return mIsDoubleBuffered;
@ -117,6 +117,7 @@ protected:
#ifdef MOZ_WIDGET_GONK
nsRefPtr<HwcComposer2D> mHwc;
#endif
bool mOwnsContext;
static EGLSurface CreatePBufferSurfaceTryingPowerOfTwo(EGLConfig config,
EGLenum bindToTextureFormat,

View File

@ -36,7 +36,7 @@ public:
return static_cast<GLContextGLX*>(gl);
}
bool Init();
bool Init() MOZ_OVERRIDE;
virtual bool MakeCurrentImpl(bool aForce) MOZ_OVERRIDE;
@ -72,6 +72,7 @@ private:
GLXLibrary* mGLX;
nsRefPtr<gfxXlibSurface> mPixmap;
bool mOwnsContext;
};
}

View File

@ -186,13 +186,15 @@ GetGlobalContextCGL()
return static_cast<GLContextCGL*>(GLContextProviderCGL::GetGlobalContext());
}
already_AddRefed<GLContext>
GLContextProviderCGL::CreateWrappingExisting(void*, void*)
{
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
{
if (!sCGLLibrary.EnsureInitialized()) {
return nullptr;
}
GLContextCGL *shareContext = GetGlobalContextCGL();
NSOpenGLContext *context = [[NSOpenGLContext alloc]

View File

@ -233,6 +233,7 @@ GLContextEGL::GLContextEGL(
, mIsDoubleBuffered(false)
, mCanBindToTexture(false)
, mShareWithEGLImage(false)
, mOwnsContext(true)
{
// any EGL contexts will always be GLESv2
SetProfileVersion(ContextProfile::OpenGLES, 200);
@ -257,6 +258,11 @@ GLContextEGL::~GLContextEGL()
{
MarkDestroyed();
// Wrapped context should not destroy eglContext/Surface
if (!mOwnsContext) {
return;
}
#ifdef DEBUG
printf_stderr("Destroying context %p surface %p on display %p\n", mContext, mSurface, EGL_DISPLAY());
#endif
@ -409,6 +415,9 @@ GLContextEGL::IsCurrent() {
bool
GLContextEGL::RenewSurface() {
if (!mOwnsContext) {
return false;
}
#ifndef MOZ_WIDGET_ANDROID
MOZ_CRASH("unimplemented");
// to support this on non-Android platforms, need to keep track of the nsIWidget that
@ -429,7 +438,9 @@ GLContextEGL::RenewSurface() {
void
GLContextEGL::ReleaseSurface() {
DestroySurface(mSurface);
if (mOwnsContext) {
DestroySurface(mSurface);
}
mSurface = EGL_NO_SURFACE;
}
@ -681,6 +692,31 @@ CreateConfig(EGLConfig* aConfig)
}
}
already_AddRefed<GLContext>
GLContextProviderEGL::CreateWrappingExisting(void* aContext, void* aSurface)
{
if (!sEGLLibrary.EnsureInitialized()) {
MOZ_CRASH("Failed to load EGL library!\n");
return nullptr;
}
if (aContext && aSurface) {
SurfaceCaps caps = SurfaceCaps::Any();
EGLConfig config = EGL_NO_CONFIG;
nsRefPtr<GLContextEGL> glContext =
new GLContextEGL(caps,
nullptr, false,
config, (EGLSurface)aSurface, (EGLContext)aContext);
glContext->SetIsDoubleBuffered(true);
glContext->mOwnsContext = false;
return glContext.forget();
}
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderEGL::CreateForWindow(nsIWidget *aWidget)
{

View File

@ -824,6 +824,11 @@ GLContextGLX::~GLContextGLX()
{
MarkDestroyed();
// Wrapped context should not destroy glxContext/Surface
if (!mOwnsContext) {
return;
}
// see bug 659842 comment 76
#ifdef DEBUG
bool success =
@ -923,7 +928,8 @@ GLContextGLX::GLContextGLX(
mDeleteDrawable(aDeleteDrawable),
mDoubleBuffered(aDoubleBuffered),
mGLX(&sGLXLibrary),
mPixmap(aPixmap)
mPixmap(aPixmap),
mOwnsContext(true)
{
MOZ_ASSERT(mGLX);
// See 899855
@ -957,6 +963,36 @@ AreCompatibleVisuals(Visual *one, Visual *two)
return true;
}
static StaticRefPtr<GLContext> gGlobalContext;
already_AddRefed<GLContext>
GLContextProviderGLX::CreateWrappingExisting(void* aContext, void* aSurface)
{
if (!sGLXLibrary.EnsureInitialized()) {
return nullptr;
}
if (aContext && aSurface) {
SurfaceCaps caps = SurfaceCaps::Any();
nsRefPtr<GLContextGLX> glContext =
new GLContextGLX(caps,
nullptr, // SharedContext
false, // Offscreen
(Display*)DefaultXDisplay(), // Display
(GLXDrawable)aSurface, (GLXContext)aContext,
false, // aDeleteDrawable,
true,
(gfxXlibSurface*)nullptr);
glContext->mOwnsContext = false;
gGlobalContext = glContext;
return glContext.forget();
}
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
{
@ -972,6 +1008,11 @@ GLContextProviderGLX::CreateForWindow(nsIWidget *aWidget)
// is a relatively safe intermediate step.
Display *display = (Display*)aWidget->GetNativeData(NS_NATIVE_DISPLAY);
if (!display) {
NS_ERROR("X Display required for GLX Context provider");
return nullptr;
}
int xscreen = DefaultScreen(display);
Window window = GET_NATIVE_WINDOW(aWidget);
@ -1188,8 +1229,6 @@ GLContextProviderGLX::CreateOffscreen(const gfxIntSize& size,
return glContext.forget();
}
static StaticRefPtr<GLContext> gGlobalContext;
GLContext*
GLContextProviderGLX::GetGlobalContext()
{

View File

@ -61,6 +61,17 @@ public:
CreateOffscreen(const gfxIntSize& size,
const SurfaceCaps& caps);
/**
* Create wrapping Gecko GLContext for external gl context.
*
* @param aContext External context which will be wrapped by Gecko GLContext.
* @param aSurface External surface which is used for external context.
*
* @return Wrapping Context to use for rendering
*/
static already_AddRefed<GLContext>
CreateWrappingExisting(void* aContext, void* aSurface);
/**
* Get a pointer to the global context, creating it if it doesn't exist.
*/

View File

@ -14,6 +14,12 @@ GLContextProviderNull::CreateForWindow(nsIWidget*)
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderNull::CreateWrappingExisting(void*, void*)
{
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderNull::CreateOffscreen(const gfxIntSize&,
const SurfaceCaps&,

View File

@ -398,6 +398,12 @@ GetGlobalContextWGL()
return static_cast<GLContextWGL*>(GLContextProviderWGL::GetGlobalContext());
}
already_AddRefed<GLContext>
GLContextProviderWGL::CreateWrappingExisting(void*, void*)
{
return nullptr;
}
already_AddRefed<GLContext>
GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget)
{

View File

@ -43,7 +43,7 @@ public:
return static_cast<GLContextWGL*>(gl);
}
bool Init();
bool Init() MOZ_OVERRIDE;
virtual bool MakeCurrentImpl(bool aForce) MOZ_OVERRIDE;