author | Ali Juma <ajuma@mozilla.com> |
Wed, 28 Mar 2012 18:00:32 -0400 | |
changeset 90568 | 5303cc81321448cd5cea7b0dc60cf5a5a4bdc9ae |
parent 90567 | 23f4b815ce82442b6450567f117f98571cf17178 |
child 90569 | 9435818930fabd03b6449f3124b9f25be2811eee |
push id | 22366 |
push user | mak77@bonardo.net |
push date | Thu, 29 Mar 2012 15:38:30 +0000 |
treeherder | mozilla-central@ff3521bc6559 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | kats |
bugs | 735230 |
milestone | 14.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
|
--- a/mobile/android/base/GeckoEvent.java +++ b/mobile/android/base/GeckoEvent.java @@ -91,16 +91,18 @@ public class GeckoEvent { private static final int VIEWPORT = 20; private static final int VISITED = 21; private static final int NETWORK_CHANGED = 22; private static final int UNUSED3_EVENT = 23; private static final int ACTIVITY_RESUMING = 24; private static final int SCREENSHOT = 25; private static final int UNUSED2_EVENT = 26; private static final int SCREENORIENTATION_CHANGED = 27; + private static final int COMPOSITOR_PAUSE = 28; + private static final int COMPOSITOR_RESUME = 29; 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; @@ -181,16 +183,24 @@ public class GeckoEvent { } public static GeckoEvent createKeyEvent(KeyEvent k) { GeckoEvent event = new GeckoEvent(KEY_EVENT); event.initKeyEvent(k); return event; } + public static GeckoEvent createCompositorPauseEvent() { + return new GeckoEvent(COMPOSITOR_PAUSE); + } + + public static GeckoEvent createCompositorResumeEvent() { + return new GeckoEvent(COMPOSITOR_RESUME); + } + private void initKeyEvent(KeyEvent k) { mAction = k.getAction(); mTime = k.getEventTime(); mMetaState = k.getMetaState(); mFlags = k.getFlags(); mKeyCode = k.getKeyCode(); mUnicodeChar = k.getUnicodeChar(); mCharacters = k.getCharacters();
--- a/widget/android/AndroidBridge.cpp +++ b/widget/android/AndroidBridge.cpp @@ -1871,25 +1871,16 @@ AndroidBridge::IsTablet() JNIEnv *env = GetJNIEnv(); if (!env) return false; return env->CallStaticBooleanMethod(mGeckoAppShellClass, jIsTablet); } void -AndroidBridge::SetCompositorParent(mozilla::layers::CompositorParent* aCompositorParent, - ::base::Thread* aCompositorThread) -{ -#ifdef MOZ_JAVA_COMPOSITOR - nsWindow::SetCompositorParent(aCompositorParent, aCompositorThread); -#endif -} - -void AndroidBridge::SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight) { AndroidGeckoLayerClient *client = mLayerClient; if (!client) return; client->SetFirstPaintViewport(aOffsetX, aOffsetY, aZoom, aPageWidth, aPageHeight); }
--- a/widget/android/AndroidBridge.h +++ b/widget/android/AndroidBridge.h @@ -400,18 +400,16 @@ public: void ClearMessageList(PRInt32 aListId); bool IsTablet(); void GetCurrentNetworkInformation(hal::NetworkInformation* aNetworkInfo); void EnableNetworkNotifications(); void DisableNetworkNotifications(); - void SetCompositorParent(mozilla::layers::CompositorParent* aCompositorParent, - base::Thread* aCompositorThread); void SetFirstPaintViewport(float aOffsetX, float aOffsetY, float aZoom, float aPageWidth, float aPageHeight); void SetPageSize(float aZoom, float aPageWidth, float aPageHeight); void SyncViewportInfo(const nsIntRect& aDisplayPort, float aDisplayResolution, bool aLayersUpdated, nsIntPoint& aScrollOffset, float& aScaleX, float& aScaleY); jobject CreateSurface(); void DestroySurface(jobject surface); void ShowSurface(jobject surface, const gfxRect& aRect, bool aInverted, bool aBlend);
--- a/widget/android/AndroidJavaWrappers.h +++ b/widget/android/AndroidJavaWrappers.h @@ -584,16 +584,18 @@ public: VIEWPORT = 20, VISITED = 21, NETWORK_CHANGED = 22, UNUSED3_EVENT = 23, ACTIVITY_RESUMING = 24, SCREENSHOT = 25, UNUSED2_EVENT = 26, SCREENORIENTATION_CHANGED = 27, + COMPOSITOR_PAUSE = 28, + COMPOSITOR_RESUME = 29, dummy_java_enum_list_end }; enum { IME_COMPOSITION_END = 0, IME_COMPOSITION_BEGIN = 1, IME_SET_TEXT = 2, IME_GET_TEXT = 3,
--- a/widget/android/nsAppShell.cpp +++ b/widget/android/nsAppShell.cpp @@ -611,16 +611,26 @@ nsAppShell::PostEvent(AndroidGeckoEvent AndroidGeckoEvent *event; for (int i = mEventQueue.Length()-1; i >=1; i--) { event = mEventQueue[i]; if (event->Type() == AndroidGeckoEvent::SURFACE_CREATED) { mEventQueue.RemoveElementAt(i); delete event; } } + } else if (ae->Type() == AndroidGeckoEvent::COMPOSITOR_PAUSE || + ae->Type() == AndroidGeckoEvent::COMPOSITOR_RESUME) { + // Give priority to these events, but maintain their order wrt each other. + int i = 0; + while (i < mEventQueue.Length() && + (mEventQueue[i]->Type() == AndroidGeckoEvent::COMPOSITOR_PAUSE || + mEventQueue[i]->Type() == AndroidGeckoEvent::COMPOSITOR_RESUME)) { + i++; + } + mEventQueue.InsertElementAt(i, ae); } else if (ae->Type() == AndroidGeckoEvent::SENSOR_EVENT) { if (!mPendingSensorEvents) mEventQueue.AppendElement(ae); mPendingSensorEvents = true; } else { mEventQueue.AppendElement(ae); }
--- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -209,19 +209,19 @@ nsWindow::~nsWindow() nsWindow *top = FindTopLevel(); if (top->mFocus == this) top->mFocus = nsnull; #ifdef ACCESSIBILITY if (mRootAccessible) mRootAccessible = nsnull; #endif ALOG("nsWindow %p destructor", (void*)this); - - AndroidBridge::Bridge()->SetCompositorParent(NULL, NULL); - +#ifdef MOZ_JAVA_COMPOSITOR + SetCompositor(NULL, NULL, NULL); +#endif } bool nsWindow::IsTopLevel() { return mWindowType == eWindowType_toplevel || mWindowType == eWindowType_dialog || mWindowType == eWindowType_invisible; @@ -767,31 +767,31 @@ nsWindow::GetLayerManager(PLayersChild*, nsWindow *topWindow = TopWindow(); if (!topWindow) { printf_stderr(" -- no topwindow\n"); mLayerManager = CreateBasicLayerManager(); return mLayerManager; } - +#ifdef MOZ_JAVA_COMPOSITOR bool useCompositor = Preferences::GetBool("layers.offmainthreadcomposition.enabled", false); if (useCompositor) { CreateCompositor(); if (mLayerManager) { - AndroidBridge::Bridge()->SetCompositorParent(mCompositorParent, mCompositorThread); + SetCompositor(mCompositorParent, mCompositorChild, mCompositorThread); return mLayerManager; } // If we get here, then off main thread compositing failed to initialize. sFailedToCreateGLContext = true; } - +#endif mUseAcceleratedRendering = GetShouldAccelerate(); if (!mUseAcceleratedRendering || sFailedToCreateGLContext) { printf_stderr(" -- creating basic, not accelerated\n"); mLayerManager = CreateBasicLayerManager(); return mLayerManager; @@ -978,16 +978,41 @@ nsWindow::OnGlobalAndroidEvent(AndroidGe if (sNativeWindow) { AndroidBridge::Bridge()->ReleaseNativeWindow(sNativeWindow); sNativeWindow = nsnull; } sSurfaceExists = false; sValidSurface = false; break; +#ifdef MOZ_JAVA_COMPOSITOR + case AndroidGeckoEvent::COMPOSITOR_PAUSE: + // The compositor gets paused when the app is about to go into the + // background. While the compositor is paused, we need to ensure that + // no layer tree updates (from draw events) occur, since the compositor + // cannot make a GL context current in order to process updates. + if (sCompositorChild) { + sCompositorChild->SendPause(); + } + sCompositorPaused = true; + break; + + case AndroidGeckoEvent::COMPOSITOR_RESUME: + // When we receive this, the compositor has already been told to + // resume. (It turns out that waiting till we reach here to tell + // the compositor to resume takes too long, resulting in a black + // flash.) This means it's now safe for layer updates to occur. + // Since we might have prevented one or more draw events from + // occurring while the compositor was paused, we need to schedule + // a draw event now. + sCompositorPaused = false; + win->RedrawAll(); + break; +#endif + case AndroidGeckoEvent::GECKO_EVENT_SYNC: AndroidBridge::Bridge()->AcknowledgeEventSync(); break; default: break; } } @@ -1130,18 +1155,18 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae) DumpWindows(); return; } nsRefPtr<nsWindow> kungFuDeathGrip(this); AndroidBridge::AutoLocalJNIFrame jniFrame; #ifdef MOZ_JAVA_COMPOSITOR - // We haven't been given a window-size yet, so do nothing - if (gAndroidBounds.width <= 0 || gAndroidBounds.height <= 0) { + // We're paused, or we haven't been given a window-size yet, so do nothing + if (sCompositorPaused || gAndroidBounds.width <= 0 || gAndroidBounds.height <= 0) { return; } /* * Check to see whether the presentation shell corresponding to the document on the screen * is suppressing painting. If it is, we bail out, as continuing would result in a mismatch * between the content on the screen and the current viewport metrics. */ @@ -2270,23 +2295,27 @@ nsWindow::DrawWindowOverlay(LayerManager client.DeactivateProgram(); mLayerRendererFrame.Dispose(); } // off-main-thread compositor fields and functions nsRefPtr<mozilla::layers::CompositorParent> nsWindow::sCompositorParent = 0; +nsRefPtr<mozilla::layers::CompositorChild> nsWindow::sCompositorChild = 0; base::Thread * nsWindow::sCompositorThread = 0; +bool nsWindow::sCompositorPaused = false; void -nsWindow::SetCompositorParent(mozilla::layers::CompositorParent* aCompositorParent, - ::base::Thread* aCompositorThread) +nsWindow::SetCompositor(mozilla::layers::CompositorParent* aCompositorParent, + mozilla::layers::CompositorChild* aCompositorChild, + ::base::Thread* aCompositorThread) { sCompositorParent = aCompositorParent; + sCompositorChild = aCompositorChild; sCompositorThread = aCompositorThread; } void nsWindow::ScheduleComposite() { if (sCompositorParent) { sCompositorParent->ScheduleRenderOnCompositorThread();
--- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -56,16 +56,17 @@ class gfxASurface; class nsIdleService; namespace mozilla { class AndroidGeckoEvent; class AndroidKeyEvent; namespace layers { class CompositorParent; + class CompositorChild; } } class nsWindow : public nsBaseWidget { public: using nsBaseWidget::GetLayerManager; @@ -183,18 +184,19 @@ public: #ifdef ACCESSIBILITY static bool sAccessibilityEnabled; #endif #ifdef MOZ_JAVA_COMPOSITOR virtual void DrawWindowUnderlay(LayerManager* aManager, nsIntRect aRect); virtual void DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect); - static void SetCompositorParent(mozilla::layers::CompositorParent* aCompositorParent, - ::base::Thread* aCompositorThread); + static void SetCompositor(mozilla::layers::CompositorParent* aCompositorParent, + mozilla::layers::CompositorChild* aCompositorChild, + ::base::Thread* aCompositorThread); static void ScheduleComposite(); static void SchedulePauseComposition(); static void ScheduleResumeComposition(); #endif protected: void BringToFront(); nsWindow *FindTopLevel(); @@ -260,13 +262,15 @@ private: */ nsAccessible *DispatchAccessibleEvent(); #endif // ACCESSIBILITY #ifdef MOZ_JAVA_COMPOSITOR mozilla::AndroidLayerRendererFrame mLayerRendererFrame; static nsRefPtr<mozilla::layers::CompositorParent> sCompositorParent; + static nsRefPtr<mozilla::layers::CompositorChild> sCompositorChild; + static bool sCompositorPaused; static base::Thread *sCompositorThread; #endif }; #endif /* NSWINDOW_H_ */