Backed out 2 changesets (bug 1718570, bug 1718569) for causing wpt failures in /css/css-flexbox/flexbox-align-self-vert-001. CLOSED TREE

Backed out changeset 59cdbaaa6a7b (bug 1718570)
Backed out changeset 489ce763c140 (bug 1718569)
This commit is contained in:
Sandor Molnar 2021-07-13 08:52:28 +03:00
Родитель b683e4147a
Коммит 6c075398dd
7 изменённых файлов: 183 добавлений и 435 удалений

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

@ -279,7 +279,9 @@ already_AddRefed<GLContext> GLContextEGLFactory::CreateImpl(
}
} else if (aHardwareWebRender && (kIsWayland || kIsX11)) {
const int bpp = 32;
if (!CreateConfig(*egl, &config, bpp, false, aUseGles, visualID)) {
const bool enableDepthBuffer = gfx::gfxVars::UseWebRenderCompositor();
if (!CreateConfig(*egl, &config, bpp, enableDepthBuffer, aUseGles,
visualID)) {
gfxCriticalNote << "Failed to create EGLConfig for WebRender!";
return nullptr;
}

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

@ -10,7 +10,6 @@
#include "gfxUtils.h"
#include "GLContextProvider.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/layers/SurfacePoolWayland.h"
#include "mozilla/StaticPrefs_widget.h"
#include "mozilla/webrender/RenderThread.h"
@ -348,7 +347,7 @@ bool NativeLayerRootWayland::CommitToScreen() {
wl_surface* wlSurface = moz_container_wayland_surface_lock(mContainer);
for (RefPtr<NativeLayerWayland>& layer : mSublayers) {
layer->mNativeSurface->Commit(layer->mDirtyRegion, layer->mValidRect);
layer->mNativeSurface->Commit(layer->mDirtyRegion);
layer->mDirtyRegion.SetEmpty();
}
@ -509,15 +508,9 @@ RefPtr<DrawTarget> NativeLayerWayland::NextSurfaceAsDrawTarget(
if (!mNativeSurface) {
mNativeSurface = mSurfacePoolHandle->ObtainSurfaceFromPool(mSize);
if (!mNativeSurface) {
gfxCriticalError() << "Failed to obtain tile surface";
wr::RenderThread::Get()->HandleWebRenderError(
wr::WebRenderError::NEW_SURFACE);
return nullptr;
}
}
return mNativeSurface->GetNextDrawTarget();
return mNativeSurface->GetAsDrawTarget();
}
Maybe<GLuint> NativeLayerWayland::NextSurfaceAsFramebuffer(
@ -530,15 +523,9 @@ Maybe<GLuint> NativeLayerWayland::NextSurfaceAsFramebuffer(
if (!mNativeSurface) {
mNativeSurface = mSurfacePoolHandle->ObtainSurfaceFromPool(mSize);
if (!mNativeSurface) {
gfxCriticalError() << "Failed to obtain tile surface";
wr::RenderThread::Get()->HandleWebRenderError(
wr::WebRenderError::NEW_SURFACE);
return Nothing();
}
}
return mNativeSurface->GetNextFramebuffer();
return mNativeSurface ? mNativeSurface->GetAsFramebuffer() : Nothing();
}
void NativeLayerWayland::NotifySurfaceReady() {

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

@ -5,14 +5,12 @@
#include "mozilla/layers/SurfacePoolWayland.h"
#include "GLBlitHelper.h"
#include "mozilla/gfx/DataSurfaceHelpers.h"
#include "GLContextEGL.h"
namespace mozilla::layers {
using gfx::IntRect;
using gl::DepthAndStencilBuffer;
using gl::MozFramebuffer;
using gl::GLContextEGL;
#define BACK_BUFFER_NUM 3
@ -50,23 +48,39 @@ void CallbackMultiplexHelper::RunCallback(uint32_t aTime) {
RefPtr<NativeSurfaceWayland> NativeSurfaceWayland::Create(const IntSize& aSize,
GLContext* aGL) {
if (aGL) {
return new NativeSurfaceWaylandDMABUF(aSize, 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;
}
return new NativeSurfaceWaylandSHM(aSize);
GLContextEGL* egl = GLContextEGL::Cast(aGL);
surfaceEGL->mEGLSurface = egl->mEgl->fCreateWindowSurface(
egl->mConfig, surfaceEGL->mEGLWindow, nullptr);
if (surfaceEGL->mEGLSurface == EGL_NO_SURFACE) {
return nullptr;
}
NativeSurfaceWayland::NativeSurfaceWayland(const IntSize& aSize)
: mMutex("NativeSurfaceWayland"), mSize(aSize) {
RefPtr<nsWaylandDisplay> waylandDisplay = widget::WaylandDisplayGet();
wl_compositor* compositor = waylandDisplay->GetCompositor();
return surfaceEGL;
}
return new NativeSurfaceWaylandSHM(widget::WaylandDisplayGet(), aSize);
}
NativeSurfaceWayland::NativeSurfaceWayland(
const RefPtr<nsWaylandDisplay>& aWaylandDisplay)
: mMutex("NativeSurfaceWayland"), 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 = waylandDisplay->GetViewporter();
wp_viewporter* viewporter = mWaylandDisplay->GetViewporter();
MOZ_ASSERT(viewporter);
mViewport = wp_viewporter_get_viewport(viewporter, mWlSurface);
}
@ -80,10 +94,8 @@ NativeSurfaceWayland::~NativeSurfaceWayland() {
}
void NativeSurfaceWayland::CreateSubsurface(wl_surface* aParentSurface) {
MutexAutoLock lock(mMutex);
if (mWlSubsurface) {
ClearSubsurface(lock);
ClearSubsurface();
}
MOZ_ASSERT(aParentSurface);
@ -94,18 +106,11 @@ void NativeSurfaceWayland::CreateSubsurface(wl_surface* aParentSurface) {
}
void NativeSurfaceWayland::ClearSubsurface() {
MutexAutoLock lock(mMutex);
ClearSubsurface(lock);
}
void NativeSurfaceWayland::ClearSubsurface(const MutexAutoLock& aProofOfLock) {
g_clear_pointer(&mWlSubsurface, wl_subsurface_destroy);
mPosition = IntPoint(0, 0);
}
void NativeSurfaceWayland::SetBufferTransformFlipped(bool aFlipped) {
MutexAutoLock lock(mMutex);
if (aFlipped == mBufferTransformFlipped) {
return;
}
@ -120,8 +125,6 @@ void NativeSurfaceWayland::SetBufferTransformFlipped(bool aFlipped) {
}
void NativeSurfaceWayland::SetPosition(int aX, int aY) {
MutexAutoLock lock(mMutex);
if ((aX == mPosition.x && aY == mPosition.y) || !mWlSubsurface) {
return;
}
@ -132,8 +135,6 @@ void NativeSurfaceWayland::SetPosition(int aX, int aY) {
}
void NativeSurfaceWayland::SetViewportSourceRect(const Rect aSourceRect) {
MutexAutoLock lock(mMutex);
if (aSourceRect == mViewportSourceRect) {
return;
}
@ -146,8 +147,6 @@ void NativeSurfaceWayland::SetViewportSourceRect(const Rect aSourceRect) {
}
void NativeSurfaceWayland::SetViewportDestinationSize(int aWidth, int aHeight) {
MutexAutoLock lock(mMutex);
if (aWidth == mViewportDestinationSize.width &&
aHeight == mViewportDestinationSize.height) {
return;
@ -192,40 +191,110 @@ void NativeSurfaceWayland::FrameCallbackHandler(wl_callback* aCallback,
mCallbackMultiplexHelpers.Clear();
}
/* static */
void NativeSurfaceWayland::FrameCallbackHandler(void* aData,
wl_callback* aCallback,
uint32_t aTime) {
auto surface = reinterpret_cast<NativeSurfaceWayland*>(aData);
auto* surface = reinterpret_cast<NativeSurfaceWayland*>(aData);
surface->FrameCallbackHandler(aCallback, aTime);
}
NativeSurfaceWaylandSHM::NativeSurfaceWaylandSHM(const IntSize& aSize)
: NativeSurfaceWayland(aSize) {}
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);
}
RefPtr<DrawTarget> NativeSurfaceWaylandSHM::GetNextDrawTarget() {
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) {
MutexAutoLock lock(mMutex);
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() {
MutexAutoLock lock(mMutex);
GLContextEGL* gl = GLContextEGL::Cast(mGL);
gl->SetEGLSurfaceOverride(nullptr);
gl->MakeCurrent();
}
void NativeSurfaceWaylandEGL::DestroyGLResources() {
MutexAutoLock lock(mMutex);
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);
}
}
void NativeSurfaceWaylandEGL::SetBufferTransformFlipped(bool aFlipped) {
if (aFlipped == mBufferTransformFlipped) {
return;
}
mBufferTransformFlipped = aFlipped;
if (mBufferTransformFlipped) {
wl_surface_set_buffer_transform(mWlSurface, WL_OUTPUT_TRANSFORM_NORMAL);
} else {
wl_surface_set_buffer_transform(mWlSurface,
WL_OUTPUT_TRANSFORM_FLIPPED_180);
}
}
NativeSurfaceWaylandSHM::NativeSurfaceWaylandSHM(
const RefPtr<nsWaylandDisplay>& aWaylandDisplay, const IntSize& aSize)
: NativeSurfaceWayland(aWaylandDisplay), mSize(aSize) {}
RefPtr<DrawTarget> NativeSurfaceWaylandSHM::GetAsDrawTarget() {
if (!mCurrentBuffer) {
mCurrentBuffer = ObtainBufferFromPool(lock);
mCurrentBuffer = ObtainBufferFromPool();
}
return mCurrentBuffer->Lock();
}
void NativeSurfaceWaylandSHM::Commit(const IntRegion& aInvalidRegion,
const IntRect& aValidRect) {
void NativeSurfaceWaylandSHM::Commit(const IntRegion& aInvalidRegion) {
MutexAutoLock lock(mMutex);
if (aInvalidRegion.IsEmpty()) {
if (mCurrentBuffer) {
ReturnBufferToPool(lock, mCurrentBuffer);
ReturnBufferToPool(mCurrentBuffer);
mCurrentBuffer = nullptr;
}
wl_surface_commit(mWlSurface);
return;
}
HandlePartialUpdate(lock, aInvalidRegion, aValidRect);
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);
@ -235,64 +304,36 @@ void NativeSurfaceWaylandSHM::Commit(const IntRegion& aInvalidRegion,
mCurrentBuffer->AttachAndCommit(mWlSurface);
mCurrentBuffer = nullptr;
EnforcePoolSizeLimit(lock);
EnforcePoolSizeLimit();
}
void NativeSurfaceWaylandSHM::HandlePartialUpdate(
const MutexAutoLock& aProofOfLock, const IntRegion& aInvalidRegion,
const IntRect& aValidRect) {
if (!mPreviousBuffer || mPreviousBuffer == mCurrentBuffer) {
mPreviousBuffer = mCurrentBuffer;
return;
}
IntRegion copyRegion = IntRegion(aValidRect);
copyRegion.SubOut(aInvalidRegion);
if (!copyRegion.IsEmpty()) {
RefPtr<gfx::DataSourceSurface> dataSourceSurface =
gfx::CreateDataSourceSurfaceFromData(
mSize, mPreviousBuffer->GetSurfaceFormat(),
(const uint8_t*)mPreviousBuffer->GetShmPool()->GetImageData(),
mSize.width * BytesPerPixel(mPreviousBuffer->GetSurfaceFormat()));
RefPtr<DrawTarget> dt = mCurrentBuffer->Lock();
for (auto iter = copyRegion.RectIter(); !iter.Done(); iter.Next()) {
IntRect r = iter.Get();
dt->CopySurface(dataSourceSurface, r, IntPoint(r.x, r.y));
}
}
mPreviousBuffer = mCurrentBuffer;
}
RefPtr<WaylandShmBuffer> NativeSurfaceWaylandSHM::ObtainBufferFromPool(
const MutexAutoLock& aProofOfLock) {
RefPtr<WaylandShmBuffer> NativeSurfaceWaylandSHM::ObtainBufferFromPool() {
if (!mAvailableBuffers.IsEmpty()) {
RefPtr<WaylandShmBuffer> buffer = mAvailableBuffers.PopLastElement();
mInUseBuffers.AppendElement(buffer);
return buffer;
}
RefPtr<nsWaylandDisplay> waylandDisplay = widget::WaylandDisplayGet();
RefPtr<WaylandShmBuffer> buffer = WaylandShmBuffer::Create(
waylandDisplay, LayoutDeviceIntSize::FromUnknownSize(mSize));
mWaylandDisplay, LayoutDeviceIntSize::FromUnknownSize(mSize));
mInUseBuffers.AppendElement(buffer);
buffer->SetBufferReleaseFunc(
&NativeSurfaceWaylandSHM::BufferReleaseCallbackHandler);
buffer->SetBufferReleaseData(this);
mInUseBuffers.AppendElement(buffer);
return buffer;
}
void NativeSurfaceWaylandSHM::ReturnBufferToPool(
const MutexAutoLock& aProofOfLock,
const RefPtr<WaylandShmBuffer>& aBuffer) {
MutexAutoLock lock(mMutex);
for (const RefPtr<WaylandShmBuffer>& buffer : mInUseBuffers) {
if (buffer == aBuffer) {
if (buffer->IsMatchingSize(LayoutDeviceIntSize::FromUnknownSize(mSize))) {
mAvailableBuffers.AppendElement(buffer);
}
mInUseBuffers.RemoveElement(buffer);
return;
}
@ -300,8 +341,7 @@ void NativeSurfaceWaylandSHM::ReturnBufferToPool(
MOZ_RELEASE_ASSERT(false, "Returned buffer not in use");
}
void NativeSurfaceWaylandSHM::EnforcePoolSizeLimit(
const MutexAutoLock& aProofOfLock) {
void NativeSurfaceWaylandSHM::EnforcePoolSizeLimit() {
// Enforce the pool size limit, removing least-recently-used entries as
// necessary.
while (mAvailableBuffers.Length() > BACK_BUFFER_NUM) {
@ -312,227 +352,17 @@ void NativeSurfaceWaylandSHM::EnforcePoolSizeLimit(
}
void NativeSurfaceWaylandSHM::BufferReleaseCallbackHandler(wl_buffer* aBuffer) {
MutexAutoLock lock(mMutex);
for (const RefPtr<WaylandShmBuffer>& buffer : mInUseBuffers) {
if (buffer->GetWlBuffer() == aBuffer) {
ReturnBufferToPool(lock, buffer);
ReturnBufferToPool(buffer);
break;
}
}
}
/* static */
void NativeSurfaceWaylandSHM::BufferReleaseCallbackHandler(void* aData,
wl_buffer* aBuffer) {
auto surface = reinterpret_cast<NativeSurfaceWaylandSHM*>(aData);
surface->BufferReleaseCallbackHandler(aBuffer);
}
/* static */
RefPtr<WaylandDMABUFBuffer> WaylandDMABUFBuffer::Create(
const LayoutDeviceIntSize& aSize, GLContext* aGL) {
RefPtr<WaylandDMABUFBuffer> buffer = new WaylandDMABUFBuffer(aSize);
const auto flags =
static_cast<DMABufSurfaceFlags>(DMABUF_TEXTURE | DMABUF_ALPHA);
buffer->mDMABufSurface =
DMABufSurfaceRGBA::CreateDMABufSurface(aSize.width, aSize.height, flags);
if (!buffer->mDMABufSurface || !buffer->mDMABufSurface->CreateTexture(aGL)) {
return nullptr;
}
if (!buffer->mDMABufSurface->CreateWlBuffer()) {
return nullptr;
}
return buffer;
}
WaylandDMABUFBuffer::WaylandDMABUFBuffer(const LayoutDeviceIntSize& aSize)
: mSize(aSize) {}
NativeSurfaceWaylandDMABUF::NativeSurfaceWaylandDMABUF(const IntSize& aSize,
GLContext* aGL)
: NativeSurfaceWayland(aSize), mGL(aGL) {}
Maybe<GLuint> NativeSurfaceWaylandDMABUF::GetNextFramebuffer() {
MutexAutoLock lock(mMutex);
if (!mCurrentBuffer) {
mCurrentBuffer = ObtainBufferFromPool(lock);
}
return Some(mCurrentBuffer->GetFramebuffer()->mFB);
}
void NativeSurfaceWaylandDMABUF::Commit(const IntRegion& aInvalidRegion,
const IntRect& aValidRect) {
MutexAutoLock lock(mMutex);
if (aInvalidRegion.IsEmpty()) {
if (mCurrentBuffer) {
ReturnBufferToPool(lock, mCurrentBuffer);
mCurrentBuffer = nullptr;
}
wl_surface_commit(mWlSurface);
return;
}
HandlePartialUpdate(lock, aInvalidRegion, aValidRect);
// We rely on implicit synchronization in the system compositor to make sure
// all GL operation have been finished befor presenting a new frame.
mGL->fFlush();
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);
wl_surface_attach(mWlSurface, mCurrentBuffer->GetWlBuffer(), 0, 0);
wl_surface_commit(mWlSurface);
mCurrentBuffer = nullptr;
EnforcePoolSizeLimit(lock);
}
void NativeSurfaceWaylandDMABUF::HandlePartialUpdate(
const MutexAutoLock& aProofOfLock, const IntRegion& aInvalidRegion,
const IntRect& aValidRect) {
if (!mPreviousBuffer || mPreviousBuffer == mCurrentBuffer) {
mPreviousBuffer = mCurrentBuffer;
return;
}
IntRegion copyRegion = IntRegion(aValidRect);
copyRegion.SubOut(aInvalidRegion);
if (!copyRegion.IsEmpty()) {
mGL->MakeCurrent();
for (auto iter = copyRegion.RectIter(); !iter.Done(); iter.Next()) {
gfx::IntRect r = iter.Get();
mGL->BlitHelper()->BlitFramebufferToFramebuffer(
mPreviousBuffer->GetFramebuffer()->mFB,
mCurrentBuffer->GetFramebuffer()->mFB, r, r, LOCAL_GL_NEAREST);
}
}
mPreviousBuffer = mCurrentBuffer;
}
void NativeSurfaceWaylandDMABUF::DestroyGLResources() {
mInUseBuffers.Clear();
mAvailableBuffers.Clear();
mDepthBuffers.Clear();
mCurrentBuffer = nullptr;
mPreviousBuffer = nullptr;
mGL = nullptr;
}
static const struct wl_buffer_listener
sBufferListenerNativeSurfaceWaylandDMABUF = {
NativeSurfaceWaylandDMABUF::BufferReleaseCallbackHandler};
RefPtr<WaylandDMABUFBuffer> NativeSurfaceWaylandDMABUF::ObtainBufferFromPool(
const MutexAutoLock& aProofOfLock) {
if (!mAvailableBuffers.IsEmpty()) {
RefPtr<WaylandDMABUFBuffer> buffer = mAvailableBuffers.PopLastElement();
mInUseBuffers.AppendElement(buffer);
return buffer;
}
RefPtr<WaylandDMABUFBuffer> buffer = WaylandDMABUFBuffer::Create(
LayoutDeviceIntSize::FromUnknownSize(mSize), mGL);
const auto tex = buffer->GetDMABufSurface()->GetTexture();
UniquePtr<MozFramebuffer> framebuffer =
CreateFramebufferForTexture(aProofOfLock, mGL, mSize, tex);
buffer->SetFramebuffer(std::move(framebuffer));
wl_buffer_add_listener(buffer->GetWlBuffer(),
&sBufferListenerNativeSurfaceWaylandDMABUF, this);
mInUseBuffers.AppendElement(buffer);
return buffer;
}
void NativeSurfaceWaylandDMABUF::ReturnBufferToPool(
const MutexAutoLock& aProofOfLock,
const RefPtr<WaylandDMABUFBuffer>& aBuffer) {
for (const RefPtr<WaylandDMABUFBuffer>& buffer : mInUseBuffers) {
if (buffer == aBuffer) {
mAvailableBuffers.AppendElement(buffer);
mInUseBuffers.RemoveElement(buffer);
return;
}
}
MOZ_RELEASE_ASSERT(false, "Returned buffer not in use");
}
void NativeSurfaceWaylandDMABUF::EnforcePoolSizeLimit(
const MutexAutoLock& aProofOfLock) {
// 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");
}
RefPtr<DepthAndStencilBuffer>
NativeSurfaceWaylandDMABUF::GetDepthBufferForSharing(
const MutexAutoLock& aProofOfLock, GLContext* aGL, const IntSize& aSize) {
// Clean out entries for which the weak pointer has become null.
mDepthBuffers.RemoveElementsBy(
[&](const DepthBufferEntry& entry) { return !entry.mBuffer; });
for (const auto& entry : mDepthBuffers) {
if (entry.mGL == aGL && entry.mSize == aSize) {
return entry.mBuffer.get();
}
}
return nullptr;
}
UniquePtr<MozFramebuffer>
NativeSurfaceWaylandDMABUF::CreateFramebufferForTexture(
const MutexAutoLock& aProofOfLock, GLContext* aGL, const IntSize& aSize,
GLuint aTexture) {
// Try to find an existing depth buffer of aSize in aGL and create a
// framebuffer that shares it.
if (auto buffer = GetDepthBufferForSharing(aProofOfLock, aGL, aSize)) {
return MozFramebuffer::CreateForBackingWithSharedDepthAndStencil(
aSize, 0, LOCAL_GL_TEXTURE_2D, aTexture, buffer);
}
UniquePtr<MozFramebuffer> fb = MozFramebuffer::CreateForBacking(
aGL, aSize, 0, true, LOCAL_GL_TEXTURE_2D, aTexture);
if (fb) {
mDepthBuffers.AppendElement(
DepthBufferEntry{aGL, aSize, fb->GetDepthAndStencilBuffer().get()});
}
return fb;
}
void NativeSurfaceWaylandDMABUF::BufferReleaseCallbackHandler(
wl_buffer* aBuffer) {
MutexAutoLock lock(mMutex);
for (const RefPtr<WaylandDMABUFBuffer>& buffer : mInUseBuffers) {
if (buffer->GetWlBuffer() == aBuffer) {
ReturnBufferToPool(lock, buffer);
break;
}
}
}
/* static */
void NativeSurfaceWaylandDMABUF::BufferReleaseCallbackHandler(
void* aData, wl_buffer* aBuffer) {
auto surface = reinterpret_cast<NativeSurfaceWaylandDMABUF*>(aData);
auto* surface = reinterpret_cast<NativeSurfaceWaylandSHM*>(aData);
surface->BufferReleaseCallbackHandler(aBuffer);
}
@ -549,16 +379,12 @@ RefPtr<SurfacePoolHandle> SurfacePoolWayland::GetHandleForGL(GLContext* aGL) {
void SurfacePoolWayland::DestroyGLResourcesForContext(GLContext* aGL) {
mAvailableEntries.RemoveElementsBy(
[aGL](const auto& entry) { return entry.mGL == aGL; });
[aGL](const auto& entry) { return entry.mGLContext == aGL; });
// std::erase_if
for (auto entry = mInUseEntries.begin(), last = mInUseEntries.end();
entry != last;) {
if (entry->second.mGL == aGL) {
entry->second.mNativeSurface->DestroyGLResources();
entry = mInUseEntries.erase(entry);
} else {
++entry;
for (auto& entry : mInUseEntries) {
if (entry.second.mGLContext == aGL) {
entry.second.mNativeSurface->DestroyGLResources();
entry.second.mRecycle = false;
}
}
}
@ -568,7 +394,7 @@ bool SurfacePoolWayland::CanRecycleSurfaceForRequest(
if (aEntry.mSize != aSize) {
return false;
}
if (aEntry.mGL != aGL) {
if (aEntry.mGLContext != aGL) {
return false;
}
return true;
@ -592,7 +418,7 @@ RefPtr<NativeSurfaceWayland> SurfacePoolWayland::ObtainSurfaceFromPool(
NativeSurfaceWayland::Create(aSize, aGL);
if (surface) {
mInUseEntries.insert(
{surface.get(), SurfacePoolEntry{aSize, surface, aGL}});
{surface.get(), SurfacePoolEntry{aSize, surface, aGL, true}});
}
return surface;
@ -601,10 +427,12 @@ RefPtr<NativeSurfaceWayland> SurfacePoolWayland::ObtainSurfaceFromPool(
void SurfacePoolWayland::ReturnSurfaceToPool(
const RefPtr<NativeSurfaceWayland>& aSurface) {
auto inUseEntryIter = mInUseEntries.find(aSurface);
if (inUseEntryIter != mInUseEntries.end()) {
MOZ_RELEASE_ASSERT(inUseEntryIter != mInUseEntries.end());
if (inUseEntryIter->second.mRecycle) {
mAvailableEntries.AppendElement(std::move(inUseEntryIter->second));
mInUseEntries.erase(inUseEntryIter);
}
mInUseEntries.erase(inUseEntryIter);
g_clear_pointer(&aSurface->mWlSubsurface, wl_subsurface_destroy);
}

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

@ -8,10 +8,7 @@
#include <wayland-egl.h>
#include "GLContext.h"
#include "MozFramebuffer.h"
#include "mozilla/layers/SurfacePool.h"
#include "mozilla/widget/DMABufSurface.h"
#include "mozilla/widget/nsWaylandDisplay.h"
#include "mozilla/widget/WaylandShmBuffer.h"
@ -19,7 +16,6 @@ namespace mozilla::layers {
using gfx::DrawTarget;
using gfx::IntPoint;
using gfx::IntRect;
using gfx::IntRegion;
using gfx::IntSize;
using gfx::Rect;
@ -56,11 +52,10 @@ class NativeSurfaceWayland {
static RefPtr<NativeSurfaceWayland> Create(const IntSize& aSize,
GLContext* aGL);
virtual Maybe<GLuint> GetNextFramebuffer() { return Nothing(); };
virtual RefPtr<DrawTarget> GetNextDrawTarget() { return nullptr; };
virtual Maybe<GLuint> GetAsFramebuffer() { return Nothing(); };
virtual RefPtr<DrawTarget> GetAsDrawTarget() { return nullptr; };
virtual void Commit(const IntRegion& aInvalidRegion,
const IntRect& aValidRect) = 0;
virtual void Commit(const IntRegion& aInvalidRegion) = 0;
virtual void NotifySurfaceReady(){};
virtual void DestroyGLResources(){};
@ -82,14 +77,14 @@ class NativeSurfaceWayland {
wl_subsurface* mWlSubsurface = nullptr;
protected:
explicit NativeSurfaceWayland(const IntSize& aSize);
explicit NativeSurfaceWayland(
const RefPtr<nsWaylandDisplay>& aWaylandDisplay);
virtual ~NativeSurfaceWayland();
void ClearSubsurface(const MutexAutoLock& aProofOfLock);
void FrameCallbackHandler(wl_callback* aCallback, uint32_t aTime);
Mutex mMutex;
const IntSize mSize;
RefPtr<nsWaylandDisplay> mWaylandDisplay;
wl_callback* mCallback = nullptr;
wp_viewport* mViewport = nullptr;
bool mBufferTransformFlipped = false;
@ -99,110 +94,50 @@ class NativeSurfaceWayland {
nsTArray<RefPtr<CallbackMultiplexHelper>> mCallbackMultiplexHelpers;
};
class NativeSurfaceWaylandEGL final : public NativeSurfaceWayland {
public:
Maybe<GLuint> GetAsFramebuffer() override;
void Commit(const IntRegion& aInvalidRegion) override;
void NotifySurfaceReady() override;
void DestroyGLResources() override;
void SetBufferTransformFlipped(bool aFlipped) override;
private:
friend RefPtr<NativeSurfaceWayland> NativeSurfaceWayland::Create(
const IntSize& aSize, GLContext* aGL);
NativeSurfaceWaylandEGL(const RefPtr<nsWaylandDisplay>& aWaylandDisplay,
GLContext* aGL);
~NativeSurfaceWaylandEGL();
GLContext* mGL = nullptr;
wl_egl_window* mEGLWindow = nullptr;
EGLSurface mEGLSurface = nullptr;
};
class NativeSurfaceWaylandSHM final : public NativeSurfaceWayland {
public:
RefPtr<DrawTarget> GetNextDrawTarget() override;
void Commit(const IntRegion& aInvalidRegion,
const IntRect& aValidRect) override;
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);
explicit NativeSurfaceWaylandSHM(const IntSize& aSize);
NativeSurfaceWaylandSHM(const RefPtr<nsWaylandDisplay>& aWaylandDisplay,
const IntSize& aSize);
void HandlePartialUpdate(const MutexAutoLock& aProofOfLock,
const IntRegion& aInvalidRegion,
const IntRect& aValidRect);
RefPtr<WaylandShmBuffer> ObtainBufferFromPool(
const MutexAutoLock& aProofOfLock);
void ReturnBufferToPool(const MutexAutoLock& aProofOfLock,
const RefPtr<WaylandShmBuffer>& aBuffer);
void EnforcePoolSizeLimit(const MutexAutoLock& aProofOfLock);
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;
RefPtr<WaylandShmBuffer> mPreviousBuffer;
};
class WaylandDMABUFBuffer {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WaylandDMABUFBuffer);
static RefPtr<WaylandDMABUFBuffer> Create(const LayoutDeviceIntSize& aSize,
GLContext* aGL);
void DestroyGLResources();
RefPtr<DMABufSurface> GetDMABufSurface() { return mDMABufSurface; };
wl_buffer* GetWlBuffer() { return mDMABufSurface->GetWlBuffer(); };
bool IsMatchingSize(const LayoutDeviceIntSize& aSize) {
return aSize == mSize;
}
gl::MozFramebuffer* GetFramebuffer() { return mFB.get(); };
void SetFramebuffer(UniquePtr<gl::MozFramebuffer> aFB) {
mFB = std::move(aFB);
};
private:
explicit WaylandDMABUFBuffer(const LayoutDeviceIntSize& aSize);
~WaylandDMABUFBuffer() = default;
const LayoutDeviceIntSize mSize;
RefPtr<DMABufSurfaceRGBA> mDMABufSurface;
UniquePtr<gl::MozFramebuffer> mFB;
};
class NativeSurfaceWaylandDMABUF final : public NativeSurfaceWayland {
public:
Maybe<GLuint> GetNextFramebuffer() override;
void Commit(const IntRegion& aInvalidRegion,
const IntRect& aValidRect) override;
void DestroyGLResources() override;
static void BufferReleaseCallbackHandler(void* aData, wl_buffer* aBuffer);
private:
friend RefPtr<NativeSurfaceWayland> NativeSurfaceWayland::Create(
const IntSize& aSize, GLContext* aGL);
NativeSurfaceWaylandDMABUF(const IntSize& aSize, GLContext* aGL);
~NativeSurfaceWaylandDMABUF() = default;
void HandlePartialUpdate(const MutexAutoLock& aProofOfLock,
const IntRegion& aInvalidRegion,
const IntRect& aValidRect);
RefPtr<WaylandDMABUFBuffer> ObtainBufferFromPool(
const MutexAutoLock& aProofOfLock);
void ReturnBufferToPool(const MutexAutoLock& aProofOfLock,
const RefPtr<WaylandDMABUFBuffer>& aBuffer);
void EnforcePoolSizeLimit(const MutexAutoLock& aProofOfLock);
UniquePtr<gl::MozFramebuffer> CreateFramebufferForTexture(
const MutexAutoLock& aProofOfLock, GLContext* aGL, const IntSize& aSize,
GLuint aTexture);
RefPtr<gl::DepthAndStencilBuffer> GetDepthBufferForSharing(
const MutexAutoLock& aProofOfLock, GLContext* aGL, const IntSize& aSize);
void BufferReleaseCallbackHandler(wl_buffer* aBuffer);
RefPtr<GLContext> mGL;
nsTArray<RefPtr<WaylandDMABUFBuffer>> mInUseBuffers;
nsTArray<RefPtr<WaylandDMABUFBuffer>> mAvailableBuffers;
RefPtr<WaylandDMABUFBuffer> mCurrentBuffer;
RefPtr<WaylandDMABUFBuffer> mPreviousBuffer;
struct DepthBufferEntry final {
RefPtr<GLContext> mGL;
IntSize mSize;
WeakPtr<gl::DepthAndStencilBuffer> mBuffer;
};
nsTArray<DepthBufferEntry> mDepthBuffers;
};
class SurfacePoolWayland final : public SurfacePool {
@ -224,10 +159,11 @@ class SurfacePoolWayland final : public SurfacePool {
void ReturnSurfaceToPool(const RefPtr<NativeSurfaceWayland>& aSurface);
void EnforcePoolSizeLimit();
struct SurfacePoolEntry final {
const IntSize mSize;
const RefPtr<NativeSurfaceWayland> mNativeSurface; // non-null
const RefPtr<gl::GLContext> mGL;
struct SurfacePoolEntry {
IntSize mSize;
RefPtr<NativeSurfaceWayland> mNativeSurface; // non-null
GLContext* mGLContext;
bool mRecycle;
};
bool CanRecycleSurfaceForRequest(const SurfacePoolEntry& aEntry,
@ -249,6 +185,7 @@ class SurfacePoolWayland final : public SurfacePool {
// Stores entries which are available for recycling. These entries are not
// in use by a NativeLayerWayland or by the window server.
nsTArray<SurfacePoolEntry> mAvailableEntries;
size_t mPoolSizeLimit;
};

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

@ -240,15 +240,7 @@ void gfxPlatformGtk::InitWebRenderConfig() {
"FEATURE_FAILURE_NO_WAYLAND"_ns);
}
#ifdef MOZ_WAYLAND
else if (gfxConfig::IsEnabled(Feature::WEBRENDER) &&
!gfxConfig::IsEnabled(Feature::DMABUF)) {
// We use zwp_linux_dmabuf_v1 and GBM directly to manage FBOs. In theory
// this is also possible vie EGLstreams, but we don't bother to implement
// it as recent NVidia drivers support GBM and DMABuf as well.
feature.ForceDisable(FeatureStatus::Unavailable,
"Hardware Webrender requires DMAbuf support",
"FEATURE_FAILURE_NO_DMABUF"_ns);
} else if (!widget::WaylandDisplayGet()->GetViewporter()) {
else if (!widget::WaylandDisplayGet()->GetViewporter()) {
feature.ForceDisable(FeatureStatus::Unavailable,
"Requires wp_viewporter protocol support",
"FEATURE_FAILURE_REQUIRES_WPVIEWPORTER"_ns);

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

@ -5047,7 +5047,11 @@
- name: gfx.webrender.compositor.max_update_rects
type: uint32_t
#if defined(XP_WIN) || defined(XP_MACOSX)
value: 1
#else
value: 0
#endif
mirror: once
- name: gfx.webrender.compositor.surface-pool-size

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

@ -246,8 +246,6 @@ bool WaylandVsyncSource::WaylandDisplay::IsVsyncEnabled() {
void WaylandVsyncSource::WaylandDisplay::Shutdown() {
MOZ_ASSERT(NS_IsMainThread());
MutexAutoLock lock(mMutex);
mContainer = nullptr;
mNativeLayerRoot = nullptr;
mIsShutdown = true;
mVsyncEnabled = false;
mCallbackRequested = false;