Bug 1711224 - Add Wayland support for RenderCompositorNativeSWGL,

In order to do that, move buffer type specific code into
`NativeSurfaceWayland` and create subclasses for SHM and EGL
buffers.

This should help identify bugs, improve the code structure for
additional buffer types (e.g. YUV) and makes us get closer
to the CA backend.

Also includes some minor unrelated cleanups.

Differential Revision: https://phabricator.services.mozilla.com/D115938
This commit is contained in:
Robert Mader 2021-05-25 21:14:39 +00:00
Родитель c7f3514be1
Коммит 067d78ddef
6 изменённых файлов: 323 добавлений и 92 удалений

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

@ -8,7 +8,6 @@
#include <algorithm>
#include "gfxUtils.h"
#include "GLContextEGL.h"
#include "GLContextProvider.h"
#include "mozilla/layers/SurfacePoolWayland.h"
#include "mozilla/StaticPrefs_widget.h"
@ -19,7 +18,6 @@ namespace mozilla::layers {
using gfx::Point;
using gfx::Rect;
using gfx::Size;
using gl::GLContextEGL;
/* static */
already_AddRefed<NativeLayerRootWayland>
@ -33,19 +31,19 @@ NativeLayerRootWayland::NativeLayerRootWayland(MozContainer* aContainer)
: mMutex("NativeLayerRootWayland"), mContainer(aContainer) {}
void NativeLayerRootWayland::EnsureSurfaceInitialized() {
MutexAutoLock lock(mMutex);
if (mShmBuffer) {
return;
}
mShmBuffer = widget::WaylandShmBuffer::Create(widget::WaylandDisplayGet(),
LayoutDeviceIntSize(1, 1));
mShmBuffer->Clear();
wl_surface* wlSurface = moz_container_wayland_surface_lock(mContainer);
mShmBuffer->AttachAndCommit(wlSurface);
moz_container_wayland_surface_unlock(mContainer, &wlSurface);
if (wlSurface) {
mShmBuffer = widget::WaylandShmBuffer::Create(widget::WaylandDisplayGet(),
LayoutDeviceIntSize(1, 1));
mShmBuffer->Clear();
mShmBuffer->AttachAndCommit(wlSurface);
moz_container_wayland_surface_unlock(mContainer, &wlSurface);
}
}
already_AddRefed<NativeLayer> NativeLayerRootWayland::CreateLayer(
@ -63,7 +61,7 @@ NativeLayerRootWayland::CreateLayerForExternalTexture(bool aIsOpaque) {
}
void NativeLayerRootWayland::AppendLayer(NativeLayer* aLayer) {
MOZ_ASSERT(false);
MOZ_RELEASE_ASSERT(false);
MutexAutoLock lock(mMutex);
RefPtr<NativeLayerWayland> layerWayland = aLayer->AsNativeLayerWayland();
@ -74,7 +72,7 @@ void NativeLayerRootWayland::AppendLayer(NativeLayer* aLayer) {
}
void NativeLayerRootWayland::RemoveLayer(NativeLayer* aLayer) {
MOZ_ASSERT(false);
MOZ_RELEASE_ASSERT(false);
MutexAutoLock lock(mMutex);
RefPtr<NativeLayerWayland> layerWayland = aLayer->AsNativeLayerWayland();
@ -83,15 +81,19 @@ void NativeLayerRootWayland::RemoveLayer(NativeLayer* aLayer) {
mSublayers.RemoveElement(layerWayland);
}
void NativeLayerRootWayland::EnsureShowLayer(
bool NativeLayerRootWayland::EnsureShowLayer(
const RefPtr<NativeLayerWayland>& aLayer) {
if (aLayer->mIsShown) {
return;
return true;
}
RefPtr<NativeSurfaceWayland> nativeSurface = aLayer->mNativeSurface;
if (!nativeSurface->mWlSubsurface) {
wl_surface* wlSurface = moz_container_wayland_surface_lock(mContainer);
if (!wlSurface) {
return false;
}
wl_subcompositor* subcompositor =
widget::WaylandDisplayGet()->GetSubcompositor();
@ -102,6 +104,7 @@ void NativeLayerRootWayland::EnsureShowLayer(
}
aLayer->mIsShown = true;
return true;
}
void NativeLayerRootWayland::EnsureHideLayer(
@ -120,8 +123,10 @@ void NativeLayerRootWayland::EnsureHideLayer(
wl_surface_commit(nativeSurface->mWlSurface);
wl_surface* wlSurface = moz_container_wayland_surface_lock(mContainer);
wl_subsurface_place_below(nativeSurface->mWlSubsurface, wlSurface);
moz_container_wayland_surface_unlock(mContainer, &wlSurface);
if (wlSurface) {
wl_subsurface_place_below(nativeSurface->mWlSubsurface, wlSurface);
moz_container_wayland_surface_unlock(mContainer, &wlSurface);
}
aLayer->mIsShown = false;
}
@ -192,7 +197,9 @@ void NativeLayerRootWayland::SetLayers(
if (roundf(surfaceRectClipped.width) > 0 &&
roundf(surfaceRectClipped.height) > 0) {
EnsureShowLayer(layer);
if (!EnsureShowLayer(layer)) {
continue;
}
} else {
EnsureHideLayer(layer);
continue;
@ -215,15 +222,6 @@ void NativeLayerRootWayland::SetLayers(
bufferClip.width /= scaleX;
bufferClip.height /= scaleY;
// WR uses top-left coordinates but our buffers are in bottom-left ones
if (layer->SurfaceIsFlipped()) {
wl_surface_set_buffer_transform(nativeSurface->mWlSurface,
WL_OUTPUT_TRANSFORM_NORMAL);
} else {
wl_surface_set_buffer_transform(nativeSurface->mWlSurface,
WL_OUTPUT_TRANSFORM_FLIPPED_180);
}
wp_viewport_set_source(nativeSurface->mViewport,
wl_fixed_from_double(bufferClip.x),
wl_fixed_from_double(bufferClip.y),
@ -236,7 +234,7 @@ void NativeLayerRootWayland::SetLayers(
StaticPrefs::widget_wayland_opaque_region_enabled_AtStartup()) {
wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX);
}
wl_surface_set_opaque_region(layer->mNativeSurface->mWlSurface, region);
wl_surface_set_opaque_region(nativeSurface->mWlSurface, region);
wl_region_destroy(region);
if (previousSurface) {
@ -244,8 +242,10 @@ void NativeLayerRootWayland::SetLayers(
previousSurface = nativeSurface->mWlSurface;
} else {
wl_surface* wlSurface = moz_container_wayland_surface_lock(mContainer);
wl_subsurface_place_above(nativeSurface->mWlSubsurface, wlSurface);
moz_container_wayland_surface_unlock(mContainer, &wlSurface);
if (wlSurface) {
wl_subsurface_place_above(nativeSurface->mWlSubsurface, wlSurface);
moz_container_wayland_surface_unlock(mContainer, &wlSurface);
}
previousSurface = nativeSurface->mWlSurface;
}
}
@ -266,31 +266,15 @@ float NativeLayerRootWayland::BackingScale() {
}
bool NativeLayerRootWayland::CommitToScreen() {
{
MutexAutoLock lock(mMutex);
MutexAutoLock lock(mMutex);
wl_surface* wlSurface = moz_container_wayland_surface_lock(mContainer);
for (RefPtr<NativeLayerWayland>& layer : mSublayers) {
RefPtr<NativeSurfaceWayland> nativeSurface = layer->mNativeSurface;
if (!layer->mDirtyRegion.IsEmpty()) {
GLContextEGL* gl = GLContextEGL::Cast(layer->mSurfacePoolHandle->gl());
auto egl = gl->mEgl;
gl->SetEGLSurfaceOverride(nativeSurface->GetEGLSurface());
gl->MakeCurrent();
egl->fSwapInterval(0);
egl->fSwapBuffers(nativeSurface->GetEGLSurface());
gl->SetEGLSurfaceOverride(nullptr);
gl->MakeCurrent();
layer->mDirtyRegion.SetEmpty();
} else {
wl_surface_commit(nativeSurface->mWlSurface);
}
}
wl_surface* wlSurface = moz_container_wayland_surface_lock(mContainer);
for (RefPtr<NativeLayerWayland>& layer : mSublayers) {
layer->mNativeSurface->Commit(layer->mDirtyRegion);
layer->mDirtyRegion.SetEmpty();
}
if (wlSurface) {
wl_surface_commit(wlSurface);
moz_container_wayland_surface_unlock(mContainer, &wlSurface);
}
@ -333,7 +317,7 @@ NativeLayerWayland::NativeLayerWayland(bool aIsOpaque)
: mMutex("NativeLayerWayland"),
mSurfacePoolHandle(nullptr),
mIsOpaque(aIsOpaque) {
MOZ_ASSERT(false); // external image
MOZ_RELEASE_ASSERT(false); // external image
}
NativeLayerWayland::~NativeLayerWayland() {
@ -344,7 +328,7 @@ NativeLayerWayland::~NativeLayerWayland() {
void NativeLayerWayland::AttachExternalImage(
wr::RenderTextureHost* aExternalImage) {
MOZ_ASSERT(false);
MOZ_RELEASE_ASSERT(false);
}
void NativeLayerWayland::SetSurfaceIsFlipped(bool aIsFlipped) {
@ -440,8 +424,16 @@ IntRect NativeLayerWayland::CurrentSurfaceDisplayRect() {
RefPtr<DrawTarget> NativeLayerWayland::NextSurfaceAsDrawTarget(
const IntRect& aDisplayRect, const IntRegion& aUpdateRegion,
BackendType aBackendType) {
MOZ_ASSERT(false);
return nullptr;
MutexAutoLock lock(mMutex);
mValidRect = IntRect(aDisplayRect);
mDirtyRegion = IntRegion(aUpdateRegion);
if (!mNativeSurface) {
mNativeSurface = mSurfacePoolHandle->ObtainSurfaceFromPool(mSize);
}
return mNativeSurface->GetAsDrawTarget();
}
Maybe<GLuint> NativeLayerWayland::NextSurfaceAsFramebuffer(
@ -455,20 +447,14 @@ Maybe<GLuint> NativeLayerWayland::NextSurfaceAsFramebuffer(
if (!mNativeSurface) {
mNativeSurface = mSurfacePoolHandle->ObtainSurfaceFromPool(mSize);
}
GLContextEGL* gl = GLContextEGL::Cast(mSurfacePoolHandle->gl());
gl->SetEGLSurfaceOverride(mNativeSurface->GetEGLSurface());
gl->MakeCurrent();
return Some(0);
return mNativeSurface ? mNativeSurface->GetAsFramebuffer() : Nothing();
}
void NativeLayerWayland::NotifySurfaceReady() {
MutexAutoLock lock(mMutex);
GLContextEGL* gl = GLContextEGL::Cast(mSurfacePoolHandle->gl());
gl->SetEGLSurfaceOverride(nullptr);
gl->MakeCurrent();
mNativeSurface->NotifySurfaceReady();
}
void NativeLayerWayland::DiscardBackbuffers() {}

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

@ -15,8 +15,9 @@
#include "mozilla/layers/SurfacePoolWayland.h"
#include "mozilla/widget/MozContainerWayland.h"
#include "mozilla/widget/WaylandShmBuffer.h"
#include "nsRegion.h"
#include "nsISupportsImpl.h"
#include "nsRegion.h"
#include "nsTArray.h"
namespace mozilla::layers {
@ -62,7 +63,7 @@ class NativeLayerRootWayland : public NativeLayerRoot {
~NativeLayerRootWayland() = default;
void EnsureSurfaceInitialized();
void EnsureShowLayer(const RefPtr<NativeLayerWayland>& aLayer);
bool EnsureShowLayer(const RefPtr<NativeLayerWayland>& aLayer);
void EnsureHideLayer(const RefPtr<NativeLayerWayland>& aLayer);
void UnmapLayer(const RefPtr<NativeLayerWayland>& aLayer);

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

@ -9,37 +9,201 @@
namespace mozilla::layers {
using gfx::IntRect;
using gl::GLContextEGL;
NativeSurfaceWayland::NativeSurfaceWayland(const IntSize& aSize, GLContext* aGL)
: mGL(aGL) {
wl_compositor* compositor = widget::WaylandDisplayGet()->GetCompositor();
#define BACK_BUFFER_NUM 3
RefPtr<NativeSurfaceWayland> NativeSurfaceWayland::Create(const IntSize& aSize,
GLContext* aGL) {
if (aGL) {
RefPtr<NativeSurfaceWaylandEGL> surfaceEGL =
new NativeSurfaceWaylandEGL(widget::WaylandDisplayGet(), aGL);
surfaceEGL->mEGLWindow =
wl_egl_window_create(surfaceEGL->mWlSurface, aSize.width, aSize.height);
if (!surfaceEGL->mEGLWindow) {
return nullptr;
}
GLContextEGL* egl = GLContextEGL::Cast(aGL);
surfaceEGL->mEGLSurface = egl->mEgl->fCreateWindowSurface(
egl->mConfig, surfaceEGL->mEGLWindow, nullptr);
if (surfaceEGL->mEGLSurface == EGL_NO_SURFACE) {
return nullptr;
}
return surfaceEGL;
}
return new NativeSurfaceWaylandSHM(widget::WaylandDisplayGet(), aSize);
}
NativeSurfaceWayland::NativeSurfaceWayland(
const RefPtr<nsWaylandDisplay>& aWaylandDisplay)
: mWaylandDisplay(aWaylandDisplay) {
wl_compositor* compositor = mWaylandDisplay->GetCompositor();
mWlSurface = wl_compositor_create_surface(compositor);
wl_region* region = wl_compositor_create_region(compositor);
wl_surface_set_input_region(mWlSurface, region);
wl_region_destroy(region);
wp_viewporter* viewporter = widget::WaylandDisplayGet()->GetViewporter();
wp_viewporter* viewporter = mWaylandDisplay->GetViewporter();
MOZ_ASSERT(viewporter);
mViewport = wp_viewporter_get_viewport(viewporter, mWlSurface);
mEGLWindow = wl_egl_window_create(mWlSurface, aSize.width, aSize.height);
GLContextEGL* egl = GLContextEGL::Cast(mGL);
mEGLSurface =
egl->mEgl->fCreateWindowSurface(egl->mConfig, mEGLWindow, nullptr);
MOZ_ASSERT(mEGLSurface != EGL_NO_SURFACE);
}
NativeSurfaceWayland::~NativeSurfaceWayland() {
GLContextEGL* egl = GLContextEGL::Cast(mGL);
egl->mEgl->fDestroySurface(mEGLSurface);
g_clear_pointer(&mEGLWindow, wl_egl_window_destroy);
g_clear_pointer(&mViewport, wp_viewport_destroy);
g_clear_pointer(&mWlSubsurface, wl_subsurface_destroy);
g_clear_pointer(&mWlSurface, wl_surface_destroy);
}
NativeSurfaceWaylandEGL::NativeSurfaceWaylandEGL(
const RefPtr<nsWaylandDisplay>& aWaylandDisplay, GLContext* aGL)
: NativeSurfaceWayland(aWaylandDisplay),
mGL(aGL),
mEGLWindow(nullptr),
mEGLSurface(nullptr) {
wl_surface_set_buffer_transform(mWlSurface, WL_OUTPUT_TRANSFORM_FLIPPED_180);
}
NativeSurfaceWaylandEGL::~NativeSurfaceWaylandEGL() { DestroyGLResources(); }
Maybe<GLuint> NativeSurfaceWaylandEGL::GetAsFramebuffer() {
GLContextEGL* gl = GLContextEGL::Cast(mGL);
gl->SetEGLSurfaceOverride(mEGLSurface);
gl->MakeCurrent();
return Some(0);
}
void NativeSurfaceWaylandEGL::Commit(const IntRegion& aInvalidRegion) {
if (aInvalidRegion.IsEmpty()) {
wl_surface_commit(mWlSurface);
return;
}
GLContextEGL* gl = GLContextEGL::Cast(mGL);
auto egl = gl->mEgl;
gl->SetEGLSurfaceOverride(mEGLSurface);
gl->MakeCurrent();
gl->mEgl->fSwapInterval(0);
gl->mEgl->fSwapBuffers(mEGLSurface);
gl->SetEGLSurfaceOverride(nullptr);
gl->MakeCurrent();
}
void NativeSurfaceWaylandEGL::NotifySurfaceReady() {
GLContextEGL* gl = GLContextEGL::Cast(mGL);
gl->SetEGLSurfaceOverride(nullptr);
gl->MakeCurrent();
}
void NativeSurfaceWaylandEGL::DestroyGLResources() {
if (mEGLSurface != EGL_NO_SURFACE) {
GLContextEGL* egl = GLContextEGL::Cast(mGL);
egl->mEgl->fDestroySurface(mEGLSurface);
mEGLSurface = EGL_NO_SURFACE;
g_clear_pointer(&mEGLWindow, wl_egl_window_destroy);
}
}
NativeSurfaceWaylandSHM::NativeSurfaceWaylandSHM(
const RefPtr<nsWaylandDisplay>& aWaylandDisplay, const IntSize& aSize)
: NativeSurfaceWayland(aWaylandDisplay), mSize(aSize) {}
RefPtr<DrawTarget> NativeSurfaceWaylandSHM::GetAsDrawTarget() {
if (!mCurrentBuffer) {
mCurrentBuffer = ObtainBufferFromPool();
}
return mCurrentBuffer->Lock();
}
void NativeSurfaceWaylandSHM::Commit(const IntRegion& aInvalidRegion) {
if (aInvalidRegion.IsEmpty()) {
if (mCurrentBuffer) {
ReturnBufferToPool(mCurrentBuffer);
mCurrentBuffer = nullptr;
}
wl_surface_commit(mWlSurface);
return;
}
for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) {
IntRect r = iter.Get();
wl_surface_damage_buffer(mWlSurface, r.x, r.y, r.width, r.height);
}
MOZ_ASSERT(mCurrentBuffer);
mCurrentBuffer->AttachAndCommit(mWlSurface);
mCurrentBuffer = nullptr;
EnforcePoolSizeLimit();
}
RefPtr<WaylandShmBuffer> NativeSurfaceWaylandSHM::ObtainBufferFromPool() {
if (!mAvailableBuffers.IsEmpty()) {
RefPtr<WaylandShmBuffer> buffer = mAvailableBuffers.PopLastElement();
mInUseBuffers.AppendElement(buffer);
return buffer;
}
RefPtr<WaylandShmBuffer> buffer = WaylandShmBuffer::Create(
mWaylandDisplay, LayoutDeviceIntSize::FromUnknownSize(mSize));
mInUseBuffers.AppendElement(buffer);
buffer->SetBufferReleaseFunc(
&NativeSurfaceWaylandSHM::BufferReleaseCallbackHandler);
buffer->SetBufferReleaseData(this);
return buffer;
}
void NativeSurfaceWaylandSHM::ReturnBufferToPool(
const RefPtr<WaylandShmBuffer>& aBuffer) {
for (const RefPtr<WaylandShmBuffer>& buffer : mInUseBuffers) {
if (buffer == aBuffer) {
if (buffer->IsMatchingSize(LayoutDeviceIntSize::FromUnknownSize(mSize))) {
mAvailableBuffers.AppendElement(buffer);
}
mInUseBuffers.RemoveElement(buffer);
return;
}
}
MOZ_RELEASE_ASSERT(false, "Returned buffer not in use");
}
void NativeSurfaceWaylandSHM::EnforcePoolSizeLimit() {
// Enforce the pool size limit, removing least-recently-used entries as
// necessary.
while (mAvailableBuffers.Length() > BACK_BUFFER_NUM) {
mAvailableBuffers.RemoveElementAt(0);
}
NS_WARNING_ASSERTION(mInUseBuffers.Length() < 10, "We are leaking buffers");
}
void NativeSurfaceWaylandSHM::BufferReleaseCallbackHandler(wl_buffer* aBuffer) {
for (const RefPtr<WaylandShmBuffer>& buffer : mInUseBuffers) {
if (buffer->GetWlBuffer() == aBuffer) {
ReturnBufferToPool(buffer);
break;
}
}
}
void NativeSurfaceWaylandSHM::BufferReleaseCallbackHandler(void* aData,
wl_buffer* aBuffer) {
auto* surface = reinterpret_cast<NativeSurfaceWaylandSHM*>(aData);
surface->BufferReleaseCallbackHandler(aBuffer);
}
/* static */ RefPtr<SurfacePool> SurfacePool::Create(size_t aPoolSizeLimit) {
return new SurfacePoolWayland(aPoolSizeLimit);
}
@ -52,14 +216,26 @@ RefPtr<SurfacePoolHandle> SurfacePoolWayland::GetHandleForGL(GLContext* aGL) {
}
void SurfacePoolWayland::DestroyGLResourcesForContext(GLContext* aGL) {
// Assume a single shared GL context for now
MOZ_ASSERT(mInUseEntries.empty());
mAvailableEntries.Clear();
mAvailableEntries.RemoveElementsBy(
[aGL](const auto& entry) { return entry.mGLContext == aGL; });
for (auto& entry : mInUseEntries) {
if (entry.second.mGLContext == aGL) {
entry.second.mNativeSurface->DestroyGLResources();
entry.second.mRecycle = false;
}
}
}
bool SurfacePoolWayland::CanRecycleSurfaceForRequest(
const SurfacePoolEntry& aEntry, const IntSize& aSize, GLContext* aGL) {
return aEntry.mSize == aSize;
if (aEntry.mSize != aSize) {
return false;
}
if (aEntry.mGLContext != aGL) {
return false;
}
return true;
}
RefPtr<NativeSurfaceWayland> SurfacePoolWayland::ObtainSurfaceFromPool(
@ -76,8 +252,12 @@ RefPtr<NativeSurfaceWayland> SurfacePoolWayland::ObtainSurfaceFromPool(
return surface;
}
RefPtr<NativeSurfaceWayland> surface = new NativeSurfaceWayland(aSize, aGL);
mInUseEntries.insert({surface.get(), SurfacePoolEntry{aSize, surface}});
RefPtr<NativeSurfaceWayland> surface =
NativeSurfaceWayland::Create(aSize, aGL);
if (surface) {
mInUseEntries.insert(
{surface.get(), SurfacePoolEntry{aSize, surface, aGL, true}});
}
return surface;
}
@ -87,7 +267,9 @@ void SurfacePoolWayland::ReturnSurfaceToPool(
auto inUseEntryIter = mInUseEntries.find(aSurface);
MOZ_RELEASE_ASSERT(inUseEntryIter != mInUseEntries.end());
mAvailableEntries.AppendElement(std::move(inUseEntryIter->second));
if (inUseEntryIter->second.mRecycle) {
mAvailableEntries.AppendElement(std::move(inUseEntryIter->second));
}
mInUseEntries.erase(inUseEntryIter);
g_clear_pointer(&aSurface->mWlSubsurface, wl_subsurface_destroy);

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

@ -10,32 +10,87 @@
#include "mozilla/layers/SurfacePool.h"
#include "mozilla/widget/nsWaylandDisplay.h"
#include "mozilla/widget/WaylandShmBuffer.h"
namespace mozilla::layers {
using gfx::DrawTarget;
using gfx::IntRegion;
using gfx::IntSize;
using gl::GLContext;
using widget::nsWaylandDisplay;
using widget::WaylandShmBuffer;
class NativeSurfaceWayland {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(NativeSurfaceWayland);
EGLSurface GetEGLSurface() { return mEGLSurface; }
static RefPtr<NativeSurfaceWayland> Create(const IntSize& aSize,
GLContext* aGL);
virtual Maybe<GLuint> GetAsFramebuffer() { return Nothing(); };
virtual RefPtr<DrawTarget> GetAsDrawTarget() { return nullptr; };
virtual void Commit(const IntRegion& aInvalidRegion) = 0;
virtual void NotifySurfaceReady(){};
virtual void DestroyGLResources(){};
struct wl_surface* mWlSurface = nullptr;
struct wl_subsurface* mWlSubsurface = nullptr;
struct wp_viewport* mViewport = nullptr;
protected:
explicit NativeSurfaceWayland(
const RefPtr<nsWaylandDisplay>& aWaylandDisplay);
virtual ~NativeSurfaceWayland();
RefPtr<nsWaylandDisplay> mWaylandDisplay;
};
class NativeSurfaceWaylandEGL final : public NativeSurfaceWayland {
public:
Maybe<GLuint> GetAsFramebuffer() override;
void Commit(const IntRegion& aInvalidRegion) override;
void NotifySurfaceReady() override;
void DestroyGLResources() override;
private:
friend class SurfacePoolWayland;
NativeSurfaceWayland(const IntSize& aSize, GLContext* aGL);
~NativeSurfaceWayland();
friend RefPtr<NativeSurfaceWayland> NativeSurfaceWayland::Create(
const IntSize& aSize, GLContext* aGL);
NativeSurfaceWaylandEGL(const RefPtr<nsWaylandDisplay>& aWaylandDisplay,
GLContext* aGL);
~NativeSurfaceWaylandEGL();
GLContext* mGL = nullptr;
struct wl_egl_window* mEGLWindow = nullptr;
EGLSurface mEGLSurface = nullptr;
};
class NativeSurfaceWaylandSHM final : public NativeSurfaceWayland {
public:
RefPtr<DrawTarget> GetAsDrawTarget() override;
void Commit(const IntRegion& aInvalidRegion) override;
static void BufferReleaseCallbackHandler(void* aData, wl_buffer* aBuffer);
private:
friend RefPtr<NativeSurfaceWayland> NativeSurfaceWayland::Create(
const IntSize& aSize, GLContext* aGL);
NativeSurfaceWaylandSHM(const RefPtr<nsWaylandDisplay>& aWaylandDisplay,
const IntSize& aSize);
RefPtr<WaylandShmBuffer> ObtainBufferFromPool();
void ReturnBufferToPool(const RefPtr<WaylandShmBuffer>& aBuffer);
void EnforcePoolSizeLimit();
void BufferReleaseCallbackHandler(wl_buffer* aBuffer);
IntSize mSize;
nsTArray<RefPtr<WaylandShmBuffer>> mInUseBuffers;
nsTArray<RefPtr<WaylandShmBuffer>> mAvailableBuffers;
RefPtr<WaylandShmBuffer> mCurrentBuffer;
};
class SurfacePoolWayland final : public SurfacePool {
public:
// Get a handle for a new window. aGL can be nullptr.
@ -58,6 +113,8 @@ class SurfacePoolWayland final : public SurfacePool {
struct SurfacePoolEntry {
IntSize mSize;
RefPtr<NativeSurfaceWayland> mNativeSurface; // non-null
GLContext* mGLContext;
bool mRecycle;
};
bool CanRecycleSurfaceForRequest(const SurfacePoolEntry& aEntry,

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

@ -229,7 +229,8 @@ void gfxPlatformGtk::InitWebRenderConfig() {
FeatureState& feature = gfxConfig::GetFeature(Feature::WEBRENDER_COMPOSITOR);
if (feature.IsEnabled()) {
if (!gfxConfig::IsEnabled(Feature::WEBRENDER)) {
if (!(gfxConfig::IsEnabled(Feature::WEBRENDER) ||
gfxConfig::IsEnabled(Feature::WEBRENDER_SOFTWARE))) {
feature.ForceDisable(FeatureStatus::Unavailable, "WebRender disabled",
"FEATURE_FAILURE_WR_DISABLED"_ns);
} else if (!IsWaylandDisplay()) {

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

@ -160,6 +160,10 @@ UniquePtr<RenderCompositor> RenderCompositor::Create(
if (!gfxPlatform::IsHeadless()) {
return RenderCompositorNativeSWGL::Create(aWidget, aError);
}
#elif defined(MOZ_WAYLAND)
if (gfx::gfxVars::UseWebRenderCompositor()) {
return RenderCompositorNativeSWGL::Create(aWidget, aError);
}
#endif
UniquePtr<RenderCompositor> comp =
RenderCompositorLayersSWGL::Create(aWidget, aError);