mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 20:30:41 +00:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
a439f12e74
@ -1481,6 +1481,9 @@ DocAccessible::DoInitialUpdate()
|
||||
if (RefPtr<dom::TabChild> tabChild = dom::TabChild::GetFrom(docShell)) {
|
||||
DocAccessibleChild* ipcDoc = new DocAccessibleChild(this, tabChild);
|
||||
SetIPCDoc(ipcDoc);
|
||||
if (IsRoot()) {
|
||||
tabChild->SetTopLevelDocAccessibleChild(ipcDoc);
|
||||
}
|
||||
|
||||
#if defined(XP_WIN)
|
||||
IAccessibleHolder holder(CreateHolderFromAccessible(this));
|
||||
|
@ -102,18 +102,8 @@ DocAccessibleChild::PushDeferredEvent(UniquePtr<DeferredEvent> aEvent)
|
||||
return;
|
||||
}
|
||||
|
||||
nsTArray<PDocAccessibleChild*> ipcDocAccs;
|
||||
tabChild->ManagedPDocAccessibleChild(ipcDocAccs);
|
||||
|
||||
// Look for the top-level DocAccessibleChild - there will only be one
|
||||
// per TabChild.
|
||||
for (uint32_t i = 0, l = ipcDocAccs.Length(); i < l; ++i) {
|
||||
auto ipcDocAcc = static_cast<DocAccessibleChild*>(ipcDocAccs[i]);
|
||||
if (ipcDocAcc->mDoc && ipcDocAcc->mDoc->IsRoot()) {
|
||||
topLevelIPCDoc = ipcDocAcc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
topLevelIPCDoc =
|
||||
static_cast<DocAccessibleChild*>(tabChild->GetTopLevelDocAccessibleChild());
|
||||
}
|
||||
|
||||
if (topLevelIPCDoc) {
|
||||
|
@ -553,7 +553,17 @@ function invokeInTab(fnc) {
|
||||
}
|
||||
|
||||
const isLinux = Services.appinfo.OS === "Linux";
|
||||
const isMac = Services.appinfo.OS === "Darwin";
|
||||
const cmdOrCtrl = isLinux ? { ctrlKey: true } : { metaKey: true };
|
||||
// On Mac, going to beginning/end only works with meta+left/right. On
|
||||
// Windows, it only works with home/end. On Linux, apparently, either
|
||||
// ctrl+left/right or home/end work.
|
||||
const endKey = isMac ?
|
||||
{ code: "VK_RIGHT", modifiers: cmdOrCtrl } :
|
||||
{ code: "VK_END" };
|
||||
const startKey = isMac ?
|
||||
{ code: "VK_LEFT", modifiers: cmdOrCtrl } :
|
||||
{ code: "VK_HOME" };
|
||||
const keyMappings = {
|
||||
sourceSearch: { code: "p", modifiers: cmdOrCtrl },
|
||||
fileSearch: { code: "f", modifiers: cmdOrCtrl },
|
||||
@ -562,8 +572,8 @@ const keyMappings = {
|
||||
Down: { code: "VK_DOWN" },
|
||||
Right: { code: "VK_RIGHT" },
|
||||
Left: { code: "VK_LEFT" },
|
||||
End: { code: "VK_RIGHT", modifiers: cmdOrCtrl },
|
||||
Start: { code: "VK_LEFT", modifiers: cmdOrCtrl },
|
||||
End: endKey,
|
||||
Start: startKey,
|
||||
Tab: { code: "VK_TAB" },
|
||||
Escape: { code: "VK_ESCAPE" },
|
||||
pauseKey: { code: "VK_F8" },
|
||||
|
@ -103,6 +103,7 @@
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocCharset.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDocumentInlines.h"
|
||||
#include "Crypto.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
@ -977,6 +978,7 @@ nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMWindowOuter *aOuterWindow)
|
||||
mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
|
||||
mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
|
||||
mMayHaveMouseEnterLeaveEventListener(false),
|
||||
mMayHaveMouseMoveEventListener(false),
|
||||
mMayHavePointerEnterLeaveEventListener(false),
|
||||
mInnerObjectsFreed(false),
|
||||
mIsModalContentWindow(false),
|
||||
@ -2044,6 +2046,23 @@ nsGlobalWindow::FreeInnerObjects()
|
||||
{
|
||||
NS_ASSERTION(IsInnerWindow(), "Don't free inner objects on an outer window");
|
||||
|
||||
if (mDoc && !nsContentUtils::IsSystemPrincipal(mDoc->NodePrincipal())) {
|
||||
EventTarget* win = this;
|
||||
EventTarget* html = mDoc->GetHtmlElement();
|
||||
EventTarget* body = mDoc->GetBodyElement();
|
||||
|
||||
bool mouseAware = AsInner()->HasMouseMoveEventListeners();
|
||||
bool keyboardAware = win->MayHaveAPZAwareKeyEventListener() ||
|
||||
mDoc->MayHaveAPZAwareKeyEventListener() ||
|
||||
(html && html->MayHaveAPZAwareKeyEventListener()) ||
|
||||
(body && body->MayHaveAPZAwareKeyEventListener());
|
||||
|
||||
Telemetry::Accumulate(Telemetry::APZ_AWARE_MOUSEMOVE_LISTENERS,
|
||||
mouseAware ? 1 : 0);
|
||||
Telemetry::Accumulate(Telemetry::APZ_AWARE_KEY_LISTENERS,
|
||||
keyboardAware ? 1 : 0);
|
||||
}
|
||||
|
||||
// Make sure that this is called before we null out the document and
|
||||
// other members that the window destroyed observers could
|
||||
// re-create.
|
||||
|
@ -539,6 +539,9 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
||||
if (elm->MayHaveTouchEventListener()) {
|
||||
window->SetHasTouchEventListeners();
|
||||
}
|
||||
if (elm->MayHaveMouseMoveEventListener()) {
|
||||
window->SetHasMouseMoveEventListeners();
|
||||
}
|
||||
if (elm->MayHaveMouseEnterLeaveEventListener()) {
|
||||
window->SetHasMouseEnterLeaveEventListeners();
|
||||
}
|
||||
|
@ -669,6 +669,7 @@ protected:
|
||||
bool mMayHavePaintEventListener;
|
||||
bool mMayHaveTouchEventListener;
|
||||
bool mMayHaveMouseEnterLeaveEventListener;
|
||||
bool mMayHaveMouseMoveEventListener;
|
||||
bool mMayHavePointerEnterLeaveEventListener;
|
||||
|
||||
// Used to detect whether we have called FreeInnerObjects() (e.g. to ensure
|
||||
@ -814,6 +815,24 @@ public:
|
||||
mMutationBits |= aType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to check whether some node (this window, its document,
|
||||
* or content in that document) has or had a mousemove event listener.
|
||||
*/
|
||||
bool HasMouseMoveEventListeners()
|
||||
{
|
||||
return mMayHaveMouseMoveEventListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to indicate that some node (this window, its document,
|
||||
* or content in that document) has or had a mousemove event listener.
|
||||
*/
|
||||
void SetHasMouseMoveEventListeners()
|
||||
{
|
||||
mMayHaveMouseMoveEventListener = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this to check whether some node (this window, its document,
|
||||
* or content in that document) has a mouseenter/leave event listener.
|
||||
|
@ -3990,11 +3990,15 @@ class CGUpdateMemberSlotsMethod(CGAbstractStaticMethod):
|
||||
body += fill(
|
||||
"""
|
||||
|
||||
static_assert(${slot} < js::shadow::Object::MAX_FIXED_SLOTS,
|
||||
"Not enough fixed slots to fit '${interface}.${member}. Ion's visitGetDOMMemberV/visitGetDOMMemberT assume StoreInSlot things are all in fixed slots.");
|
||||
if (!get_${member}(aCx, aWrapper, aObject, args)) {
|
||||
return false;
|
||||
}
|
||||
// Getter handled setting our reserved slots
|
||||
""",
|
||||
slot=memberReservedSlot(m, self.descriptor),
|
||||
interface=self.descriptor.interface.identifier.name,
|
||||
member=m.identifier.name)
|
||||
|
||||
body += "\nreturn true;\n"
|
||||
|
@ -127,8 +127,10 @@ EventListenerManagerBase::EventListenerManagerBase()
|
||||
, mMayHaveCapturingListeners(false)
|
||||
, mMayHaveSystemGroupListeners(false)
|
||||
, mMayHaveTouchEventListener(false)
|
||||
, mMayHaveMouseMoveEventListener(false)
|
||||
, mMayHaveMouseEnterLeaveEventListener(false)
|
||||
, mMayHavePointerEnterLeaveEventListener(false)
|
||||
, mMayHaveAPZAwareKeyEventListener(false)
|
||||
, mMayHaveKeyEventListener(false)
|
||||
, mMayHaveInputOrCompositionEventListener(false)
|
||||
, mClearingListeners(false)
|
||||
@ -411,6 +413,9 @@ EventListenerManager::AddEventListenerInternal(
|
||||
if (!aFlags.mInSystemGroup) {
|
||||
mMayHaveKeyEventListener = true;
|
||||
}
|
||||
if (!aFlags.mPassive && aTypeAtom != nsGkAtoms::onkeyup) {
|
||||
mMayHaveAPZAwareKeyEventListener = true;
|
||||
}
|
||||
} else if (aTypeAtom == nsGkAtoms::oncompositionend ||
|
||||
aTypeAtom == nsGkAtoms::oncompositionstart ||
|
||||
aTypeAtom == nsGkAtoms::oncompositionupdate ||
|
||||
@ -418,6 +423,11 @@ EventListenerManager::AddEventListenerInternal(
|
||||
if (!aFlags.mInSystemGroup) {
|
||||
mMayHaveInputOrCompositionEventListener = true;
|
||||
}
|
||||
} else if (aTypeAtom == nsGkAtoms::onmousemove) {
|
||||
mMayHaveMouseMoveEventListener = true;
|
||||
if (nsPIDOMWindowInner* window = GetInnerWindowForTarget()) {
|
||||
window->SetHasMouseMoveEventListeners();
|
||||
}
|
||||
}
|
||||
|
||||
if (IsApzAwareListener(listener)) {
|
||||
|
@ -161,13 +161,15 @@ protected:
|
||||
uint16_t mMayHaveCapturingListeners : 1;
|
||||
uint16_t mMayHaveSystemGroupListeners : 1;
|
||||
uint16_t mMayHaveTouchEventListener : 1;
|
||||
uint16_t mMayHaveMouseMoveEventListener : 1;
|
||||
uint16_t mMayHaveMouseEnterLeaveEventListener : 1;
|
||||
uint16_t mMayHavePointerEnterLeaveEventListener : 1;
|
||||
uint16_t mMayHaveAPZAwareKeyEventListener : 1;
|
||||
uint16_t mMayHaveKeyEventListener : 1;
|
||||
uint16_t mMayHaveInputOrCompositionEventListener : 1;
|
||||
uint16_t mClearingListeners : 1;
|
||||
uint16_t mIsMainThreadELM : 1;
|
||||
// uint16_t mUnused : 5;
|
||||
// uint16_t mUnused : 3;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -439,9 +441,13 @@ public:
|
||||
*/
|
||||
bool MayHaveTouchEventListener() { return mMayHaveTouchEventListener; }
|
||||
|
||||
bool MayHaveMouseMoveEventListener() { return mMayHaveMouseMoveEventListener; }
|
||||
|
||||
bool MayHaveMouseEnterLeaveEventListener() { return mMayHaveMouseEnterLeaveEventListener; }
|
||||
bool MayHavePointerEnterLeaveEventListener() { return mMayHavePointerEnterLeaveEventListener; }
|
||||
|
||||
bool MayHaveAPZAwareKeyEventListener() const { return mMayHaveAPZAwareKeyEventListener; }
|
||||
|
||||
/**
|
||||
* Returns true if there may be a key event listener (keydown, keypress,
|
||||
* or keyup) registered, or false if there definitely isn't.
|
||||
|
@ -64,6 +64,13 @@ EventTarget::IsApzAware() const
|
||||
return elm && elm->HasApzAwareListeners();
|
||||
}
|
||||
|
||||
bool
|
||||
EventTarget::MayHaveAPZAwareKeyEventListener() const
|
||||
{
|
||||
EventListenerManager* elm = GetExistingListenerManager();
|
||||
return elm && elm->MayHaveAPZAwareKeyEventListener();
|
||||
}
|
||||
|
||||
bool
|
||||
EventTarget::DispatchEvent(Event& aEvent,
|
||||
CallerType aCallerType,
|
||||
|
@ -100,6 +100,7 @@ public:
|
||||
virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) {}
|
||||
|
||||
virtual bool IsApzAware() const;
|
||||
bool MayHaveAPZAwareKeyEventListener() const;
|
||||
|
||||
protected:
|
||||
EventHandlerNonNull* GetEventHandler(nsIAtom* aType,
|
||||
|
@ -403,6 +403,9 @@ TabChild::TabChild(nsIContentChild* aManager,
|
||||
#if defined(XP_WIN) && defined(ACCESSIBILITY)
|
||||
, mNativeWindowHandle(0)
|
||||
#endif
|
||||
#if defined(ACCESSIBILITY)
|
||||
, mTopLevelDocAccessibleChild(nullptr)
|
||||
#endif
|
||||
{
|
||||
nsWeakPtr weakPtrThis(do_GetWeakReference(static_cast<nsITabChild*>(this))); // for capture by the lambda
|
||||
mSetAllowedTouchBehaviorCallback = [weakPtrThis](uint64_t aInputBlockId,
|
||||
|
@ -675,6 +675,18 @@ public:
|
||||
|
||||
mozilla::dom::TabGroup* TabGroup();
|
||||
|
||||
#if defined(ACCESSIBILITY)
|
||||
void SetTopLevelDocAccessibleChild(PDocAccessibleChild* aTopLevelChild)
|
||||
{
|
||||
mTopLevelDocAccessibleChild = aTopLevelChild;
|
||||
}
|
||||
|
||||
PDocAccessibleChild* GetTopLevelDocAccessibleChild()
|
||||
{
|
||||
return mTopLevelDocAccessibleChild;
|
||||
}
|
||||
#endif
|
||||
|
||||
protected:
|
||||
virtual ~TabChild();
|
||||
|
||||
@ -843,6 +855,10 @@ private:
|
||||
uintptr_t mNativeWindowHandle;
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
#if defined(ACCESSIBILITY)
|
||||
PDocAccessibleChild* mTopLevelDocAccessibleChild;
|
||||
#endif
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
|
||||
};
|
||||
|
||||
|
@ -44,13 +44,6 @@ public:
|
||||
// All set methods return true if values changed, false otherwise.
|
||||
//
|
||||
|
||||
bool SetLayerBounds(const gfx::IntRect& aLayerBounds) {
|
||||
if (mLayerBounds.IsEqualEdges(aLayerBounds)) {
|
||||
return false;
|
||||
}
|
||||
mLayerBounds = aLayerBounds;
|
||||
return true;
|
||||
}
|
||||
bool SetPostScale(float aXScale, float aYScale) {
|
||||
if (mPostXScale == aXScale && mPostYScale == aYScale) {
|
||||
return false;
|
||||
@ -195,9 +188,6 @@ public:
|
||||
// Getters.
|
||||
//
|
||||
|
||||
const gfx::IntRect& LayerBounds() const {
|
||||
return mLayerBounds;
|
||||
}
|
||||
float PostXScale() const {
|
||||
return mPostXScale;
|
||||
}
|
||||
@ -265,8 +255,7 @@ public:
|
||||
}
|
||||
|
||||
bool operator ==(const SimpleLayerAttributes& aOther) const {
|
||||
return mLayerBounds == aOther.mLayerBounds &&
|
||||
mTransform == aOther.mTransform &&
|
||||
return mTransform == aOther.mTransform &&
|
||||
mTransformIsPerspective == aOther.mTransformIsPerspective &&
|
||||
mScrolledClip == aOther.mScrolledClip &&
|
||||
mPostXScale == aOther.mPostXScale &&
|
||||
@ -283,7 +272,6 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
gfx::IntRect mLayerBounds;
|
||||
gfx::Matrix4x4 mTransform;
|
||||
bool mTransformIsPerspective;
|
||||
Maybe<LayerClip> mScrolledClip;
|
||||
|
@ -576,8 +576,7 @@ Layer::CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect)
|
||||
return currentClip;
|
||||
}
|
||||
|
||||
if (GetLocalVisibleRegion().IsEmpty() &&
|
||||
!(AsHostLayer() && AsHostLayer()->NeedToDrawCheckerboarding())) {
|
||||
if (GetLocalVisibleRegion().IsEmpty()) {
|
||||
// When our visible region is empty, our parent may not have created the
|
||||
// intermediate surface that we would require for correct clipping; however,
|
||||
// this does not matter since we are invisible.
|
||||
@ -1850,9 +1849,6 @@ Layer::PrintInfo(std::stringstream& aStream, const char* aPrefix)
|
||||
if (GetTransformIsPerspective()) {
|
||||
aStream << " [perspective]";
|
||||
}
|
||||
if (!GetLayerBounds().IsEmpty()) {
|
||||
AppendToString(aStream, GetLayerBounds(), " [bounds=", "]");
|
||||
}
|
||||
if (!mVisibleRegion.IsEmpty()) {
|
||||
AppendToString(aStream, mVisibleRegion.ToUnknownRegion(), " [visible=", "]");
|
||||
} else {
|
||||
|
@ -898,22 +898,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* The union of the bounds of all the display item that got flattened
|
||||
* into this layer. This is intended to be an approximation to the
|
||||
* size of the layer if the nearest scrollable ancestor had an infinitely
|
||||
* large displayport. Computing this more exactly is too expensive,
|
||||
* but this approximation is sufficient for what we need to use it for.
|
||||
*/
|
||||
virtual void SetLayerBounds(const gfx::IntRect& aLayerBounds)
|
||||
{
|
||||
if (mSimpleAttrs.SetLayerBounds(aLayerBounds)) {
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) LayerBounds", this));
|
||||
MutatedSimple();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* Tell this layer which region will be visible. The visible region
|
||||
@ -1340,7 +1324,6 @@ public:
|
||||
const Maybe<LayerClip>& GetScrolledClip() const { return mSimpleAttrs.ScrolledClip(); }
|
||||
Maybe<ParentLayerIntRect> GetScrolledClipRect() const;
|
||||
uint32_t GetContentFlags() { return mSimpleAttrs.ContentFlags(); }
|
||||
const gfx::IntRect& GetLayerBounds() const { return mSimpleAttrs.LayerBounds(); }
|
||||
const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
|
||||
const ScrollMetadata& GetScrollMetadata(uint32_t aIndex) const;
|
||||
const FrameMetrics& GetFrameMetrics(uint32_t aIndex) const;
|
||||
|
@ -169,7 +169,7 @@ ClientTiledPaintedLayer::BeginPaint()
|
||||
ParentLayerToLayerMatrix4x4 transformDisplayPortToLayer =
|
||||
GetTransformToAncestorsParentLayer(this, displayPortAncestor).Inverse();
|
||||
|
||||
LayerRect layerBounds = ViewAs<LayerPixel>(Rect(GetLayerBounds()));
|
||||
LayerRect layerBounds(GetVisibleRegion().GetBounds());
|
||||
|
||||
// Compute the critical display port that applies to this layer in the
|
||||
// LayoutDevice space of this layer, but only if there is no OMT animation
|
||||
|
@ -1218,7 +1218,7 @@ ClientMultiTiledLayerBuffer::ComputeProgressiveUpdateRegion(const nsIntRegion& a
|
||||
GetCompositorSideCompositionBounds(scrollAncestor,
|
||||
aPaintData->mTransformToCompBounds,
|
||||
viewTransform,
|
||||
ViewAs<LayerPixel>(Rect(mPaintedLayer.GetLayerBounds())));
|
||||
LayerRect(mPaintedLayer.GetVisibleRegion().GetBounds()));
|
||||
|
||||
if (!transformedCompositionBounds) {
|
||||
aPaintData->mPaintFinished = true;
|
||||
|
@ -212,8 +212,7 @@ ContainerPrepare(ContainerT* aContainer,
|
||||
// We don't want to skip container layers because otherwise their mPrepared
|
||||
// may be null which is not allowed.
|
||||
if (!layerToRender->GetLayer()->AsContainerLayer()) {
|
||||
if (!layerToRender->GetLayer()->IsVisible() &&
|
||||
!layerToRender->NeedToDrawCheckerboarding(nullptr)) {
|
||||
if (!layerToRender->GetLayer()->IsVisible()) {
|
||||
CULLING_LOG("Sublayer %p has no effective visible region\n", layerToRender->GetLayer());
|
||||
continue;
|
||||
}
|
||||
@ -423,24 +422,6 @@ RenderLayers(ContainerT* aContainer, LayerManagerComposite* aManager,
|
||||
}
|
||||
}
|
||||
|
||||
Color color;
|
||||
if (layerToRender->NeedToDrawCheckerboarding(&color)) {
|
||||
if (gfxPrefs::APZHighlightCheckerboardedAreas()) {
|
||||
color = Color(255 / 255.f, 188 / 255.f, 217 / 255.f, 1.f); // "Cotton Candy"
|
||||
}
|
||||
// Ideally we would want to intersect the checkerboard region from the APZ with the layer bounds
|
||||
// and only fill in that area. However the layer bounds takes into account the base translation
|
||||
// for the painted layer whereas the checkerboard region does not. One does not simply
|
||||
// intersect areas in different coordinate spaces. So we do this a little more permissively
|
||||
// and only fill in the background when we know there is checkerboard, which in theory
|
||||
// should only occur transiently.
|
||||
EffectChain effectChain(layer);
|
||||
effectChain.mPrimaryEffect = new EffectSolidColor(color);
|
||||
aManager->GetCompositor()->DrawGeometry(gfx::Rect(layer->GetLayerBounds()), clipRect,
|
||||
effectChain, layer->GetEffectiveOpacity(),
|
||||
layer->GetEffectiveTransform(), Nothing());
|
||||
}
|
||||
|
||||
if (layerToRender->HasLayerBeenComposited()) {
|
||||
// Composer2D will compose this layer so skip GPU composition
|
||||
// this time. The flag will be reset for the next composition phase
|
||||
|
@ -1501,35 +1501,6 @@ LayerComposite::HasStaleCompositor() const
|
||||
return mCompositeManager->GetCompositor() != mCompositor;
|
||||
}
|
||||
|
||||
static bool
|
||||
LayerHasCheckerboardingAPZC(Layer* aLayer, Color* aOutColor)
|
||||
{
|
||||
bool answer = false;
|
||||
for (LayerMetricsWrapper i(aLayer, LayerMetricsWrapper::StartAt::BOTTOM); i; i = i.GetParent()) {
|
||||
if (!i.Metrics().IsScrollable()) {
|
||||
continue;
|
||||
}
|
||||
if (i.GetApzc() && i.GetApzc()->IsCurrentlyCheckerboarding()) {
|
||||
if (aOutColor) {
|
||||
*aOutColor = i.Metadata().GetBackgroundColor();
|
||||
}
|
||||
answer = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
bool
|
||||
LayerComposite::NeedToDrawCheckerboarding(gfx::Color* aOutCheckerboardingColor)
|
||||
{
|
||||
return GetLayer()->Manager()->AsyncPanZoomEnabled() &&
|
||||
(GetLayer()->GetContentFlags() & Layer::CONTENT_OPAQUE) &&
|
||||
GetLayer()->IsOpaqueForVisibility() &&
|
||||
LayerHasCheckerboardingAPZC(GetLayer(), aOutCheckerboardingColor);
|
||||
}
|
||||
|
||||
#ifndef MOZ_HAVE_PLATFORM_SPECIFIC_LAYER_BUFFERS
|
||||
|
||||
/*static*/ bool
|
||||
|
@ -589,12 +589,6 @@ public:
|
||||
bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; }
|
||||
bool GetShadowOpacitySetByAnimation() { return mShadowOpacitySetByAnimation; }
|
||||
|
||||
/**
|
||||
* Return true if a checkerboarding background color needs to be drawn
|
||||
* for this layer.
|
||||
*/
|
||||
virtual bool NeedToDrawCheckerboarding(gfx::Color* aOutCheckerboardingColor = nullptr) { return false; }
|
||||
|
||||
protected:
|
||||
HostLayerManager* mCompositorManager;
|
||||
|
||||
@ -694,8 +688,6 @@ public:
|
||||
*/
|
||||
virtual nsIntRegion GetFullyRenderedRegion();
|
||||
|
||||
virtual bool NeedToDrawCheckerboarding(gfx::Color* aOutCheckerboardingColor = nullptr);
|
||||
|
||||
protected:
|
||||
LayerManagerComposite* mCompositeManager;
|
||||
|
||||
|
@ -57,12 +57,17 @@ ZoneGroup::~ZoneGroup()
|
||||
}
|
||||
|
||||
void
|
||||
ZoneGroup::enter()
|
||||
ZoneGroup::enter(JSContext* cx)
|
||||
{
|
||||
JSContext* cx = TlsContext.get();
|
||||
if (ownerContext().context() == cx) {
|
||||
MOZ_ASSERT(enterCount);
|
||||
} else {
|
||||
if (useExclusiveLocking) {
|
||||
MOZ_ASSERT(!usedByHelperThread);
|
||||
while (ownerContext().context() != nullptr) {
|
||||
cx->yieldToEmbedding();
|
||||
}
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(ownerContext().context() == nullptr);
|
||||
MOZ_ASSERT(enterCount == 0);
|
||||
ownerContext_ = CooperatingContext(cx);
|
||||
|
@ -41,11 +41,15 @@ class ZoneGroup
|
||||
// The number of times the context has entered this zone group.
|
||||
UnprotectedData<size_t> enterCount;
|
||||
|
||||
// If this flag is true, then we may need to block before entering this zone
|
||||
// group. Blocking happens using JSContext::yieldToEmbedding.
|
||||
UnprotectedData<bool> useExclusiveLocking;
|
||||
|
||||
public:
|
||||
CooperatingContext& ownerContext() { return ownerContext_.ref(); }
|
||||
void* addressOfOwnerContext() { return &ownerContext_.ref().cx; }
|
||||
|
||||
void enter();
|
||||
void enter(JSContext* cx);
|
||||
void leave();
|
||||
bool ownedByCurrentThread();
|
||||
|
||||
@ -72,6 +76,9 @@ class ZoneGroup
|
||||
inline bool isCollecting();
|
||||
inline bool isGCScheduled();
|
||||
|
||||
// See the useExclusiveLocking field above.
|
||||
void setUseExclusiveLocking() { useExclusiveLocking = true; }
|
||||
|
||||
#ifdef DEBUG
|
||||
private:
|
||||
// The number of possible bailing places encounters before forcefully bailing
|
||||
|
@ -201,10 +201,14 @@ struct JSContext : public JS::RootingContext,
|
||||
#endif
|
||||
|
||||
private:
|
||||
// If |c| or |oldCompartment| is the atoms compartment, the
|
||||
// |exclusiveAccessLock| must be held.
|
||||
inline void enterCompartment(JSCompartment* c,
|
||||
const js::AutoLockForExclusiveAccess* maybeLock = nullptr);
|
||||
// We distinguish between entering the atoms compartment and all other
|
||||
// compartments. Entering the atoms compartment requires a lock. Also, we
|
||||
// don't call enterZoneGroup when entering the atoms compartment since that
|
||||
// can induce GC hazards.
|
||||
inline void enterNonAtomsCompartment(JSCompartment* c);
|
||||
inline void enterAtomsCompartment(JSCompartment* c,
|
||||
const js::AutoLockForExclusiveAccess& lock);
|
||||
|
||||
friend class js::AutoCompartment;
|
||||
|
||||
public:
|
||||
@ -303,10 +307,26 @@ struct JSContext : public JS::RootingContext,
|
||||
friend class js::jit::DebugModeOSRVolatileJitFrameIterator;
|
||||
friend void js::ReportOverRecursed(JSContext*, unsigned errorNumber);
|
||||
|
||||
// Returns to the embedding to allow other cooperative threads to run. We
|
||||
// may do this if we need access to a ZoneGroup that is in use by another
|
||||
// thread.
|
||||
void yieldToEmbedding() {
|
||||
(*yieldCallback_)(this);
|
||||
}
|
||||
|
||||
void setYieldCallback(js::YieldCallback callback) {
|
||||
yieldCallback_ = callback;
|
||||
}
|
||||
|
||||
private:
|
||||
static JS::Error reportedError;
|
||||
static JS::OOM reportedOOM;
|
||||
|
||||
// This callback is used to ask the embedding to allow other cooperative
|
||||
// threads to run. We may do this if we need access to a ZoneGroup that is
|
||||
// in use by another thread.
|
||||
js::ThreadLocalData<js::YieldCallback> yieldCallback_;
|
||||
|
||||
public:
|
||||
inline JS::Result<> boolToResult(bool ok);
|
||||
|
||||
|
@ -451,17 +451,27 @@ JSContext::runningWithTrustedPrincipals()
|
||||
}
|
||||
|
||||
inline void
|
||||
JSContext::enterCompartment(
|
||||
JSCompartment* c,
|
||||
const js::AutoLockForExclusiveAccess* maybeLock /* = nullptr */)
|
||||
JSContext::enterNonAtomsCompartment(JSCompartment* c)
|
||||
{
|
||||
enterCompartmentDepth_++;
|
||||
|
||||
if (!c->zone()->isAtomsZone())
|
||||
enterZoneGroup(c->zone()->group());
|
||||
MOZ_ASSERT(!c->zone()->isAtomsZone());
|
||||
enterZoneGroup(c->zone()->group());
|
||||
|
||||
c->enter();
|
||||
setCompartment(c, maybeLock);
|
||||
setCompartment(c, nullptr);
|
||||
}
|
||||
|
||||
inline void
|
||||
JSContext::enterAtomsCompartment(JSCompartment* c,
|
||||
const js::AutoLockForExclusiveAccess& lock)
|
||||
{
|
||||
enterCompartmentDepth_++;
|
||||
|
||||
MOZ_ASSERT(c->zone()->isAtomsZone());
|
||||
|
||||
c->enter();
|
||||
setCompartment(c, &lock);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -469,7 +479,7 @@ inline void
|
||||
JSContext::enterCompartmentOf(const T& target)
|
||||
{
|
||||
MOZ_ASSERT(JS::CellIsNotGray(target));
|
||||
enterCompartment(target->compartment(), nullptr);
|
||||
enterNonAtomsCompartment(target->compartment());
|
||||
}
|
||||
|
||||
inline void
|
||||
@ -529,7 +539,7 @@ inline void
|
||||
JSContext::enterZoneGroup(js::ZoneGroup* group)
|
||||
{
|
||||
MOZ_ASSERT(this == js::TlsContext.get());
|
||||
group->enter();
|
||||
group->enter(this);
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -1053,8 +1053,11 @@ class AutoCompartment
|
||||
JSCompartment* origin() const { return origin_; }
|
||||
|
||||
protected:
|
||||
inline AutoCompartment(JSContext* cx, JSCompartment* target);
|
||||
|
||||
// Used only for entering the atoms compartment.
|
||||
inline AutoCompartment(JSContext* cx, JSCompartment* target,
|
||||
AutoLockForExclusiveAccess* maybeLock = nullptr);
|
||||
AutoLockForExclusiveAccess& lock);
|
||||
|
||||
private:
|
||||
AutoCompartment(const AutoCompartment&) = delete;
|
||||
|
@ -44,14 +44,27 @@ js::AutoCompartment::AutoCompartment(JSContext* cx, const T& target)
|
||||
cx_->enterCompartmentOf(target);
|
||||
}
|
||||
|
||||
// Protected constructor that bypasses assertions in enterCompartmentOf.
|
||||
// Protected constructor that bypasses assertions in enterCompartmentOf. Used
|
||||
// only for entering the atoms compartment.
|
||||
js::AutoCompartment::AutoCompartment(JSContext* cx, JSCompartment* target,
|
||||
js::AutoLockForExclusiveAccess* maybeLock /* = nullptr */)
|
||||
js::AutoLockForExclusiveAccess& lock)
|
||||
: cx_(cx),
|
||||
origin_(cx->compartment()),
|
||||
maybeLock_(maybeLock)
|
||||
maybeLock_(&lock)
|
||||
{
|
||||
cx_->enterCompartment(target, maybeLock);
|
||||
MOZ_ASSERT(target->isAtomsCompartment());
|
||||
cx_->enterAtomsCompartment(target, lock);
|
||||
}
|
||||
|
||||
// Protected constructor that bypasses assertions in enterCompartmentOf. Should
|
||||
// not be used to enter the atoms compartment.
|
||||
js::AutoCompartment::AutoCompartment(JSContext* cx, JSCompartment* target)
|
||||
: cx_(cx),
|
||||
origin_(cx->compartment()),
|
||||
maybeLock_(nullptr)
|
||||
{
|
||||
MOZ_ASSERT(!target->isAtomsCompartment());
|
||||
cx_->enterNonAtomsCompartment(target);
|
||||
}
|
||||
|
||||
js::AutoCompartment::~AutoCompartment()
|
||||
@ -61,7 +74,7 @@ js::AutoCompartment::~AutoCompartment()
|
||||
|
||||
js::AutoAtomsCompartment::AutoAtomsCompartment(JSContext* cx,
|
||||
js::AutoLockForExclusiveAccess& lock)
|
||||
: AutoCompartment(cx, cx->atomsCompartment(lock), &lock)
|
||||
: AutoCompartment(cx, cx->atomsCompartment(lock), lock)
|
||||
{}
|
||||
|
||||
js::AutoCompartmentUnchecked::AutoCompartmentUnchecked(JSContext* cx, JSCompartment* target)
|
||||
|
@ -1482,3 +1482,16 @@ js::SetCompartmentValidAccessPtr(JSContext* cx, JS::HandleObject global, bool* a
|
||||
{
|
||||
global->compartment()->setValidAccessPtr(accessp);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
js::SetCooperativeYieldCallback(JSContext* cx, YieldCallback callback)
|
||||
{
|
||||
cx->setYieldCallback(callback);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::SystemZoneAvailable(JSContext* cx)
|
||||
{
|
||||
CooperatingContext& owner = cx->runtime()->gc.systemZoneGroup->ownerContext();
|
||||
return owner.context() == cx || owner.context() == nullptr;
|
||||
}
|
||||
|
@ -2963,6 +2963,20 @@ EnableAccessValidation(JSContext* cx, bool enabled);
|
||||
extern JS_FRIEND_API(void)
|
||||
SetCompartmentValidAccessPtr(JSContext* cx, JS::HandleObject global, bool* accessp);
|
||||
|
||||
// If the JS engine wants to block so that other cooperative threads can run, it
|
||||
// will call the yield callback. It may do this if it needs to access a ZoneGroup
|
||||
// that is held by another thread (such as the system zone group).
|
||||
typedef void
|
||||
(* YieldCallback)(JSContext* cx);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
SetCooperativeYieldCallback(JSContext* cx, YieldCallback callback);
|
||||
|
||||
// Returns true if the system zone is available (i.e., if no cooperative contexts
|
||||
// are using it now).
|
||||
extern JS_FRIEND_API(bool)
|
||||
SystemZoneAvailable(JSContext* cx);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
class NativeProfiler
|
||||
|
@ -6971,7 +6971,7 @@ js::NewCompartment(JSContext* cx, JSPrincipals* principals,
|
||||
|
||||
if (group) {
|
||||
// Take over ownership of the group while we create the compartment/zone.
|
||||
group->enter();
|
||||
group->enter(cx);
|
||||
} else {
|
||||
MOZ_ASSERT(!zone);
|
||||
group = cx->new_<ZoneGroup>(rt);
|
||||
@ -7042,6 +7042,7 @@ js::NewCompartment(JSContext* cx, JSPrincipals* principals,
|
||||
if (zoneSpec == JS::SystemZone || zoneSpec == JS::NewZoneInSystemZoneGroup) {
|
||||
MOZ_RELEASE_ASSERT(!rt->gc.systemZoneGroup);
|
||||
rt->gc.systemZoneGroup = group;
|
||||
group->setUseExclusiveLocking();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5313,20 +5313,39 @@ PresShell::AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
|
||||
// color background behind a scrolled transparent background. Instead,
|
||||
// we'll try to move the color background into the scrolled content
|
||||
// by making nsDisplayCanvasBackground paint it.
|
||||
if (!aFrame->GetParent()) {
|
||||
// If we're only adding an unscrolled item, then pretend that we've
|
||||
// already done it.
|
||||
bool addedScrollingBackgroundColor = (aFlags & APPEND_UNSCROLLED_ONLY);
|
||||
if (!aFrame->GetParent() && !addedScrollingBackgroundColor) {
|
||||
nsIScrollableFrame* sf =
|
||||
aFrame->PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
|
||||
if (sf) {
|
||||
nsCanvasFrame* canvasFrame = do_QueryFrame(sf->GetScrolledFrame());
|
||||
if (canvasFrame && canvasFrame->IsVisibleForPainting(&aBuilder)) {
|
||||
if (AddCanvasBackgroundColor(aList, canvasFrame, bgcolor, mHasCSSBackgroundColor))
|
||||
return;
|
||||
addedScrollingBackgroundColor =
|
||||
AddCanvasBackgroundColor(aList, canvasFrame, bgcolor, mHasCSSBackgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aList.AppendNewToBottom(
|
||||
new (&aBuilder) nsDisplaySolidColor(&aBuilder, aFrame, aBounds, bgcolor));
|
||||
// With async scrolling, we'd like to have two instances of the background
|
||||
// color: one that scrolls with the content (for the reasons stated above),
|
||||
// and one underneath which does not scroll with the content, but which can
|
||||
// be shown during checkerboarding and overscroll.
|
||||
// We can only do that if the color is opaque.
|
||||
bool forceUnscrolledItem = nsLayoutUtils::UsesAsyncScrolling(aFrame) &&
|
||||
NS_GET_A(bgcolor) == 255;
|
||||
if ((aFlags & ADD_FOR_SUBDOC) && gfxPrefs::LayoutUseContainersForRootFrames()) {
|
||||
// If we're using ContainerLayers for a subdoc, then any items we add here will
|
||||
// still be scrolled (since we're inside the container at this point), so don't
|
||||
// bother and we will do it manually later.
|
||||
forceUnscrolledItem = false;
|
||||
}
|
||||
|
||||
if (!addedScrollingBackgroundColor || forceUnscrolledItem) {
|
||||
aList.AppendNewToBottom(
|
||||
new (&aBuilder) nsDisplaySolidColor(&aBuilder, aFrame, aBounds, bgcolor));
|
||||
}
|
||||
}
|
||||
|
||||
static bool IsTransparentContainerElement(nsPresContext* aPresContext)
|
||||
|
@ -1272,9 +1272,21 @@ public:
|
||||
* canvas frame (if the FORCE_DRAW flag is passed then this check is skipped).
|
||||
* aBackstopColor is composed behind the background color of the canvas, it is
|
||||
* transparent by default.
|
||||
* We attempt to make the background color part of the scrolled canvas (to reduce
|
||||
* transparent layers), and if async scrolling is enabled (and the background
|
||||
* is opaque) then we add a second, unscrolled item to handle the checkerboarding
|
||||
* case.
|
||||
* ADD_FOR_SUBDOC shoud be specified when calling this for a subdocument, and
|
||||
* LayoutUseContainersForRootFrame might cause the whole list to be scrolled. In
|
||||
* that case the second unscrolled item will be elided.
|
||||
* APPEND_UNSCROLLED_ONLY only attempts to add the unscrolled item, so that we
|
||||
* can add it manually after LayoutUseContainersForRootFrame has built the
|
||||
* scrolling ContainerLayer.
|
||||
*/
|
||||
enum {
|
||||
FORCE_DRAW = 0x01
|
||||
FORCE_DRAW = 0x01,
|
||||
ADD_FOR_SUBDOC = 0x02,
|
||||
APPEND_UNSCROLLED_ONLY = 0x04,
|
||||
};
|
||||
virtual void AddCanvasBackgroundColorItem(nsDisplayListBuilder& aBuilder,
|
||||
nsDisplayList& aList,
|
||||
|
@ -494,7 +494,7 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
// Add the canvas background color to the bottom of the list. This
|
||||
// happens after we've built the list so that AddCanvasBackgroundColorItem
|
||||
// can monkey with the contents if necessary.
|
||||
uint32_t flags = nsIPresShell::FORCE_DRAW;
|
||||
uint32_t flags = nsIPresShell::FORCE_DRAW | nsIPresShell::ADD_FOR_SUBDOC;
|
||||
presShell->AddCanvasBackgroundColorItem(
|
||||
*aBuilder, childItems, frame, bounds, NS_RGBA(0,0,0,0), flags);
|
||||
}
|
||||
@ -548,6 +548,29 @@ nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
childItems.AppendToTop(layerItem);
|
||||
}
|
||||
|
||||
// If we're using containers for root frames, then the earlier call
|
||||
// to AddCanvasBackgroundColorItem won't have been able to add an
|
||||
// unscrolled color item for overscroll. Try again now that we're
|
||||
// outside the scrolled ContainerLayer.
|
||||
if (!aBuilder->IsForEventDelivery() &&
|
||||
gfxPrefs::LayoutUseContainersForRootFrames() &&
|
||||
!nsLayoutUtils::NeedsPrintPreviewBackground(presContext)) {
|
||||
nsRect bounds = GetContentRectRelativeToSelf() +
|
||||
aBuilder->ToReferenceFrame(this);
|
||||
|
||||
// Invoke AutoBuildingDisplayList to ensure that the correct dirty rect
|
||||
// is used to compute the visible rect if AddCanvasBackgroundColorItem
|
||||
// creates a display item.
|
||||
nsDisplayListBuilder::AutoBuildingDisplayList
|
||||
building(aBuilder, this, dirty, true);
|
||||
// Add the canvas background color to the bottom of the list. This
|
||||
// happens after we've built the list so that AddCanvasBackgroundColorItem
|
||||
// can monkey with the contents if necessary.
|
||||
uint32_t flags = nsIPresShell::FORCE_DRAW | nsIPresShell::APPEND_UNSCROLLED_ONLY;
|
||||
presShell->AddCanvasBackgroundColorItem(
|
||||
*aBuilder, childItems, this, bounds, NS_RGBA(0,0,0,0), flags);
|
||||
}
|
||||
|
||||
if (aBuilder->IsForFrameVisibility()) {
|
||||
// We don't add the childItems to the return list as we're dealing with them here.
|
||||
presShell->RebuildApproximateFrameVisibilityDisplayList(childItems);
|
||||
|
@ -660,10 +660,6 @@ public:
|
||||
* in mItemClip).
|
||||
*/
|
||||
void UpdateCommonClipCount(const DisplayItemClip& aCurrentClip);
|
||||
/**
|
||||
* The union of all the bounds of the display items in this layer.
|
||||
*/
|
||||
nsIntRect mBounds;
|
||||
/**
|
||||
* The region of visible content above the layer and below the
|
||||
* next PaintedLayerData currently in the stack, if any.
|
||||
@ -1329,6 +1325,7 @@ protected:
|
||||
*/
|
||||
nsIntRegion ComputeOpaqueRect(nsDisplayItem* aItem,
|
||||
AnimatedGeometryRoot* aAnimatedGeometryRoot,
|
||||
const ActiveScrolledRoot* aASR,
|
||||
const DisplayItemClip& aClip,
|
||||
nsDisplayList* aList,
|
||||
bool* aHideAllLayersBelow,
|
||||
@ -3241,10 +3238,6 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
|
||||
SetOuterVisibleRegionForLayer(layer, data->mVisibleRegion);
|
||||
}
|
||||
|
||||
nsIntRect layerBounds = data->mBounds;
|
||||
layerBounds.MoveBy(-GetTranslationForPaintedLayer(data->mLayer));
|
||||
layer->SetLayerBounds(layerBounds);
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (!data->mLog.IsEmpty()) {
|
||||
if (PaintedLayerData* containingPld = mLayerBuilder->GetContainingPaintedLayerData()) {
|
||||
@ -3441,10 +3434,6 @@ PaintedLayerData::Accumulate(ContainerState* aState,
|
||||
{
|
||||
FLB_LOG_PAINTED_LAYER_DECISION(this, "Accumulating dp=%s(%p), f=%p against pld=%p\n", aItem->Name(), aItem, aItem->Frame(), this);
|
||||
|
||||
bool snap;
|
||||
nsRect itemBounds = aItem->GetBounds(aState->mBuilder, &snap);
|
||||
mBounds = mBounds.Union(aState->ScaleToOutsidePixels(itemBounds, snap));
|
||||
|
||||
if (aState->mBuilder->NeedToForceTransparentSurfaceForItem(aItem)) {
|
||||
mForceTransparentSurface = true;
|
||||
}
|
||||
@ -3766,7 +3755,7 @@ ContainerState::GetDisplayPortForAnimatedGeometryRoot(AnimatedGeometryRoot* aAni
|
||||
mLastDisplayPortAGR = aAnimatedGeometryRoot;
|
||||
|
||||
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
|
||||
if (sf == nullptr) {
|
||||
if (sf == nullptr || nsLayoutUtils::UsesAsyncScrolling(*aAnimatedGeometryRoot)) {
|
||||
mLastDisplayPortRect = nsRect();
|
||||
return mLastDisplayPortRect;
|
||||
}
|
||||
@ -3787,6 +3776,7 @@ ContainerState::GetDisplayPortForAnimatedGeometryRoot(AnimatedGeometryRoot* aAni
|
||||
nsIntRegion
|
||||
ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
|
||||
AnimatedGeometryRoot* aAnimatedGeometryRoot,
|
||||
const ActiveScrolledRoot* aASR,
|
||||
const DisplayItemClip& aClip,
|
||||
nsDisplayList* aList,
|
||||
bool* aHideAllLayersBelow,
|
||||
@ -3805,6 +3795,7 @@ ContainerState::ComputeOpaqueRect(nsDisplayItem* aItem,
|
||||
aClip.ApproximateIntersectInward(iter.Get()));
|
||||
}
|
||||
if (aAnimatedGeometryRoot == mContainerAnimatedGeometryRoot &&
|
||||
aASR == mContainerASR &&
|
||||
opaqueClipped.Contains(mContainerBounds)) {
|
||||
*aHideAllLayersBelow = true;
|
||||
aList->SetIsOpaque();
|
||||
@ -4389,7 +4380,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
newLayerEntry->mVisibleRegion = itemVisibleRegion;
|
||||
}
|
||||
newLayerEntry->mOpaqueRegion = ComputeOpaqueRect(item,
|
||||
animatedGeometryRoot, itemClip, aList,
|
||||
animatedGeometryRoot, itemASR, itemClip, aList,
|
||||
&newLayerEntry->mHideAllLayersBelow,
|
||||
&newLayerEntry->mOpaqueForAnimatedGeometryRootParent);
|
||||
} else {
|
||||
@ -4445,7 +4436,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
||||
paintedLayerData->UpdateCommonClipCount(itemClip);
|
||||
}
|
||||
nsIntRegion opaquePixels = ComputeOpaqueRect(item,
|
||||
animatedGeometryRoot, itemClip, aList,
|
||||
animatedGeometryRoot, itemASR, itemClip, aList,
|
||||
&paintedLayerData->mHideAllLayersBelow,
|
||||
&paintedLayerData->mOpaqueForAnimatedGeometryRootParent);
|
||||
MOZ_ASSERT(nsIntRegion(itemDrawRect).Contains(opaquePixels));
|
||||
@ -4928,16 +4919,19 @@ ContainerState::CollectOldLayers()
|
||||
|
||||
struct OpaqueRegionEntry {
|
||||
AnimatedGeometryRoot* mAnimatedGeometryRoot;
|
||||
const ActiveScrolledRoot* mASR;
|
||||
nsIntRegion mOpaqueRegion;
|
||||
};
|
||||
|
||||
static OpaqueRegionEntry*
|
||||
FindOpaqueRegionEntry(nsTArray<OpaqueRegionEntry>& aEntries,
|
||||
AnimatedGeometryRoot* aAnimatedGeometryRoot)
|
||||
AnimatedGeometryRoot* aAnimatedGeometryRoot,
|
||||
const ActiveScrolledRoot* aASR)
|
||||
{
|
||||
for (uint32_t i = 0; i < aEntries.Length(); ++i) {
|
||||
OpaqueRegionEntry* d = &aEntries[i];
|
||||
if (d->mAnimatedGeometryRoot == aAnimatedGeometryRoot) {
|
||||
if (d->mAnimatedGeometryRoot == aAnimatedGeometryRoot &&
|
||||
d->mASR == aASR) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
@ -5167,7 +5161,7 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
|
||||
continue;
|
||||
}
|
||||
|
||||
OpaqueRegionEntry* data = FindOpaqueRegionEntry(opaqueRegions, e->mAnimatedGeometryRoot);
|
||||
OpaqueRegionEntry* data = FindOpaqueRegionEntry(opaqueRegions, e->mAnimatedGeometryRoot, e->mASR);
|
||||
|
||||
SetupScrollingMetadata(e);
|
||||
|
||||
@ -5190,19 +5184,23 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer
|
||||
|
||||
if (!e->mOpaqueRegion.IsEmpty()) {
|
||||
AnimatedGeometryRoot* animatedGeometryRootToCover = e->mAnimatedGeometryRoot;
|
||||
const ActiveScrolledRoot* asrToCover = e->mASR;
|
||||
if (e->mOpaqueForAnimatedGeometryRootParent &&
|
||||
e->mAnimatedGeometryRoot->mParentAGR == mContainerAnimatedGeometryRoot) {
|
||||
animatedGeometryRootToCover = mContainerAnimatedGeometryRoot;
|
||||
data = FindOpaqueRegionEntry(opaqueRegions, animatedGeometryRootToCover);
|
||||
asrToCover = mContainerASR;
|
||||
data = FindOpaqueRegionEntry(opaqueRegions, animatedGeometryRootToCover, asrToCover);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (animatedGeometryRootToCover == mContainerAnimatedGeometryRoot) {
|
||||
if (animatedGeometryRootToCover == mContainerAnimatedGeometryRoot &&
|
||||
asrToCover == mContainerASR) {
|
||||
NS_ASSERTION(opaqueRegionForContainer == -1, "Already found it?");
|
||||
opaqueRegionForContainer = opaqueRegions.Length();
|
||||
}
|
||||
data = opaqueRegions.AppendElement();
|
||||
data->mAnimatedGeometryRoot = animatedGeometryRootToCover;
|
||||
data->mASR = asrToCover;
|
||||
}
|
||||
|
||||
nsIntRegion clippedOpaque = e->mOpaqueRegion;
|
||||
|
@ -1,6 +1,7 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body style="background-color: green; overflow:hidden">
|
||||
<div style="position:fixed; left: 0px; top: 0px; width: 100px; height: 500px; background-color: purple; z-index: -1"></div>
|
||||
<div style="position:absolute; left: 0px; top: 0px; background-color: yellow; width: 100px; height: 200px"></div>
|
||||
<div style="position:fixed; left: 10px; top: 10px; width: 10px; height: 10px; background-color: blue"></div>
|
||||
</body>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<body style="background-color: green; overflow:hidden">
|
||||
<div style="position:fixed; left: 0px; top: 0px; width: 100px; height: 500px; background-color: purple; z-index: -1"></div>
|
||||
<div style="position:fixed; left: 10px; top: 10px; width: 10px; height: 10px; background-color: blue"></div>
|
||||
</body>
|
||||
|
@ -8764,6 +8764,10 @@ CSSParserImpl::ParseGridTrackSize(nsCSSValue& aValue,
|
||||
return CSSParseResult::NotFound;
|
||||
}
|
||||
if (mToken.mIdent.LowerCaseEqualsLiteral("fit-content")) {
|
||||
if (requireFixedSize) {
|
||||
UngetToken();
|
||||
return CSSParseResult::Error;
|
||||
}
|
||||
nsCSSValue::Array* func = aValue.InitFunction(eCSSKeyword_fit_content, 1);
|
||||
if (ParseGridTrackBreadth(func->Item(1)) == CSSParseResult::Ok &&
|
||||
func->Item(1).IsLengthPercentCalcUnit() &&
|
||||
|
@ -6238,6 +6238,7 @@ if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) {
|
||||
"repeat(auto-fill,minmax(1%,auto))",
|
||||
"repeat(auto-fill,minmax(1em,min-content)) minmax(min-content,0)",
|
||||
"repeat(auto-fill,minmax(max-content,1mm))",
|
||||
"repeat(2, fit-content(1px))",
|
||||
"fit-content(1px) 1fr",
|
||||
"[a] fit-content(calc(1px - 99%)) [b]",
|
||||
"[a] fit-content(10%) [b c] fit-content(1em)",
|
||||
@ -6282,6 +6283,8 @@ if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) {
|
||||
"repeat(1, repeat(1, 20px))",
|
||||
"repeat(auto-fill, auto)",
|
||||
"repeat(auto-fit,auto)",
|
||||
"repeat(auto-fill, fit-content(1px))",
|
||||
"repeat(auto-fit, fit-content(1px))",
|
||||
"repeat(auto-fit,[])",
|
||||
"repeat(auto-fill, 0) repeat(auto-fit, 0) ",
|
||||
"repeat(auto-fit, 0) repeat(auto-fill, 0) ",
|
||||
@ -6303,6 +6306,8 @@ if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) {
|
||||
"fit-content(-1px)",
|
||||
"fit-content(auto)",
|
||||
"fit-content(min-content)",
|
||||
"fit-content(1px) repeat(auto-fit, 1px)",
|
||||
"fit-content(1px) repeat(auto-fill, 1px)",
|
||||
],
|
||||
unbalanced_values: [
|
||||
"(foo] 40px",
|
||||
|
@ -23,7 +23,7 @@
|
||||
* all the columns). However, multiple levels of groups are allowed, so
|
||||
* the parent or child could instead be another group.
|
||||
*/
|
||||
class nsGridRowGroupFrame : public nsBoxFrame
|
||||
class nsGridRowGroupFrame final : public nsBoxFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
@ -2001,7 +2001,8 @@ nsBoxFrame::XULRelayoutChildAtOrdinal(nsIFrame* aChild)
|
||||
// REVIEW: This is roughly of what nsMenuFrame::GetFrameForPoint used to do.
|
||||
// I've made 'allowevents' affect child elements because that seems the only
|
||||
// reasonable thing to do.
|
||||
class nsDisplayXULEventRedirector : public nsDisplayWrapList {
|
||||
class nsDisplayXULEventRedirector final : public nsDisplayWrapList
|
||||
{
|
||||
public:
|
||||
nsDisplayXULEventRedirector(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, nsDisplayItem* aItem,
|
||||
@ -2053,7 +2054,7 @@ void nsDisplayXULEventRedirector::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
}
|
||||
|
||||
class nsXULEventRedirectorWrapper : public nsDisplayWrapper
|
||||
class nsXULEventRedirectorWrapper final : public nsDisplayWrapper
|
||||
{
|
||||
public:
|
||||
explicit nsXULEventRedirectorWrapper(nsIFrame* aTargetFrame)
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsBoxFrame.h"
|
||||
|
||||
class nsDeckFrame : public nsBoxFrame
|
||||
class nsDeckFrame final : public nsBoxFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_QUERYFRAME_TARGET(nsDeckFrame)
|
||||
|
@ -26,8 +26,8 @@
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
class nsDocElementBoxFrame : public nsBoxFrame,
|
||||
public nsIAnonymousContentCreator
|
||||
class nsDocElementBoxFrame final : public nsBoxFrame
|
||||
, public nsIAnonymousContentCreator
|
||||
{
|
||||
public:
|
||||
virtual void DestroyFrom(nsIFrame* aDestructRoot) override;
|
||||
|
@ -18,7 +18,8 @@ using namespace mozilla;
|
||||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::image;
|
||||
|
||||
class nsGroupBoxFrame : public nsBoxFrame {
|
||||
class nsGroupBoxFrame final : public nsBoxFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
||||
@ -83,7 +84,8 @@ NS_NewGroupBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
|
||||
|
||||
NS_IMPL_FRAMEARENA_HELPERS(nsGroupBoxFrame)
|
||||
|
||||
class nsDisplayXULGroupBorder : public nsDisplayItem {
|
||||
class nsDisplayXULGroupBorder final : public nsDisplayItem
|
||||
{
|
||||
public:
|
||||
nsDisplayXULGroupBorder(nsDisplayListBuilder* aBuilder,
|
||||
nsGroupBoxFrame* aFrame) :
|
||||
|
@ -126,7 +126,8 @@ private:
|
||||
bool mSuppressStyleCheck;
|
||||
}; // class nsImageBoxFrame
|
||||
|
||||
class nsDisplayXULImage : public nsDisplayImageContainer {
|
||||
class nsDisplayXULImage final : public nsDisplayImageContainer
|
||||
{
|
||||
public:
|
||||
nsDisplayXULImage(nsDisplayListBuilder* aBuilder,
|
||||
nsImageBoxFrame* aFrame) :
|
||||
|
@ -13,7 +13,7 @@ class nsIFrame;
|
||||
typedef class nsIFrame nsIFrame;
|
||||
class nsBoxLayoutState;
|
||||
|
||||
class nsListBoxLayout : public nsGridRowGroupLayout
|
||||
class nsListBoxLayout final : public nsGridRowGroupLayout
|
||||
{
|
||||
public:
|
||||
nsListBoxLayout();
|
||||
|
@ -9,7 +9,7 @@
|
||||
nsIFrame* NS_NewListItemFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext *aContext);
|
||||
|
||||
class nsListItemFrame : public nsGridRowLeafFrame
|
||||
class nsListItemFrame final : public nsGridRowLeafFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
class nsIBaseWindow;
|
||||
|
||||
class nsResizerFrame : public nsTitleBarFrame
|
||||
class nsResizerFrame final : public nsTitleBarFrame
|
||||
{
|
||||
protected:
|
||||
struct Direction {
|
||||
|
@ -41,7 +41,8 @@ nsIRootBox::GetRootBox(nsIPresShell* aShell)
|
||||
return rootBox;
|
||||
}
|
||||
|
||||
class nsRootBoxFrame : public nsBoxFrame, public nsIRootBox {
|
||||
class nsRootBoxFrame final : public nsBoxFrame, public nsIRootBox
|
||||
{
|
||||
public:
|
||||
|
||||
friend nsIFrame* NS_NewBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
class nsAutoRepeatBoxFrame : public nsButtonBoxFrame
|
||||
class nsAutoRepeatBoxFrame final : public nsButtonBoxFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "nsITimer.h"
|
||||
#include "nsRepeatService.h"
|
||||
|
||||
class nsScrollbarButtonFrame : public nsButtonBoxFrame
|
||||
class nsScrollbarButtonFrame final : public nsButtonBoxFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
@ -17,7 +17,7 @@ class nsIScrollbarMediator;
|
||||
|
||||
nsIFrame* NS_NewScrollbarFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
||||
class nsScrollbarFrame : public nsBoxFrame
|
||||
class nsScrollbarFrame final : public nsBoxFrame
|
||||
{
|
||||
public:
|
||||
explicit nsScrollbarFrame(nsStyleContext* aContext)
|
||||
|
@ -18,7 +18,7 @@ class nsSplitterFrameInner;
|
||||
|
||||
nsIFrame* NS_NewSplitterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
|
||||
class nsSplitterFrame : public nsBoxFrame
|
||||
class nsSplitterFrame final : public nsBoxFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsBoxFrame.h"
|
||||
|
||||
class nsStackFrame : public nsBoxFrame
|
||||
class nsStackFrame final : public nsBoxFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
@ -277,7 +277,8 @@ nsTextBoxFrame::UpdateAttributes(nsIAtom* aAttribute,
|
||||
|
||||
}
|
||||
|
||||
class nsDisplayXULTextBox : public nsDisplayItem {
|
||||
class nsDisplayXULTextBox final : public nsDisplayItem
|
||||
{
|
||||
public:
|
||||
nsDisplayXULTextBox(nsDisplayListBuilder* aBuilder,
|
||||
nsTextBoxFrame* aFrame) :
|
||||
|
@ -12,7 +12,7 @@ class nsAccessKeyInfo;
|
||||
class nsAsyncAccesskeyUpdate;
|
||||
class nsFontMetrics;
|
||||
|
||||
class nsTextBoxFrame : public nsLeafBoxFrame
|
||||
class nsTextBoxFrame final : public nsLeafBoxFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_QUERYFRAME_TARGET(nsTextBoxFrame)
|
||||
|
@ -15,7 +15,7 @@
|
||||
#error "This file should not be included"
|
||||
#endif
|
||||
|
||||
class nsXULLabelFrame : public nsBlockFrame
|
||||
class nsXULLabelFrame final : public nsBlockFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
@ -53,7 +53,8 @@ nsTreeColFrame::DestroyFrom(nsIFrame* aDestructRoot)
|
||||
nsBoxFrame::DestroyFrom(aDestructRoot);
|
||||
}
|
||||
|
||||
class nsDisplayXULTreeColSplitterTarget : public nsDisplayItem {
|
||||
class nsDisplayXULTreeColSplitterTarget final : public nsDisplayItem
|
||||
{
|
||||
public:
|
||||
nsDisplayXULTreeColSplitterTarget(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame) :
|
||||
|
@ -11,7 +11,7 @@ class nsITreeBoxObject;
|
||||
nsIFrame* NS_NewTreeColFrame(nsIPresShell* aPresShell,
|
||||
nsStyleContext* aContext);
|
||||
|
||||
class nsTreeColFrame : public nsBoxFrame
|
||||
class nsTreeColFrame final : public nsBoxFrame
|
||||
{
|
||||
public:
|
||||
NS_DECL_FRAMEARENA_HELPERS
|
||||
|
@ -1253,7 +1253,7 @@ pref("dom.input.dirpicker", false);
|
||||
|
||||
// Enable not moving the cursor to end when a text input or textarea has .value
|
||||
// set to the value it already has. By default, enabled.
|
||||
pref("dom.input.skip_cursor_move_for_same_value_set", false);
|
||||
pref("dom.input.skip_cursor_move_for_same_value_set", true);
|
||||
|
||||
// Enables system messages and activities
|
||||
pref("dom.sysmsg.enabled", false);
|
||||
|
@ -233,6 +233,8 @@ static const DllBlockInfo sWindowsDllBlocklist[] = {
|
||||
// Crashes with Internet Download Manager, bug 1333486
|
||||
{ "idmcchandler7.dll", ALL_VERSIONS },
|
||||
{ "idmcchandler7_64.dll", ALL_VERSIONS },
|
||||
{ "idmcchandler5.dll", ALL_VERSIONS },
|
||||
{ "idmcchandler5_64.dll", ALL_VERSIONS },
|
||||
|
||||
// Nahimic 2 breaks applicaton update (bug 1356637)
|
||||
{ "nahimic2devprops.dll", ALL_VERSIONS },
|
||||
|
@ -10435,6 +10435,20 @@
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"description": "Graphics Crash Reason (...)"
|
||||
},
|
||||
"APZ_AWARE_KEY_LISTENERS": {
|
||||
"alert_emails": ["rhunt@mozilla.com"],
|
||||
"bug_numbers": [1352654],
|
||||
"expires_in_version": "58",
|
||||
"kind": "boolean",
|
||||
"description": "The percentage of pages with a non-passive key event on the path to the root scrolling element that would disable APZ key scrolling. This is tracked for non system principal windows, so it applies to toplevel windows and subframes/iframes, but not chrome windows. "
|
||||
},
|
||||
"APZ_AWARE_MOUSEMOVE_LISTENERS": {
|
||||
"alert_emails": ["rhunt@mozilla.com"],
|
||||
"bug_numbers": [1352654],
|
||||
"expires_in_version": "58",
|
||||
"kind": "boolean",
|
||||
"description": "The percentage of pages with a mousemove listener anywhere in the document that would disable APZ key scrolling. This is tracked for non system principal windows, so it applies to toplevel windows and subframes/iframes, but not chrome windows."
|
||||
},
|
||||
"SCROLL_INPUT_METHODS": {
|
||||
"alert_emails": ["botond@mozilla.com"],
|
||||
"bug_numbers": [1238137],
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/prctl.h> // set name
|
||||
#include <stdlib.h>
|
||||
#include <sched.h>
|
||||
#include <ucontext.h>
|
||||
@ -273,7 +272,6 @@ static void*
|
||||
ThreadEntry(void* aArg)
|
||||
{
|
||||
auto thread = static_cast<SamplerThread*>(aArg);
|
||||
prctl(PR_SET_NAME, "SamplerThread", 0, 0, 0);
|
||||
thread->mSamplerTid = gettid();
|
||||
thread->Run();
|
||||
return nullptr;
|
||||
|
@ -4,11 +4,9 @@
|
||||
* 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 <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/getsect.h>
|
||||
|
||||
#include <AvailabilityMacros.h>
|
||||
@ -78,25 +76,10 @@ private:
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// BEGIN SamplerThread target specifics
|
||||
|
||||
static void
|
||||
SetThreadName()
|
||||
{
|
||||
// pthread_setname_np is only available in 10.6 or later, so test
|
||||
// for it at runtime.
|
||||
int (*dynamic_pthread_setname_np)(const char*);
|
||||
*reinterpret_cast<void**>(&dynamic_pthread_setname_np) =
|
||||
dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||
if (!dynamic_pthread_setname_np)
|
||||
return;
|
||||
|
||||
dynamic_pthread_setname_np("SamplerThread");
|
||||
}
|
||||
|
||||
static void*
|
||||
ThreadEntry(void* aArg)
|
||||
{
|
||||
auto thread = static_cast<SamplerThread*>(aArg);
|
||||
SetThreadName();
|
||||
thread->Run();
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1774,6 +1774,8 @@ NewSamplerThread(PSLockRef aLock, uint32_t aGeneration, double aInterval)
|
||||
void
|
||||
SamplerThread::Run()
|
||||
{
|
||||
PR_SetCurrentThreadName("SamplerThread");
|
||||
|
||||
// This will be positive if we are running behind schedule (sampling less
|
||||
// frequently than desired) and negative if we are ahead of schedule.
|
||||
TimeDuration lastSleepOvershoot = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user