diff --git a/gfx/2d/Rect.h b/gfx/2d/Rect.h index db0f45d373b67..c102e501b6168 100644 --- a/gfx/2d/Rect.h +++ b/gfx/2d/Rect.h @@ -99,6 +99,12 @@ struct IntRectTyped : yMost += this->height; return !xMost.isValid() || !yMost.isValid(); } + + // This is here only to keep IPDL-generated code happy. DO NOT USE. + bool operator==(const IntRectTyped& aRect) const + { + return IntRectTyped::IsEqualEdges(aRect); + } }; typedef IntRectTyped IntRect; diff --git a/gfx/layers/LayerMetricsWrapper.h b/gfx/layers/LayerMetricsWrapper.h index e92e2fcd382a3..19d8e82124ffa 100644 --- a/gfx/layers/LayerMetricsWrapper.h +++ b/gfx/layers/LayerMetricsWrapper.h @@ -341,15 +341,17 @@ class MOZ_STACK_CLASS LayerMetricsWrapper { return region; } - const nsIntRect* GetClipRect() const + const Maybe& GetClipRect() const { MOZ_ASSERT(IsValid()); + static const Maybe sNoClipRect = Nothing(); + if (AtBottomLayer()) { return mLayer->GetClipRect(); } - return nullptr; + return sNoClipRect; } EventRegionsOverride GetEventRegionsOverride() const diff --git a/gfx/layers/LayerTreeInvalidation.cpp b/gfx/layers/LayerTreeInvalidation.cpp index 836f8661f1be3..56a8f08bf070d 100644 --- a/gfx/layers/LayerTreeInvalidation.cpp +++ b/gfx/layers/LayerTreeInvalidation.cpp @@ -8,6 +8,7 @@ #include "ImageContainer.h" // for ImageContainer #include "ImageLayers.h" // for ImageLayer, etc #include "Layers.h" // for Layer, ContainerLayer, etc +#include "Units.h" // for ParentLayerIntRect #include "gfxColor.h" // for gfxRGBA #include "GraphicsFilter.h" // for GraphicsFilter #include "gfxRect.h" // for gfxRect @@ -140,7 +141,7 @@ struct LayerPropertiesBase : public LayerProperties mLayer->GetPostXScale() != mPostXScale || mLayer->GetPostYScale() != mPostYScale; Layer* otherMask = mLayer->GetMaskLayer(); - const nsIntRect* otherClip = mLayer->GetClipRect(); + const Maybe& otherClip = mLayer->GetClipRect(); nsIntRegion result; if ((mMaskLayer ? mMaskLayer->mLayer : nullptr) != otherMask || (mUseClipRect != !!otherClip) || @@ -166,7 +167,7 @@ struct LayerPropertiesBase : public LayerProperties if (!mClipRect.IsEqualInterior(*otherClip)) { aGeometryChanged = true; nsIntRegion tmp; - tmp.Xor(mClipRect, *otherClip); + tmp.Xor(ParentLayerIntRect::ToUntyped(mClipRect), ParentLayerIntRect::ToUntyped(*otherClip)); AddRegion(result, tmp); } } @@ -199,7 +200,7 @@ struct LayerPropertiesBase : public LayerProperties float mPostXScale; float mPostYScale; float mOpacity; - nsIntRect mClipRect; + ParentLayerIntRect mClipRect; bool mUseClipRect; }; diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 94f642439e02b..2488ca18ae8bd 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -14,6 +14,7 @@ #include "LayerSorter.h" // for SortLayersBy3DZOrder #include "LayersLogging.h" // for AppendToString #include "ReadbackLayer.h" // for ReadbackLayer +#include "UnitTransforms.h" // for ViewAs #include "gfxPlatform.h" // for gfxPlatform #include "gfxPrefs.h" #include "gfxUtils.h" // for gfxUtils, etc @@ -201,7 +202,6 @@ Layer::Layer(LayerManager* aManager, void* aImplData) : mMixBlendMode(CompositionOp::OP_OVER), mForceIsolatedGroup(false), mContentFlags(0), - mUseClipRect(false), mUseTileSourceRect(false), mIsFixedPosition(false), mMargins(0, 0, 0, 0), @@ -547,7 +547,7 @@ Layer::CanUseOpaqueSurface() // NB: eventually these methods will be defined unconditionally, and // can be moved into Layers.h -const nsIntRect* +const Maybe& Layer::GetEffectiveClipRect() { if (LayerComposite* shadow = AsLayerComposite()) { @@ -673,7 +673,9 @@ Layer::CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect) return currentClip; } - const RenderTargetIntRect clipRect = RenderTargetPixel::FromUntyped(*GetEffectiveClipRect()); + const RenderTargetIntRect clipRect = + ViewAs(*GetEffectiveClipRect(), + PixelCastJustification::RenderTargetIsParentLayerForRoot); if (clipRect.IsEmpty()) { // We might have a non-translation transform in the container so we can't // use the code path below. @@ -694,7 +696,7 @@ Layer::CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect) if (!gfxUtils::GfxRectToIntRect(trScissor, &tmp)) { return RenderTargetIntRect(currentClip.TopLeft(), RenderTargetIntSize(0, 0)); } - scissor = RenderTargetPixel::FromUntyped(tmp); + scissor = ViewAs(tmp); // Find the nearest ancestor with an intermediate surface do { @@ -884,7 +886,7 @@ Layer::GetVisibleRegionRelativeToRootLayer(nsIntRegion& aResult, // If the parent layer clips its lower layers, clip the visible region // we're accumulating. if (layer->GetEffectiveClipRect()) { - aResult.AndWith(*layer->GetEffectiveClipRect()); + aResult.AndWith(ParentLayerIntRect::ToUntyped(*layer->GetEffectiveClipRect())); } // Now we need to walk across the list of siblings for this parent layer, @@ -1099,7 +1101,7 @@ ContainerLayer::HasMultipleChildren() { uint32_t count = 0; for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) { - const nsIntRect *clipRect = child->GetEffectiveClipRect(); + const Maybe& clipRect = child->GetEffectiveClipRect(); if (clipRect && clipRect->IsEmpty()) continue; if (child->GetVisibleRegion().IsEmpty()) @@ -1166,7 +1168,7 @@ ContainerLayer::DefaultComputeEffectiveTransforms(const Matrix4x4& aTransformToS gfx::ThebesMatrix(contTransform).HasNonIntegerTranslation()) { #endif for (Layer* child = GetFirstChild(); child; child = child->GetNextSibling()) { - const nsIntRect *clipRect = child->GetEffectiveClipRect(); + const Maybe& clipRect = child->GetEffectiveClipRect(); /* We can't (easily) forward our transform to children with a non-empty clip * rect since it would need to be adjusted for the transform. See * the calculations performed by CalculateScissorRect above. @@ -1565,8 +1567,8 @@ Layer::PrintInfo(std::stringstream& aStream, const char* aPrefix) layers::PrintInfo(aStream, AsLayerComposite()); - if (mUseClipRect) { - AppendToString(aStream, mClipRect, " [clip=", "]"); + if (mClipRect) { + AppendToString(aStream, *mClipRect, " [clip=", "]"); } if (1.0 != mPostXScale || 1.0 != mPostYScale) { aStream << nsPrintfCString(" [postScale=%g, %g]", mPostXScale, mPostYScale).get(); @@ -1650,8 +1652,10 @@ DumpTransform(layerscope::LayersPacket::Layer::Matrix* aLayerMatrix, const Matri } // The static helper function sets the nsIntRect into the packet +template static void -DumpRect(layerscope::LayersPacket::Layer::Rect* aLayerRect, const nsIntRect& aRect) +DumpRect(layerscope::LayersPacket::Layer::Rect* aLayerRect, + const BaseRect& aRect) { aLayerRect->set_x(aRect.x); aLayerRect->set_y(aRect.y); @@ -1682,7 +1686,7 @@ Layer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) // Shadow if (LayerComposite* lc = AsLayerComposite()) { LayersPacket::Layer::Shadow* s = layer->mutable_shadow(); - if (const nsIntRect* clipRect = lc->GetShadowClipRect()) { + if (const Maybe& clipRect = lc->GetShadowClipRect()) { DumpRect(s->mutable_clip(), *clipRect); } if (!lc->GetShadowTransform().IsIdentity()) { @@ -1693,8 +1697,8 @@ Layer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) } } // Clip - if (mUseClipRect) { - DumpRect(layer->mutable_clip(), mClipRect); + if (mClipRect) { + DumpRect(layer->mutable_clip(), *mClipRect); } // Transform if (!mTransform.IsIdentity()) { @@ -2047,7 +2051,7 @@ PrintInfo(std::stringstream& aStream, LayerComposite* aLayerComposite) if (!aLayerComposite) { return; } - if (const nsIntRect* clipRect = aLayerComposite->GetShadowClipRect()) { + if (const Maybe& clipRect = aLayerComposite->GetShadowClipRect()) { AppendToString(aStream, *clipRect, " [shadow-clip=", "]"); } if (!aLayerComposite->GetShadowTransform().IsIdentity()) { diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index aef6f01248732..962c7bcc4cc22 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -10,7 +10,7 @@ #include // for FILE #include // for int32_t, int64_t #include "FrameMetrics.h" // for FrameMetrics -#include "Units.h" // for LayerMargin, LayerPoint +#include "Units.h" // for LayerMargin, LayerPoint, ParentLayerIntRect #include "gfxContext.h" // for GraphicsOperator #include "gfxTypes.h" #include "gfxColor.h" // for gfxRGBA @@ -21,6 +21,7 @@ #include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2, etc #include "mozilla/DebugOnly.h" // for DebugOnly #include "mozilla/EventForwards.h" // for nsPaintEvent +#include "mozilla/Maybe.h" // for Maybe #include "mozilla/RefPtr.h" // for TemporaryRef #include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc #include "mozilla/TimeStamp.h" // for TimeStamp, TimeDuration @@ -990,20 +991,20 @@ class Layer { * in device pixels. * If aRect is null no clipping will be performed. */ - void SetClipRect(const nsIntRect* aRect) + void SetClipRect(const Maybe& aRect) { - if (mUseClipRect) { + if (mClipRect) { if (!aRect) { MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is ", this, - mClipRect.x, mClipRect.y, mClipRect.width, mClipRect.height)); - mUseClipRect = false; + mClipRect->x, mClipRect->y, mClipRect->width, mClipRect->height)); + mClipRect.reset(); Mutated(); } else { - if (!aRect->IsEqualEdges(mClipRect)) { + if (!aRect->IsEqualEdges(*mClipRect)) { MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was %d,%d,%d,%d is %d,%d,%d,%d", this, - mClipRect.x, mClipRect.y, mClipRect.width, mClipRect.height, + mClipRect->x, mClipRect->y, mClipRect->width, mClipRect->height, aRect->x, aRect->y, aRect->width, aRect->height)); - mClipRect = *aRect; + mClipRect = aRect; Mutated(); } } @@ -1011,8 +1012,7 @@ class Layer { if (aRect) { MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ClipRect was is %d,%d,%d,%d", this, aRect->x, aRect->y, aRect->width, aRect->height)); - mUseClipRect = true; - mClipRect = *aRect; + mClipRect = aRect; Mutated(); } } @@ -1227,7 +1227,7 @@ class Layer { // These getters can be used anytime. float GetOpacity() { return mOpacity; } gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; } - const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nullptr; } + const Maybe& GetClipRect() const { return mClipRect; } uint32_t GetContentFlags() { return mContentFlags; } const nsIntRect& GetLayerBounds() const { return mLayerBounds; } const nsIntRegion& GetVisibleRegion() const { return mVisibleRegion; } @@ -1418,7 +1418,7 @@ class Layer { // These getters can be used anytime. They return the effective // values that should be used when drawing this layer to screen, // accounting for this layer possibly being a shadow. - const nsIntRect* GetEffectiveClipRect(); + const Maybe& GetEffectiveClipRect(); const nsIntRegion& GetEffectiveVisibleRegion(); /** @@ -1700,12 +1700,11 @@ class Layer { float mOpacity; gfx::CompositionOp mMixBlendMode; bool mForceIsolatedGroup; - nsIntRect mClipRect; + Maybe mClipRect; nsIntRect mTileSourceRect; nsIntRegion mInvalidRegion; nsTArray > mApzcs; uint32_t mContentFlags; - bool mUseClipRect; bool mUseTileSourceRect; bool mIsFixedPosition; LayerPoint mAnchor; diff --git a/gfx/layers/ReadbackProcessor.cpp b/gfx/layers/ReadbackProcessor.cpp index b478ffb2c37c0..d0b40c4edc51b 100644 --- a/gfx/layers/ReadbackProcessor.cpp +++ b/gfx/layers/ReadbackProcessor.cpp @@ -7,6 +7,8 @@ #include // for int32_t #include "Layers.h" // for Layer, PaintedLayer, etc #include "ReadbackLayer.h" // for ReadbackLayer, ReadbackSink +#include "UnitTransforms.h" // for ViewAs +#include "Units.h" // for ParentLayerIntRect #include "gfxColor.h" // for gfxRGBA #include "gfxContext.h" // for gfxContext #include "gfxUtils.h" @@ -76,8 +78,8 @@ FindBackgroundLayer(ReadbackLayer* aLayer, nsIntPoint* aOffset) return nullptr; // cliprects are post-transform - const nsIntRect* clipRect = l->GetEffectiveClipRect(); - if (clipRect && !clipRect->Contains(nsIntRect(transformOffset, aLayer->GetSize()))) + const Maybe& clipRect = l->GetEffectiveClipRect(); + if (clipRect && !clipRect->Contains(ViewAs(nsIntRect(transformOffset, aLayer->GetSize())))) return nullptr; Layer::LayerType type = l->GetType(); diff --git a/gfx/layers/apz/src/APZCTreeManager.cpp b/gfx/layers/apz/src/APZCTreeManager.cpp index f552db5c30795..e9cf259e233a7 100644 --- a/gfx/layers/apz/src/APZCTreeManager.cpp +++ b/gfx/layers/apz/src/APZCTreeManager.cpp @@ -29,6 +29,7 @@ #include "gfxPrefs.h" // for gfxPrefs #include "OverscrollHandoffState.h" // for OverscrollHandoffState #include "LayersLogging.h" // for Stringify +#include "Units.h" // for ParentlayerPixel #define ENABLE_APZCTM_LOGGING 0 // #define ENABLE_APZCTM_LOGGING 1 @@ -202,7 +203,7 @@ ComputeClipRegion(GeckoContentController* aController, { ParentLayerIntRegion clipRegion; if (aLayer.GetClipRect()) { - clipRegion = ViewAs(*aLayer.GetClipRect()); + clipRegion = *aLayer.GetClipRect(); } else { // if there is no clip on this layer (which should only happen for the // root scrollable layer in a process, or for some of the LayerMetrics @@ -334,7 +335,7 @@ APZCTreeManager::PrepareNodeForLayer(const LayerMetricsWrapper& aLayer, node = RecycleOrCreateNode(aState, nullptr); AttachNodeToTree(node, aParent, aNextSibling); node->SetHitTestData(GetEventRegions(aLayer), aLayer.GetTransform(), - aLayer.GetClipRect() ? Some(ParentLayerIntRegion(ViewAs(*aLayer.GetClipRect()))) : Nothing(), + aLayer.GetClipRect() ? Some(ParentLayerIntRegion(*aLayer.GetClipRect())) : Nothing(), GetEventRegionsOverride(aParent, aLayer)); return node; } diff --git a/gfx/layers/basic/BasicContainerLayer.cpp b/gfx/layers/basic/BasicContainerLayer.cpp index 409bd6cb36b8e..116aaa3e37af2 100644 --- a/gfx/layers/basic/BasicContainerLayer.cpp +++ b/gfx/layers/basic/BasicContainerLayer.cpp @@ -102,7 +102,7 @@ BasicContainerLayer::ChildrenPartitionVisibleRegion(const nsIntRect& aInRect) childRegion.MoveBy(int32_t(childTransform._31), int32_t(childTransform._32)); childRegion.And(childRegion, rect); if (l->GetClipRect()) { - childRegion.And(childRegion, *l->GetClipRect() + offset); + childRegion.And(childRegion, ParentLayerIntRect::ToUntyped(*l->GetClipRect()) + offset); } nsIntRegion intersection; intersection.And(covered, childRegion); diff --git a/gfx/layers/basic/BasicLayerManager.cpp b/gfx/layers/basic/BasicLayerManager.cpp index bc38a2f2cb8b5..b9f4caa54bd23 100644 --- a/gfx/layers/basic/BasicLayerManager.cpp +++ b/gfx/layers/basic/BasicLayerManager.cpp @@ -324,9 +324,9 @@ MarkLayersHidden(Layer* aLayer, const nsIntRect& aClipRect, } { - const nsIntRect* clipRect = aLayer->GetEffectiveClipRect(); + const Maybe& clipRect = aLayer->GetEffectiveClipRect(); if (clipRect) { - nsIntRect cr = *clipRect; + nsIntRect cr = ParentLayerIntRect::ToUntyped(*clipRect); // clipRect is in the container's coordinate system. Get it into the // global coordinate system. if (aLayer->GetParent()) { @@ -404,9 +404,9 @@ ApplyDoubleBuffering(Layer* aLayer, const nsIntRect& aVisibleRect) nsIntRect newVisibleRect(aVisibleRect); { - const nsIntRect* clipRect = aLayer->GetEffectiveClipRect(); + const Maybe& clipRect = aLayer->GetEffectiveClipRect(); if (clipRect) { - nsIntRect cr = *clipRect; + nsIntRect cr = ParentLayerIntRect::ToUntyped(*clipRect); // clipRect is in the container's coordinate system. Get it into the // global coordinate system. if (aLayer->GetParent()) { @@ -865,7 +865,7 @@ BasicLayerManager::PaintLayer(gfxContext* aTarget, RenderTraceScope trace("BasicLayerManager::PaintLayer", "707070"); - const nsIntRect* clipRect = aLayer->GetEffectiveClipRect(); + const Maybe& clipRect = aLayer->GetEffectiveClipRect(); BasicContainerLayer* container = static_cast(aLayer->AsContainerLayer()); bool needsGroup = container && container->UseIntermediateSurface(); diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index 71646a7b2a367..571e475b43d03 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -140,12 +140,10 @@ static void TransformClipRect(Layer* aLayer, const Matrix4x4& aTransform) { - const nsIntRect* clipRect = aLayer->AsLayerComposite()->GetShadowClipRect(); + const Maybe& clipRect = aLayer->AsLayerComposite()->GetShadowClipRect(); if (clipRect) { - LayerIntRect transformed = TransformTo( - aTransform, LayerIntRect::FromUntyped(*clipRect)); - nsIntRect shadowClip = LayerIntRect::ToUntyped(transformed); - aLayer->AsLayerComposite()->SetShadowClipRect(&shadowClip); + ParentLayerIntRect transformed = TransformTo(aTransform, *clipRect); + aLayer->AsLayerComposite()->SetShadowClipRect(Some(transformed)); } } @@ -565,8 +563,8 @@ AdjustForClip(const Matrix4x4& asyncTransform, Layer* aLayer) // then applying it to container as-is will produce incorrect results. To // avoid this, translate the layer so that the clip rect starts at the origin, // apply the tree transform, and translate back. - if (const nsIntRect* shadowClipRect = aLayer->AsLayerComposite()->GetShadowClipRect()) { - if (shadowClipRect->TopLeft() != nsIntPoint()) { // avoid a gratuitous change of basis + if (const Maybe& shadowClipRect = aLayer->AsLayerComposite()->GetShadowClipRect()) { + if (shadowClipRect->TopLeft() != ParentLayerIntPoint()) { // avoid a gratuitous change of basis result.ChangeBasis(shadowClipRect->x, shadowClipRect->y, 0); } } @@ -589,7 +587,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer) Matrix4x4 combinedAsyncTransform; bool hasAsyncTransform = false; LayerMargin fixedLayerMargins(0, 0, 0, 0); - Maybe clipRect = ToMaybe(aLayer->AsLayerComposite()->GetShadowClipRect()); + Maybe clipRect = aLayer->AsLayerComposite()->GetShadowClipRect(); for (uint32_t i = 0; i < aLayer->GetFrameMetricsCount(); i++) { AsyncPanZoomController* controller = aLayer->GetAsyncPanZoomController(i); @@ -639,15 +637,14 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer) // bounds at that level. ParentLayerRect transformed = TransformTo( (Matrix4x4(asyncTransformWithoutOverscroll) * overscrollTransform), - ParentLayerRect(ViewAs(*clipRect))); - clipRect = Some(ParentLayerIntRect::ToUntyped( - RoundedOut(transformed.Intersect(metrics.mCompositionBounds)))); + ParentLayerRect(*clipRect)); + clipRect = Some(RoundedOut(transformed.Intersect(metrics.mCompositionBounds))); } } if (hasAsyncTransform) { if (clipRect) { - aLayer->AsLayerComposite()->SetShadowClipRect(clipRect.ptr()); + aLayer->AsLayerComposite()->SetShadowClipRect(clipRect); } // Apply the APZ transform on top of GetLocalTransform() here (rather than // GetTransform()) in case the OMTA code in SampleAnimations already set a diff --git a/gfx/layers/composite/LayerManagerComposite.cpp b/gfx/layers/composite/LayerManagerComposite.cpp index 54b7c66eb1078..d634a97834f70 100644 --- a/gfx/layers/composite/LayerManagerComposite.cpp +++ b/gfx/layers/composite/LayerManagerComposite.cpp @@ -21,6 +21,7 @@ #include "PaintedLayerComposite.h" // for PaintedLayerComposite #include "TiledLayerBuffer.h" // for TiledLayerComposer #include "Units.h" // for ScreenIntRect +#include "UnitTransforms.h" // for ViewAs #include "gfx2DGlue.h" // for ToMatrix4x4 #include "gfxPrefs.h" // for gfxPrefs #ifdef XP_MACOSX @@ -234,9 +235,9 @@ LayerManagerComposite::ApplyOcclusionCulling(Layer* aLayer, nsIntRegion& aOpaque localOpaque.Or(localOpaque, composite->GetFullyRenderedRegion()); } localOpaque.MoveBy(transform2d._31, transform2d._32); - const nsIntRect* clip = aLayer->GetEffectiveClipRect(); + const Maybe& clip = aLayer->GetEffectiveClipRect(); if (clip) { - localOpaque.And(localOpaque, *clip); + localOpaque.And(localOpaque, ParentLayerIntRect::ToUntyped(*clip)); } aOpaqueRegion.Or(aOpaqueRegion, localOpaque); } @@ -694,7 +695,7 @@ LayerManagerComposite::Render() mInvalidRegion.SetEmpty(); } - nsIntRect clipRect; + ParentLayerIntRect clipRect; Rect bounds(mRenderBounds.x, mRenderBounds.y, mRenderBounds.width, mRenderBounds.height); Rect actualBounds; @@ -707,7 +708,7 @@ LayerManagerComposite::Render() } else { gfx::Rect rect; mCompositor->BeginFrame(invalid, nullptr, bounds, &rect, &actualBounds); - clipRect = nsIntRect(rect.x, rect.y, rect.width, rect.height); + clipRect = ParentLayerIntRect(rect.x, rect.y, rect.width, rect.height); } if (actualBounds.IsEmpty()) { @@ -729,8 +730,8 @@ LayerManagerComposite::Render() } // Render our layers. - RootLayer()->Prepare(RenderTargetPixel::FromUntyped(clipRect)); - RootLayer()->RenderLayer(clipRect); + RootLayer()->Prepare(ViewAs(clipRect, PixelCastJustification::RenderTargetIsParentLayerForRoot)); + RootLayer()->RenderLayer(ParentLayerIntRect::ToUntyped(clipRect)); if (!mRegionToClear.IsEmpty()) { nsIntRegionRectIterator iter(mRegionToClear); @@ -742,7 +743,7 @@ LayerManagerComposite::Render() if (mTwoPassTmpTarget) { MOZ_ASSERT(haveLayerEffects); - PopGroupForLayerEffects(previousTarget, clipRect, + PopGroupForLayerEffects(previousTarget, ParentLayerIntRect::ToUntyped(clipRect), grayscaleVal, invertVal, contrastVal); } @@ -1096,7 +1097,6 @@ LayerComposite::LayerComposite(LayerManagerComposite *aManager) : mCompositeManager(aManager) , mCompositor(aManager->GetCompositor()) , mShadowOpacity(1.0) - , mUseShadowClipRect(false) , mShadowTransformSetByAnimation(false) , mDestroyed(false) , mLayerComposited(false) diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 0e6552099dc21..ca5f071292640 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -9,6 +9,7 @@ #include // for int32_t, uint32_t #include "GLDefs.h" // for GLenum #include "Layers.h" +#include "Units.h" // for ParentLayerIntRect #include "mozilla/Assertions.h" // for MOZ_ASSERT, etc #include "mozilla/Attributes.h" // for override #include "mozilla/RefPtr.h" // for RefPtr, TemporaryRef @@ -18,6 +19,7 @@ #include "mozilla/gfx/Types.h" // for SurfaceFormat #include "mozilla/layers/CompositorTypes.h" #include "mozilla/layers/LayersTypes.h" // for LayersBackend, etc +#include "mozilla/Maybe.h" // for Maybe #include "mozilla/RefPtr.h" #include "mozilla/UniquePtr.h" #include "nsAString.h" @@ -403,12 +405,9 @@ class LayerComposite mShadowOpacity = aOpacity; } - void SetShadowClipRect(const nsIntRect* aRect) + void SetShadowClipRect(const Maybe& aRect) { - mUseShadowClipRect = aRect != nullptr; - if (aRect) { - mShadowClipRect = *aRect; - } + mShadowClipRect = aRect; } void SetShadowTransform(const gfx::Matrix4x4& aMatrix) @@ -432,7 +431,7 @@ class LayerComposite // These getters can be used anytime. float GetShadowOpacity() { return mShadowOpacity; } - const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nullptr; } + const Maybe& GetShadowClipRect() { return mShadowClipRect; } const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; } const gfx::Matrix4x4& GetShadowTransform() { return mShadowTransform; } bool GetShadowTransformSetByAnimation() { return mShadowTransformSetByAnimation; } @@ -449,11 +448,10 @@ class LayerComposite protected: gfx::Matrix4x4 mShadowTransform; nsIntRegion mShadowVisibleRegion; - nsIntRect mShadowClipRect; + Maybe mShadowClipRect; LayerManagerComposite* mCompositeManager; RefPtr mCompositor; float mShadowOpacity; - bool mUseShadowClipRect; bool mShadowTransformSetByAnimation; bool mDestroyed; bool mLayerComposited; diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index d8c1f9ffd987b..7d1007318cc41 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -327,7 +327,7 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray&& cset, layer->SetEventRegions(common.eventRegions()); layer->SetContentFlags(common.contentFlags()); layer->SetOpacity(common.opacity()); - layer->SetClipRect(common.useClipRect() ? &common.clipRect() : nullptr); + layer->SetClipRect(common.useClipRect() ? Some(common.clipRect()) : Nothing()); layer->SetBaseTransform(common.transform().value()); layer->SetPostScale(common.postXScale(), common.postYScale()); layer->SetIsFixedPosition(common.isFixedPosition()); diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 0176840717a38..fe5996e269361 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -33,6 +33,7 @@ using struct mozilla::layers::TextureInfo from "mozilla/layers/CompositorTypes.h using mozilla::LayerMargin from "Units.h"; using mozilla::LayerPoint from "Units.h"; using mozilla::LayerRect from "Units.h"; +using mozilla::ParentLayerIntRect from "Units.h"; using mozilla::layers::ScaleMode from "mozilla/layers/LayersTypes.h"; using mozilla::layers::EventRegions from "mozilla/layers/LayersTypes.h"; using mozilla::layers::EventRegionsOverride from "mozilla/layers/LayersTypes.h"; @@ -204,7 +205,7 @@ struct CommonLayerAttributes { uint32_t contentFlags; float opacity; bool useClipRect; - nsIntRect clipRect; + ParentLayerIntRect clipRect; bool isFixedPosition; LayerPoint fixedPositionAnchor; LayerMargin fixedPositionMargin; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index d9c294257c07a..6cfc9d39ca666 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -587,7 +587,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies, common.opacity() = mutant->GetOpacity(); common.useClipRect() = !!mutant->GetClipRect(); common.clipRect() = (common.useClipRect() ? - *mutant->GetClipRect() : nsIntRect()); + *mutant->GetClipRect() : ParentLayerIntRect()); common.isFixedPosition() = mutant->GetIsFixedPosition(); common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor(); common.fixedPositionMargin() = mutant->GetFixedPositionMargins(); diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 0496d9284c855..2f0e22b228790 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -19,6 +19,7 @@ #include "base/task.h" #include "Layers.h" #include "TestLayers.h" +#include "UnitTransforms.h" #include "gfxPrefs.h" using namespace mozilla; @@ -1789,7 +1790,7 @@ class APZCTreeManagerTester : public ::testing::Test { metrics.SetScrollableRect(aScrollableRect); metrics.SetScrollOffset(CSSPoint(0, 0)); aLayer->SetFrameMetrics(metrics); - aLayer->SetClipRect(&layerBound); + aLayer->SetClipRect(Some(ViewAs(layerBound))); if (!aScrollableRect.IsEqualEdges(CSSRect(-1, -1, -1, -1))) { // The purpose of this is to roughly mimic what layout would do in the // case of a scrollable frame with the event regions and clip. This lets diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index e8dc0adf427df..c2d349a107774 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -7,35 +7,38 @@ #include "FrameLayerBuilder.h" +#include "mozilla/LookAndFeel.h" +#include "mozilla/Maybe.h" +#include "mozilla/dom/ProfileTimelineMarkerBinding.h" #include "mozilla/gfx/Matrix.h" -#include "nsDisplayList.h" -#include "nsPresContext.h" -#include "nsLayoutUtils.h" -#include "Layers.h" +#include "ActiveLayerTracker.h" #include "BasicLayers.h" -#include "gfxUtils.h" -#include "nsRenderingContext.h" -#include "MaskLayerImageCache.h" -#include "nsIScrollableFrame.h" -#include "nsPrintfCString.h" -#include "LayerTreeInvalidation.h" -#include "nsSVGIntegrationUtils.h" #include "ImageContainer.h" -#include "ActiveLayerTracker.h" +#include "LayerTreeInvalidation.h" +#include "Layers.h" +#include "MaskLayerImageCache.h" +#include "UnitTransforms.h" +#include "Units.h" #include "gfx2DGlue.h" -#include "mozilla/LookAndFeel.h" +#include "gfxUtils.h" +#include "nsDisplayList.h" #include "nsDocShell.h" +#include "nsIScrollableFrame.h" #include "nsImageFrame.h" -#include "mozilla/dom/ProfileTimelineMarkerBinding.h" +#include "nsLayoutUtils.h" +#include "nsPresContext.h" +#include "nsPrintfCString.h" +#include "nsRenderingContext.h" +#include "nsSVGIntegrationUtils.h" -#include "GeckoProfiler.h" -#include "mozilla/gfx/Tools.h" +#include "mozilla/Move.h" +#include "mozilla/ReverseIterator.h" #include "mozilla/gfx/2D.h" -#include "gfxPrefs.h" -#include "LayersLogging.h" +#include "mozilla/gfx/Tools.h" #include "mozilla/unused.h" -#include "mozilla/ReverseIterator.h" -#include "mozilla/Move.h" +#include "GeckoProfiler.h" +#include "LayersLogging.h" +#include "gfxPrefs.h" #include @@ -2828,11 +2831,11 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB imageLayer->SetPostScale(mParameters.mXScale, mParameters.mYScale); if (data->mItemClip.HasClip()) { - nsIntRect clip = ScaleToNearestPixels(data->mItemClip.GetClipRect()); - clip.MoveBy(mParameters.mOffset); - imageLayer->SetClipRect(&clip); + ParentLayerIntRect clip = ViewAs(ScaleToNearestPixels(data->mItemClip.GetClipRect())); + clip.MoveBy(ViewAs(mParameters.mOffset)); + imageLayer->SetClipRect(Some(clip)); } else { - imageLayer->SetClipRect(nullptr); + imageLayer->SetClipRect(Nothing()); } layer = imageLayer; mLayerBuilder->StoreOptimizedLayerForFrame(data->mImage, @@ -2849,7 +2852,7 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB nsIntRect visibleRect = data->mVisibleRegion.GetBounds(); visibleRect.MoveBy(-GetTranslationForPaintedLayer(data->mLayer)); colorLayer->SetBounds(visibleRect); - colorLayer->SetClipRect(nullptr); + colorLayer->SetClipRect(Nothing()); layer = colorLayer; FLB_LOG_PAINTED_LAYER_DECISION(data, " Selected color layer=%p\n", layer.get()); @@ -2868,15 +2871,15 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB // Hide the PaintedLayer. We leave it in the layer tree so that we // can find and recycle it later. - nsIntRect emptyRect; - data->mLayer->SetClipRect(&emptyRect); + ParentLayerIntRect emptyRect; + data->mLayer->SetClipRect(Some(emptyRect)); data->mLayer->SetVisibleRegion(nsIntRegion()); data->mLayer->InvalidateRegion(data->mLayer->GetValidRegion().GetBounds()); data->mLayer->SetEventRegions(EventRegions()); } else { layer = data->mLayer; imageContainer = nullptr; - layer->SetClipRect(nullptr); + layer->SetClipRect(Nothing()); FLB_LOG_PAINTED_LAYER_DECISION(data, " Selected painted layer=%p\n", layer.get()); } @@ -3508,15 +3511,15 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList) nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap); bool prerenderedTransform = itemType == nsDisplayItem::TYPE_TRANSFORM && static_cast(item)->ShouldPrerender(mBuilder); - nsIntRect clipRect; + ParentLayerIntRect clipRect; const DisplayItemClip& itemClip = item->GetClip(); if (itemClip.HasClip()) { itemContent.IntersectRect(itemContent, itemClip.GetClipRect()); - clipRect = ScaleToNearestPixels(itemClip.GetClipRect()); + clipRect = ViewAs(ScaleToNearestPixels(itemClip.GetClipRect())); if (!prerenderedTransform) { - itemDrawRect.IntersectRect(itemDrawRect, clipRect); + itemDrawRect.IntersectRect(itemDrawRect, ParentLayerIntRect::ToUntyped(clipRect)); } - clipRect.MoveBy(mParameters.mOffset); + clipRect.MoveBy(ViewAs(mParameters.mOffset)); } #ifdef DEBUG nsRect bounds = itemContent; @@ -3614,7 +3617,11 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList) // visible rect for the two important cases. nscolor uniformColor = NS_RGBA(0,0,0,0); nscolor* uniformColorPtr = !mayDrawOutOfOrder ? &uniformColor : nullptr; - nsIntRect* clipPtr = itemClip.HasClip() ? &clipRect : nullptr; + nsIntRect clipRectUntyped; + nsIntRect* clipPtr = itemClip.HasClip() ? &clipRectUntyped : nullptr; + if (clipPtr) { + clipRectUntyped = ParentLayerIntRect::ToUntyped(clipRect); + } if (animatedGeometryRoot == item->Frame() && animatedGeometryRoot != mBuilder->RootReferenceFrame()) { // This is the case for scrollbar thumbs, for example. In that case the @@ -3622,10 +3629,12 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList) const nsIFrame* clipAnimatedGeometryRoot = mPaintedLayerDataTree.GetParentAnimatedGeometryRoot(animatedGeometryRoot); mPaintedLayerDataTree.AddingOwnLayer(clipAnimatedGeometryRoot, - clipPtr, uniformColorPtr); + clipPtr, + uniformColorPtr); } else if (prerenderedTransform) { mPaintedLayerDataTree.AddingOwnLayer(animatedGeometryRoot, - clipPtr, uniformColorPtr); + clipPtr, + uniformColorPtr); } else { // Using itemVisibleRect here isn't perfect. itemVisibleRect can be // larger or smaller than the potential bounds of item's contents in @@ -3680,9 +3689,9 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList) "If we have rounded rects, we must have a clip rect"); // It has its own layer. Update that layer's clip and visible rects. if (itemClip.HasClip()) { - ownLayer->SetClipRect(&clipRect); + ownLayer->SetClipRect(Some(clipRect)); } else { - ownLayer->SetClipRect(nullptr); + ownLayer->SetClipRect(Nothing()); } // rounded rectangle clipping using mask layers @@ -4225,8 +4234,8 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry) } uint32_t baseLength = metricsArray.Length(); - nsIntRect tmpClipRect; - const nsIntRect* layerClip = aEntry->mLayer->GetClipRect(); + ParentLayerIntRect tmpClipRect; + const ParentLayerIntRect* layerClip = aEntry->mLayer->GetClipRect().ptrOr(nullptr); nsIFrame* fParent; for (const nsIFrame* f = aEntry->mAnimatedGeometryRoot; f != mContainerAnimatedGeometryRoot; @@ -4255,7 +4264,7 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry) scrollFrame->ComputeFrameMetrics(aEntry->mLayer, mContainerReferenceFrame, mParameters, &clipRect, &metricsArray); if (clipRect.width >= 0) { - nsIntRect pixClip = ScaleToNearestPixels(clipRect); + ParentLayerIntRect pixClip = ViewAs(ScaleToNearestPixels(clipRect)); if (layerClip) { tmpClipRect.IntersectRect(pixClip, *layerClip); } else { @@ -4267,7 +4276,7 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry) // both CSS and scroll clipping. } } - aEntry->mLayer->SetClipRect(layerClip); + aEntry->mLayer->SetClipRect(ToMaybe(layerClip)); // Watch out for FrameMetrics copies in profiles aEntry->mLayer->SetFrameMetrics(metricsArray); } @@ -4298,9 +4307,9 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer if (hideAll) { e->mVisibleRegion.SetEmpty(); } else if (!e->mLayer->IsScrollbarContainer()) { - const nsIntRect* clipRect = e->mLayer->GetClipRect(); + const Maybe& clipRect = e->mLayer->GetClipRect(); if (clipRect && opaqueRegionForContainer >= 0 && - opaqueRegions[opaqueRegionForContainer].mOpaqueRegion.Contains(*clipRect)) { + opaqueRegions[opaqueRegionForContainer].mOpaqueRegion.Contains(ParentLayerIntRect::ToUntyped(*clipRect))) { e->mVisibleRegion.SetEmpty(); } else if (data) { e->mVisibleRegion.Sub(e->mVisibleRegion, data->mOpaqueRegion); @@ -4333,9 +4342,9 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer } nsIntRegion clippedOpaque = e->mOpaqueRegion; - const nsIntRect* clipRect = e->mLayer->GetClipRect(); + const Maybe& clipRect = e->mLayer->GetClipRect(); if (clipRect) { - clippedOpaque.AndWith(*clipRect); + clippedOpaque.AndWith(ParentLayerIntRect::ToUntyped(*clipRect)); } data->mOpaqueRegion.Or(data->mOpaqueRegion, clippedOpaque); if (e->mHideAllLayersBelow) { diff --git a/layout/base/UnitTransforms.h b/layout/base/UnitTransforms.h index 0b9dfc442dc38..37485510530f6 100644 --- a/layout/base/UnitTransforms.h +++ b/layout/base/UnitTransforms.h @@ -22,6 +22,8 @@ namespace mozilla { enum class PixelCastJustification : uint8_t { // For the root layer, Screen Pixel = Parent Layer Pixel. ScreenIsParentLayerForRoot, + // For the root layer, Render Target Pixel = Parent Layer Pixel. + RenderTargetIsParentLayerForRoot, // For the root composition size we want to view it as layer pixels in any layer ParentLayerToLayerForRootComposition, // The Layer coordinate space for one layer is the ParentLayer coordinate @@ -54,6 +56,14 @@ template gfx::IntPointTyped ViewAs(const gfx::IntPointTyped& aPoint, PixelCastJustification) { return gfx::IntPointTyped(aPoint.x, aPoint.y); } +template +gfx::RectTyped ViewAs(const gfx::RectTyped& aRect, PixelCastJustification) { + return gfx::RectTyped(aRect.x, aRect.y, aRect.width, aRect.height); +} +template +gfx::IntRectTyped ViewAs(const gfx::IntRectTyped& aRect, PixelCastJustification) { + return gfx::IntRectTyped(aRect.x, aRect.y, aRect.width, aRect.height); +} template gfx::ScaleFactor ViewTargetAs( const gfx::ScaleFactor& aScaleFactor,