Bug 1586696 [Wayland] Use wayland dmabuf as WebGL backend, r=jgilbert

- Create new SharedSurfaceType called EGLSurfaceDMABUF
- Implement EGLSurfaceDMABUF by SharedSurfaceDMABUF which is backed by WaylandDMABufSurface.
  It can be used by Wayland/EGL WebGL backend.
- It's disabled by default, can be enabled by widget.wayland_dmabuf_webgl.enabled pref.

Differential Revision: https://phabricator.services.mozilla.com/D60114

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Martin Stransky 2020-02-05 06:32:25 +00:00
Родитель f6dd475e70
Коммит 849ffb22b3
6 изменённых файлов: 153 добавлений и 1 удалений

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

@ -34,6 +34,11 @@
# include "SharedSurfaceGLX.h"
#endif
#ifdef MOZ_WAYLAND
# include "gfxPlatformGtk.h"
# include "SharedSurfaceDMABUF.h"
#endif
namespace mozilla::gl {
using gfx::SurfaceFormat;
@ -84,6 +89,13 @@ UniquePtr<SurfaceFactory> GLScreenBuffer::CreateFactory(
if (useGl) {
#if defined(XP_MACOSX)
factory = SurfaceFactory_IOSurface::Create(gl, caps, ipcChannel, flags);
#elif defined(MOZ_WAYLAND)
if (gl->GetContextType() == GLContextType::EGL) {
if (gfxPlatformGtk::GetPlatform()->UseWaylandDMABufWebGL()) {
factory =
MakeUnique<SurfaceFactory_DMABUF>(gl, caps, ipcChannel, flags);
}
}
#elif defined(MOZ_X11)
if (sGLXLibrary.UseTextureFromPixmap())
factory = SurfaceFactory_GLXDrawable::Create(gl, caps, ipcChannel, flags);

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

@ -0,0 +1,59 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */
/* 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 "SharedSurfaceDMABUF.h"
#include "GLContextEGL.h"
#include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor, etc
namespace mozilla::gl {
/*static*/
UniquePtr<SharedSurface_DMABUF> SharedSurface_DMABUF::Create(
GLContext* prodGL, const GLFormats& formats, const gfx::IntSize& size,
bool hasAlpha) {
auto flags = static_cast<WaylandDMABufSurfaceFlags>(DMABUF_TEXTURE |
DMABUF_USE_MODIFIERS);
if (hasAlpha) {
flags = static_cast<WaylandDMABufSurfaceFlags>(flags | DMABUF_ALPHA);
}
RefPtr<WaylandDMABufSurface> surface =
WaylandDMABufSurface::CreateDMABufSurface(size.width, size.height, flags);
if (!surface || !surface->CreateEGLImage(prodGL)) {
return nullptr;
}
UniquePtr<SharedSurface_DMABUF> ret;
ret.reset(new SharedSurface_DMABUF(prodGL, size, hasAlpha, surface));
return ret;
}
SharedSurface_DMABUF::SharedSurface_DMABUF(
GLContext* gl, const gfx::IntSize& size, bool hasAlpha,
RefPtr<WaylandDMABufSurface> aSurface)
: SharedSurface(SharedSurfaceType::EGLSurfaceDMABUF,
AttachmentType::GLTexture, gl, size, hasAlpha, true),
mSurface(aSurface) {}
SharedSurface_DMABUF::~SharedSurface_DMABUF() {
if (!mGL || !mGL->MakeCurrent()) {
return;
}
mSurface->ReleaseEGLImage();
}
void SharedSurface_DMABUF::ProducerReleaseImpl() {
mGL->MakeCurrent();
// We don't have a better sync mechanism here so use glFinish() at least.
mGL->fFinish();
}
bool SharedSurface_DMABUF::ToSurfaceDescriptor(
layers::SurfaceDescriptor* const out_descriptor) {
MOZ_ASSERT(mSurface);
return mSurface->Serialize(*out_descriptor);
}
} // namespace mozilla::gl

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

@ -0,0 +1,80 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 4; -*- */
/* 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 SHARED_SURFACE_DMABUF_H_
#define SHARED_SURFACE_DMABUF_H_
#include "SharedSurface.h"
#include "mozilla/widget/WaylandDMABufSurface.h"
namespace mozilla {
namespace gl {
class GLContext;
class GLLibraryEGL;
class SharedSurface_DMABUF final : public SharedSurface {
public:
static UniquePtr<SharedSurface_DMABUF> Create(GLContext* prodGL,
const GLFormats& formats,
const gfx::IntSize& size,
bool hasAlpha);
static SharedSurface_DMABUF* Cast(SharedSurface* surf) {
MOZ_ASSERT(surf->mType == SharedSurfaceType::EGLSurfaceDMABUF);
return (SharedSurface_DMABUF*)surf;
}
protected:
RefPtr<WaylandDMABufSurface> mSurface;
SharedSurface_DMABUF(GLContext* gl, const gfx::IntSize& size, bool hasAlpha,
RefPtr<WaylandDMABufSurface> aSurface);
void UpdateProdTexture(const MutexAutoLock& curAutoLock);
public:
virtual ~SharedSurface_DMABUF();
// Exclusive Content/WebGL lock/unlock of surface for write
virtual void LockProdImpl() override {}
virtual void UnlockProdImpl() override {}
// Non-exclusive Content/WebGL lock/unlock of surface for write
virtual void ProducerAcquireImpl() override {}
virtual void ProducerReleaseImpl() override;
// Non-exclusive Content/WebGL lock/unlock for read from surface
virtual void ProducerReadAcquireImpl() override {}
virtual void ProducerReadReleaseImpl() override {}
virtual GLuint ProdTexture() override { return mSurface->GetGLTexture(); }
virtual bool ToSurfaceDescriptor(
layers::SurfaceDescriptor* const out_descriptor) override;
};
class SurfaceFactory_DMABUF : public SurfaceFactory {
public:
SurfaceFactory_DMABUF(GLContext* prodGL, const SurfaceCaps& caps,
const RefPtr<layers::LayersIPCChannel>& allocator,
const layers::TextureFlags& flags)
: SurfaceFactory(SharedSurfaceType::EGLSurfaceDMABUF, prodGL, caps,
allocator, flags){};
public:
virtual UniquePtr<SharedSurface> CreateShared(
const gfx::IntSize& size) override {
bool hasAlpha = mReadCaps.alpha;
return SharedSurface_DMABUF::Create(mGL, mFormats, size, hasAlpha);
}
};
} // namespace gl
} // namespace mozilla
#endif /* SHARED_SURFACE_DMABUF_H_ */

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

@ -78,6 +78,7 @@ enum class SharedSurfaceType : uint8_t {
GLXDrawable,
SharedGLTexture,
AndroidSurfaceTexture,
EGLSurfaceDMABUF,
Max
};

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

@ -118,6 +118,7 @@ elif gl_provider == 'GLX':
if CONFIG['MOZ_WAYLAND']:
SOURCES += [
'GLContextProviderWayland.cpp',
'SharedSurfaceDMABUF.cpp'
]
UNIFIED_SOURCES += [

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

@ -74,7 +74,6 @@ void WaylandDMABUFTextureHostOGL::SetTextureSourceProvider(
}
gfx::SurfaceFormat WaylandDMABUFTextureHostOGL::GetFormat() const {
MOZ_ASSERT(mTextureSource);
return mTextureSource ? mTextureSource->GetFormat()
: gfx::SurfaceFormat::UNKNOWN;
}