mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 07:13:20 +00:00
Bug 1796130 [Wayland] Track and release Vsync frame callbacks so we don't get frame callback after nsWindow::Destroy() r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D160364
This commit is contained in:
parent
ca6356c35d
commit
35f7c05de1
@ -38,19 +38,18 @@ namespace mozilla {
|
|||||||
static void WaylandVsyncSourceCallbackHandler(void* aData,
|
static void WaylandVsyncSourceCallbackHandler(void* aData,
|
||||||
struct wl_callback* aCallback,
|
struct wl_callback* aCallback,
|
||||||
uint32_t aTime) {
|
uint32_t aTime) {
|
||||||
WaylandVsyncSource* context = (WaylandVsyncSource*)aData;
|
RefPtr<WaylandVsyncSource> context(static_cast<WaylandVsyncSource*>(aData));
|
||||||
wl_callback_destroy(aCallback);
|
context->FrameCallback(aCallback, aTime);
|
||||||
context->FrameCallback(aTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void WaylandVsyncSourceCallbackHandler(void* aData, uint32_t aTime) {
|
|
||||||
WaylandVsyncSource* context = (WaylandVsyncSource*)aData;
|
|
||||||
context->FrameCallback(aTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_callback_listener WaylandVsyncSourceCallbackListener = {
|
static const struct wl_callback_listener WaylandVsyncSourceCallbackListener = {
|
||||||
WaylandVsyncSourceCallbackHandler};
|
WaylandVsyncSourceCallbackHandler};
|
||||||
|
|
||||||
|
static void NativeLayerRootWaylandVsyncCallback(void* aData, uint32_t aTime) {
|
||||||
|
RefPtr<WaylandVsyncSource> context(static_cast<WaylandVsyncSource*>(aData));
|
||||||
|
context->FrameCallback(nullptr, aTime);
|
||||||
|
}
|
||||||
|
|
||||||
static float GetFPS(TimeDuration aVsyncRate) {
|
static float GetFPS(TimeDuration aVsyncRate) {
|
||||||
return 1000.0 / aVsyncRate.ToMilliseconds();
|
return 1000.0 / aVsyncRate.ToMilliseconds();
|
||||||
}
|
}
|
||||||
@ -207,7 +206,7 @@ void WaylandVsyncSource::SetupFrameCallback(const MutexAutoLock& aProofOfLock) {
|
|||||||
|
|
||||||
if (mNativeLayerRoot) {
|
if (mNativeLayerRoot) {
|
||||||
LOG(" use mNativeLayerRoot");
|
LOG(" use mNativeLayerRoot");
|
||||||
mNativeLayerRoot->RequestFrameCallback(&WaylandVsyncSourceCallbackHandler,
|
mNativeLayerRoot->RequestFrameCallback(&NativeLayerRootWaylandVsyncCallback,
|
||||||
this);
|
this);
|
||||||
} else {
|
} else {
|
||||||
MozContainerSurfaceLock lock(mContainer);
|
MozContainerSurfaceLock lock(mContainer);
|
||||||
@ -222,8 +221,9 @@ void WaylandVsyncSource::SetupFrameCallback(const MutexAutoLock& aProofOfLock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LOG(" register frame callback");
|
LOG(" register frame callback");
|
||||||
wl_callback* callback = wl_surface_frame(surface);
|
MozClearPointer(mCallback, wl_callback_destroy);
|
||||||
wl_callback_add_listener(callback, &WaylandVsyncSourceCallbackListener,
|
mCallback = wl_surface_frame(surface);
|
||||||
|
wl_callback_add_listener(mCallback, &WaylandVsyncSourceCallbackListener,
|
||||||
this);
|
this);
|
||||||
wl_surface_commit(surface);
|
wl_surface_commit(surface);
|
||||||
wl_display_flush(WaylandDisplayGet()->GetDisplay());
|
wl_display_flush(WaylandDisplayGet()->GetDisplay());
|
||||||
@ -286,7 +286,7 @@ void WaylandVsyncSource::IdleCallback() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaylandVsyncSource::FrameCallback(uint32_t aTime) {
|
void WaylandVsyncSource::FrameCallback(wl_callback* aCallback, uint32_t aTime) {
|
||||||
LOG("WaylandVsyncSource::FrameCallback");
|
LOG("WaylandVsyncSource::FrameCallback");
|
||||||
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
MOZ_DIAGNOSTIC_ASSERT(NS_IsMainThread());
|
||||||
|
|
||||||
@ -294,11 +294,20 @@ void WaylandVsyncSource::FrameCallback(uint32_t aTime) {
|
|||||||
// This might enable vsync.
|
// This might enable vsync.
|
||||||
RefPtr window = mWindow;
|
RefPtr window = mWindow;
|
||||||
window->NotifyOcclusionState(OcclusionState::VISIBLE);
|
window->NotifyOcclusionState(OcclusionState::VISIBLE);
|
||||||
|
// NotifyOcclusionState can destroy us.
|
||||||
|
if (window->IsDestroyed()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MutexAutoLock lock(mMutex);
|
MutexAutoLock lock(mMutex);
|
||||||
mCallbackRequested = false;
|
mCallbackRequested = false;
|
||||||
|
|
||||||
|
if (aCallback) {
|
||||||
|
MOZ_RELEASE_ASSERT(aCallback == mCallback);
|
||||||
|
MozClearPointer(mCallback, wl_callback_destroy);
|
||||||
|
}
|
||||||
|
|
||||||
if (!mVsyncEnabled || !mMonitorEnabled) {
|
if (!mVsyncEnabled || !mMonitorEnabled) {
|
||||||
// We are unwanted by either our creator or our consumer, so we just stop
|
// We are unwanted by either our creator or our consumer, so we just stop
|
||||||
// here without setting up a new frame callback.
|
// here without setting up a new frame callback.
|
||||||
@ -404,6 +413,7 @@ void WaylandVsyncSource::Shutdown() {
|
|||||||
mVsyncEnabled = false;
|
mVsyncEnabled = false;
|
||||||
mCallbackRequested = false;
|
mCallbackRequested = false;
|
||||||
MozClearHandleID(mIdleTimerID, g_source_remove);
|
MozClearHandleID(mIdleTimerID, g_source_remove);
|
||||||
|
MozClearPointer(mCallback, wl_callback_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -55,7 +55,7 @@ class WaylandVsyncSource final : public gfx::VsyncSource {
|
|||||||
void EnableMonitor();
|
void EnableMonitor();
|
||||||
void DisableMonitor();
|
void DisableMonitor();
|
||||||
|
|
||||||
void FrameCallback(uint32_t aTime);
|
void FrameCallback(wl_callback* aCallback, uint32_t aTime);
|
||||||
void IdleCallback();
|
void IdleCallback();
|
||||||
|
|
||||||
TimeDuration GetVsyncRate() override;
|
TimeDuration GetVsyncRate() override;
|
||||||
@ -87,6 +87,7 @@ class WaylandVsyncSource final : public gfx::VsyncSource {
|
|||||||
TimeDuration mVsyncRate MOZ_GUARDED_BY(mMutex);
|
TimeDuration mVsyncRate MOZ_GUARDED_BY(mMutex);
|
||||||
TimeStamp mLastVsyncTimeStamp MOZ_GUARDED_BY(mMutex);
|
TimeStamp mLastVsyncTimeStamp MOZ_GUARDED_BY(mMutex);
|
||||||
guint mIdleTimerID MOZ_GUARDED_BY(mMutex) = 0;
|
guint mIdleTimerID MOZ_GUARDED_BY(mMutex) = 0;
|
||||||
|
wl_callback* mCallback MOZ_GUARDED_BY(mMutex) = nullptr;
|
||||||
|
|
||||||
nsWindow* const mWindow; // Main thread only, except for logging.
|
nsWindow* const mWindow; // Main thread only, except for logging.
|
||||||
const guint mIdleTimeout;
|
const guint mIdleTimeout;
|
||||||
|
Loading…
Reference in New Issue
Block a user