Open Bug 582236 Opened 10 years ago Updated 8 years ago

D2D has sloppy gradients

Categories

(Core :: Graphics, defect)

x86
Windows 7
defect
Not set
normal

Tracking

()

People

(Reporter: jrmuizel, Assigned: jrmuizel)

References

(Blocks 1 open bug)

Details

No description provided.
It appears D2D gradients can suffer from resampling artifacts. If we draw a larger gradient hard stops will become slightly fuzzy (both radial and linear). The theory here is that Direct2D designed their gradients to behave well with gradients and not so much hard stops. They rasterize the gradient to a relatively small texture. The upsampling will then make gradients still look good when linearly interpolating, hard stops however, will become slightly 'gradient'.
Assignee: nobody → jmuizelaar
Blocks: d2d-reftest
So it looks like gradients are implemented as follows:
- in software, create a 1x1024 bitmap that represents the gradient.
- distribute the stops along this bitmap and interpolate between them.
- create a texture from the bitmap
- draw a primitive that has texture coordinates that properly distribute the gradient texture
- in the case of a radial gradient a simple shader computes the distance from center
- regular texture interpolation does the rest

This seems like a pretty good scheme but has obvious problems when using hard stops because the gradient function sample rate doesn't match the pixel sample rate and so we get interpolation artifacts.

So what should we do about this? I'm not sure we have many options. I'm not positive that the gradient texture is limited to 1024 but if it is, we could possibly do multiple passes that paint subsets but that seems complicated and I'm not sure it's worth it.

I'd love to hear other opinions.
is "not worry about it" an option?
(In reply to comment #3)
> is "not worry about it" an option?

I think that it is.
I think not worrying about this is fine.

But if the entire gradient function was put in a shader, wouldn't that work pretty well? Assuming there aren't too many stops. Then again, does D2D support using your own shaders for fills?
(In reply to comment #5)
> I think not worrying about this is fine.

Disable the reftests on d2d then?

> But if the entire gradient function was put in a shader, wouldn't that work
> pretty well?

Perhaps, it feels like the shader would need to branch to find out what stops to interpolate between which isn't much fun on older hardware.
 
> Assuming there aren't too many stops. Then again, does D2D support
> using your own shaders for fills?

Nope it does not.
(In reply to comment #6)
> (In reply to comment #5)
> > I think not worrying about this is fine.
> 
> Disable the reftests on d2d then?

Probably. How many reftests are affected? Which tests?

Quartz uses coarse-ish sampling of the gradient function but we didn't have to disable tests for it. I guess Quartz isn't interpolating between positions in the bitmap. I suppose there's no way to turn that off in D2D.

> > But if the entire gradient function was put in a shader, wouldn't that work
> > pretty well?
> 
> Perhaps, it feels like the shader would need to branch to find out what stops
> to interpolate between which isn't much fun on older hardware.

OK.

> > Assuming there aren't too many stops. Then again, does D2D support
> > using your own shaders for fills?
> 
> Nope it does not.

That is unfortunate. It seems like an obvious and every useful feature. Maybe we should ask for it.
You need to log in before you can comment on or make changes to this bug.