Bug 1271931 - Make DisplayItem::IsUniform to return Maybe<nscolor>. r?tnikkel
Maybe<nscolor> ensures that correct value is returned and also makes the
error checking clearer than using a out param.
MozReview-Commit-ID: 39uHIFCZzqn
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -2507,19 +2507,19 @@ ContainerState::FindOpaqueBackgroundColo
if (assignedItem.mClip.IsRectAffectedByClip(deviceRect,
mParameters.mXScale,
mParameters.mYScale,
mAppUnitsPerDevPixel)) {
return NS_RGBA(0,0,0,0);
}
- nscolor color;
- if (item->IsUniform(mBuilder, &color) && NS_GET_A(color) == 255)
- return color;
+ Maybe<nscolor> color = item->IsUniform(mBuilder);
+ if (color && NS_GET_A(*color) == 255)
+ return *color;
return NS_RGBA(0,0,0,0);
}
*aOutIntersectsLayer = false;
return NS_RGBA(0,0,0,0);
}
@@ -3417,44 +3417,43 @@ PaintedLayerData::Accumulate(ContainerSt
bool isFirstVisibleItem = mVisibleRegion.IsEmpty();
if (isFirstVisibleItem) {
nscolor fontSmoothingBGColor;
if (aItem->ProvidesFontSmoothingBackgroundColor(&fontSmoothingBGColor)) {
mFontSmoothingBackgroundColor = fontSmoothingBGColor;
}
}
- nscolor uniformColor;
- bool isUniform = aItem->IsUniform(aState->mBuilder, &uniformColor);
+ Maybe<nscolor> uniformColor = aItem->IsUniform(aState->mBuilder);
// Some display items have to exist (so they can set forceTransparentSurface
// below) but don't draw anything. They'll return true for isUniform but
// a color with opacity 0.
- if (!isUniform || NS_GET_A(uniformColor) > 0) {
+ if (!uniformColor || NS_GET_A(*uniformColor) > 0) {
// Make sure that the visible area is covered by uniform pixels. In
// particular this excludes cases where the edges of the item are not
// pixel-aligned (thus the item will not be truly uniform).
- if (isUniform) {
+ if (uniformColor) {
bool snap;
nsRect bounds = aItem->GetBounds(aState->mBuilder, &snap);
if (!aState->ScaleToInsidePixels(bounds, snap).Contains(aVisibleRect)) {
- isUniform = false;
+ uniformColor = Nothing();
FLB_LOG_PAINTED_LAYER_DECISION(this, " Display item does not cover the visible rect\n");
}
}
- if (isUniform) {
+ if (uniformColor) {
if (isFirstVisibleItem) {
// This color is all we have
- mSolidColor = uniformColor;
+ mSolidColor = *uniformColor;
mIsSolidColorInVisibleRegion = true;
} else if (mIsSolidColorInVisibleRegion &&
mVisibleRegion.IsEqual(nsIntRegion(aVisibleRect)) &&
clipMatches) {
// we can just blend the colors together
- mSolidColor = NS_ComposeColors(mSolidColor, uniformColor);
+ mSolidColor = NS_ComposeColors(mSolidColor, *uniformColor);
} else {
FLB_LOG_PAINTED_LAYER_DECISION(this, " Layer not a solid color: Can't blend colors togethers\n");
mIsSolidColorInVisibleRegion = false;
}
} else {
FLB_LOG_PAINTED_LAYER_DECISION(this, " Layer is not a solid color: Display item is not uniform over the visible bound\n");
mIsSolidColorInVisibleRegion = false;
}
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2878,23 +2878,22 @@ nsDisplayBackgroundImage::GetOpaqueRegio
layer.mClip != NS_STYLE_IMAGELAYER_CLIP_TEXT) {
result = GetInsideClipRegion(this, layer.mClip, mBounds, mBackgroundRect);
}
}
return result;
}
-bool
-nsDisplayBackgroundImage::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) {
+Maybe<nscolor>
+nsDisplayBackgroundImage::IsUniform(nsDisplayListBuilder* aBuilder) {
if (!mBackgroundStyle) {
- *aColor = NS_RGBA(0,0,0,0);
- return true;
- }
- return false;
+ return Some(NS_RGBA(0,0,0,0));
+ }
+ return Nothing();
}
nsRect
nsDisplayBackgroundImage::GetPositioningArea()
{
if (!mBackgroundStyle) {
return nsRect();
}
@@ -3126,24 +3125,23 @@ nsDisplayThemedBackground::GetOpaqueRegi
*aSnap = false;
if (mThemeTransparency == nsITheme::eOpaque) {
result = mBackgroundRect;
}
return result;
}
-bool
-nsDisplayThemedBackground::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) {
+Maybe<nscolor>
+nsDisplayThemedBackground::IsUniform(nsDisplayListBuilder* aBuilder) {
if (mAppearance == NS_THEME_WIN_BORDERLESS_GLASS ||
mAppearance == NS_THEME_WIN_GLASS) {
- *aColor = NS_RGBA(0,0,0,0);
- return true;
- }
- return false;
+ return Some(NS_RGBA(0,0,0,0));
+ }
+ return Nothing();
}
bool
nsDisplayThemedBackground::ProvidesFontSmoothingBackgroundColor(nscolor* aColor)
{
nsITheme* theme = mFrame->PresContext()->GetTheme();
return theme->WidgetProvidesFontSmoothingBackgroundColor(mFrame, mAppearance, aColor);
}
@@ -3420,21 +3418,20 @@ nsDisplayBackgroundColor::GetOpaqueRegio
*aSnap = true;
const nsStyleImageLayers::Layer& bottomLayer = mBackgroundStyle->BottomLayer();
return nsDisplayBackgroundImage::GetInsideClipRegion(this, bottomLayer.mClip,
mBackgroundRect, mBackgroundRect);
}
-bool
-nsDisplayBackgroundColor::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
-{
- *aColor = mColor.ToABGR();
- return true;
+Maybe<nscolor>
+nsDisplayBackgroundColor::IsUniform(nsDisplayListBuilder* aBuilder)
+{
+ return Some(mColor.ToABGR());
}
void
nsDisplayBackgroundColor::HitTest(nsDisplayListBuilder* aBuilder,
const nsRect& aRect,
HitTestState* aState,
nsTArray<nsIFrame*> *aOutFrames)
{
@@ -4084,19 +4081,20 @@ nsDisplayWrapList::GetOpaqueRegion(nsDis
nsRegion result;
if (mList.IsOpaque()) {
// Everything within GetBounds that's visible is opaque.
result = GetBounds(aBuilder, aSnap);
}
return result;
}
-bool nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) {
- // We could try to do something but let's conservatively just return false.
- return false;
+Maybe<nscolor>
+nsDisplayWrapList::IsUniform(nsDisplayListBuilder* aBuilder) {
+ // We could try to do something but let's conservatively just return Nothing.
+ return Nothing();
}
void nsDisplayWrapList::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) {
NS_ERROR("nsDisplayWrapList should have been flattened away for painting");
}
/**
@@ -6314,29 +6312,33 @@ nsRegion nsDisplayTransform::GetOpaqueRe
}
return result;
}
/* The transform is uniform if it fills the entire bounding rect and the
* wrapped list is uniform. See GetOpaqueRegion for discussion of why this
* works.
*/
-bool nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor)
+Maybe<nscolor>
+nsDisplayTransform::IsUniform(nsDisplayListBuilder *aBuilder)
{
nsRect untransformedVisible;
if (!UntransformVisibleRect(aBuilder, &untransformedVisible)) {
- return false;
+ return Nothing();
}
const Matrix4x4& matrix = GetTransform();
Matrix matrix2d;
- return matrix.Is2D(&matrix2d) &&
- matrix2d.PreservesAxisAlignedRectangles() &&
- mStoredList.GetVisibleRect().Contains(untransformedVisible) &&
- mStoredList.IsUniform(aBuilder, aColor);
+ if (matrix.Is2D(&matrix2d) &&
+ matrix2d.PreservesAxisAlignedRectangles() &&
+ mStoredList.GetVisibleRect().Contains(untransformedVisible)) {
+ return mStoredList.IsUniform(aBuilder);
+ }
+
+ return Nothing();
}
/* If UNIFIED_CONTINUATIONS is defined, we can merge two display lists that
* share the same underlying content. Otherwise, doing so results in graphical
* glitches.
*/
#ifndef UNIFIED_CONTINUATIONS
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -1554,21 +1554,21 @@ public:
*/
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap)
{
*aSnap = false;
return nsRegion();
}
/**
- * If this returns true, then aColor is set to the uniform color
- * @return true if the item is guaranteed to paint every pixel in its
+ * @return Some(nscolor) if the item is guaranteed to paint every pixel in its
* bounds with the same (possibly translucent) color
*/
- virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) { return false; }
+ virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder)
+ { return mozilla::Nothing(); }
/**
* @return true if the contents of this item are rendered fixed relative
* to the nearest viewport.
*/
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
{ return false; }
virtual bool ClearsBackground()
@@ -2616,20 +2616,19 @@ public:
*aSnap = false;
nsRegion result;
if (NS_GET_A(mColor) == 255) {
result = GetBounds(aBuilder, aSnap);
}
return result;
}
- virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override
+ virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override
{
- *aColor = mColor;
- return true;
+ return mozilla::Some(mColor);
}
protected:
nscolor mColor;
};
class nsDisplaySolidColor : public nsDisplaySolidColorBase {
public:
@@ -2696,17 +2695,17 @@ public:
const ContainerLayerParameters& aContainerParameters) override;
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) override;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) override;
- virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override;
+ virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
/**
* GetBounds() returns the background painting area.
*/
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
virtual uint32_t GetPerFrameKey() override;
NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
@@ -2792,17 +2791,17 @@ public:
nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
const nsRect& aBackgroundRect);
virtual ~nsDisplayThemedBackground();
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) override;
- virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override;
+ virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
virtual bool ProvidesFontSmoothingBackgroundColor(nscolor* aColor) override;
/**
* GetBounds() returns the background painting area.
*/
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
NS_DISPLAY_DECL_NAME("ThemedBackground", TYPE_THEMED_BACKGROUND)
@@ -2856,17 +2855,17 @@ public:
, mBackgroundStyle(aBackgroundStyle)
, mColor(Color::FromABGR(aColor))
{ }
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) override;
- virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override;
+ virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
virtual void ApplyOpacity(nsDisplayListBuilder* aBuilder,
float aOpacity,
const DisplayItemClip* aClip) override;
virtual bool CanApplyOpacity() const override;
@@ -2917,20 +2916,19 @@ public:
}
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) override {
*aSnap = false;
return GetBounds(aBuilder, aSnap);
}
- virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override
+ virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override
{
- *aColor = NS_RGBA(0, 0, 0, 0);
- return true;
+ return mozilla::Some(NS_RGBA(0, 0, 0, 0));
}
virtual bool ClearsBackground() override
{
return true;
}
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
@@ -3228,17 +3226,17 @@ public:
// the frame.
mVisibleRect.UnionRect(mBaseVisibleRect, mList.GetVisibleRect());
}
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames) override;
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) override;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) override;
- virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override;
+ virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override;
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) override;
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) override;
virtual bool TryMerge(nsDisplayItem* aItem) override {
return false;
}
virtual void GetMergedFrames(nsTArray<nsIFrame*>* aFrames) override
{
@@ -3928,17 +3926,17 @@ public:
virtual nsDisplayList* GetChildren() override { return mStoredList.GetChildren(); }
virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames) override;
virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap) override;
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
bool* aSnap) override;
- virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor) override;
+ virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder *aBuilder) override;
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aContainerParameters) override;
virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override;
virtual bool ComputeVisibility(nsDisplayListBuilder *aBuilder,
@@ -4263,19 +4261,19 @@ public:
{}
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) override
{
return mList.GetOpaqueRegion(aBuilder, aSnap);
}
- virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) override
+ virtual mozilla::Maybe<nscolor> IsUniform(nsDisplayListBuilder* aBuilder) override
{
- return mList.IsUniform(aBuilder, aColor);
+ return mList.IsUniform(aBuilder);
}
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerLayerParameters& aParameters) override;
virtual bool ShouldBuildLayerEvenIfInvisible(nsDisplayListBuilder* aBuilder) override
{
--- a/layout/base/nsLayoutDebugger.cpp
+++ b/layout/base/nsLayoutDebugger.cpp
@@ -129,17 +129,16 @@ PrintDisplayItemTo(nsDisplayListBuilder*
content->GetClasses()->ToString(tmp);
contentData.AppendLiteral(" class:");
contentData.Append(tmp);
}
}
bool snap;
nsRect rect = aItem->GetBounds(aBuilder, &snap);
nsRect layerRect = rect - (*aItem->GetAnimatedGeometryRoot())->GetOffsetToCrossDoc(aItem->ReferenceFrame());
- nscolor color;
nsRect vis = aItem->GetVisibleRect();
nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
nsDisplayList* list = aItem->GetChildren();
const DisplayItemClip& clip = aItem->GetClip();
nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, &snap);
#ifdef MOZ_DUMP_PAINTING
if (aDumpHtml && aItem->Painted()) {
@@ -154,17 +153,17 @@ PrintDisplayItemTo(nsDisplayListBuilder*
aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(contentData).get(),
(aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""),
rect.x, rect.y, rect.width, rect.height,
layerRect.x, layerRect.y, layerRect.width, layerRect.height,
vis.x, vis.y, vis.width, vis.height,
component.x, component.y, component.width, component.height,
clip.ToString().get(),
DisplayItemScrollClip::ToString(aItem->ScrollClip()).get(),
- aItem->IsUniform(aBuilder, &color) ? " uniform" : "",
+ aItem->IsUniform(aBuilder) ? " uniform" : "",
aItem->ReferenceFrame(), aItem->GetAnimatedGeometryRoot()->mFrame);
for (auto iter = opaque.RectIter(); !iter.Done(); iter.Next()) {
const nsRect& r = iter.Get();
aStream << nsPrintfCString(" (opaque %d,%d,%d,%d)", r.x, r.y, r.width, r.height);
}
if (aItem->Frame()->StyleDisplay()->mWillChange.Length() > 0) {