Closed Bug 1250037 Opened 8 years ago Closed 8 years ago

box-shadow extremely slow when width or height exceeds certain size, especially noticeable when combined with animation

Categories

(Core :: Graphics, defect, P3)

defect

Tracking

()

RESOLVED FIXED
mozilla53
Tracking Status
firefox53 --- fixed

People

(Reporter: kanru, Assigned: lsalzman)

References

Details

(Keywords: perf, Whiteboard: [gfx-noted])

Attachments

(6 files, 1 obsolete file)

I noticed this big jank on the workday front-page. The animation used to enlarge a button to fill whole screen used something like |transform: scale(40,40)|, I think. The profile I captured spent a fair amount of time in mozilla::gfx::BoxBlurVertical.

Compare to google chrome, they managed to display the same animation without noticeable jank. I think the difference is they use low resolution shadow in and after the animation while we recompute a higher resolution shadow every time. See the attached screenshot.
Attached image Screenshot Firefox 46
Attached image Screenshot Chrome 48
Attached file Test case (obsolete) —
Whiteboard: [gfx-noted]
Our box shadows were always super slow. I just made it fast in common cases where we could make a minimum box shadow. The problem here is the 9999x border radius probably. 

If chrome does a low resolution shadow then a high resolution, that could explain it. I know our actual box shadow code generation is super super slow.
Keywords: perf
(In reply to Mason Chang [:mchang] from comment #4)
> Our box shadows were always super slow. I just made it fast in common cases
> where we could make a minimum box shadow. The problem here is the 9999x
> border radius probably. 
> 
> If chrome does a low resolution shadow then a high resolution, that could
> explain it. I know our actual box shadow code generation is super super slow.

I think that we recompute the shadow for each frame is also very slow.
(In reply to Kan-Ru Chen [:kanru] (UTC+8) from comment #5)
> (In reply to Mason Chang [:mchang] from comment #4)
> > Our box shadows were always super slow. I just made it fast in common cases
> > where we could make a minimum box shadow. The problem here is the 9999x
> > border radius probably. 
> > 
> > If chrome does a low resolution shadow then a high resolution, that could
> > explain it. I know our actual box shadow code generation is super super slow.
> 
> I think that we recompute the shadow for each frame is also very slow.

Yes because if a box-shadow is too big, we don't cache the box-shadow to save memory :/.
Attached file bug-1250037.html
Better test case
Attachment #8721847 - Attachment is obsolete: true
milan, would you consider to fix this issue in near future ? The **** animation really let me down every time I use Workday...
Flags: needinfo?(milan)
That's your first mistake, trying to use Workday :)  Lee is looking at this a bit, we may get some improvements shortly.
Flags: needinfo?(milan)
I measured the current BoxBlur impl performance a few days ago. It does have O(n) performance against the blur area. So to improve this we should try to reduce amount of blurs we have to recompute during animation.
So the basic idea of this patch is a lot of box shadows are symmetric with respects to their corners. For those shadows, blurring all 4 quadrants is a waste, since we can just only blur one and mirror it out to the rest.

For large box shadows this was measured to give an overall 2-3x speedup as measured.

In the process of this patch, I did a lot of drive-by cleanups to just make things saner in here:

Removed the need to allocate the AlphaBoxBlur class (via MakeUnique) which required adding an Init() constructor to deal with how gfxAlphaBoxBlur and nsCSSRendering were using it. Removed some other questionable allocations for dirtyRect/skipRect thanks to the Maybe utility.

Added a new InitDrawTarget constructor since the Init variant that returned a gfxContext was essentially useless - we immediately pulled the DrawTarget from it and just totally ignored it, thus doing wasteful extra allocations/initialization of an expensive object we don't use here.

Use calloc to allocate the blur data instead of new + memset, since the calloc may avoid the memset if the memory pages are already mapped in zeroed, and thus save us some performance.

Cleaned up the strangeness that outset box shadows used a pointer to RectCornerRadii being null to indicate no border radius, while insets used a boolean plus a reference. Just made it all use a pointer so that we have fewer parameters everywhere now.

Removed some strangeness with DrawTarget&, whereas it is more customary these days to use DrawTarget*.

Use IntSize::Truncate/IntSize::Ceil/etc. where appropriate.

Cleaned up some function parameters that were large objects passed by value (thus causing a lot of stack shuffling), so these are now passed by const-ref.

Fixed weirdness with spread radius being passed to BlurInsetBox even though we ignore it since it is factored into the corner radii already.
Attachment #8807409 - Flags: review?(mchang)
Comment on attachment 8807409 [details] [diff] [review]
only blur one quadrant of a box-shadow and mirror it to the other quadrants

Review of attachment 8807409 [details] [diff] [review]:
-----------------------------------------------------------------

::: gfx/2d/PathHelpers.h
@@ +224,5 @@
>      return true;
>    }
>  
> +  bool AreRadiiSame() const {
> +    for (size_t i = 1; i < RectCorner::Count; i++) {

Probably worth commenting why this loop starts at 1.
First, this patch extends DrawSurfaceWithShadow to support A8 inputs, which for Skia and D2D is pretty trivial, though Cairo's tee surface stuff (where the tee surface is essentially a dual surface that wrote to an A8 and a BGRA8 simultaneously) required a bit more hackery to fix.

Some of the code in gfxAlpaBoxBlur needed to be refactored since DrawSurfaceWithShadow is essentially blurring the mask and coloring it all in one step, whereas previously gfxAlphaBoxBlur separated these out as two phases/functions.

Also, the Init constructors for gfxAlphaBoxBlur now need to know about the destination gfxContext/DrawTarget early so they can make the decision whether to accelerate the shadow or not, rather than deferring this decision all the way to DoBlur.
Assignee: nobody → lsalzman
Status: NEW → ASSIGNED
Attachment #8808254 - Flags: review?(mchang)
Comment on attachment 8807409 [details] [diff] [review]
only blur one quadrant of a box-shadow and mirror it to the other quadrants

Review of attachment 8807409 [details] [diff] [review]:
-----------------------------------------------------------------

::: gfx/thebes/gfxBlur.cpp
@@ +448,5 @@
> +  // If mirroring corners, we only need to draw the top-left quadrant.
> +  // Use ceil to preserve the remaining 1x1 middle area for minimized box
> +  // shadows.
> +  if (aMirrorCorners) {
> +    blurRect.SizeTo(ceil(blurRect.width * 0.5f), ceil(blurRect.height * 0.5f));

What am I missing here? Where are we telling the blur to only blur the top left corner. From my understanding of this code, we're still blurring the whole aMinSize.
(In reply to Mason Chang [:mchang] from comment #15)
> Comment on attachment 8807409 [details] [diff] [review]
> only blur one quadrant of a box-shadow and mirror it to the other quadrants
> 
> Review of attachment 8807409 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: gfx/thebes/gfxBlur.cpp
> @@ +448,5 @@
> > +  // If mirroring corners, we only need to draw the top-left quadrant.
> > +  // Use ceil to preserve the remaining 1x1 middle area for minimized box
> > +  // shadows.
> > +  if (aMirrorCorners) {
> > +    blurRect.SizeTo(ceil(blurRect.width * 0.5f), ceil(blurRect.height * 0.5f));
> 
> What am I missing here? Where are we telling the blur to only blur the top
> left corner. From my understanding of this code, we're still blurring the
> whole aMinSize.

It is exactly that line that does it. We are resizing the rect (blurRect) we pass to InitDrawTarget to be half the size in each dimension, so what is left over IS the top-left quadrant, rather than the full size. With the one caveat we need to just leave the 1 pixel boundary at the bottom and to the right of the corner intact for minimized shadows, which will be stretching that area, taken care of that ceil there as described. In any case, the size that we pass in to InitDrawTarget is all that will end up getting allocated and blurred.
This speeds up the fallback box blur implementation that we use when blurs are too large to be processed by the integral image method.

Total speedup is at least 2-3x times the original fallback and is pretty damned close to even with the performance of the SSE2 integral image blur. This way, we shouldn't have much of a performance cliff when transferring from one to the other.

This incorporates a few ideas of my own plus some lifted from the Skia implementation all of which individually give measurable speedup:

Does all 3 passes of the blur on each row in turn, thus requiring much less temporary storage and being much more cache-friendly.

Moves all of the bounds clamping of samples out of the inner loops.

Forcefully unrolls the inner loops to better amortize the cost of the branch condition/jump relative to the small cost of the inner loop itself.

Uses a smaller shift which generates more friendly code for 32 bit platforms. Adds some cheap biasing to make the result round out better none the less.

Fixes the old code's confusion about width and stride too.

Also, templates the horizontal/vertical distinction so that we don't need to have two almost duplicate versions of the blur.

Maybe in the future it would be worth investigating whether we still need the integral image code, but for now I will set that aside and would like to at least get the fallback code up to par.
Attachment #8808465 - Flags: review?(bas)
Attachment #8807409 - Flags: review?(mchang) → review+
Comment on attachment 8808254 [details] [diff] [review]
use DrawTarget::DrawSurfaceWithShadow to render box shadows on platforms that accelerate it

Review of attachment 8808254 [details] [diff] [review]:
-----------------------------------------------------------------

Thanks, just some minor fixes.

::: gfx/thebes/gfxBlur.cpp
@@ +88,5 @@
> +    mData = static_cast<uint8_t*>(calloc(1, blurDataSize));
> +    if (!mData) {
> +      return nullptr;
> +    }
> +    mDrawTarget =

Can't we just make a DrawTargetSkia and assume we're going to use that here?

@@ +149,2 @@
>  {
> +  if (mData) {

nit: if (mAccelerated) and assert mData exists. Seems like aOutTopLeft only matters if we're accelerated also?

::: gfx/thebes/gfxBlur.h
@@ +56,5 @@
>  
>      /**
>       * Constructs a box blur and initializes the temporary surface.
> +     *
> +     * @param aDestinationCtx The destination to blur to.

I thought we don't want gfxContexts anymore?

::: gfx/thebes/gfxPlatform.cpp
@@ +1435,5 @@
>  
>    if (Factory::DoesBackendSupportDataDrawtarget(aDT->GetBackendType())) {
>      dt = aDT->CreateSimilarDrawTarget(aSize, aFormat);
>    } else {
> +#ifdef USE_SKIA

Since we depend on Skia now, I'd just create a skia backend instead of falling back to cairo. Do we ever not use  USE_SKIA anymore?
Attachment #8808254 - Flags: review?(mchang) → review+
Comment on attachment 8808465 [details] [diff] [review]
optimize the Moz2d fallback box blur implementation

Review of attachment 8808465 [details] [diff] [review]:
-----------------------------------------------------------------

::: gfx/2d/Blur.cpp
@@ +138,5 @@
> +    *dst = (alphaSum * reciprocal) >> 24; \
> +    alphaSum += *src - firstVal; \
> +    dst += outputStep; \
> +    src += inputStep;
> +  while (dst + 16*outputStep <= iterEnd) {

nit: whitespace
Attachment #8808465 - Flags: review?(bas) → review+
Pushed by lsalzman@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/25840ab0d453
part 1 - only blur one quadrant of a box-shadow and mirror it to the other quadrants. r=mchang
https://hg.mozilla.org/integration/mozilla-inbound/rev/5504280ce43c
part 2 - use DrawTarget::DrawSurfaceWithShadow to render box shadows on platforms that accelerate it. r=mchang
https://hg.mozilla.org/integration/mozilla-inbound/rev/c4646823814d
part 3 - optimize the Moz2d fallback box blur implementation. r=bas
Pushed by lsalzman@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/fb4d2febca8d
followup - fix AlphaBoxBlur comments. r=me
Backed out for assertion in Windows 8 x64 debug bc6 in browser_UITour.js:

https://hg.mozilla.org/integration/mozilla-inbound/rev/144ca2b74fd2c4f37fde99e293b2f4104e87b9e1
https://hg.mozilla.org/integration/mozilla-inbound/rev/436011c88130cd63ec6e96b6ef5213bb5e98320e
https://hg.mozilla.org/integration/mozilla-inbound/rev/3e43267d9e86e9074d98235ed343cb2dcaa22553
https://hg.mozilla.org/integration/mozilla-inbound/rev/5fc5fa72325d75f7ab81458c9c839d5d8783b74a

Push with failure: https://treeherder.mozilla.org/#/jobs?repo=mozilla-inbound&revision=c4646823814dd3aba384c6bf414804eb06234db3
Failure log: https://treeherder.mozilla.org/logviewer.html#?job_id=39404547&repo=mozilla-inbound

14:10:49     INFO - Assertion failure: subimage.Contains(aSubImage), at c:/builds/moz2_slave/m-in-w64-d-0000000000000000000/build/src/gfx/2d/DrawTargetCairo.cpp:347
14:11:01     INFO - #01: mozilla::gfx::GfxPatternToCairoPattern [gfx/2d/DrawTargetCairo.cpp:509]
14:11:01     INFO - 
14:11:01     INFO - #02: mozilla::gfx::DrawTargetCairo::DrawPattern(mozilla::gfx::Pattern const &,mozilla::gfx::StrokeOptions const &,mozilla::gfx::DrawOptions const &,mozilla::gfx::DrawTargetCairo::DrawPatternType,bool) [gfx/2d/DrawTargetCairo.cpp:994]
14:11:01     INFO - 
14:11:01     INFO - #03: mozilla::gfx::DrawTargetCairo::FillRect(mozilla::gfx::RectTyped<mozilla::gfx::UnknownUnits,float> const &,mozilla::gfx::Pattern const &,mozilla::gfx::DrawOptions const &) [gfx/2d/DrawTargetCairo.cpp:1092]
14:11:01     INFO - 
14:11:01     INFO - #04: RepeatOrStretchMirroredSurface [gfx/thebes/gfxBlur.cpp:789]
14:11:01     INFO - 
14:11:01     INFO - #05: DrawMirroredMinBoxShadow [gfx/thebes/gfxBlur.cpp:828]
14:11:01     INFO - 
14:11:01     INFO - #06: gfxAlphaBoxBlur::BlurRectangle(gfxContext *,gfxRect const &,mozilla::gfx::RectCornerRadii const *,gfxPoint const &,mozilla::gfx::Color const &,gfxRect const &,gfxRect const &) [gfx/thebes/gfxBlur.cpp:906]
14:11:01     INFO - 
14:11:01     INFO - #07: nsContextBoxBlur::BlurRectangle(gfxContext *,nsRect const &,int,mozilla::gfx::RectCornerRadii *,int,mozilla::gfx::Color const &,nsRect const &,gfxRect const &) [layout/base/nsCSSRendering.cpp:6029]
14:11:01     INFO - 
14:11:01     INFO - #08: nsCSSRendering::PaintBoxShadowOuter(nsPresContext *,nsRenderingContext &,nsIFrame *,nsRect const &,nsRect const &,float) [layout/base/nsCSSRendering.cpp:1504]
14:11:01     INFO - 
14:11:01     INFO - #09: nsDisplayBoxShadowOuter::Paint(nsDisplayListBuilder *,nsRenderingContext *) [layout/base/nsDisplayList.cpp:4137]
14:11:01     INFO - 
14:11:01     INFO - #10: mozilla::FrameLayerBuilder::PaintItems(nsTArray<mozilla::FrameLayerBuilder::ClippedDisplayItem> &,mozilla::gfx::IntRectTyped<mozilla::gfx::UnknownUnits> const &,gfxContext *,nsRenderingContext *,nsDisplayListBuilder *,nsPresContext *,mozilla::gfx::IntPointTyped<mozilla::gfx::UnknownUnits> const &,float,float,int) [layout/base/FrameLayerBuilder.cpp:5931]
14:11:01     INFO - 
14:11:01     INFO - #11: mozilla::FrameLayerBuilder::DrawPaintedLayer(mozilla::layers::PaintedLayer *,gfxContext *,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::layers::DrawRegionClip,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,void *) [layout/base/FrameLayerBuilder.cpp:6106]
14:11:01     INFO - 
14:11:01     INFO - #12: mozilla::layers::BasicPaintedLayer::PaintBuffer(gfxContext *,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,bool,mozilla::layers::DrawRegionClip,void (*)(mozilla::layers::PaintedLayer *,gfxContext *,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::layers::DrawRegionClip,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,void *),void *) [gfx/layers/basic/BasicPaintedLayer.h:121]
14:11:01     INFO - 
14:11:01     INFO - #13: mozilla::layers::BasicPaintedLayer::Validate(void (*)(mozilla::layers::PaintedLayer *,gfxContext *,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::layers::DrawRegionClip,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,void *),void *,mozilla::layers::ReadbackProcessor *) [gfx/layers/basic/BasicPaintedLayer.cpp:189]
14:11:01     INFO - 
14:11:01     INFO - #14: mozilla::layers::BasicContainerLayer::Validate(void (*)(mozilla::layers::PaintedLayer *,gfxContext *,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::layers::DrawRegionClip,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,void *),void *,mozilla::layers::ReadbackProcessor *) [gfx/layers/basic/BasicContainerLayer.cpp:156]
14:11:01     INFO - 
14:11:01     INFO - #15: mozilla::layers::BasicLayerManager::EndTransactionInternal(void (*)(mozilla::layers::PaintedLayer *,gfxContext *,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,mozilla::layers::DrawRegionClip,mozilla::gfx::IntRegionTyped<mozilla::gfx::UnknownUnits> const &,void *),void *,mozilla::layers::LayerManager::EndTransactionFlags) [gfx/layers/basic/BasicLayerManager.cpp:598]
14:11:01     INFO - 
14:11:01     INFO - #16: nsDisplayList::PaintRoot(nsDisplayListBuilder *,nsRenderingContext *,unsigned int) [layout/base/nsDisplayList.cpp:2004]
14:11:01     INFO - 
14:11:01     INFO - #17: nsLayoutUtils::PaintFrame(nsRenderingContext *,nsIFrame *,nsRegion const &,unsigned int,nsDisplayListBuilderMode,nsLayoutUtils::PaintFrameFlags) [layout/base/nsLayoutUtils.cpp:3619]
14:11:01     INFO - 
14:11:01     INFO - #18: PresShell::Paint(nsView *,nsRegion const &,unsigned int) [layout/base/nsPresShell.cpp:6378]
14:11:01     INFO - 
14:11:01     INFO - #19: nsViewManager::ProcessPendingUpdatesPaint(nsIWidget *) [view/nsViewManager.cpp:484]
14:11:01     INFO - 
14:11:01     INFO - #20: nsViewManager::ProcessPendingUpdatesForView(nsView *,bool) [view/nsViewManager.cpp:411]
14:11:01     INFO - 
14:11:01     INFO - #21: nsViewManager::ProcessPendingUpdates() [view/nsViewManager.cpp:1119]
14:11:01     INFO - 
14:11:01     INFO - #22: nsRefreshDriver::Tick(__int64,mozilla::TimeStamp) [layout/base/nsRefreshDriver.cpp:2019]
14:11:01     INFO - 
14:11:01     INFO - #23: mozilla::RefreshDriverTimer::TickDriver(nsRefreshDriver *,__int64,mozilla::TimeStamp) [layout/base/nsRefreshDriver.cpp:327]
14:11:01     INFO - 
14:11:01     INFO - #24: mozilla::RefreshDriverTimer::TickRefreshDrivers(__int64,mozilla::TimeStamp,nsTArray<RefPtr<nsRefreshDriver> > &) [layout/base/nsRefreshDriver.cpp:297]
14:11:01     INFO - 
14:11:01     INFO - #25: mozilla::RefreshDriverTimer::Tick(__int64,mozilla::TimeStamp) [layout/base/nsRefreshDriver.cpp:319]
14:11:01     INFO - 
14:11:01     INFO - #26: mozilla::VsyncRefreshDriverTimer::RunRefreshDrivers(mozilla::TimeStamp) [layout/base/nsRefreshDriver.cpp:670]
14:11:01     INFO - 
14:11:01     INFO - #27: mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::TickRefreshDriver(mozilla::TimeStamp) [layout/base/nsRefreshDriver.cpp:591]
14:11:01     INFO - 
14:11:01     INFO - #28: mozilla::detail::RunnableMethodImpl<void ( mozilla::VsyncRefreshDriverTimer::RefreshDriverVsyncObserver::*)(mozilla::TimeStamp),1,0,mozilla::TimeStamp>::Run() [obj-firefox/dist/include/nsThreadUtils.h:812]
14:11:01     INFO - 
14:11:01     INFO - #29: nsThread::ProcessNextEvent(bool,bool *) [xpcom/threads/nsThread.cpp:1213]
14:11:01     INFO - 
14:11:01     INFO - #30: NS_ProcessNextEvent(nsIThread *,bool) [xpcom/glue/nsThreadUtils.cpp:361]
14:11:01     INFO - 
14:11:01     INFO - #31: mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate *) [ipc/glue/MessagePump.cpp:96]
14:11:01     INFO - 
14:11:01     INFO - #32: MessageLoop::RunHandler() [ipc/chromium/src/base/message_loop.cc:226]
14:11:01     INFO - 
14:11:01     INFO - #33: MessageLoop::Run() [ipc/chromium/src/base/message_loop.cc:206]
14:11:01     INFO - 
14:11:01     INFO - #34: nsBaseAppShell::Run() [widget/nsBaseAppShell.cpp:158]
14:11:01     INFO - 
14:11:01     INFO - #35: nsAppShell::Run() [widget/windows/nsAppShell.cpp:264]
14:11:01     INFO - 
14:11:01     INFO - #36: nsAppStartup::Run() [toolkit/components/startup/nsAppStartup.cpp:283]
14:11:01     INFO - 
14:11:01     INFO - #37: XREMain::XRE_mainRun() [toolkit/xre/nsAppRunner.cpp:4480]
14:11:01     INFO - 
14:11:01     INFO - #38: XREMain::XRE_main(int,char * * const,nsXREAppData const *) [toolkit/xre/nsAppRunner.cpp:4613]
14:11:01     INFO - 
14:11:01     INFO - #39: XRE_main [toolkit/xre/nsAppRunner.cpp:4704]
14:11:01     INFO - 
14:11:01     INFO - #40: do_main [browser/app/nsBrowserApp.cpp:328]
14:11:01     INFO - 
14:11:01     INFO - #41: NS_internal_main(int,char * *,char * *) [browser/app/nsBrowserApp.cpp:461]
14:11:01     INFO - 
14:11:01     INFO - #42: wmain [toolkit/xre/nsWindowsWMain.cpp:118]
14:11:01     INFO - 
14:11:01     INFO - #43: __scrt_common_main_seh [f:/dd/vctools/crt/vcstartup/src/startup/exe_common.inl:253]
14:11:01     INFO - 
14:11:01     INFO - #44: KERNEL32.DLL + 0x167e
14:11:01     INFO - 
14:11:01     INFO - #45: ntdll.dll + 0x1c3f1
14:11:01     INFO - 
14:11:01     INFO - TEST-INFO | Main app process: exit 1
14:11:01  WARNING - TEST-UNEXPECTED-FAIL | ShutdownLeaks | process() called before end of test suite
Flags: needinfo?(lsalzman)
Pushed by lsalzman@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/9b47a1c822ae
part 1 - only blur one quadrant of a box-shadow and mirror it to the other quadrants. r=mchang
https://hg.mozilla.org/integration/mozilla-inbound/rev/fddfac71bb12
part 2 - use DrawTarget::DrawSurfaceWithShadow to render box shadows on platforms that accelerate it. r=mchang
https://hg.mozilla.org/integration/mozilla-inbound/rev/edefce9fdb67
part 3 - optimize the Moz2d fallback box blur implementation. r=bas
https://hg.mozilla.org/mozilla-central/rev/9b47a1c822ae
https://hg.mozilla.org/mozilla-central/rev/fddfac71bb12
https://hg.mozilla.org/mozilla-central/rev/edefce9fdb67
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla53
Thanks! The home screen of Workday is much faster now though I won't call it smooth. Still a improvement!
Flags: needinfo?(lsalzman)
Depends on: 1333749
Setting qe-verify- since this fix seems to have automated coverage. Lee, if you think manual QA should instead be looking at this, feel free to flip the flag or ni? me.
Flags: qe-verify-
Depends on: 1357692
See Also: → 1383825
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: