Bug 598482 part 11 - Set up a connection between the view manager and the refresh driver. r=roc

This commit is contained in:
Markus Stange 2011-12-23 22:52:22 -05:00
Родитель c5f5e5536a
Коммит 837db98189
8 изменённых файлов: 55 добавлений и 7 удалений

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

@ -141,8 +141,8 @@ typedef struct CapturingContentInfo {
} CapturingContentInfo;
#define NS_IPRESSHELL_IID \
{ 0x4e23d557, 0x741a, 0x4fd0,\
{ 0x91, 0x52, 0x34, 0xe2, 0xb4, 0xef, 0xe8, 0x2e } }
{ 0x3ab5b116, 0x2d73, 0x431c, \
{ 0x9a, 0x4b, 0x6c, 0x91, 0x9e, 0x42, 0x45, 0xc3 } }
// Constants for ScrollContentIntoView() function
#define NS_PRESSHELL_SCROLL_TOP 0
@ -1148,6 +1148,7 @@ public:
virtual bool ShouldIgnoreInvalidation() = 0;
virtual void WillPaint(bool aWillSendDidPaint) = 0;
virtual void DidPaint() = 0;
virtual void ScheduleViewManagerFlush() = 0;
virtual void ClearMouseCaptureOnView(nsIView* aView) = 0;
virtual bool IsVisible() = 0;
virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange) = 0;

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

@ -1253,6 +1253,8 @@ PresShell::Destroy()
// before we destroy the frame manager, since apparently frame destruction
// sometimes spins the event queue when plug-ins are involved(!).
rd->RemoveLayoutFlushObserver(this);
rd->RevokeViewManagerFlush();
mResizeEvent.Revoke();
if (mAsyncResizeTimerIsActive) {
mAsyncResizeEventTimer->Cancel();
@ -3612,6 +3614,15 @@ nsresult PresShell::GetLinkLocation(nsIDOMNode* aNode, nsAString& aLocationStrin
return NS_ERROR_FAILURE;
}
void
PresShell::ScheduleViewManagerFlush()
{
nsPresContext* presContext = GetPresContext();
if (presContext) {
presContext->RefreshDriver()->ScheduleViewManagerFlush();
}
}
void
PresShell::DispatchSynthMouseMove(nsGUIEvent *aEvent,
bool aFlushOnHoverChange)

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

@ -330,6 +330,7 @@ public:
virtual bool ShouldIgnoreInvalidation();
virtual void WillPaint(bool aWillSendDidPaint);
virtual void DidPaint();
virtual void ScheduleViewManagerFlush();
virtual void DispatchSynthMouseMove(nsGUIEvent *aEvent, bool aFlushOnHoverChange);
virtual void ClearMouseCaptureOnView(nsIView* aView);
virtual bool IsVisible();

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

@ -55,6 +55,7 @@
#include "jsapi.h"
#include "nsContentUtils.h"
#include "mozilla/Preferences.h"
#include "nsIViewManager.h"
using mozilla::TimeStamp;
using mozilla::TimeDuration;
@ -112,6 +113,7 @@ nsRefreshDriver::nsRefreshDriver(nsPresContext *aPresContext)
mThrottled(false),
mTestControllingRefreshes(false),
mTimerIsPrecise(false),
mViewManagerFlushIsPending(false),
mLastTimerInterval(0)
{
mRequests.Init();
@ -270,6 +272,7 @@ nsRefreshDriver::ObserverCount() const
sum += mStyleFlushObservers.Length();
sum += mLayoutFlushObservers.Length();
sum += mFrameRequestCallbackDocs.Length();
sum += mViewManagerFlushIsPending;
return sum;
}
@ -431,6 +434,11 @@ nsRefreshDriver::Notify(nsITimer *aTimer)
EnsureTimerStarted(false);
}
if (mViewManagerFlushIsPending) {
mViewManagerFlushIsPending = false;
mPresContext->GetPresShell()->GetViewManager()->ProcessPendingUpdates();
}
if (mThrottled ||
(mTimerIsPrecise !=
(GetRefreshTimerType() == nsITimer::TYPE_REPEATING_PRECISE_CAN_SKIP))) {

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

@ -176,6 +176,17 @@ public:
return mLayoutFlushObservers.Contains(aShell);
}
/**
* Remember whether our presshell's view manager needs a flush
*/
void ScheduleViewManagerFlush() {
mViewManagerFlushIsPending = true;
EnsureTimerStarted(false);
}
void RevokeViewManagerFlush() {
mViewManagerFlushIsPending = false;
}
/**
* Add a document for which we have nsIFrameRequestCallbacks
*/
@ -265,6 +276,7 @@ private:
a precise timer. If mTimer is null, this boolean's value can be
anything. */
bool mTimerIsPrecise;
bool mViewManagerFlushIsPending;
// separate arrays for each flush type we support
ObserverArray mObservers[3];

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

@ -348,6 +348,12 @@ public:
* the nearest enclosing popup or the root view for the root document.
*/
static nsIView* GetDisplayRootFor(nsIView* aView);
/**
* Flush the accumulated dirty region to the widget and update widget
* geometry.
*/
virtual void ProcessPendingUpdates()=0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIViewManager, NS_IVIEWMANAGER_IID)

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

@ -398,7 +398,8 @@ void nsViewManager::RenderViews(nsView *aView, nsIWidget *aWidget,
}
}
void nsViewManager::ProcessPendingUpdates(nsView* aView, bool aDoInvalidate)
void nsViewManager::ProcessPendingUpdatesForView(nsView* aView,
bool aDoInvalidate)
{
NS_ASSERTION(IsRootVM(), "Updates will be missed");
@ -414,7 +415,7 @@ void nsViewManager::ProcessPendingUpdates(nsView* aView, bool aDoInvalidate)
// process pending updates in child view.
for (nsView* childView = aView->GetFirstChild(); childView;
childView = childView->GetNextSibling()) {
ProcessPendingUpdates(childView, aDoInvalidate);
ProcessPendingUpdatesForView(childView, aDoInvalidate);
}
if (aDoInvalidate) {
@ -828,7 +829,7 @@ NS_IMETHODIMP nsViewManager::DispatchEvent(nsGUIEvent *aEvent,
// Make sure to sync up any widget geometry changes we
// have pending before we paint.
if (rootVM->mHasPendingUpdates) {
rootVM->ProcessPendingUpdates(mRootView, false);
rootVM->ProcessPendingUpdatesForView(mRootView, false);
}
if (view && aEvent->message == NS_PAINT) {
@ -1424,6 +1425,12 @@ nsViewManager::IsPainting(bool& aIsPainting)
return NS_OK;
}
void
nsViewManager::ProcessPendingUpdates()
{
// To be implemented.
}
void
nsViewManager::FlushPendingInvalidates()
{
@ -1431,7 +1438,7 @@ nsViewManager::FlushPendingInvalidates()
NS_ASSERTION(mUpdateBatchCnt == 0, "Must not be in an update batch!");
if (mHasPendingUpdates) {
ProcessPendingUpdates(mRootView, true);
ProcessPendingUpdatesForView(mRootView, true);
mHasPendingUpdates = false;
}
}

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

@ -144,13 +144,15 @@ public:
/* Update the cached RootViewManager pointer on this view manager. */
void InvalidateHierarchy();
virtual void ProcessPendingUpdates();
protected:
virtual ~nsViewManager();
private:
void FlushPendingInvalidates();
void ProcessPendingUpdates(nsView *aView, bool aDoInvalidate);
void ProcessPendingUpdatesForView(nsView *aView, bool aDoInvalidate);
void FlushDirtyRegionToWidget(nsView* aView);
/**
* Call WillPaint() on all view observers under this vm root.