mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 10:00:54 +00:00
Bug 799401 - Throttle APZC paint requests. r=cjones
This commit is contained in:
parent
e156d1a1d8
commit
1cc8f4f693
@ -142,6 +142,7 @@ EXPORTS_mozilla/layers =\
|
||||
RenderTrace.h \
|
||||
SharedImageUtils.h \
|
||||
ShmemYCbCrImage.h \
|
||||
TaskThrottler.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS += \
|
||||
@ -161,6 +162,7 @@ CPPSRCS += \
|
||||
ShadowLayerParent.cpp \
|
||||
ShadowLayersParent.cpp \
|
||||
ShmemYCbCrImage.cpp \
|
||||
TaskThrottler.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifdef MOZ_X11 #{
|
||||
|
@ -967,7 +967,11 @@ void AsyncPanZoomController::RequestContentRepaint() {
|
||||
// This message is compressed, so fire whether or not we already have a paint
|
||||
// queued up. We need to know whether or not a paint was requested anyways,
|
||||
// for the purposes of content calling window.scrollTo().
|
||||
mGeckoContentController->RequestContentRepaint(mFrameMetrics);
|
||||
mPaintThrottler.PostTask(
|
||||
FROM_HERE,
|
||||
NewRunnableMethod(mGeckoContentController.get(),
|
||||
&GeckoContentController::RequestContentRepaint,
|
||||
mFrameMetrics));
|
||||
mLastPaintRequestMetrics = mFrameMetrics;
|
||||
mWaitingForContentToPaint = true;
|
||||
|
||||
@ -1081,6 +1085,8 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
|
||||
void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFrame, bool aIsFirstPaint) {
|
||||
MonitorAutoLock monitor(mMonitor);
|
||||
|
||||
mPaintThrottler.TaskComplete();
|
||||
|
||||
mLastContentPaintMetrics = aViewportFrame;
|
||||
|
||||
if (mWaitingForContentToPaint) {
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "InputData.h"
|
||||
#include "Axis.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "TaskThrottler.h"
|
||||
|
||||
#include "base/message_loop.h"
|
||||
|
||||
@ -458,6 +459,7 @@ private:
|
||||
void SetState(PanZoomState aState);
|
||||
|
||||
nsRefPtr<CompositorParent> mCompositorParent;
|
||||
TaskThrottler mPaintThrottler;
|
||||
nsRefPtr<GeckoContentController> mGeckoContentController;
|
||||
nsRefPtr<GestureEventListener> mGestureEventListener;
|
||||
|
||||
|
49
gfx/layers/ipc/TaskThrottler.cpp
Normal file
49
gfx/layers/ipc/TaskThrottler.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8; -*- */
|
||||
/* vim: set sw=2 sts=2 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "TaskThrottler.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
TaskThrottler::TaskThrottler()
|
||||
: mOutstanding(false)
|
||||
, mQueuedTask(nullptr)
|
||||
{ }
|
||||
|
||||
void
|
||||
TaskThrottler::PostTask(const tracked_objects::Location& aLocation,
|
||||
CancelableTask* aTask)
|
||||
{
|
||||
aTask->SetBirthPlace(aLocation);
|
||||
|
||||
if (mOutstanding) {
|
||||
if (mQueuedTask) {
|
||||
mQueuedTask->Cancel();
|
||||
}
|
||||
mQueuedTask = aTask;
|
||||
} else {
|
||||
aTask->Run();
|
||||
delete aTask;
|
||||
mOutstanding = true;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
TaskThrottler::TaskComplete()
|
||||
{
|
||||
if (mQueuedTask) {
|
||||
mQueuedTask->Run();
|
||||
mQueuedTask = nullptr;
|
||||
} else {
|
||||
mOutstanding = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
56
gfx/layers/ipc/TaskThrottler.h
Normal file
56
gfx/layers/ipc/TaskThrottler.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_TaskThrottler_h
|
||||
#define mozilla_dom_TaskThrottler_h
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
class CancelableTask;
|
||||
namespace tracked_objects {
|
||||
class Location;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/** The TaskThrottler prevents update event overruns. It is used in cases where
|
||||
* you're sending an async message and waiting for a reply. You need to call
|
||||
* PostTask to queue a task and TaskComplete when you get a response.
|
||||
*
|
||||
* The call to TaskComplete will run the recent task posted since the last
|
||||
* request was sent, if any. This means that at any time there can be at most 1
|
||||
* outstanding request being processed and at most 1 queued behind it.
|
||||
*
|
||||
* This is used in the context of repainting a scrollable region. While another
|
||||
* process is painting you might get several updates from the UI thread but when
|
||||
* the paint is complete you want to send the most recent.
|
||||
*/
|
||||
|
||||
class TaskThrottler {
|
||||
public:
|
||||
TaskThrottler();
|
||||
|
||||
/** Post a task to be run as soon as there are no outstanding tasks.
|
||||
*
|
||||
* @param aLocation Use the macro FROM_HERE
|
||||
* @param aTask Ownership of this object is transferred to TaskThrottler
|
||||
* which will delete it when it is either run or becomes
|
||||
* obsolete or the TaskThrottler is destructed.
|
||||
*/
|
||||
void PostTask(const tracked_objects::Location& aLocation,
|
||||
CancelableTask* aTask);
|
||||
void TaskComplete();
|
||||
|
||||
private:
|
||||
bool mOutstanding;
|
||||
nsAutoPtr<CancelableTask> mQueuedTask;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // mozilla_dom_TaskThrottler_h
|
Loading…
Reference in New Issue
Block a user