author | Randall Barker <rbarker@mozilla.com> |
Thu, 01 Sep 2016 09:24:39 -0700 | |
changeset 312929 | a981c221c363453eac4fefff27073ce41c1edf02 |
parent 312928 | d4ddc0a0cf6d70a72ed580c88baf0fe4cef077bf |
child 312930 | eb90834c4f107ebdeb369702d66e5257ff352d36 |
push id | 30665 |
push user | cbook@mozilla.com |
push date | Wed, 07 Sep 2016 15:20:43 +0000 |
treeherder | mozilla-central@95acb9299faf [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jchen, kats |
bugs | 1297853 |
milestone | 51.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/gfx/layers/Compositor.cpp +++ b/gfx/layers/Compositor.cpp @@ -33,19 +33,21 @@ Compositor::Compositor(widget::Composito , mPixelsPerFrame(0) , mPixelsFilled(0) , mScreenRotation(ROTATION_0) , mWidget(aWidget) , mIsDestroyed(false) #if defined(MOZ_WIDGET_ANDROID) // If the default color isn't white for Fennec, there is a black // flash before the first page of a tab is loaded. - , mBeginFrameClearColor(1.0, 1.0, 1.0, 1.0) + , mClearColor(1.0, 1.0, 1.0, 1.0) + , mDefaultClearColor(1.0, 1.0, 1.0, 1.0) #else - , mBeginFrameClearColor(0.0, 0.0, 0.0, 0.0) + , mClearColor(0.0, 0.0, 0.0, 0.0) + , mDefaultClearColor(0.0, 0.0, 0.0, 0.0) #endif { } Compositor::~Compositor() { ReadUnlockTextures(); }
--- a/gfx/layers/Compositor.h +++ b/gfx/layers/Compositor.h @@ -344,18 +344,26 @@ public: /** * Draw a solid color filled rect. This is a simple DrawQuad helper. */ void FillRect(const gfx::Rect& aRect, const gfx::Color& color, const gfx::IntRect& aClipRect = gfx::IntRect(), const gfx::Matrix4x4& aTransform = gfx::Matrix4x4()); - void SetBeginFrameClearColor(const gfx::Color& aColor) { - mBeginFrameClearColor = aColor; + void SetClearColor(const gfx::Color& aColor) { + mClearColor = aColor; + } + + void SetDefaultClearColor(const gfx::Color& aColor) { + mDefaultClearColor = aColor; + } + + void SetClearColorToDefault() { + mClearColor = mDefaultClearColor; } /* * Clear aRect on current render target. */ virtual void ClearRect(const gfx::Rect& aRect) = 0; /** @@ -637,17 +645,18 @@ protected: widget::CompositorWidget* mWidget; bool mIsDestroyed; #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17 FenceHandle mReleaseFenceHandle; #endif - gfx::Color mBeginFrameClearColor; + gfx::Color mClearColor; + gfx::Color mDefaultClearColor; private: static LayersBackend sBackend; }; // Returns the number of rects. (Up to 4) typedef gfx::Rect decomposedRectArrayT[4];
--- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -927,17 +927,19 @@ LayerManagerComposite::Render(const nsIn IntRect actualBounds; CompositorBench(mCompositor, bounds); MOZ_ASSERT(mRoot->GetOpacity() == 1); #if defined(MOZ_WIDGET_ANDROID) LayerMetricsWrapper wrapper = GetRootContentLayer(); if (wrapper) { - mCompositor->SetBeginFrameClearColor(wrapper.Metadata().GetBackgroundColor()); + mCompositor->SetClearColor(wrapper.Metadata().GetBackgroundColor()); + } else { + mCompositor->SetClearColorToDefault(); } #endif if (mRoot->GetClipRect()) { clipRect = *mRoot->GetClipRect(); IntRect rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); mCompositor->BeginFrame(aInvalidRegion, &rect, bounds, aOpaqueRegion, nullptr, &actualBounds); } else { gfx::IntRect rect; @@ -997,23 +999,16 @@ LayerManagerComposite::Render(const nsIn if (composer2D) { composer2D->Render(mCompositor->GetWidget()->RealWidget()); } mCompositor->GetWidget()->PostRender(this); RecordFrame(); - -#if defined(MOZ_WIDGET_ANDROID) - // Reset the clear color to white so that if a page is loaded with a different background - // color, the page will be white while the new page is loading instead of the background - // color of the previous page. - mCompositor->SetBeginFrameClearColor(gfx::Color(1.0, 1.0, 1.0, 1.0)); -#endif } #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK) class ScopedCompositorProjMatrix { public: ScopedCompositorProjMatrix(CompositorOGL* aCompositor, const Matrix4x4& aProjMatrix): mCompositor(aCompositor), mOriginalProjMatrix(mCompositor->GetProjMatrix())
--- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -705,17 +705,17 @@ CompositorOGL::BeginFrame(const nsIntReg #ifdef DEBUG mWindowRenderTarget = mCurrentRenderTarget; #endif if (aClipRectOut && !aClipRectIn) { aClipRectOut->SetRect(0, 0, width, height); } - mGLContext->fClearColor(mBeginFrameClearColor.r, mBeginFrameClearColor.g, mBeginFrameClearColor.b, mBeginFrameClearColor.a); + mGLContext->fClearColor(mClearColor.r, mClearColor.g, mClearColor.b, mClearColor.a); mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT); } void CompositorOGL::CreateFBOWithTexture(const gfx::IntRect& aRect, bool aCopyFromSource, GLuint aSourceFrameBuffer, GLuint *aFBO, GLuint *aTexture) {
--- a/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java +++ b/mobile/android/base/java/org/mozilla/gecko/GeckoApp.java @@ -1149,18 +1149,16 @@ public abstract class GeckoApp // `(GeckoApplication) getApplication()` here. GeckoAppShell.setContextGetter(this); GeckoAppShell.setApplicationContext(getApplicationContext()); GeckoAppShell.setGeckoInterface(this); // We need to set the notification client before launching Gecko, since Gecko could start // sending notifications immediately after startup, which we don't want to lose/crash on. GeckoAppShell.setNotificationClient(makeNotificationClient()); - Tabs.getInstance().attachToContext(this); - // Tell Stumbler to register a local broadcast listener to listen for preference intents. // We do this via intents since we can't easily access Stumbler directly, // as it might be compiled outside of Fennec. getApplicationContext().sendBroadcast( new Intent(INTENT_REGISTER_STUMBLER_LISTENER) ); // Did the OS locale change while we were backgrounded? If so, @@ -1262,16 +1260,18 @@ public abstract class GeckoApp setContentView(getLayout()); // Set up Gecko layout. mRootLayout = (RelativeLayout) findViewById(R.id.root_layout); mGeckoLayout = (RelativeLayout) findViewById(R.id.gecko_layout); mMainLayout = (RelativeLayout) findViewById(R.id.main_layout); mLayerView = (GeckoView) findViewById(R.id.layer_view); + Tabs.getInstance().attachToContext(this, mLayerView); + // Use global layout state change to kick off additional initialization mMainLayout.getViewTreeObserver().addOnGlobalLayoutListener(this); if (Versions.preMarshmallow) { mTextSelection = new ActionBarTextSelection( (TextSelectionHandle) findViewById(R.id.anchor_handle)); } else { mTextSelection = new FloatingToolbarTextSelection(this, mLayerView); @@ -2874,9 +2874,13 @@ public abstract class GeckoApp return IntentHelper.getHandlersForIntent(intent); } @Override public String getDefaultChromeURI() { // Use the chrome URI specified by Gecko's defaultChromeURI pref. return null; } + + public GeckoView getGeckoView() { + return mLayerView; + } }
--- a/mobile/android/base/java/org/mozilla/gecko/PrivateTab.java +++ b/mobile/android/base/java/org/mozilla/gecko/PrivateTab.java @@ -2,18 +2,16 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko; import android.content.Context; -import android.support.v4.content.ContextCompat; - import org.json.JSONObject; import org.mozilla.gecko.db.BrowserDB; public class PrivateTab extends Tab { public PrivateTab(Context context, int id, String url, boolean external, int parentId, String title) { super(context, id, url, external, parentId, title); }
--- a/mobile/android/base/java/org/mozilla/gecko/Tabs.java +++ b/mobile/android/base/java/org/mozilla/gecko/Tabs.java @@ -14,16 +14,17 @@ import java.util.concurrent.atomic.Atomi import android.support.annotation.Nullable; import org.json.JSONException; import org.json.JSONObject; import org.mozilla.gecko.annotation.JNITarget; import org.mozilla.gecko.annotation.RobocopTarget; import org.mozilla.gecko.AppConstants.Versions; import org.mozilla.gecko.db.BrowserDB; +import org.mozilla.gecko.gfx.LayerView; import org.mozilla.gecko.mozglue.SafeIntent; import org.mozilla.gecko.notifications.WhatsNewReceiver; import org.mozilla.gecko.reader.ReaderModeUtils; import org.mozilla.gecko.util.GeckoEventListener; import org.mozilla.gecko.util.ThreadUtils; import android.accounts.Account; import android.accounts.AccountManager; @@ -31,16 +32,17 @@ import android.accounts.OnAccountsUpdate import android.content.ContentResolver; import android.content.Context; import android.database.ContentObserver; import android.database.sqlite.SQLiteException; import android.graphics.Color; import android.net.Uri; import android.os.Handler; import android.provider.Browser; +import android.support.v4.content.ContextCompat; import android.util.Log; public class Tabs implements GeckoEventListener { private static final String LOGTAG = "GeckoTabs"; // mOrder and mTabs are always of the same cardinality, and contain the same values. private final CopyOnWriteArrayList<Tab> mOrder = new CopyOnWriteArrayList<Tab>(); @@ -70,18 +72,20 @@ public class Tabs implements GeckoEventL private static final long PERSIST_TABS_AFTER_MILLISECONDS = 1000 * 2; public static final int INVALID_TAB_ID = -1; private static final AtomicInteger sTabId = new AtomicInteger(0); private volatile boolean mInitialTabsAdded; private Context mAppContext; + private LayerView mLayerView; private ContentObserver mBookmarksContentObserver; private PersistTabsRunnable mPersistTabsRunnable; + private int mPrivateClearColor; private static class PersistTabsRunnable implements Runnable { private final BrowserDB db; private final Context context; private final Iterable<Tab> tabs; public PersistTabsRunnable(final Context context, Iterable<Tab> tabsInOrder) { this.context = context; @@ -116,30 +120,34 @@ public class Tabs implements GeckoEventL "Link:Feed", "Link:OpenSearch", "DesktopMode:Changed", "Tab:ViewportMetadata", "Tab:StreamStart", "Tab:StreamStop", "Tab:AudioPlayingChange"); + mPrivateClearColor = Color.RED; + } - public synchronized void attachToContext(Context context) { + public synchronized void attachToContext(Context context, LayerView layerView) { final Context appContext = context.getApplicationContext(); if (mAppContext == appContext) { return; } if (mAppContext != null) { // This should never happen. Log.w(LOGTAG, "The application context has changed!"); } mAppContext = appContext; + mLayerView = layerView; + mPrivateClearColor = ContextCompat.getColor(context, R.color.tabs_tray_grey_pressed); mAccountManager = AccountManager.get(appContext); mAccountListener = new OnAccountsUpdateListener() { @Override public void onAccountsUpdated(Account[] accounts) { queuePersistAllTabs(); } }; @@ -245,16 +253,20 @@ public class Tabs implements GeckoEventL // handle this case. if (tab == null || oldTab == tab) { return null; } mSelectedTab = tab; notifyListeners(tab, TabEvents.SELECTED); + if (mLayerView != null) { + mLayerView.setClearColor(tab.isPrivate() ? mPrivateClearColor : Color.WHITE); + } + if (oldTab != null) { notifyListeners(oldTab, TabEvents.UNSELECTED); } // Pass a message to Gecko to update tab state in BrowserApp. GeckoAppShell.notifyObservers("Tab:Selected", String.valueOf(tab.getId())); return tab; }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/GeckoLayerClient.java @@ -12,16 +12,17 @@ import org.mozilla.gecko.gfx.LayerView.D import org.mozilla.gecko.Tab; import org.mozilla.gecko.Tabs; import org.mozilla.gecko.ZoomConstraints; import org.mozilla.gecko.EventDispatcher; import org.mozilla.gecko.util.FloatUtils; import org.mozilla.gecko.AppConstants; import android.content.Context; +import android.graphics.Color; import android.graphics.Matrix; import android.graphics.PointF; import android.graphics.RectF; import android.os.SystemClock; import android.util.DisplayMetrics; import android.util.Log; import android.view.InputDevice; import android.view.MotionEvent; @@ -101,16 +102,19 @@ class GeckoLayerClient implements LayerV * have the first-paint flag set, and the second paint happens concurrently with the * composite for the first paint, then this flag may be set to true prematurely. Fixing this * is possible but risky; see https://bugzilla.mozilla.org/show_bug.cgi?id=797615#c751 */ private volatile boolean mContentDocumentIsDisplayed; private SynthesizedEventState mPointerState; + @WrapForJNI(stubName = "ClearColor") + private volatile int mClearColor = Color.WHITE; + public GeckoLayerClient(Context context, LayerView view, EventDispatcher eventDispatcher) { // we can fill these in with dummy values because they are always written // to before being read mContext = context; mScreenSize = new IntSize(0, 0); mWindowSize = new IntSize(0, 0); mDisplayPort = new DisplayPortMetrics(); mRecordDrawTimes = true; @@ -896,9 +900,13 @@ class GeckoLayerClient implements LayerV public void addDrawListener(DrawListener listener) { mDrawListeners.add(listener); } public void removeDrawListener(DrawListener listener) { mDrawListeners.remove(listener); } + + public void setClearColor(int color) { + mClearColor = color; + } }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/gfx/LayerView.java @@ -789,9 +789,14 @@ public class LayerView extends ScrollVie public void addZoomedViewListener(ZoomedViewListener listener) { mRenderer.addZoomedViewListener(listener); } public void removeZoomedViewListener(ZoomedViewListener listener) { mRenderer.removeZoomedViewListener(listener); } + public void setClearColor(int color) { + if (mLayerClient != null) { + mLayerClient.setClearColor(color); + } + } }
--- a/widget/android/GeneratedJNIWrappers.cpp +++ b/widget/android/GeneratedJNIWrappers.cpp @@ -1357,16 +1357,29 @@ auto GeckoLayerClient::SynthesizeNativeM constexpr char GeckoLayerClient::SynthesizeNativeTouchPoint_t::name[]; constexpr char GeckoLayerClient::SynthesizeNativeTouchPoint_t::signature[]; auto GeckoLayerClient::SynthesizeNativeTouchPoint(int32_t a0, int32_t a1, int32_t a2, int32_t a3, double a4, int32_t a5) const -> void { return mozilla::jni::Method<SynthesizeNativeTouchPoint_t>::Call(GeckoLayerClient::mCtx, nullptr, a0, a1, a2, a3, a4, a5); } +constexpr char GeckoLayerClient::ClearColor_t::name[]; +constexpr char GeckoLayerClient::ClearColor_t::signature[]; + +auto GeckoLayerClient::ClearColor() const -> int32_t +{ + return mozilla::jni::Field<ClearColor_t>::Get(GeckoLayerClient::mCtx, nullptr); +} + +auto GeckoLayerClient::ClearColor(int32_t a0) const -> void +{ + return mozilla::jni::Field<ClearColor_t>::Set(GeckoLayerClient::mCtx, nullptr, a0); +} + const char ImmutableViewportMetrics::name[] = "org/mozilla/gecko/gfx/ImmutableViewportMetrics"; constexpr char ImmutableViewportMetrics::New_t::name[]; constexpr char ImmutableViewportMetrics::New_t::signature[]; auto ImmutableViewportMetrics::New(float a0, float a1, float a2, float a3, float a4, float a5, float a6, float a7, float a8, float a9, int32_t a10, int32_t a11, float a12) -> ImmutableViewportMetrics::LocalRef {
--- a/widget/android/GeneratedJNIWrappers.h +++ b/widget/android/GeneratedJNIWrappers.h @@ -4443,16 +4443,37 @@ public: static const mozilla::jni::CallingThread callingThread = mozilla::jni::CallingThread::GECKO; static const mozilla::jni::DispatchTarget dispatchTarget = mozilla::jni::DispatchTarget::CURRENT; }; auto SynthesizeNativeTouchPoint(int32_t, int32_t, int32_t, int32_t, double, int32_t) const -> void; + struct ClearColor_t { + typedef GeckoLayerClient Owner; + typedef int32_t ReturnType; + typedef int32_t SetterType; + typedef mozilla::jni::Args<> Args; + static constexpr char name[] = "mClearColor"; + static constexpr char signature[] = + "I"; + static const bool isStatic = false; + static const mozilla::jni::ExceptionMode exceptionMode = + mozilla::jni::ExceptionMode::ABORT; + static const mozilla::jni::CallingThread callingThread = + mozilla::jni::CallingThread::ANY; + static const mozilla::jni::DispatchTarget dispatchTarget = + mozilla::jni::DispatchTarget::CURRENT; + }; + + auto ClearColor() const -> int32_t; + + auto ClearColor(int32_t) const -> void; + static const mozilla::jni::CallingThread callingThread = mozilla::jni::CallingThread::ANY; }; class ImmutableViewportMetrics : public mozilla::jni::ObjectBase<ImmutableViewportMetrics> { public:
--- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -3484,30 +3484,56 @@ nsWindow::SynthesizeNativeMouseMove(Layo MOZ_ASSERT(mLayerViewSupport); GeckoLayerClient::LocalRef client = mLayerViewSupport->GetLayerClient(); client->SynthesizeNativeMouseEvent(sdk::MotionEvent::ACTION_HOVER_MOVE, aPoint.x, aPoint.y); return NS_OK; } +bool +nsWindow::PreRender(LayerManagerComposite* aManager) +{ + if (Destroyed()) { + return true; + } + + layers::Compositor* compositor = aManager->GetCompositor(); + + GeckoLayerClient::LocalRef client; + + if (NativePtr<LayerViewSupport>::Locked lvs{mLayerViewSupport}) { + client = lvs->GetLayerClient(); + } + + if (compositor && client) { + // Android Color is ARGB which is apparently unusual. + compositor->SetDefaultClearColor(gfx::Color::UnusualFromARGB((uint32_t)client->ClearColor())); + } + + return true; +} void nsWindow::DrawWindowUnderlay(LayerManagerComposite* aManager, LayoutDeviceIntRect aRect) { if (Destroyed()) { return; } GeckoLayerClient::LocalRef client; if (NativePtr<LayerViewSupport>::Locked lvs{mLayerViewSupport}) { client = lvs->GetLayerClient(); } + if (!client) { + return; + } + LayerRenderer::Frame::LocalRef frame = client->CreateFrame(); mLayerRendererFrame = frame; if (NS_WARN_IF(!mLayerRendererFrame)) { return; } if (!WidgetPaintsBackground()) { return;
--- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -194,16 +194,17 @@ public: virtual nsIMEUpdatePreference GetIMEUpdatePreference() override; void SetSelectionDragState(bool aState); LayerManager* GetLayerManager(PLayerTransactionChild* aShadowManager = nullptr, LayersBackend aBackendHint = mozilla::layers::LayersBackend::LAYERS_NONE, LayerManagerPersistence aPersistence = LAYER_MANAGER_CURRENT) override; virtual bool NeedsPaint() override; + virtual bool PreRender(LayerManagerComposite* aManager) override; virtual void DrawWindowUnderlay(LayerManagerComposite* aManager, LayoutDeviceIntRect aRect) override; virtual void DrawWindowOverlay(LayerManagerComposite* aManager, LayoutDeviceIntRect aRect) override; virtual bool WidgetPaintsBackground() override; virtual uint32_t GetMaxTouchPoints() const override; void UpdateZoomConstraints(const uint32_t& aPresShellId,