Skip to content

Commit

Permalink
Bug 1227216. Part 2: Fallback to blur destination rect if a large sha…
Browse files Browse the repository at this point in the history
…dow offset occurs. r=mstange
  • Loading branch information
Mason Chang committed Dec 4, 2015
1 parent 380d965 commit 4300e45
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 6 deletions.
39 changes: 33 additions & 6 deletions gfx/thebes/gfxBlur.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,8 @@ gfxAlphaBoxBlur::GetInsetBlur(IntMargin& aExtendDestBy,
const RectCornerRadii& aInnerClipRadii,
const Color& aShadowColor,
const bool& aHasBorderRadius,
const Point aShadowOffset,
bool& aMovedOffset,
gfxContext* aDestinationCtx)
{
if (!gBlurCache) {
Expand All @@ -933,14 +935,27 @@ gfxAlphaBoxBlur::GetInsetBlur(IntMargin& aExtendDestBy,
aShadowClipRect, aHasBorderRadius,
aInnerClipRadii);

// If we have a shadow offset larger than the min rect,
// there's no clean way we can properly create a min rect with the offset
// in the correct place and still render correctly. In those cases,
// fallback to just rendering the dest rect as is.
bool useDestRect = (std::abs(aShadowOffset.x) > aSlice.left) ||
(std::abs(aShadowOffset.y) > aSlice.top);
aMovedOffset = false;
if (useDestRect) {
aDestinationRect.ToIntRect(&outerRect);
aShadowClipRect.ToIntRect(&innerRect);
aMovedOffset = true;
}

DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
BlurCacheData* cached =
gBlurCache->LookupInsetBoxShadow(outerRect.Size(), innerRect.Size(),
aBlurRadius, aSpreadRadius,
&aInnerClipRadii, aShadowColor,
aHasBorderRadius,
destDrawTarget->GetBackendType());
if (cached) {
if (cached && !useDestRect) {
aExtendDestBy = cached->mExtendDest;
// Need to extend it twice: once for the outer rect and once for the inner rect.
aSlice += aExtendDestBy;
Expand Down Expand Up @@ -985,14 +1000,22 @@ gfxAlphaBoxBlur::GetInsetBlur(IntMargin& aExtendDestBy,

IntRect blurRect(topLeft, minInsetBlur->GetSize());
aExtendDestBy = blurRect - outerRect;
aSlice += aExtendDestBy;
aSlice += aExtendDestBy;

CacheInsetBlur(outerRect.Size(), innerRect.Size(),
if (useDestRect) {
// Since we're just going to paint the actual rect to the destination
aSlice.SizeTo(0, 0, 0, 0);
} else {
aSlice += aExtendDestBy;
aSlice += aExtendDestBy;

CacheInsetBlur(outerRect.Size(), innerRect.Size(),
aBlurRadius, aSpreadRadius,
&aInnerClipRadii, aShadowColor,
aHasBorderRadius, destDrawTarget->GetBackendType(),
aExtendDestBy, minInsetBlur);

}

return minInsetBlur.forget();
}

Expand Down Expand Up @@ -1027,11 +1050,13 @@ gfxAlphaBoxBlur::BlurInsetBox(gfxContext* aDestinationCtx,

IntMargin extendDest;
IntMargin slice;
bool didMoveOffset;
RefPtr<SourceSurface> minInsetBlur = GetInsetBlur(extendDest, slice,
aDestinationRect, aShadowClipRect,
aBlurRadius, aSpreadRadius,
aInnerClipRadii, aShadowColor,
aHasBorderRadius, aDestinationCtx);
aHasBorderRadius, aShadowOffset,
didMoveOffset, aDestinationCtx);
if (!minInsetBlur) {
return;
}
Expand All @@ -1041,7 +1066,9 @@ gfxAlphaBoxBlur::BlurInsetBox(gfxContext* aDestinationCtx,
srcInner.Deflate(Margin(slice));

Rect dstOuter(aDestinationRect);
dstOuter.MoveBy(aShadowOffset);
if (!didMoveOffset) {
dstOuter.MoveBy(aShadowOffset);
}
dstOuter.Inflate(Margin(extendDest));
Rect dstInner = dstOuter;
dstInner.Deflate(Margin(slice));
Expand Down
2 changes: 2 additions & 0 deletions gfx/thebes/gfxBlur.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ class gfxAlphaBoxBlur
const RectCornerRadii& aInnerClipRadii,
const mozilla::gfx::Color& aShadowColor,
const bool& aHasBorderRadius,
const mozilla::gfx::Point aShadowOffset,
bool& aMovedOffset,
gfxContext* aDestinationCtx);

/**
Expand Down
50 changes: 50 additions & 0 deletions layout/reftests/box-shadow/boxshadow-large-offset-ref.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<style>
.top {
background-color: red;
width: 800px;
height: 400px;
}

.bottom {
background-color: #fec;
width: 800px;
height: 400px;
}

.leftCut {
position: absolute;
margin-left: 0px;
margin-top: 0px;
width: 10px;
height: 800px;
background-color: black;
}

.rightCut {
position: absolute;
margin-left: 790px;
margin-top: 0px;
width: 10px;
height: 800px;
background-color: black;
}

.centerCut {
position: absolute;
margin-top: 395px;
width: 800px;
height: 20px;
background-color: black;
}
</style>

<body>
<div class="leftCut"></div>
<div class="rightCut"></div>
<div class="centerCut"></div>
<div class="top"></div>
<div class="bottom"></div>
</body>
</html>
49 changes: 49 additions & 0 deletions layout/reftests/box-shadow/boxshadow-large-offset.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<style>
.test {
background-color: #fec;
display: inline-block;
width: 800px;
height: 800px;
}

.second {
box-shadow: inset 0 400px 1px 0px red;
}

.leftCut {
position: absolute;
margin-left: 0px;
margin-top: 0px;
width: 10px;
height: 800px;
background-color: black;
}

.rightCut {
position: absolute;
margin-left: 790px;
margin-top: 0px;
width: 10px;
height: 800px;
background-color: black;
}

.centerCut {
position: absolute;
margin-top: 395px;
width: 800px;
height: 20px;
background-color: black;
}

</style>

<body>
<div class="leftCut"></div>
<div class="rightCut"></div>
<div class="centerCut"></div>
<div class="test second"></div>
</body>
</html>
1 change: 1 addition & 0 deletions layout/reftests/box-shadow/reftest.list
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ fuzzy-if(winWidget,5,30) == fieldset-inset.html fieldset-inset-ref.html # minor
== 1178575.html 1178575-ref.html
== 1178575-2.html 1178575-2-ref.html
fuzzy(159,2) fails-if(!d2d) == 1212823-1.html 1212823-1-ref.html
== boxshadow-large-offset.html boxshadow-large-offset-ref.html

0 comments on commit 4300e45

Please sign in to comment.