Closed Bug 1816775 Opened 1 year ago Closed 1 year ago

Implement globalCompositeOperation "clear"

Categories

(Core :: Graphics: Canvas2D, task)

task

Tracking

()

RESOLVED FIXED
113 Branch
Tracking Status
firefox113 --- fixed

People

(Reporter: evilpie, Assigned: evilpie)

References

(Blocks 1 open bug)

Details

Attachments

(4 files)

Assignee: nobody → evilpies

Depends on D171020

I have been starring at the code in DrawTargetD2D1 for a while now and I am still not sure how to implement clear there. It's obvious to me that we can't use D2DCompositionMode, because clear is not part of D2D1_COMPOSITE_MODE. I guess there must be some other way of doing this in D2D.

Somewhat related I am puzzled why CONIC_GRADIENT/RADIAL_GRADIENT in FinalizeDrawing only handle blending and not compositing modes.

Flags: needinfo?(lsalzman)

Ultimately you will have to implement something in FinalizeDrawing that does something like ClearRect, i.e. a brush with color white.

Flags: needinfo?(lsalzman)

I don't really understand how to get the correct bounds for the clear. I just don't have enough experience with graphics and D2D in particular to make much progress here myself. Maybe someone else wants to finish this up. I think most of the other stuff is in acceptable state.

Flags: needinfo?(lsalzman)
Flags: needinfo?(lsalzman) → needinfo?(tnikkel)

I believe if you just do something like the following it should just work: https://paste.mozilla.org/kdbv8uM5

Make sure D2DSupportsCompositeMode(CompositionOp::OP_CLEAR) returns false. Rather, you don't need to modify the D2DSupportsCompositeMode/D2DCompositionMode at all in your patch if you just do things like I show above.

Flags: needinfo?(tnikkel) → needinfo?(evilpies)

This results in the whole canvas being cleared. I had tried something similar before as well.

Flags: needinfo?(evilpies)

It's an unbounded operator as you spceified it, so that's what it should do if there is no clip?

Here is an example: https://jsfiddle.net/o1e6s8q9/. This should show the page background where the two rects are being drawn.

(In reply to Tom S [:evilpie] from comment #9)

Here is an example: https://jsfiddle.net/o1e6s8q9/. This should show the page background where the two rects are being drawn.

That's not what I would expect based on how you specified the operator - that it is not bound by the mask. For example, look at how the 'copy' operator behaves in that demo. That's how an operator not bound by mask would behave. So the whole canvas should be cleared as it is currently specified.

Do we have any third-party tests that indicate whether clear is actually supposed to be bound by the mask or not?

That's not what I would expect based on how you specified the operator - that it is not bound by the mask.

If you mean IsOperatorBoundByMask that was not really intentional, I thought this would give me access to the clipped bounds.

Do we have any third-party tests that indicate whether clear is actually supposed to be bound by the mask or not?

Sadly not in WPT at least. Chrome and Safari both seem to have a bounded clear as the jsfiddle shows. I think it's possible that this behavior was inherited from cairo?

CAIRO_OPERATOR_CLEAR: clear destination layer (bounded) (Since 1.0)

For bounded operators, we need a different approach then. We will probably have to override the pattern supplied by CreateBrushForPattern(aSource) to return a clear pattern, and override the blend mode. Looks like this would be dest-out to be compatible with D2D layers and such, but here's a patch that might work (so long as IsOperatorBoundByMask is fixed):

https://paste.mozilla.org/FzyWWxh9

I hadn't seen your patch so I wrote something similar based on your comments. My approach basically requires us to lie for IsOperatorBoundByMask, which is not great.

Attachment #9319897 - Attachment description: WIP: Bug 1816775 - Implement globalCompositeOperation "clear" → Bug 1816775 - Implement globalCompositeOperation "clear". r?lsalzman
Attachment #9319907 - Attachment description: WIP: Bug 1816775 - Add test for clear → Bug 1816775 - Add test for clear. r?lsalzman

This implements OP_CLEAR by ensuring the shader always outputs a mask value that
represents coverage. Clear color is then blended in proportion to the coverage
value.

Attachment #9319897 - Attachment description: Bug 1816775 - Implement globalCompositeOperation "clear". r?lsalzman → Bug 1816775 - Implement globalCompositeOperation "clear" without Windows. r?lsalzman
Pushed by evilpies@gmail.com:
https://hg.mozilla.org/integration/autoland/rev/77863ad34930
Implement globalCompositeOperation "clear" without Windows. r=lsalzman
https://hg.mozilla.org/integration/autoland/rev/4cf858f7a3d6
Add test for clear. r=lsalzman
https://hg.mozilla.org/integration/autoland/rev/5e069b4ea9ac
Handle OP_CLEAR in DrawTargetWebgl. r=aosmond,gfx-reviewers
https://hg.mozilla.org/integration/autoland/rev/f7afb890b556
Handle OP_CLEAR in DrawTargetD2D1. r=aosmond
Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/39300 for changes under testing/web-platform/tests
Upstream PR merged by moz-wptsync-bot
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: