Bug 1174966 part 4 - Move pending fullscreen counter manipulation from nsCallRequestFullScreen to FullscreenRequest. r=smaug
authorXidorn Quan <quanxunzhen@gmail.com>
Fri, 19 Jun 2015 10:09:52 +1000
changeset 280467 83e032875162e177f5a4e16eefbf643151585152
parent 280466 49fd389060e2f9aabd19d98d6b28e6029bcc38bb
child 280468 88c6b4df3eb20b7ab54365cfca1465229dbf789b
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-beta@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1174966
milestone41.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 1174966 part 4 - Move pending fullscreen counter manipulation from nsCallRequestFullScreen to FullscreenRequest. r=smaug
dom/base/nsDocument.cpp
dom/base/nsDocument.h
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -11281,39 +11281,31 @@ nsDocument::IsFullScreenDoc()
 {
   return GetFullScreenElement() != nullptr;
 }
 
 class nsCallRequestFullScreen : public nsRunnable
 {
 public:
   explicit nsCallRequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
-    : mRequest(Move(aRequest)),
-      mDoc(mRequest->mElement->OwnerDoc())
-  {
-    auto doc = static_cast<nsDocument*>(mDoc.get());
-    doc->mPendingFullscreenRequests++;
-  }
+    : mRequest(Move(aRequest)) { }
 
   NS_IMETHOD Run()
   {
-    nsDocument* doc = static_cast<nsDocument*>(mDoc.get());
-    doc->mPendingFullscreenRequests--;
-    doc->RequestFullScreen(Move(mRequest));
+    mRequest->GetDocument()->RequestFullScreen(Move(mRequest));
     return NS_OK;
   }
 
   UniquePtr<FullscreenRequest> mRequest;
-  nsCOMPtr<nsIDocument> mDoc;
 };
 
 void
 nsDocument::AsyncRequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
 {
-  if (!aRequest->mElement) {
+  if (!aRequest->GetElement()) {
     MOZ_ASSERT_UNREACHABLE(
       "Must pass non-null element to nsDocument::AsyncRequestFullScreen");
     return;
   }
 
   // Request full-screen asynchronously.
   nsCOMPtr<nsIRunnable> event(new nsCallRequestFullScreen(Move(aRequest)));
   NS_DispatchToCurrentThread(event);
@@ -11586,23 +11578,33 @@ nsDocument::FullscreenElementReadyCheck(
       return false;
     }
   }
   return true;
 }
 
 FullscreenRequest::FullscreenRequest(Element* aElement)
   : mElement(aElement)
+  , mDocument(static_cast<nsDocument*>(aElement->OwnerDoc()))
 {
   MOZ_COUNT_CTOR(FullscreenRequest);
+  mDocument->mPendingFullscreenRequests++;
+  if (MOZ_UNLIKELY(!mDocument->mPendingFullscreenRequests)) {
+    NS_WARNING("Pending fullscreen request counter overflow");
+  }
 }
 
 FullscreenRequest::~FullscreenRequest()
 {
   MOZ_COUNT_DTOR(FullscreenRequest);
+  if (MOZ_UNLIKELY(!mDocument->mPendingFullscreenRequests)) {
+    NS_WARNING("Pending fullscreen request counter underflow");
+    return;
+  }
+  mDocument->mPendingFullscreenRequests--;
 }
 
 // Any fullscreen request waiting for the widget to finish being full-
 // screen is queued here. This is declared static instead of a member
 // of nsDocument because in the majority of time, there would be at most
 // one document requesting fullscreen. We shouldn't waste the space to
 // hold for it in every document.
 static LinkedList<FullscreenRequest> sPendingFullscreenRequests;
@@ -11633,17 +11635,17 @@ nsDocument::RequestFullScreen(UniquePtr<
   if (static_cast<nsGlobalWindow*>(rootWin.get())->FullScreen() ||
       nsContentUtils::GetRootDocument(this)->IsFullScreenDoc()) {
     ApplyFullscreen(*aRequest);
     return;
   }
 
   // We don't need to check element ready before this point, because
   // if we called ApplyFullscreen, it would check that for us.
-  Element* elem = aRequest->mElement;
+  Element* elem = aRequest->GetElement();
   if (!FullscreenElementReadyCheck(elem, aRequest->mIsCallerChrome)) {
     return;
   }
 
   sPendingFullscreenRequests.insertBack(aRequest.release());
   if (XRE_GetProcessType() == GeckoProcessType_Content) {
     // If we are not the top level process, dispatch an event to make
     // our parent process go fullscreen first.
@@ -11657,18 +11659,17 @@ nsDocument::RequestFullScreen(UniquePtr<
   }
 }
 
 /* static */ bool
 nsIDocument::HandlePendingFullscreenRequest(const FullscreenRequest& aRequest,
                                             nsIDocShellTreeItem* aRootShell,
                                             bool* aHandled)
 {
-  nsRefPtr<nsDocument> doc =
-    static_cast<nsDocument*>(aRequest.mElement->OwnerDoc());
+  nsDocument* doc = aRequest.GetDocument();
   nsIDocShellTreeItem* shell = doc->GetDocShell();
   if (!shell) {
     return true;
   }
   nsCOMPtr<nsIDocShellTreeItem> rootShell;
   shell->GetRootTreeItem(getter_AddRefs(rootShell));
   if (rootShell != aRootShell) {
     return false;
@@ -11705,17 +11706,17 @@ nsIDocument::HandlePendingFullscreenRequ
     }
   }
   return handled;
 }
 
 void
 nsDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
 {
-  Element* elem = aRequest.mElement;
+  Element* elem = aRequest.GetElement();
   if (!FullscreenElementReadyCheck(elem, aRequest.mIsCallerChrome)) {
     return;
   }
 
   // Stash a reference to any existing fullscreen doc, we'll use this later
   // to detect if the origin which is fullscreen has changed.
   nsCOMPtr<nsIDocument> previousFullscreenDoc = GetFullscreenLeaf(this);
 
@@ -11741,17 +11742,17 @@ nsDocument::ApplyFullscreen(const Fullsc
     nsRefPtr<gfx::VRHMDInfo> hmdRef = aRequest.mVRHMDDevice;
     elem->SetProperty(nsGkAtoms::vr_state, hmdRef.forget().take(),
                       ReleaseHMDInfoRef, true);
   }
 
   // Set the full-screen element. This sets the full-screen style on the
   // element, and the full-screen-ancestor styles on ancestors of the element
   // in this document.
-  DebugOnly<bool> x = FullScreenStackPush(aRequest.mElement);
+  DebugOnly<bool> x = FullScreenStackPush(elem);
   NS_ASSERTION(x, "Full-screen state of requesting doc should always change!");
   changed.AppendElement(this);
 
   // Propagate up the document hierarchy, setting the full-screen element as
   // the element's container in ancestor documents. This also sets the
   // appropriate css styles as well. Note we don't propagate down the
   // document hierarchy, the full-screen element (or its container) is not
   // visible there. Stop when we reach the root document.
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -98,18 +98,24 @@ class UndoManager;
 struct LifecycleCallbacks;
 class CallbackFunction;
 
 struct FullscreenRequest : public LinkedListElement<FullscreenRequest>
 {
   explicit FullscreenRequest(Element* aElement);
   ~FullscreenRequest();
 
+  Element* GetElement() const { return mElement; }
+  nsDocument* GetDocument() const { return mDocument; }
+
+private:
   nsRefPtr<Element> mElement;
+  nsRefPtr<nsDocument> mDocument;
 
+public:
   nsRefPtr<gfx::VRHMDInfo> mVRHMDDevice;
   // This value should be true if the fullscreen request is
   // originated from chrome code.
   bool mIsCallerChrome = false;
   // This value denotes whether we should trigger a NewOrigin event if
   // requesting fullscreen in its document causes the origin which is
   // fullscreen to change. We may want *not* to trigger that event if
   // we're calling RequestFullScreen() as part of a continuation of a