Bug 704575 - Union dirty rects instead of painting all of them. r=kats

In bug #703821 we disabled the squashing of multiple draw events, as it caused
corruption due to the dirty rects being ignored. Re-enable it, and union the
dirty rectangles to avoid this corruption.
This commit is contained in:
Chris Lord 2011-12-02 21:13:16 -08:00
parent 31e8371c3f
commit e3f1b6026f
2 changed files with 31 additions and 28 deletions

View File

@ -214,7 +214,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
{
MutexAutoLock lock(mCondLock);
curEvent = GetNextEvent();
curEvent = PopNextEvent();
if (!curEvent && mayWait) {
// hmm, should we really hardcode this 10s?
#if defined(DEBUG_ANDROID_EVENTS)
@ -229,7 +229,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
mQueueCond.Wait();
#endif
curEvent = GetNextEvent();
curEvent = PopNextEvent();
}
}
@ -244,10 +244,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
int curType = curEvent->Type();
int nextType = nextEvent->Type();
// Do not skip draw events if the Java compositor is in use, since the Java compositor
// updates only the rect that changed - thus we will lose updates.
#ifndef MOZ_JAVA_COMPOSITOR
while (nextType == AndroidGeckoEvent::DRAW &&
while (nextType == AndroidGeckoEvent::DRAW && mLastDrawEvent &&
mNumDraws > 1)
{
// skip this draw, since there's a later one already in the queue.. this will let us
@ -256,7 +253,27 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
// and end up with just
// MOVE DRAW
// when we process all the events.
RemoveNextEvent();
// Combine the next draw event's rect with the last one in the queue
const nsIntRect& nextRect = nextEvent->Rect();
const nsIntRect& lastRect = mLastDrawEvent->Rect();
int combinedArea = (lastRect.width * lastRect.height) +
(nextRect.width * nextRect.height);
nsIntRect combinedRect = lastRect.Union(nextRect);
mLastDrawEvent->Init(AndroidGeckoEvent::DRAW, combinedRect);
// XXX We may want to consider using regions instead of rectangles.
// Print an error if we're upload a lot more than we would
// if we handled this as two separate events.
int boundsArea = combinedRect.width * combinedRect.height;
if (boundsArea > combinedArea * 8)
ALOG("nsAppShell::ProcessNextNativeEvent: "
"Area of bounds greatly exceeds combined area: %d > %d",
boundsArea, combinedArea);
// Remove the next draw event
PopNextEvent();
delete nextEvent;
#if defined(DEBUG_ANDROID_EVENTS)
@ -266,7 +283,6 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
nextEvent = PeekNextEvent();
nextType = nextEvent->Type();
}
#endif
// If the next type of event isn't the same as the current type,
// we don't coalesce.
@ -285,8 +301,7 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
ALOG("# Removing % 2d event", curType);
#endif
RemoveNextEvent();
curEvent = nextEvent;
curEvent = PopNextEvent();
nextEvent = PeekNextEvent();
}
@ -438,7 +453,7 @@ nsAppShell::ResendLastResizeEvent(nsWindow* aDest) {
}
AndroidGeckoEvent*
nsAppShell::GetNextEvent()
nsAppShell::PopNextEvent()
{
AndroidGeckoEvent *ae = nsnull;
MutexAutoLock lock(mQueueLock);
@ -446,7 +461,8 @@ nsAppShell::GetNextEvent()
ae = mEventQueue[0];
mEventQueue.RemoveElementAt(0);
if (ae->Type() == AndroidGeckoEvent::DRAW) {
mNumDraws--;
if (--mNumDraws == 0)
mLastDrawEvent = nsnull;
}
}
@ -488,25 +504,12 @@ nsAppShell::PostEvent(AndroidGeckoEvent *ae)
if (ae->Type() == AndroidGeckoEvent::DRAW) {
mNumDraws++;
mLastDrawEvent = ae;
}
}
NotifyNativeEvent();
}
void
nsAppShell::RemoveNextEvent()
{
AndroidGeckoEvent *ae = nsnull;
MutexAutoLock lock(mQueueLock);
if (mEventQueue.Length()) {
ae = mEventQueue[0];
mEventQueue.RemoveElementAt(0);
if (ae->Type() == AndroidGeckoEvent::DRAW) {
mNumDraws--;
}
}
}
void
nsAppShell::OnResume()
{

View File

@ -76,7 +76,6 @@ public:
virtual bool ProcessNextNativeEvent(bool mayWait);
void PostEvent(mozilla::AndroidGeckoEvent *event);
void RemoveNextEvent();
void OnResume();
nsresult AddObserver(const nsAString &aObserverKey, nsIObserver *aObserver);
@ -93,10 +92,11 @@ protected:
Mutex mCondLock;
CondVar mQueueCond;
int mNumDraws;
mozilla::AndroidGeckoEvent *mLastDrawEvent;
nsTArray<mozilla::AndroidGeckoEvent *> mEventQueue;
nsInterfaceHashtable<nsStringHashKey, nsIObserver> mObserversHash;
mozilla::AndroidGeckoEvent *GetNextEvent();
mozilla::AndroidGeckoEvent *PopNextEvent();
mozilla::AndroidGeckoEvent *PeekNextEvent();
};