Ensure that content processes recreate rendering devices. (bug 1245765 part 8, r=mattwoodrow)
authorDavid Anderson <danderson@mozilla.com>
Mon, 29 Feb 2016 01:53:15 -0500
changeset 286061 de97989a2d9b4775fc7cb0adef2b393ab6ecea97
parent 286060 966bbc65931a548f4938670fb1835226fecfa0ef
child 286062 8ad96eb28e4fb4903c326987e07cf2fded0e67b6
push id30039
push usercbook@mozilla.com
push dateTue, 01 Mar 2016 11:02:11 +0000
treeherdermozilla-central@5cafa6f3019b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1245765
milestone47.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
Ensure that content processes recreate rendering devices. (bug 1245765 part 8, r=mattwoodrow)
dom/ipc/TabChild.cpp
gfx/thebes/gfxPlatform.h
gfx/thebes/gfxWindowsPlatform.cpp
gfx/thebes/gfxWindowsPlatform.h
layout/base/nsRefreshDriver.cpp
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2878,16 +2878,18 @@ TabChild::InvalidateLayers()
 
   RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
   FrameLayerBuilder::InvalidateAllLayers(lm);
 }
 
 void
 TabChild::CompositorUpdated(const TextureFactoryIdentifier& aNewIdentifier)
 {
+  gfxPlatform::GetPlatform()->UpdateRenderModeIfDeviceReset();
+
   RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
   ClientLayerManager* clm = lm->AsClientLayerManager();
 
   mTextureFactoryIdentifier = aNewIdentifier;
   clm->UpdateTextureFactoryIdentifier(aNewIdentifier);
   FrameLayerBuilder::InvalidateAllLayers(clm);
 }
 
--- a/gfx/thebes/gfxPlatform.h
+++ b/gfx/thebes/gfxPlatform.h
@@ -604,21 +604,24 @@ public:
     }
     virtual bool SupportsApzTouchInput() const {
       return false;
     }
     bool SupportsApzDragInput() const;
 
     virtual void FlushContentDrawing() {}
 
-    // If a device reset has occurred, update the necessary platform backend
-    // bits.
-    virtual bool UpdateForDeviceReset() {
-      return false;
-    }
+    // If a device reset has occurred, schedule any necessary paints in the
+    // widget. This should only be used within nsRefreshDriver.
+    virtual void SchedulePaintIfDeviceReset() {}
+
+    // Immediately update all platform bits if a device reset has occurred.
+    // This should only be used at the top of the callstack (i.e. within
+    // a task, OS event, or IPDL message).
+    virtual void UpdateRenderModeIfDeviceReset() {}
 
     /**
      * Helper method, creates a draw target for a specific Azure backend.
      * Used by CreateOffscreenDrawTarget.
      */
     already_AddRefed<DrawTarget>
       CreateDrawTargetForBackend(mozilla::gfx::BackendType aBackend,
                                  const mozilla::gfx::IntSize& aSize,
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -1051,32 +1051,41 @@ gfxWindowsPlatform::DidRenderingDeviceRe
 BOOL CALLBACK
 InvalidateWindowForDeviceReset(HWND aWnd, LPARAM aMsg)
 {
     RedrawWindow(aWnd, nullptr, nullptr,
                  RDW_INVALIDATE|RDW_INTERNALPAINT|RDW_FRAME);
     return TRUE;
 }
 
-bool
-gfxWindowsPlatform::UpdateForDeviceReset()
+void
+gfxWindowsPlatform::SchedulePaintIfDeviceReset()
 {
   PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
 
   if (!DidRenderingDeviceReset()) {
-    return false;
+    return;
   }
 
   // Trigger an ::OnPaint for each window.
   ::EnumThreadWindows(GetCurrentThreadId(),
                       InvalidateWindowForDeviceReset,
                       0);
 
   gfxCriticalNote << "Detected rendering device reset on refresh";
-  return true;
+}
+
+void
+gfxWindowsPlatform::UpdateRenderModeIfDeviceReset()
+{
+  PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS);
+
+  if (DidRenderingDeviceReset()) {
+    UpdateRenderMode();
+  }
 }
 
 void
 gfxWindowsPlatform::GetPlatformCMSOutputProfile(void* &mem, size_t &mem_size)
 {
     WCHAR str[MAX_PATH];
     DWORD size = MAX_PATH;
     BOOL res;
--- a/gfx/thebes/gfxWindowsPlatform.h
+++ b/gfx/thebes/gfxWindowsPlatform.h
@@ -199,17 +199,18 @@ public:
     virtual bool CanUseHardwareVideoDecoding() override;
 
     /**
      * Check whether format is supported on a platform or not (if unclear, returns true)
      */
     virtual bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags) override;
 
     bool DidRenderingDeviceReset(DeviceResetReason* aResetReason = nullptr) override;
-    bool UpdateForDeviceReset() override;
+    void SchedulePaintIfDeviceReset() override;
+    void UpdateRenderModeIfDeviceReset() override;
 
     mozilla::gfx::BackendType GetContentBackendFor(mozilla::layers::LayersBackend aLayers) override;
 
     // ClearType is not always enabled even when available (e.g. Windows XP)
     // if either of these prefs are enabled and apply, use ClearType rendering
     bool UseClearTypeForDownloadableFonts();
     bool UseClearTypeAlways();
 
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1671,17 +1671,17 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
   }
 
   AutoRestore<bool> restoreInRefresh(mInRefresh);
   mInRefresh = true;
 
   AutoRestore<TimeStamp> restoreTickStart(mTickStart);
   mTickStart = TimeStamp::Now();
 
-  gfxPlatform::GetPlatform()->UpdateForDeviceReset();
+  gfxPlatform::GetPlatform()->SchedulePaintIfDeviceReset();
 
   /*
    * The timer holds a reference to |this| while calling |Notify|.
    * However, implementations of |WillRefresh| are permitted to destroy
    * the pres context, which will cause our |mPresContext| to become
    * null.  If this happens, we must stop notifying observers.
    */
   for (uint32_t i = 0; i < ArrayLength(mObservers); ++i) {