зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
b683e4147a
Коммит
6c075398dd
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче