зеркало из https://github.com/mozilla/gecko-dev.git
Bug 876321. Track restyling of top/left/right/bottom and treat such nodes as active scrolled roots. r=mattwoodrow
--HG-- extra : rebase_source : 24e7900efdb476a0533808956b9604d144e4db89
This commit is contained in:
Родитель
cdd20f889b
Коммит
8cf17406d8
|
@ -38,6 +38,10 @@ public:
|
|||
switch (aProperty) {
|
||||
case eCSSProperty_opacity: return mOpacityRestyleCount;
|
||||
case eCSSProperty_transform: return mTransformRestyleCount;
|
||||
case eCSSProperty_left: return mLeftRestyleCount;
|
||||
case eCSSProperty_top: return mTopRestyleCount;
|
||||
case eCSSProperty_right: return mRightRestyleCount;
|
||||
case eCSSProperty_bottom: return mBottomRestyleCount;
|
||||
default: MOZ_ASSERT(false); return mOpacityRestyleCount;
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +51,10 @@ public:
|
|||
// Number of restyle operations detected
|
||||
uint8_t mOpacityRestyleCount;
|
||||
uint8_t mTransformRestyleCount;
|
||||
uint8_t mLeftRestyleCount;
|
||||
uint8_t mTopRestyleCount;
|
||||
uint8_t mRightRestyleCount;
|
||||
uint8_t mBottomRestyleCount;
|
||||
bool mContentActive;
|
||||
};
|
||||
|
||||
|
@ -78,6 +86,7 @@ static void DestroyLayerActivity(void* aPropertyValue)
|
|||
delete static_cast<LayerActivity*>(aPropertyValue);
|
||||
}
|
||||
|
||||
// Frames with this property have NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY set
|
||||
NS_DECLARE_FRAME_PROPERTY(LayerActivityProperty, DestroyLayerActivity)
|
||||
|
||||
void
|
||||
|
@ -89,12 +98,16 @@ LayerActivityTracker::NotifyExpired(LayerActivity* aObject)
|
|||
aObject->mFrame = nullptr;
|
||||
|
||||
f->SchedulePaint();
|
||||
f->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
|
||||
f->Properties().Delete(LayerActivityProperty());
|
||||
}
|
||||
|
||||
static LayerActivity*
|
||||
GetLayerActivity(nsIFrame* aFrame)
|
||||
{
|
||||
if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) {
|
||||
return nullptr;
|
||||
}
|
||||
FrameProperties properties = aFrame->Properties();
|
||||
return static_cast<LayerActivity*>(properties.Get(LayerActivityProperty()));
|
||||
}
|
||||
|
@ -113,17 +126,34 @@ GetLayerActivityForUpdate(nsIFrame* aFrame)
|
|||
}
|
||||
layerActivity = new LayerActivity(aFrame);
|
||||
gLayerActivityTracker->AddObject(layerActivity);
|
||||
aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
|
||||
properties.Set(LayerActivityProperty(), layerActivity);
|
||||
}
|
||||
return layerActivity;
|
||||
}
|
||||
|
||||
static void
|
||||
IncrementMutationCount(uint8_t* aCount)
|
||||
{
|
||||
*aCount = uint8_t(std::min(0xFF, *aCount + 1));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ActiveLayerTracker::NotifyRestyle(nsIFrame* aFrame, nsCSSProperty aProperty)
|
||||
{
|
||||
LayerActivity* layerActivity = GetLayerActivityForUpdate(aFrame);
|
||||
uint8_t& mutationCount = layerActivity->RestyleCountForProperty(aProperty);
|
||||
mutationCount = uint8_t(std::min(0xFF, mutationCount + 1));
|
||||
IncrementMutationCount(&mutationCount);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ActiveLayerTracker::NotifyOffsetRestyle(nsIFrame* aFrame)
|
||||
{
|
||||
LayerActivity* layerActivity = GetLayerActivityForUpdate(aFrame);
|
||||
IncrementMutationCount(&layerActivity->mLeftRestyleCount);
|
||||
IncrementMutationCount(&layerActivity->mTopRestyleCount);
|
||||
IncrementMutationCount(&layerActivity->mRightRestyleCount);
|
||||
IncrementMutationCount(&layerActivity->mBottomRestyleCount);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
@ -172,6 +202,21 @@ ActiveLayerTracker::IsStyleAnimated(nsIFrame* aFrame, nsCSSProperty aProperty)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
ActiveLayerTracker::IsOffsetStyleAnimated(nsIFrame* aFrame)
|
||||
{
|
||||
LayerActivity* layerActivity = GetLayerActivity(aFrame);
|
||||
if (layerActivity) {
|
||||
if (layerActivity->mLeftRestyleCount >= 2 ||
|
||||
layerActivity->mTopRestyleCount >= 2 ||
|
||||
layerActivity->mRightRestyleCount >= 2 ||
|
||||
layerActivity->mBottomRestyleCount >= 2) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
ActiveLayerTracker::NotifyContentChange(nsIFrame* aFrame)
|
||||
{
|
||||
|
|
|
@ -22,7 +22,10 @@ public:
|
|||
static void Shutdown();
|
||||
|
||||
/*
|
||||
* We track eCSSProperty_transform and eCSSProperty_opacity style changes
|
||||
* We track style changes to selected styles:
|
||||
* eCSSProperty_transform
|
||||
* eCSSProperty_opacity
|
||||
* eCSSProperty_left, eCSSProperty_top, eCSSProperty_right, eCSSProperty_bottom
|
||||
* and use that information to guess whether style changes are animated.
|
||||
*/
|
||||
|
||||
|
@ -33,6 +36,12 @@ public:
|
|||
* @param aProperty the property that has changed
|
||||
*/
|
||||
static void NotifyRestyle(nsIFrame* aFrame, nsCSSProperty aProperty);
|
||||
/**
|
||||
* Notify aFrame's left/top/right/bottom properties as having (maybe)
|
||||
* changed due to a restyle, and therefore possibly wanting an active layer
|
||||
* to render that style. Any such marking will time out after a short period.
|
||||
*/
|
||||
static void NotifyOffsetRestyle(nsIFrame* aFrame);
|
||||
/**
|
||||
* Mark aFrame as being known to have an animation of aProperty.
|
||||
* Any such marking will time out after a short period.
|
||||
|
@ -50,6 +59,11 @@ public:
|
|||
* for constructing active layers.
|
||||
*/
|
||||
static bool IsStyleAnimated(nsIFrame* aFrame, nsCSSProperty aProperty);
|
||||
/**
|
||||
* Return true if any of aFrame's offset property styles should be considered
|
||||
* as being animated for constructing active layers.
|
||||
*/
|
||||
static bool IsOffsetStyleAnimated(nsIFrame* aFrame);
|
||||
|
||||
/*
|
||||
* We track modifications to the content of certain frames (i.e. canvas frames)
|
||||
|
|
|
@ -693,6 +693,7 @@ RestyleManager::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
|
|||
ApplyRenderingChangeToTree(mPresContext, frame, hint);
|
||||
}
|
||||
if ((hint & nsChangeHint_RecomputePosition) && !didReflowThisFrame) {
|
||||
ActiveLayerTracker::NotifyOffsetRestyle(frame);
|
||||
// It is possible for this to fall back to a reflow
|
||||
if (!RecomputePosition(frame)) {
|
||||
didReflowThisFrame = true;
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include "nsIFrameInlines.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "ActiveLayerTracker.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
|
@ -1206,6 +1207,8 @@ nsLayoutUtils::GetActiveScrolledRootFor(nsIFrame* aFrame,
|
|||
while (f != aStopAtAncestor) {
|
||||
if (IsPopup(f))
|
||||
break;
|
||||
if (ActiveLayerTracker::IsOffsetStyleAnimated(f))
|
||||
break;
|
||||
nsIFrame* parent = GetCrossDocParentFrame(f);
|
||||
if (!parent)
|
||||
break;
|
||||
|
|
|
@ -327,6 +327,9 @@ typedef uint64_t nsFrameState;
|
|||
// <defs> element or an SVG resource element (<mask>, <pattern>, etc.)
|
||||
#define NS_FRAME_IS_NONDISPLAY NS_FRAME_STATE_BIT(53)
|
||||
|
||||
// Frame has a LayerActivityProperty property
|
||||
#define NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY NS_FRAME_STATE_BIT(54)
|
||||
|
||||
// Box layout bits
|
||||
#define NS_STATE_IS_HORIZONTAL NS_FRAME_STATE_BIT(22)
|
||||
#define NS_STATE_IS_DIRECTION_NORMAL NS_FRAME_STATE_BIT(31)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-right-bottom.html move-right-bottom-ref.html # Bug 742176
|
||||
random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-top-left.html move-top-left-ref.html # Bug 688545, bug 742176
|
||||
random-if(cocoaWidget) fuzzy-if(d2d,85,80) == move-right-bottom.html move-right-bottom-ref.html # Bug 742176
|
||||
random-if(cocoaWidget) fuzzy-if(d2d,85,80) == move-top-left.html move-top-left-ref.html # Bug 688545, bug 742176
|
||||
random-if(cocoaWidget) fuzzy-if(d2d,85,80) == move-right-bottom-table.html move-right-bottom-table-ref.html # Bug 742176
|
||||
random-if(cocoaWidget) fuzzy-if(d2d,85,80) == move-top-left-table.html move-top-left-table-ref.html # Bug 688545, bug 742176
|
||||
== percent.html percent-ref.html
|
||||
|
|
|
@ -178,7 +178,9 @@ nsDOMCSSAttributeDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
|
|||
// Scripted modifications to style.opacity or style.transform
|
||||
// could immediately force us into the animated state if heuristics suggest
|
||||
// this is scripted animation.
|
||||
if (aPropID == eCSSProperty_opacity || aPropID == eCSSProperty_transform) {
|
||||
if (aPropID == eCSSProperty_opacity || aPropID == eCSSProperty_transform ||
|
||||
aPropID == eCSSProperty_left || aPropID == eCSSProperty_top ||
|
||||
aPropID == eCSSProperty_right || aPropID == eCSSProperty_bottom) {
|
||||
nsIFrame* frame = mElement->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
ActiveLayerTracker::NotifyInlineStyleRuleModified(frame, aPropID);
|
||||
|
|
Загрузка…
Ссылка в новой задаче