Bug 1248864 - Part 2: Add skeleton ServoRestyleManager and a RestyleManagerHandle smart pointer. r=dholbert

This commit is contained in:
Cameron McCormack 2016-02-24 18:01:12 +11:00
parent 736a5f47e7
commit 60253e6183
5 changed files with 556 additions and 0 deletions

View File

@ -0,0 +1,208 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_RestyleManagerHandle_h
#define mozilla_RestyleManagerHandle_h
#include "mozilla/Assertions.h"
#include "mozilla/EventStates.h"
#include "mozilla/HandleRefPtr.h"
#include "mozilla/RefCountType.h"
#include "mozilla/StyleBackendType.h"
#include "nsChangeHint.h"
namespace mozilla {
class RestyleManager;
class ServoRestyleManager;
namespace dom {
class Element;
} // namespace dom
} // namespace mozilla
class nsAttrValue;
class nsIAtom;
class nsIContent;
class nsIFrame;
namespace mozilla {
#define SERVO_BIT 0x1
/**
* Smart pointer class that can hold a pointer to either a RestyleManager
* or a ServoRestyleManager.
*/
class RestyleManagerHandle
{
public:
typedef HandleRefPtr<RestyleManagerHandle> RefPtr;
// We define this Ptr class with a RestyleManager API that forwards on to the
// wrapped pointer, rather than putting these methods on RestyleManagerHandle
// itself, so that we can have RestyleManagerHandle behave like a smart
// pointer and be dereferenced with operator->.
class Ptr
{
public:
friend class ::mozilla::RestyleManagerHandle;
bool IsGecko() const { return !IsServo(); }
bool IsServo() const
{
MOZ_ASSERT(mValue, "RestyleManagerHandle null pointer dereference");
#ifdef MOZ_STYLO
return mValue & SERVO_BIT;
#else
return false;
#endif
}
StyleBackendType BackendType() const
{
return IsGecko() ? StyleBackendType::Gecko :
StyleBackendType::Servo;
}
RestyleManager* AsGecko()
{
MOZ_ASSERT(IsGecko());
return reinterpret_cast<RestyleManager*>(mValue);
}
ServoRestyleManager* AsServo()
{
MOZ_ASSERT(IsServo());
return reinterpret_cast<ServoRestyleManager*>(mValue & ~SERVO_BIT);
}
RestyleManager* GetAsGecko() { return IsGecko() ? AsGecko() : nullptr; }
ServoRestyleManager* GetAsServo() { return IsServo() ? AsServo() : nullptr; }
const RestyleManager* AsGecko() const
{
return const_cast<Ptr*>(this)->AsGecko();
}
const ServoRestyleManager* AsServo() const
{
MOZ_ASSERT(IsServo());
return const_cast<Ptr*>(this)->AsServo();
}
const RestyleManager* GetAsGecko() const { return IsGecko() ? AsGecko() : nullptr; }
const ServoRestyleManager* GetAsServo() const { return IsServo() ? AsServo() : nullptr; }
// These inline methods are defined in RestyleManagerHandleInlines.h.
inline MozExternalRefCountType AddRef();
inline MozExternalRefCountType Release();
// Restyle manager interface. These inline methods are defined in
// RestyleManagerHandleInlines.h and just forward to the underlying
// RestyleManager or ServoRestyleManager. See corresponding comments in
// RestyleManager.h for descriptions of these methods.
inline void Disconnect();
inline void PostRestyleEvent(dom::Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint);
inline void PostRestyleEventForLazyConstruction();
inline void RebuildAllStyleData(nsChangeHint aExtraHint,
nsRestyleHint aRestyleHint);
inline void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
nsRestyleHint aRestyleHint);
inline void ProcessPendingRestyles();
inline void RestyleForInsertOrChange(dom::Element* aContainer,
nsIContent* aChild);
inline void RestyleForAppend(dom::Element* aContainer,
nsIContent* aFirstNewContent);
inline void RestyleForRemove(dom::Element* aContainer,
nsIContent* aOldChild,
nsIContent* aFollowingSibling);
inline nsresult ContentStateChanged(nsIContent* aContent,
EventStates aStateMask);
inline void AttributeWillChange(dom::Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aNewValue);
inline void AttributeChanged(dom::Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aOldValue);
inline nsresult ReparentStyleContext(nsIFrame* aFrame);
inline bool HasPendingRestyles();
inline uint64_t GetRestyleGeneration() const;
private:
// Stores a pointer to an RestyleManager or a ServoRestyleManager. The least
// significant bit is 0 for the former, 1 for the latter. This is
// valid as the least significant bit will never be used for a pointer
// value on platforms we care about.
uintptr_t mValue;
};
MOZ_IMPLICIT RestyleManagerHandle(decltype(nullptr) = nullptr)
{
mPtr.mValue = 0;
}
RestyleManagerHandle(const RestyleManagerHandle& aOth)
{
mPtr.mValue = aOth.mPtr.mValue;
}
MOZ_IMPLICIT RestyleManagerHandle(RestyleManager* aManager)
{
*this = aManager;
}
MOZ_IMPLICIT RestyleManagerHandle(ServoRestyleManager* aManager)
{
*this = aManager;
}
RestyleManagerHandle& operator=(decltype(nullptr))
{
mPtr.mValue = 0;
return *this;
}
RestyleManagerHandle& operator=(RestyleManager* aManager)
{
MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aManager) & SERVO_BIT),
"least significant bit shouldn't be set; we use it for state");
mPtr.mValue = reinterpret_cast<uintptr_t>(aManager);
return *this;
}
RestyleManagerHandle& operator=(ServoRestyleManager* aManager)
{
#ifdef MOZ_STYLO
MOZ_ASSERT(!(reinterpret_cast<uintptr_t>(aManager) & SERVO_BIT),
"least significant bit shouldn't be set; we use it for state");
mPtr.mValue =
aManager ? (reinterpret_cast<uintptr_t>(aManager) | SERVO_BIT) : 0;
return *this;
#else
MOZ_CRASH("should not have a ServoRestyleManager object when MOZ_STYLO is "
"disabled");
#endif
}
// Make RestyleManagerHandle usable in boolean contexts.
explicit operator bool() const { return !!mPtr.mValue; }
bool operator!() const { return !mPtr.mValue; }
// Make RestyleManagerHandle behave like a smart pointer.
Ptr* operator->() { return &mPtr; }
const Ptr* operator->() const { return &mPtr; }
private:
Ptr mPtr;
};
#undef SERVO_BIT
} // namespace mozilla
#endif // mozilla_RestyleManagerHandle_h

View File

@ -0,0 +1,151 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_RestyleManagerHandleInlines_h
#define mozilla_RestyleManagerHandleInlines_h
#include "mozilla/RestyleManager.h"
#include "mozilla/ServoRestyleManager.h"
#define FORWARD_CONCRETE(method_, geckoargs_, servoargs_) \
if (IsGecko()) { \
return AsGecko()->method_ geckoargs_; \
} else { \
return AsServo()->method_ servoargs_; \
}
#define FORWARD(method_, args_) FORWARD_CONCRETE(method_, args_, args_)
namespace mozilla {
MozExternalRefCountType
RestyleManagerHandle::Ptr::AddRef()
{
FORWARD(AddRef, ());
}
MozExternalRefCountType
RestyleManagerHandle::Ptr::Release()
{
FORWARD(Release, ());
}
void
RestyleManagerHandle::Ptr::Disconnect()
{
FORWARD(Disconnect, ());
}
void
RestyleManagerHandle::Ptr::PostRestyleEvent(dom::Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint)
{
FORWARD(PostRestyleEvent, (aElement, aRestyleHint, aMinChangeHint));
}
void
RestyleManagerHandle::Ptr::PostRestyleEventForLazyConstruction()
{
FORWARD(PostRestyleEventForLazyConstruction, ());
}
void
RestyleManagerHandle::Ptr::RebuildAllStyleData(nsChangeHint aExtraHint,
nsRestyleHint aRestyleHint)
{
FORWARD(RebuildAllStyleData, (aExtraHint, aRestyleHint));
}
void
RestyleManagerHandle::Ptr::PostRebuildAllStyleDataEvent(
nsChangeHint aExtraHint,
nsRestyleHint aRestyleHint)
{
FORWARD(PostRebuildAllStyleDataEvent, (aExtraHint, aRestyleHint));
}
void
RestyleManagerHandle::Ptr::ProcessPendingRestyles()
{
FORWARD(ProcessPendingRestyles, ());
}
void
RestyleManagerHandle::Ptr::RestyleForInsertOrChange(dom::Element* aContainer,
nsIContent* aChild)
{
FORWARD(RestyleForInsertOrChange, (aContainer, aChild));
}
void
RestyleManagerHandle::Ptr::RestyleForAppend(dom::Element* aContainer,
nsIContent* aFirstNewContent)
{
FORWARD(RestyleForAppend, (aContainer, aFirstNewContent));
}
void
RestyleManagerHandle::Ptr::RestyleForRemove(dom::Element* aContainer,
nsIContent* aOldChild,
nsIContent* aFollowingSibling)
{
FORWARD(RestyleForRemove, (aContainer, aOldChild, aFollowingSibling));
}
nsresult
RestyleManagerHandle::Ptr::ContentStateChanged(nsIContent* aContent,
EventStates aStateMask)
{
FORWARD(ContentStateChanged, (aContent, aStateMask));
}
void
RestyleManagerHandle::Ptr::AttributeWillChange(dom::Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aNewValue)
{
FORWARD(AttributeWillChange, (aElement, aNameSpaceID, aAttribute, aModType,
aNewValue));
}
void
RestyleManagerHandle::Ptr::AttributeChanged(dom::Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aOldValue)
{
FORWARD(AttributeChanged, (aElement, aNameSpaceID, aAttribute, aModType,
aOldValue));
}
nsresult
RestyleManagerHandle::Ptr::ReparentStyleContext(nsIFrame* aFrame)
{
FORWARD(ReparentStyleContext, (aFrame));
}
bool
RestyleManagerHandle::Ptr::HasPendingRestyles()
{
FORWARD(HasPendingRestyles, ());
}
uint64_t
RestyleManagerHandle::Ptr::GetRestyleGeneration() const
{
FORWARD(GetRestyleGeneration, ());
}
} // namespace mozilla
#undef FORWARD
#undef FORWARD_CONCRETE
#endif // mozilla_RestyleManagerHandleInlines_h

View File

@ -0,0 +1,120 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#include "mozilla/ServoRestyleManager.h"
using namespace mozilla::dom;
namespace mozilla {
void
ServoRestyleManager::Disconnect()
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::PostRestyleEvent(Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint)
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::PostRestyleEventForLazyConstruction()
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::RebuildAllStyleData(nsChangeHint aExtraHint,
nsRestyleHint aRestyleHint)
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
nsRestyleHint aRestyleHint)
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::ProcessPendingRestyles()
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::RestyleForInsertOrChange(Element* aContainer,
nsIContent* aChild)
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::RestyleForAppend(Element* aContainer,
nsIContent* aFirstNewContent)
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::RestyleForRemove(Element* aContainer,
nsIContent* aOldChild,
nsIContent* aFollowingSibling)
{
MOZ_CRASH("stylo: not implemented");
}
nsresult
ServoRestyleManager::ContentStateChanged(nsIContent* aContent,
EventStates aStateMask)
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::AttributeWillChange(Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aNewValue)
{
MOZ_CRASH("stylo: not implemented");
}
void
ServoRestyleManager::AttributeChanged(Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aOldValue)
{
MOZ_CRASH("stylo: not implemented");
}
nsresult
ServoRestyleManager::ReparentStyleContext(nsIFrame* aFrame)
{
MOZ_CRASH("stylo: not implemented");
}
bool
ServoRestyleManager::HasPendingRestyles()
{
MOZ_CRASH("stylo: not implemented");
}
uint64_t
ServoRestyleManager::GetRestyleGeneration() const
{
MOZ_CRASH("stylo: not implemented");
}
} // namespace mozilla

View File

@ -0,0 +1,73 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_ServoRestyleManager_h
#define mozilla_ServoRestyleManager_h
#include "mozilla/EventStates.h"
#include "nsChangeHint.h"
#include "nsISupportsImpl.h"
namespace mozilla {
namespace dom {
class Element;
} // namespace dom
} // namespace mozilla
class nsAttrValue;
class nsIAtom;
class nsIContent;
class nsIFrame;
namespace mozilla {
/**
* Restyle manager for a Servo-backed style system.
*/
class ServoRestyleManager
{
public:
NS_INLINE_DECL_REFCOUNTING(ServoRestyleManager)
void Disconnect();
void PostRestyleEvent(dom::Element* aElement,
nsRestyleHint aRestyleHint,
nsChangeHint aMinChangeHint);
void PostRestyleEventForLazyConstruction();
void RebuildAllStyleData(nsChangeHint aExtraHint,
nsRestyleHint aRestyleHint);
void PostRebuildAllStyleDataEvent(nsChangeHint aExtraHint,
nsRestyleHint aRestyleHint);
void ProcessPendingRestyles();
void RestyleForInsertOrChange(dom::Element* aContainer,
nsIContent* aChild);
void RestyleForAppend(dom::Element* aContainer,
nsIContent* aFirstNewContent);
void RestyleForRemove(dom::Element* aContainer,
nsIContent* aOldChild,
nsIContent* aFollowingSibling);
nsresult ContentStateChanged(nsIContent* aContent,
EventStates aStateMask);
void AttributeWillChange(dom::Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aNewValue);
void AttributeChanged(dom::Element* aElement,
int32_t aNameSpaceID,
nsIAtom* aAttribute,
int32_t aModType,
const nsAttrValue* aOldValue);
nsresult ReparentStyleContext(nsIFrame* aFrame);
bool HasPendingRestyles();
uint64_t GetRestyleGeneration() const;
protected:
~ServoRestyleManager() {}
};
} // namespace mozilla
#endif // mozilla_ServoRestyleManager_h

View File

@ -106,6 +106,9 @@ EXPORTS.mozilla += [
'PaintTracker.h',
'RestyleLogging.h',
'RestyleManager.h',
'RestyleManagerHandle.h',
'RestyleManagerHandleInlines.h',
'ServoRestyleManager.h',
]
UNIFIED_SOURCES += [
@ -149,6 +152,7 @@ UNIFIED_SOURCES += [
'RestyleManager.cpp',
'RestyleTracker.cpp',
'ScrollbarStyles.cpp',
'ServoRestyleManager.cpp',
'StackArena.cpp',
'TouchManager.cpp',
'ZoomConstraintsClient.cpp',