Bug 1444580: Devirtualize the fullscreen stuff. r=smaug

MozReview-Commit-ID: CgPENqExkQh
This commit is contained in:
Emilio Cobos Álvarez 2018-03-10 06:15:28 +01:00
Родитель 0f6e1aec50
Коммит 6100eb8087
3 изменённых файлов: 78 добавлений и 99 удалений

Просмотреть файл

@ -1495,6 +1495,7 @@ nsIDocument::nsIDocument()
mDOMCompleteSet(false),
mAutoFocusFired(false),
mIsScopedStyleEnabled(eScopedStyle_Unknown),
mPendingFullscreenRequests(0),
mCompatMode(eCompatibility_FullStandards),
mReadyState(ReadyState::READYSTATE_UNINITIALIZED),
mStyleBackendType(StyleBackendType::None),
@ -1551,7 +1552,6 @@ nsDocument::nsDocument(const char* aContentType)
, mCurrentOrientationAngle(0)
, mCurrentOrientationType(OrientationType::Portrait_primary)
, mReportedUseCounters(false)
, mPendingFullscreenRequests(0)
, mXMLDeclarationBits(0)
, mBoxObjectTable(nullptr)
, mOnloadBlockCount(0)
@ -10513,14 +10513,14 @@ FullscreenRoots::IsEmpty()
using mozilla::FullscreenRoots;
nsIDocument*
nsDocument::GetFullscreenRoot()
nsIDocument::GetFullscreenRoot()
{
nsCOMPtr<nsIDocument> root = do_QueryReferent(mFullscreenRoot);
return root;
}
void
nsDocument::SetFullscreenRoot(nsIDocument* aRoot)
nsIDocument::SetFullscreenRoot(nsIDocument* aRoot)
{
mFullscreenRoot = do_GetWeakReference(aRoot);
}
@ -10600,7 +10600,7 @@ CountFullscreenSubDocuments(nsIDocument* aDoc)
}
bool
nsDocument::IsFullscreenLeaf()
nsIDocument::IsFullscreenLeaf()
{
// A fullscreen leaf document is fullscreen, and has no fullscreen
// subdocuments.
@ -10616,7 +10616,7 @@ ResetFullScreen(nsIDocument* aDocument, void* aData)
if (aDocument->FullScreenStackTop()) {
NS_ASSERTION(CountFullscreenSubDocuments(aDocument) <= 1,
"Should have at most 1 fullscreen subdocument.");
static_cast<nsDocument*>(aDocument)->CleanupFullscreenState();
aDocument->CleanupFullscreenState();
NS_ASSERTION(!aDocument->FullScreenStackTop(),
"Should reset full-screen");
auto changed = reinterpret_cast<nsCOMArray<nsIDocument>*>(aData);
@ -10741,7 +10741,7 @@ GetFullscreenLeaf(nsIDocument* aDoc)
}
void
nsDocument::RestorePreviousFullScreenState()
nsIDocument::RestorePreviousFullScreenState()
{
NS_ASSERTION(!FullScreenStackTop() || !FullscreenRoots::IsEmpty(),
"Should have at least 1 fullscreen root when fullscreen!");
@ -10751,21 +10751,20 @@ nsDocument::RestorePreviousFullScreenState()
}
nsCOMPtr<nsIDocument> fullScreenDoc = GetFullscreenLeaf(this);
AutoTArray<nsDocument*, 8> exitDocs;
AutoTArray<nsIDocument*, 8> exitDocs;
nsIDocument* doc = fullScreenDoc;
// Collect all subdocuments.
for (; doc != this; doc = doc->GetParentDocument()) {
exitDocs.AppendElement(static_cast<nsDocument*>(doc));
exitDocs.AppendElement(doc);
}
MOZ_ASSERT(doc == this, "Must have reached this doc");
// Collect all ancestor documents which we are going to change.
for (; doc; doc = doc->GetParentDocument()) {
nsDocument* theDoc = static_cast<nsDocument*>(doc);
MOZ_ASSERT(!theDoc->mFullScreenStack.IsEmpty(),
MOZ_ASSERT(!doc->mFullScreenStack.IsEmpty(),
"Ancestor of fullscreen document must also be in fullscreen");
if (doc != this) {
Element* top = theDoc->FullScreenStackTop();
Element* top = doc->FullScreenStackTop();
if (top->IsHTMLElement(nsGkAtoms::iframe)) {
if (static_cast<HTMLIFrameElement*>(top)->FullscreenFlag()) {
// If this is an iframe, and it explicitly requested
@ -10774,13 +10773,13 @@ nsDocument::RestorePreviousFullScreenState()
}
}
}
exitDocs.AppendElement(theDoc);
if (theDoc->mFullScreenStack.Length() > 1) {
exitDocs.AppendElement(doc);
if (doc->mFullScreenStack.Length() > 1) {
break;
}
}
nsDocument* lastDoc = exitDocs.LastElement();
nsIDocument* lastDoc = exitDocs.LastElement();
if (!lastDoc->GetParentDocument() &&
lastDoc->mFullScreenStack.Length() == 1) {
// If we are fully exiting fullscreen, don't touch anything here,
@ -10807,7 +10806,7 @@ nsDocument::RestorePreviousFullScreenState()
newFullscreenDoc = lastDoc->GetParentDocument();
}
// Dispatch the fullscreenchange event to all document listed.
for (nsDocument* d : exitDocs) {
for (nsIDocument* d : exitDocs) {
DispatchFullScreenChange(d);
}
@ -10845,7 +10844,7 @@ public:
};
void
nsDocument::AsyncRequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
nsIDocument::AsyncRequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
{
if (!aRequest->GetElement()) {
MOZ_ASSERT_UNREACHABLE(
@ -10894,7 +10893,7 @@ ClearFullscreenStateOnElement(Element* aElement)
}
void
nsDocument::CleanupFullscreenState()
nsIDocument::CleanupFullscreenState()
{
// Iterate the fullscreen stack and clear the fullscreen states.
// Since we also need to clear the fullscreen-ancestor state, and
@ -10914,7 +10913,7 @@ nsDocument::CleanupFullscreenState()
}
bool
nsDocument::FullScreenStackPush(Element* aElement)
nsIDocument::FullScreenStackPush(Element* aElement)
{
NS_ASSERTION(aElement, "Must pass non-null to FullScreenStackPush()");
Element* top = FullScreenStackTop();
@ -10929,7 +10928,7 @@ nsDocument::FullScreenStackPush(Element* aElement)
}
void
nsDocument::FullScreenStackPop()
nsIDocument::FullScreenStackPop()
{
if (mFullScreenStack.IsEmpty()) {
return;
@ -10963,7 +10962,7 @@ nsDocument::FullScreenStackPop()
}
Element*
nsDocument::FullScreenStackTop()
nsIDocument::FullScreenStackTop()
{
if (mFullScreenStack.IsEmpty()) {
return nullptr;
@ -10976,8 +10975,8 @@ nsDocument::FullScreenStackTop()
return element;
}
/* virtual */ nsTArray<Element*>
nsDocument::GetFullscreenStack() const
nsTArray<Element*>
nsIDocument::GetFullscreenStack() const
{
nsTArray<Element*> elements;
for (const nsWeakPtr& ptr : mFullScreenStack) {
@ -11028,7 +11027,7 @@ IsInActiveTab(nsIDocument* aDoc)
return activeWindow == rootWin;
}
nsresult nsDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
nsresult nsIDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
{
// Ensure the frame element is the fullscreen element in this document.
// If the frame element is already the fullscreen element in this document,
@ -11042,7 +11041,7 @@ nsresult nsDocument::RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement)
return NS_OK;
}
nsresult nsDocument::RemoteFrameFullscreenReverted()
nsresult nsIDocument::RemoteFrameFullscreenReverted()
{
RestorePreviousFullScreenState();
return NS_OK;
@ -11091,7 +11090,7 @@ GetFullscreenError(nsIDocument* aDoc, bool aCallerIsChrome)
}
bool
nsDocument::FullscreenElementReadyCheck(Element* aElement,
nsIDocument::FullscreenElementReadyCheck(Element* aElement,
bool aWasCallerChrome)
{
NS_ASSERTION(aElement,
@ -11310,7 +11309,7 @@ ShouldApplyFullscreenDirectly(nsIDocument* aDoc,
}
void
nsDocument::RequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
nsIDocument::RequestFullScreen(UniquePtr<FullscreenRequest>&& aRequest)
{
nsCOMPtr<nsPIDOMWindowOuter> rootWin = GetRootWindow(this);
if (!rootWin) {
@ -11378,7 +11377,7 @@ ClearPendingFullscreenRequests(nsIDocument* aDoc)
}
bool
nsDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
nsIDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
{
Element* elem = aRequest.GetElement();
if (!FullscreenElementReadyCheck(elem, aRequest.mIsCallerChrome)) {
@ -11479,7 +11478,7 @@ nsDocument::ApplyFullscreen(const FullscreenRequest& aRequest)
}
bool
nsDocument::FullscreenEnabled(CallerType aCallerType)
nsIDocument::FullscreenEnabled(CallerType aCallerType)
{
return !GetFullscreenError(this, aCallerType == CallerType::System);
}

Просмотреть файл

@ -107,11 +107,11 @@ struct FullscreenRequest : public LinkedListElement<FullscreenRequest>
~FullscreenRequest();
Element* GetElement() const { return mElement; }
nsDocument* GetDocument() const { return mDocument; }
nsIDocument* GetDocument() const { return mDocument; }
private:
RefPtr<Element> mElement;
RefPtr<nsDocument> mDocument;
RefPtr<nsIDocument> mDocument;
public:
// This value should be true if the fullscreen request is
@ -669,18 +669,6 @@ public:
virtual Element* FindImageMap(const nsAString& aNormalizedMapName) override;
virtual nsTArray<Element*> GetFullscreenStack() const override;
virtual void AsyncRequestFullScreen(
mozilla::UniquePtr<FullscreenRequest>&& aRequest) override;
virtual void RestorePreviousFullScreenState() override;
virtual bool IsFullscreenLeaf() override;
virtual nsresult
RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement) override;
virtual nsresult RemoteFrameFullscreenReverted() override;
virtual nsIDocument* GetFullscreenRoot() override;
virtual void SetFullscreenRoot(nsIDocument* aRoot) override;
// Returns the size of the mBlockedTrackingNodes array. (nsIDocument.h)
//
// This array contains nodes that have been blocked to prevent
@ -707,34 +695,6 @@ public:
//
already_AddRefed<nsSimpleContentList> BlockedTrackingNodes() const;
// Do the "fullscreen element ready check" from the fullscreen spec.
// It returns true if the given element is allowed to go into fullscreen.
bool FullscreenElementReadyCheck(Element* aElement, bool aWasCallerChrome);
// This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
// to move this document into full-screen mode if allowed.
void RequestFullScreen(mozilla::UniquePtr<FullscreenRequest>&& aRequest);
// Removes all elements from the full-screen stack, removing full-scren
// styles from the top element in the stack.
void CleanupFullscreenState();
// Pushes aElement onto the full-screen stack, and removes full-screen styles
// from the former full-screen stack top, and its ancestors, and applies the
// styles to aElement. aElement becomes the new "full-screen element".
bool FullScreenStackPush(Element* aElement);
// Remove the top element from the full-screen stack. Removes the full-screen
// styles from the former top element, and applies them to the new top
// element, if there is one.
void FullScreenStackPop();
// Returns the top element from the full-screen stack.
Element* FullScreenStackTop() override;
// DOM-exposed fullscreen API
bool FullscreenEnabled(mozilla::dom::CallerType aCallerType) override;
void RequestPointerLock(Element* aElement,
mozilla::dom::CallerType aCallerType) override;
bool SetPointerLock(Element* aElement, int aCursorStyle);
@ -820,11 +780,6 @@ protected:
void EnsureOnloadBlocker();
// Apply the fullscreen state to the document, and trigger related
// events. It returns false if the fullscreen element ready check
// fails and nothing gets changed.
bool ApplyFullscreen(const FullscreenRequest& aRequest);
// Array of owning references to all children
nsAttrAndChildArray mChildren;
@ -832,15 +787,6 @@ protected:
// nullptr until GetOrCreatePendingAnimationTracker is called.
RefPtr<mozilla::PendingAnimationTracker> mPendingAnimationTracker;
// Stack of full-screen elements. When we request full-screen we push the
// full-screen element onto this stack, and when we cancel full-screen we
// pop one off this stack, restoring the previous full-screen state
nsTArray<nsWeakPtr> mFullScreenStack;
// The root of the doc tree in which this document is in. This is only
// non-null when this document is in fullscreen mode.
nsWeakPtr mFullscreenRoot;
public:
RefPtr<mozilla::EventListenerManager> mListenerManager;
RefPtr<mozilla::dom::ScriptLoader> mScriptLoader;
@ -874,8 +820,6 @@ public:
// that we only report them once for the document.
bool mReportedUseCounters:1;
uint8_t mPendingFullscreenRequests;
uint8_t mXMLDeclarationBits;
nsRefPtrHashtable<nsPtrHashKey<nsIContent>, mozilla::dom::BoxObject>* mBoxObjectTable;

Просмотреть файл

@ -1611,7 +1611,7 @@ public:
/**
* Returns all elements in the fullscreen stack in the insertion order.
*/
virtual nsTArray<Element*> GetFullscreenStack() const = 0;
nsTArray<Element*> GetFullscreenStack() const;
/**
* Asynchronously requests that the document make aElement the fullscreen
@ -1624,8 +1624,29 @@ public:
* the <iframe> or <browser> that contains this document is also mode
* fullscreen. This happens recursively in all ancestor documents.
*/
virtual void AsyncRequestFullScreen(
mozilla::UniquePtr<FullscreenRequest>&& aRequest) = 0;
void AsyncRequestFullScreen(mozilla::UniquePtr<FullscreenRequest>&&);
// Do the "fullscreen element ready check" from the fullscreen spec.
// It returns true if the given element is allowed to go into fullscreen.
bool FullscreenElementReadyCheck(Element* aElement, bool aWasCallerChrome);
// This is called asynchronously by nsIDocument::AsyncRequestFullScreen()
// to move this document into full-screen mode if allowed.
void RequestFullScreen(mozilla::UniquePtr<FullscreenRequest>&& aRequest);
// Removes all elements from the full-screen stack, removing full-scren
// styles from the top element in the stack.
void CleanupFullscreenState();
// Pushes aElement onto the full-screen stack, and removes full-screen styles
// from the former full-screen stack top, and its ancestors, and applies the
// styles to aElement. aElement becomes the new "full-screen element".
bool FullScreenStackPush(Element* aElement);
// Remove the top element from the full-screen stack. Removes the full-screen
// styles from the former top element, and applies them to the new top
// element, if there is one.
void FullScreenStackPop();
/**
* Called when a frame in a child process has entered fullscreen or when a
@ -1633,8 +1654,7 @@ public:
* aFrameElement is the frame element which contains the child-process
* fullscreen document.
*/
virtual nsresult
RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement) = 0;
nsresult RemoteFrameFullscreenChanged(nsIDOMElement* aFrameElement);
/**
* Called when a frame in a remote child document has rolled back fullscreen
@ -1645,33 +1665,33 @@ public:
* fullscreen document has a parent and that parent isn't fullscreen. We
* preserve this property across process boundaries.
*/
virtual nsresult RemoteFrameFullscreenReverted() = 0;
nsresult RemoteFrameFullscreenReverted();
/**
* Restores the previous full-screen element to full-screen status. If there
* is no former full-screen element, this exits full-screen, moving the
* top-level browser window out of full-screen mode.
*/
virtual void RestorePreviousFullScreenState() = 0;
void RestorePreviousFullScreenState();
/**
* Returns true if this document is a fullscreen leaf document, i.e. it
* is in fullscreen mode and has no fullscreen children.
*/
virtual bool IsFullscreenLeaf() = 0;
bool IsFullscreenLeaf();
/**
* Returns the document which is at the root of this document's branch
* in the in-process document tree. Returns nullptr if the document isn't
* fullscreen.
*/
virtual nsIDocument* GetFullscreenRoot() = 0;
nsIDocument* GetFullscreenRoot();
/**
* Sets the fullscreen root to aRoot. This stores a weak reference to aRoot
* in this document.
*/
virtual void SetFullscreenRoot(nsIDocument* aRoot) = 0;
void SetFullscreenRoot(nsIDocument* aRoot);
/**
* Synchronously cleans up the fullscreen state on the given document.
@ -3002,8 +3022,8 @@ public:
void MozSetImageElement(const nsAString& aImageElementId, Element* aElement);
nsIURI* GetDocumentURIObject() const;
// Not const because all the full-screen goop is not const
virtual bool FullscreenEnabled(mozilla::dom::CallerType aCallerType) = 0;
virtual Element* FullScreenStackTop() = 0;
bool FullscreenEnabled(mozilla::dom::CallerType aCallerType);
Element* FullScreenStackTop();
bool Fullscreen()
{
return !!GetFullscreenElement();
@ -3344,6 +3364,11 @@ protected:
// to notify window when the page was first visited.
void MaybeActiveMediaComponents();
// Apply the fullscreen state to the document, and trigger related
// events. It returns false if the fullscreen element ready check
// fails and nothing gets changed.
bool ApplyFullscreen(const FullscreenRequest& aRequest);
bool GetUseCounter(mozilla::UseCounter aUseCounter)
{
return mUseCounters[aUseCounter];
@ -3781,6 +3806,8 @@ protected:
enum { eScopedStyle_Unknown, eScopedStyle_Disabled, eScopedStyle_Enabled };
unsigned int mIsScopedStyleEnabled : 2;
uint8_t mPendingFullscreenRequests;
// Compatibility mode
nsCompatibility mCompatMode;
@ -4016,6 +4043,15 @@ protected:
nsTHashtable<nsPtrHashKey<mozilla::dom::DOMIntersectionObserver>>
mIntersectionObservers;
// Stack of full-screen elements. When we request full-screen we push the
// full-screen element onto this stack, and when we cancel full-screen we
// pop one off this stack, restoring the previous full-screen state
nsTArray<nsWeakPtr> mFullScreenStack;
// The root of the doc tree in which this document is in. This is only
// non-null when this document is in fullscreen mode.
nsWeakPtr mFullscreenRoot;
nsTArray<RefPtr<mozilla::StyleSheet>> mOnDemandBuiltInUASheets;
nsTArray<RefPtr<mozilla::StyleSheet>> mAdditionalSheets[AdditionalSheetTypeCount];