Bug 709152 - Squash multiple viewport events in nsAppShell. r=pcwalton
authorChris Lord <chrislord.net@gmail.com>
Thu, 22 Dec 2011 11:35:32 +0000
changeset 83252 943ac1d43ad4799bd83d155929ed1c76d4e7b9e0
parent 83251 28a81df3d02bac4562563381d56f4e6aa4563733
child 83253 f75ee6fa2587786a28716c62896f33c198ffaecc
push id21744
push userbmo@edmorley.co.uk
push dateFri, 23 Dec 2011 23:56:40 +0000
treeherdermozilla-central@ede336ccaed0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspcwalton
bugs709152
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 709152 - Squash multiple viewport events in nsAppShell. r=pcwalton We only ever want to respond to the latest viewport sent, separate the viewport change into its own event and remove all but the latest in the queue when processing events.
mobile/android/base/GeckoEvent.java
mobile/android/base/gfx/GeckoSoftwareLayerClient.java
widget/src/android/AndroidJavaWrappers.cpp
widget/src/android/AndroidJavaWrappers.h
widget/src/android/nsAppShell.cpp
widget/src/android/nsAppShell.h
--- a/mobile/android/base/GeckoEvent.java
+++ b/mobile/android/base/GeckoEvent.java
@@ -32,16 +32,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 package org.mozilla.gecko;
 
+import org.mozilla.gecko.gfx.ViewportMetrics;
 import android.os.*;
 import android.app.*;
 import android.view.*;
 import android.content.*;
 import android.graphics.*;
 import android.widget.*;
 import android.hardware.*;
 import android.location.*;
@@ -71,16 +72,17 @@ public class GeckoEvent {
     public static final int ACTIVITY_PAUSING = 10;
     public static final int ACTIVITY_SHUTDOWN = 11;
     public static final int LOAD_URI = 12;
     public static final int SURFACE_CREATED = 13;
     public static final int SURFACE_DESTROYED = 14;
     public static final int GECKO_EVENT_SYNC = 15;
     public static final int ACTIVITY_START = 17;
     public static final int BROADCAST = 19;
+    public static final int VIEWPORT = 20;
 
     public static final int IME_COMPOSITION_END = 0;
     public static final int IME_COMPOSITION_BEGIN = 1;
     public static final int IME_SET_TEXT = 2;
     public static final int IME_GET_TEXT = 3;
     public static final int IME_DELETE_TEXT = 4;
     public static final int IME_SET_SELECTION = 5;
     public static final int IME_GET_SELECTION = 6;
@@ -227,14 +229,20 @@ public class GeckoEvent {
     }
 
     public GeckoEvent(String subject, String data) {
         mType = BROADCAST;
         mCharacters = subject;
         mCharactersExtra = data;
     }
 
+    public GeckoEvent(ViewportMetrics viewport) {
+        mType = VIEWPORT;
+        mCharacters = "Viewport:Change";
+        mCharactersExtra = viewport.toJSON();
+    }
+
     public GeckoEvent(String uri) {
         mType = LOAD_URI;
         mCharacters = uri;
     }
 
 }
--- a/mobile/android/base/gfx/GeckoSoftwareLayerClient.java
+++ b/mobile/android/base/gfx/GeckoSoftwareLayerClient.java
@@ -310,18 +310,17 @@ public class GeckoSoftwareLayerClient ex
         Log.i(LOGTAG, "Adjusting viewport");
         ViewportMetrics viewportMetrics =
             new ViewportMetrics(getLayerController().getViewportMetrics());
 
         PointF viewportOffset = viewportMetrics.getOptimumViewportOffset(mBufferSize);
         viewportMetrics.setViewportOffset(viewportOffset);
         viewportMetrics.setViewport(viewportMetrics.getClampedViewport());
 
-        GeckoEvent event = new GeckoEvent("Viewport:Change", viewportMetrics.toJSON());
-        GeckoAppShell.sendEventToGecko(event);
+        GeckoAppShell.sendEventToGecko(new GeckoEvent(viewportMetrics));
         if (mViewportSizeChanged) {
             mViewportSizeChanged = false;
             GeckoAppShell.viewSizeChanged();
         }
 
         mLastViewportChangeTime = System.currentTimeMillis();
     }
 
--- a/widget/src/android/AndroidJavaWrappers.cpp
+++ b/widget/src/android/AndroidJavaWrappers.cpp
@@ -475,16 +475,17 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jo
             break;
         }
 
         case LOAD_URI: {
             ReadCharactersField(jenv);
             break;
         }
 
+        case VIEWPORT:
         case BROADCAST: {
             ReadCharactersField(jenv);
             ReadCharactersExtraField(jenv);
             break;
         }
 
         default:
             break;
--- a/widget/src/android/AndroidJavaWrappers.h
+++ b/widget/src/android/AndroidJavaWrappers.h
@@ -526,16 +526,17 @@ public:
         ACTIVITY_SHUTDOWN = 11,
         LOAD_URI = 12,
         SURFACE_CREATED = 13,
         SURFACE_DESTROYED = 14,
         GECKO_EVENT_SYNC = 15,
         FORCED_RESIZE = 16,
         ACTIVITY_START = 17,
         BROADCAST = 19,
+        VIEWPORT = 20,
         dummy_java_enum_list_end
     };
 
     enum {
         IME_COMPOSITION_END = 0,
         IME_COMPOSITION_BEGIN = 1,
         IME_SET_TEXT = 2,
         IME_GET_TEXT = 3,
--- a/widget/src/android/nsAppShell.cpp
+++ b/widget/src/android/nsAppShell.cpp
@@ -79,17 +79,18 @@ nsAutoPtr<mozilla::AndroidGeckoEvent> gL
 nsAppShell *nsAppShell::gAppShell = nsnull;
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsAppShell, nsBaseAppShell, nsIObserver)
 
 nsAppShell::nsAppShell()
     : mQueueLock("nsAppShell.mQueueLock"),
       mCondLock("nsAppShell.mCondLock"),
       mQueueCond(mCondLock, "nsAppShell.mQueueCond"),
-      mNumDraws(0)
+      mNumDraws(0),
+      mNumViewports(0)
 {
     gAppShell = this;
 }
 
 nsAppShell::~nsAppShell()
 {
     gAppShell = nsnull;
 }
@@ -237,16 +238,25 @@ nsAppShell::ProcessNextNativeEvent(bool 
     // Combine subsequent events of the same type
 
     nextEvent = PeekNextEvent();
 
     while (nextEvent) {
         int curType = curEvent->Type();
         int nextType = nextEvent->Type();
 
+        while (nextType == AndroidGeckoEvent::VIEWPORT && mNumViewports > 1) {
+            // Skip this viewport change, as there's another one later and
+            // processing this one will only cause more unnecessary work
+            PopNextEvent();
+            delete nextEvent;
+            nextEvent = PeekNextEvent();
+            nextType = nextEvent->Type();
+        }
+
         while (nextType == AndroidGeckoEvent::DRAW && mLastDrawEvent &&
                mNumDraws > 1)
         {
             // skip this draw, since there's a later one already in the queue.. this will let us
             // deal with sequences that look like:
             //   MOVE DRAW MOVE DRAW MOVE DRAW
             // and end up with just
             //   MOVE DRAW
@@ -380,16 +390,17 @@ nsAppShell::ProcessNextNativeEvent(bool 
     case AndroidGeckoEvent::ACTIVITY_START: {
         nsCOMPtr<nsIObserverService> obsServ =
             mozilla::services::GetObserverService();
         obsServ->NotifyObservers(nsnull, "application-foreground", nsnull);
 
         break;
     }
 
+    case AndroidGeckoEvent::VIEWPORT:
     case AndroidGeckoEvent::BROADCAST: {
 
         if (curEvent->Characters().Length() == 0)
             break;
 
         nsCOMPtr<nsIObserverService> obsServ =
             mozilla::services::GetObserverService();
 
@@ -456,16 +467,18 @@ nsAppShell::PopNextEvent()
     AndroidGeckoEvent *ae = nsnull;
     MutexAutoLock lock(mQueueLock);
     if (mEventQueue.Length()) {
         ae = mEventQueue[0];
         mEventQueue.RemoveElementAt(0);
         if (ae->Type() == AndroidGeckoEvent::DRAW) {
             if (--mNumDraws == 0)
                 mLastDrawEvent = nsnull;
+        } else if (ae->Type() == AndroidGeckoEvent::VIEWPORT) {
+            mNumViewports--;
         }
     }
 
     return ae;
 }
 
 AndroidGeckoEvent*
 nsAppShell::PeekNextEvent()
@@ -498,16 +511,18 @@ nsAppShell::PostEvent(AndroidGeckoEvent 
             }
         } else {
             mEventQueue.AppendElement(ae);
         }
 
         if (ae->Type() == AndroidGeckoEvent::DRAW) {
             mNumDraws++;
             mLastDrawEvent = ae;
+        } else if (ae->Type() == AndroidGeckoEvent::VIEWPORT) {
+            mNumViewports++;
         }
     }
     NotifyNativeEvent();
 }
 
 void
 nsAppShell::OnResume()
 {
--- a/widget/src/android/nsAppShell.h
+++ b/widget/src/android/nsAppShell.h
@@ -87,16 +87,17 @@ public:
 protected:
     virtual void ScheduleNativeEventCallback();
     virtual ~nsAppShell();
 
     Mutex mQueueLock;
     Mutex mCondLock;
     CondVar mQueueCond;
     int mNumDraws;
+    int mNumViewports;
     mozilla::AndroidGeckoEvent *mLastDrawEvent;
     nsTArray<mozilla::AndroidGeckoEvent *> mEventQueue;
     nsInterfaceHashtable<nsStringHashKey, nsIObserver> mObserversHash;
 
     mozilla::AndroidGeckoEvent *PopNextEvent();
     mozilla::AndroidGeckoEvent *PeekNextEvent();
 };