diff --git a/widget/src/android/nsAppShell.cpp b/widget/src/android/nsAppShell.cpp index 4fb87b182fa..53164a1a34d 100644 --- a/widget/src/android/nsAppShell.cpp +++ b/widget/src/android/nsAppShell.cpp @@ -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() { diff --git a/widget/src/android/nsAppShell.h b/widget/src/android/nsAppShell.h index 1ed1f33be8e..431e10a467e 100644 --- a/widget/src/android/nsAppShell.h +++ b/widget/src/android/nsAppShell.h @@ -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 mEventQueue; nsInterfaceHashtable mObserversHash; - mozilla::AndroidGeckoEvent *GetNextEvent(); + mozilla::AndroidGeckoEvent *PopNextEvent(); mozilla::AndroidGeckoEvent *PeekNextEvent(); };