Bug 1456978 - Ensure that all generate_frame transactions end up clearing the pending frame count. r?sotaro
This prevents us from getting stuck in the frame throttling code where
TooManyPendingFrames always returns true.
MozReview-Commit-ID: 92tybPOaOTP
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -379,16 +379,35 @@ RenderThread::IncPendingFrameCount(wr::W
return;
}
// Update pending frame count.
info.mPendingCount = info.mPendingCount + 1;
mWindowInfos.Put(AsUint64(aWindowId), info);
}
void
+RenderThread::DecPendingFrameCount(wr::WindowId aWindowId)
+{
+ MutexAutoLock lock(mFrameCountMapLock);
+ // Get the old count.
+ WindowInfo info;
+ if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
+ MOZ_ASSERT(false);
+ return;
+ }
+ MOZ_ASSERT(info.mPendingCount > 0);
+ if (info.mPendingCount <= 0) {
+ return;
+ }
+ // Update pending frame count.
+ info.mPendingCount = info.mPendingCount - 1;
+ mWindowInfos.Put(AsUint64(aWindowId), info);
+}
+
+void
RenderThread::IncRenderingFrameCount(wr::WindowId aWindowId)
{
MutexAutoLock lock(mFrameCountMapLock);
// Get the old count.
WindowInfo info;
if (!mWindowInfos.Get(AsUint64(aWindowId), &info)) {
MOZ_ASSERT(false);
return;
@@ -531,25 +550,19 @@ void wr_notifier_wake_up(mozilla::wr::Wr
mozilla::wr::RenderThread::Get()->WakeUp(aWindowId);
}
void wr_notifier_new_frame_ready(mozilla::wr::WrWindowId aWindowId)
{
NewFrameReady(aWindowId);
}
-void wr_notifier_new_scroll_frame_ready(mozilla::wr::WrWindowId aWindowId, bool aCompositeNeeded)
+void wr_notifier_nop_frame_done(mozilla::wr::WrWindowId aWindowId)
{
- // If we sent a transaction that contained both scrolling updates and a
- // GenerateFrame, we can get this function called with aCompositeNeeded=true
- // instead of wr_notifier_new_frame_ready. In that case we want to update the
- // rendering.
- if (aCompositeNeeded) {
- NewFrameReady(aWindowId);
- }
+ mozilla::wr::RenderThread::Get()->DecPendingFrameCount(aWindowId);
}
void wr_notifier_external_event(mozilla::wr::WrWindowId aWindowId, size_t aRawEvent)
{
mozilla::UniquePtr<mozilla::wr::RendererEvent> evt(
reinterpret_cast<mozilla::wr::RendererEvent*>(aRawEvent));
mozilla::wr::RenderThread::Get()->RunEvent(mozilla::wr::WindowId(aWindowId),
mozilla::Move(evt));
--- a/gfx/webrender_bindings/RenderThread.h
+++ b/gfx/webrender_bindings/RenderThread.h
@@ -148,16 +148,18 @@ public:
bool IsDestroyed(wr::WindowId aWindowId);
/// Can be called from any thread.
void SetDestroyed(wr::WindowId aWindowId);
/// Can be called from any thread.
bool TooManyPendingFrames(wr::WindowId aWindowId);
/// Can be called from any thread.
void IncPendingFrameCount(wr::WindowId aWindowId);
/// Can be called from any thread.
+ void DecPendingFrameCount(wr::WindowId aWindowId);
+ /// Can be called from any thread.
void IncRenderingFrameCount(wr::WindowId aWindowId);
/// Can be called from any thread.
void FrameRenderingComplete(wr::WindowId aWindowId);
/// Can be called from any thread.
WebRenderThreadPool& ThreadPool() { return mThreadPool; }
/// Can only be called from the render thread.
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -490,18 +490,17 @@ struct CppNotifier {
window_id: WrWindowId,
}
unsafe impl Send for CppNotifier {}
extern "C" {
fn wr_notifier_wake_up(window_id: WrWindowId);
fn wr_notifier_new_frame_ready(window_id: WrWindowId);
- fn wr_notifier_new_scroll_frame_ready(window_id: WrWindowId,
- composite_needed: bool);
+ fn wr_notifier_nop_frame_done(window_id: WrWindowId);
fn wr_notifier_external_event(window_id: WrWindowId,
raw_event: usize);
}
impl RenderNotifier for CppNotifier {
fn clone(&self) -> Box<RenderNotifier> {
Box::new(CppNotifier {
window_id: self.window_id,
@@ -511,23 +510,23 @@ impl RenderNotifier for CppNotifier {
fn wake_up(&self) {
unsafe {
wr_notifier_wake_up(self.window_id);
}
}
fn new_frame_ready(&self,
_: DocumentId,
- scrolled: bool,
+ _scrolled: bool,
composite_needed: bool) {
unsafe {
- if scrolled {
- wr_notifier_new_scroll_frame_ready(self.window_id, composite_needed);
- } else if composite_needed {
+ if composite_needed {
wr_notifier_new_frame_ready(self.window_id);
+ } else {
+ wr_notifier_nop_frame_done(self.window_id);
}
}
}
fn external_event(&self,
event: ExternalEvent) {
unsafe {
wr_notifier_external_event(self.window_id, event.unwrap());
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1363,18 +1363,17 @@ extern bool wr_moz2d_render_cb(ByteSlice
const DeviceUintRect *aDirtyRect,
MutByteSlice aOutput);
extern void wr_notifier_external_event(WrWindowId aWindowId,
uintptr_t aRawEvent);
extern void wr_notifier_new_frame_ready(WrWindowId aWindowId);
-extern void wr_notifier_new_scroll_frame_ready(WrWindowId aWindowId,
- bool aCompositeNeeded);
+extern void wr_notifier_nop_frame_done(WrWindowId aWindowId);
extern void wr_notifier_wake_up(WrWindowId aWindowId);
WR_INLINE
void wr_pipeline_info_delete(WrPipelineInfo aInfo)
WR_DESTRUCTOR_SAFE_FUNC;
WR_INLINE