зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 3910de7acce3 (bug 1349418)
--HG-- extra : rebase_source : e0ddc3d0c48256acd0996f16d3198560041f9c3e
This commit is contained in:
Родитель
9be4542d32
Коммит
22dd380d12
|
@ -44,6 +44,13 @@ 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;
|
||||
|
@ -167,6 +174,9 @@ public:
|
|||
// Getters.
|
||||
//
|
||||
|
||||
const gfx::IntRect& LayerBounds() const {
|
||||
return mLayerBounds;
|
||||
}
|
||||
float PostXScale() const {
|
||||
return mPostXScale;
|
||||
}
|
||||
|
@ -234,7 +244,8 @@ public:
|
|||
}
|
||||
|
||||
bool operator ==(const SimpleLayerAttributes& aOther) const {
|
||||
return mTransform == aOther.mTransform &&
|
||||
return mLayerBounds == aOther.mLayerBounds &&
|
||||
mTransform == aOther.mTransform &&
|
||||
mTransformIsPerspective == aOther.mTransformIsPerspective &&
|
||||
mScrolledClip == aOther.mScrolledClip &&
|
||||
mPostXScale == aOther.mPostXScale &&
|
||||
|
@ -251,6 +262,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
gfx::IntRect mLayerBounds;
|
||||
gfx::Matrix4x4 mTransform;
|
||||
bool mTransformIsPerspective;
|
||||
Maybe<LayerClip> mScrolledClip;
|
||||
|
|
|
@ -576,7 +576,8 @@ Layer::CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect)
|
|||
return currentClip;
|
||||
}
|
||||
|
||||
if (GetLocalVisibleRegion().IsEmpty()) {
|
||||
if (GetLocalVisibleRegion().IsEmpty() &&
|
||||
!(AsHostLayer() && AsHostLayer()->NeedToDrawCheckerboarding())) {
|
||||
// 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.
|
||||
|
@ -1854,6 +1855,9 @@ 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 {
|
||||
|
|
|
@ -897,6 +897,22 @@ 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
|
||||
|
@ -1323,6 +1339,7 @@ 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(GetVisibleRegion().GetBounds());
|
||||
LayerRect layerBounds = ViewAs<LayerPixel>(Rect(GetLayerBounds()));
|
||||
|
||||
// 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,
|
||||
LayerRect(mPaintedLayer.GetVisibleRegion().GetBounds()));
|
||||
ViewAs<LayerPixel>(Rect(mPaintedLayer.GetLayerBounds())));
|
||||
|
||||
if (!transformedCompositionBounds) {
|
||||
aPaintData->mPaintFinished = true;
|
||||
|
|
|
@ -209,7 +209,8 @@ 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()) {
|
||||
if (!layerToRender->GetLayer()->IsVisible() &&
|
||||
!layerToRender->NeedToDrawCheckerboarding(nullptr)) {
|
||||
CULLING_LOG("Sublayer %p has no effective visible region\n", layerToRender->GetLayer());
|
||||
continue;
|
||||
}
|
||||
|
@ -418,6 +419,24 @@ 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
|
||||
|
|
|
@ -1450,6 +1450,35 @@ 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
|
||||
|
|
|
@ -565,6 +565,12 @@ 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;
|
||||
|
||||
|
@ -664,6 +670,8 @@ public:
|
|||
*/
|
||||
virtual nsIntRegion GetFullyRenderedRegion();
|
||||
|
||||
virtual bool NeedToDrawCheckerboarding(gfx::Color* aOutCheckerboardingColor = nullptr);
|
||||
|
||||
protected:
|
||||
LayerManagerComposite* mCompositeManager;
|
||||
|
||||
|
|
|
@ -5352,29 +5352,20 @@ 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.
|
||||
bool addedScrollingBackgroundColor = false;
|
||||
if (!aFrame->GetParent()) {
|
||||
nsIScrollableFrame* sf =
|
||||
aFrame->PresContext()->PresShell()->GetRootScrollFrameAsScrollable();
|
||||
if (sf) {
|
||||
nsCanvasFrame* canvasFrame = do_QueryFrame(sf->GetScrolledFrame());
|
||||
if (canvasFrame && canvasFrame->IsVisibleForPainting(&aBuilder)) {
|
||||
addedScrollingBackgroundColor =
|
||||
AddCanvasBackgroundColor(aList, canvasFrame, bgcolor, mHasCSSBackgroundColor);
|
||||
if (AddCanvasBackgroundColor(aList, canvasFrame, bgcolor, mHasCSSBackgroundColor))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!addedScrollingBackgroundColor ||
|
||||
(nsLayoutUtils::UsesAsyncScrolling(aFrame) && NS_GET_A(bgcolor) == 255)) {
|
||||
// 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.
|
||||
aList.AppendNewToBottom(
|
||||
new (&aBuilder) nsDisplaySolidColor(&aBuilder, aFrame, aBounds, bgcolor));
|
||||
}
|
||||
aList.AppendNewToBottom(
|
||||
new (&aBuilder) nsDisplaySolidColor(&aBuilder, aFrame, aBounds, bgcolor));
|
||||
}
|
||||
|
||||
static bool IsTransparentContainerElement(nsPresContext* aPresContext)
|
||||
|
|
|
@ -651,6 +651,10 @@ 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.
|
||||
|
@ -3271,6 +3275,10 @@ 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()) {
|
||||
|
@ -3467,6 +3475,10 @@ 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;
|
||||
}
|
||||
|
@ -3786,7 +3798,7 @@ ContainerState::GetDisplayPortForAnimatedGeometryRoot(AnimatedGeometryRoot* aAni
|
|||
}
|
||||
|
||||
nsIScrollableFrame* sf = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
|
||||
if (sf == nullptr || nsLayoutUtils::UsesAsyncScrolling(*aAnimatedGeometryRoot)) {
|
||||
if (sf == nullptr) {
|
||||
return nsRect();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +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: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,6 +1,5 @@
|
|||
<!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>
|
||||
|
|
Загрузка…
Ссылка в новой задаче