зеркало из https://github.com/mozilla/pjs.git
Bug 642246 Don't build ThebesLayers for elements with no displayports r=roc
This commit is contained in:
Родитель
8bdf42ec06
Коммит
885567bc0f
|
@ -762,6 +762,12 @@ public:
|
|||
*/
|
||||
virtual ThebesLayer* AsThebesLayer() { return nsnull; }
|
||||
|
||||
/**
|
||||
* Dynamic cast to a ContainerLayer. Returns null if this is not
|
||||
* a ContainerLayer.
|
||||
*/
|
||||
virtual ContainerLayer* AsContainerLayer() { return nsnull; }
|
||||
|
||||
/**
|
||||
* Dynamic cast to a ShadowLayer. Return null if this is not a
|
||||
* ShadowLayer. Can be used anytime.
|
||||
|
@ -1029,6 +1035,8 @@ public:
|
|||
|
||||
// These getters can be used anytime.
|
||||
|
||||
virtual ContainerLayer* AsContainerLayer() { return this; }
|
||||
|
||||
virtual Layer* GetFirstChild() { return mFirstChild; }
|
||||
virtual Layer* GetLastChild() { return mLastChild; }
|
||||
const FrameMetrics& GetFrameMetrics() { return mFrameMetrics; }
|
||||
|
|
|
@ -59,7 +59,9 @@ enum LayerState {
|
|||
LAYER_ACTIVE,
|
||||
// Force an active layer even if it causes incorrect rendering, e.g.
|
||||
// when the layer has rounded rect clips.
|
||||
LAYER_ACTIVE_FORCE
|
||||
LAYER_ACTIVE_FORCE,
|
||||
// Special layer that is metadata only.
|
||||
LAYER_ACTIVE_EMPTY
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -84,6 +84,7 @@ enum Type {
|
|||
TYPE_REMOTE,
|
||||
TYPE_REMOTE_SHADOW,
|
||||
TYPE_SCROLL_LAYER,
|
||||
TYPE_SCROLL_INFO_LAYER,
|
||||
TYPE_SELECTION_OVERLAY,
|
||||
TYPE_SOLID_COLOR,
|
||||
TYPE_TABLE_CELL_BACKGROUND,
|
||||
|
|
|
@ -1836,6 +1836,25 @@ nsDisplayScrollLayer::~nsDisplayScrollLayer()
|
|||
}
|
||||
#endif
|
||||
|
||||
nsDisplayScrollInfoLayer::nsDisplayScrollInfoLayer(
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList,
|
||||
nsIFrame* aForFrame,
|
||||
nsIFrame* aViewportFrame)
|
||||
: nsDisplayScrollLayer(aBuilder, aList, aForFrame, aViewportFrame)
|
||||
{
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
MOZ_COUNT_CTOR(nsDisplayScrollInfoLayer);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
nsDisplayScrollInfoLayer::~nsDisplayScrollInfoLayer()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsDisplayScrollInfoLayer);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder,
|
||||
nsIFrame* aFrame, nsDisplayItem* aItem,
|
||||
const nsRect& aRect)
|
||||
|
|
|
@ -1836,6 +1836,30 @@ private:
|
|||
nsIFrame* mViewportFrame;
|
||||
};
|
||||
|
||||
/**
|
||||
* Like nsDisplayScrollLayer, but only has metadata on the scroll frame. This
|
||||
* creates a layer that has no Thebes child layer, but still allows the
|
||||
* compositor process to know of the scroll frame's existence.
|
||||
*/
|
||||
class nsDisplayScrollInfoLayer : public nsDisplayScrollLayer
|
||||
{
|
||||
public:
|
||||
nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList,
|
||||
nsIFrame* aForFrame, nsIFrame* aViewportFrame);
|
||||
NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER)
|
||||
|
||||
#ifdef NS_BUILD_REFCNT_LOGGING
|
||||
virtual ~nsDisplayScrollInfoLayer();
|
||||
#endif
|
||||
|
||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager)
|
||||
{
|
||||
return mozilla::LAYER_ACTIVE_EMPTY;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* nsDisplayClip can clip a list of items, but we take a single item
|
||||
* initially and then later merge other items into it when we merge
|
||||
|
|
|
@ -1961,7 +1961,8 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
dirtyRect.IntersectRect(aDirtyRect, mScrollPort);
|
||||
|
||||
// Override the dirty rectangle if the displayport has been set.
|
||||
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &dirtyRect);
|
||||
PRBool usingDisplayport =
|
||||
nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &dirtyRect);
|
||||
|
||||
nsDisplayListCollection set;
|
||||
|
||||
|
@ -1976,30 +1977,42 @@ nsGfxScrollFrameInner::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
// range of 20 pixels to eliminate many gfx scroll frames from becoming a
|
||||
// layer.
|
||||
//
|
||||
PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
|
||||
nsRect scrollRange = GetScrollRange();
|
||||
ScrollbarStyles styles = GetScrollbarStylesFromFrame();
|
||||
mShouldBuildLayer =
|
||||
(XRE_GetProcessType() == GeckoProcessType_Content &&
|
||||
(styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN ||
|
||||
styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN) &&
|
||||
(scrollRange.width >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel) ||
|
||||
scrollRange.height >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel))) &&
|
||||
(!mIsRoot || !mOuter->PresContext()->IsRootContentDocument());
|
||||
(!mIsRoot || !mOuter->PresContext()->IsRootContentDocument()));
|
||||
|
||||
if (ShouldBuildLayer()) {
|
||||
// Note that using StackingContext breaks z order, so the resulting
|
||||
// rendering can be incorrect for weird edge cases!
|
||||
|
||||
nsDisplayList list;
|
||||
rv = mScrolledFrame->BuildDisplayListForStackingContext(
|
||||
aBuilder, dirtyRect + mOuter->GetOffsetTo(mScrolledFrame), &list);
|
||||
if (usingDisplayport) {
|
||||
// Once a displayport is set, assume that scrolling needs to be fast
|
||||
// so create a layer with all the content inside. The compositor
|
||||
// process will be able to scroll the content asynchronously.
|
||||
//
|
||||
// Note that using StackingContext breaks z order, so the resulting
|
||||
// rendering can be incorrect for weird edge cases!
|
||||
|
||||
nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollLayer(
|
||||
aBuilder, &list, mScrolledFrame, mOuter);
|
||||
set.Content()->AppendNewToTop(layerItem);
|
||||
} else
|
||||
{
|
||||
rv = mScrolledFrame->BuildDisplayListForStackingContext(
|
||||
aBuilder, dirtyRect + mOuter->GetOffsetTo(mScrolledFrame), &list);
|
||||
|
||||
nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollLayer(
|
||||
aBuilder, &list, mScrolledFrame, mOuter);
|
||||
set.Content()->AppendNewToTop(layerItem);
|
||||
} else {
|
||||
// If there is no displayport set, there is no reason here to force a
|
||||
// layer that needs a memory-expensive allocation, but the compositor
|
||||
// process would still like to know that it exists.
|
||||
|
||||
nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollInfoLayer(
|
||||
aBuilder, &list, mScrolledFrame, mOuter);
|
||||
set.Content()->AppendNewToTop(layerItem);
|
||||
|
||||
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set);
|
||||
}
|
||||
} else {
|
||||
rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set);
|
||||
}
|
||||
|
||||
|
|
|
@ -139,13 +139,8 @@ FindViewForId(const ViewMap& aMap, ViewID aId)
|
|||
static const FrameMetrics*
|
||||
GetFrameMetrics(Layer* aLayer)
|
||||
{
|
||||
// Children are not container layers, so they don't have frame metrics. Give
|
||||
// them a blank metric.
|
||||
if (!aLayer->GetFirstChild())
|
||||
return NULL;
|
||||
|
||||
ContainerLayer* container = static_cast<ContainerLayer*>(aLayer);
|
||||
return &container->GetFrameMetrics();
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
return container ? &container->GetFrameMetrics() : NULL;
|
||||
}
|
||||
|
||||
static nsIntPoint
|
||||
|
@ -346,10 +341,9 @@ BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews,
|
|||
nsFrameLoader* aFrameLoader, Layer* aLayer,
|
||||
float aXScale = 1, float aYScale = 1)
|
||||
{
|
||||
if (!aLayer->GetFirstChild())
|
||||
ContainerLayer* container = aLayer->AsContainerLayer();
|
||||
if (!container)
|
||||
return;
|
||||
|
||||
ContainerLayer* container = static_cast<ContainerLayer*>(aLayer);
|
||||
const FrameMetrics metrics = container->GetFrameMetrics();
|
||||
const ViewID scrollId = metrics.mScrollId;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче