Bug 63871 - [Chromium] canvas/philip/tests/2d.gradient.object.update.html is failed on chromium.
Summary: [Chromium] canvas/philip/tests/2d.gradient.object.update.html is failed on ch...
Status: RESOLVED DUPLICATE of bug 64281
Alias: None
Product: WebKit
Classification: Unclassified
Component: Canvas (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Linux
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-07-03 02:41 PDT by Dongseong Hwang
Modified: 2011-07-11 18:22 PDT (History)
10 users (show)

See Also:


Attachments
patch (11.90 KB, patch)
2011-07-03 02:52 PDT, Dongseong Hwang
no flags Details | Formatted Diff | Diff
patch (12.23 KB, patch)
2011-07-05 18:44 PDT, Dongseong Hwang
jamesr: review-
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dongseong Hwang 2011-07-03 02:41:49 PDT
From HTML5 canvas spec:
http://dev.w3.org/html5/2dcontext/#colors-and-styles

"When set to a CanvasPattern or CanvasGradient object, the assignment is live, meaning that changes made to the object after the assignment do affect subsequent stroking or filling of shapes."

However, after setting CanvasPattern or CanvasGradient object and changing the object, changes made to the object after the assignment do not affect subsequent stroking or filling of shapes on chromium.
Comment 1 Dongseong Hwang 2011-07-03 02:52:03 PDT
Created attachment 99570 [details]
patch
Comment 2 Dongseong Hwang 2011-07-03 02:54:30 PDT
[Chromium] Update Gradient and Pattern every time to draw similar to PlatformContext::prepareForSoftwareDraw() 
    
GraphicsContextSkia::set[Fill|Stroke][Gradient|Pattern] has the problem that GraphicsContextSkia does not apply gradient or pattern style if the gradient or pattern is changed after GraphicsContextSkia::set[Fill|Stroke][Gradient|Pattern].
 
For example,
 Gradient* gradient;
 gradient->doSomething();
 graphicsContext.setFillGradient(gradient);
 gradient->addColorStop(...);  <- GraphicsContextSkia does not apply this.

It is because GraphicsContextSkia creates new platform gradient or pattern object and it would be different from original gradient or pattern object in the above case.

This patch makes Chromium comform following Canvas spec.
From HTML5 canvas spec:
http://dev.w3.org/html5/2dcontext/#colors-and-styles

"When set to a CanvasPattern or CanvasGradient object, the assignment is live, meaning that changes made to the object after the assignment do affect subsequent stroking or filling of shapes."
        
This patch makes chromium pass canvas/philip/tests/2d.gradient.object.update.html
Comment 3 Eric Seidel (no email) 2011-07-05 17:50:04 PDT
Really?  We need to call that in so many places?
Comment 4 Dongseong Hwang 2011-07-05 18:44:09 PDT
Created attachment 99773 [details]
patch
Comment 5 Dongseong Hwang 2011-07-05 18:52:32 PDT
Comment on attachment 99773 [details]
patch

I think we need to call before all drawing.
I separated stroke and fill updates like CG port.
CG calls those only on fillPath, fillRect, drawRect, strokePath, and strokRect because other drawing functions render through fillPath, fillRect, drawRect, strokePath, and strokRect. However, skia drawing function directly call SkCanvas's drawing functions.

I wonders how I handle drawLineForTextChecking and drawLineForText.
I put both applyStrokePatternOrGradient and applyFillPatternOrGradient in those.
I need advice.
Comment 6 Mike Reed 2011-07-08 06:03:30 PDT
I agree this looks very invasive. Looking further up, I wonder why skia has this dual between graphicscontext->m_state (which has the gradient) and platformcontext which has the skia gradient. I notice the the webkit Gradient object itself holds a cache of the skia gradient, and it is correctly purged when addColorStop is called. If skia always went directly to m_state.fillGradient, I think we could skip all of these pushes.

Another clue that something funny is going on. Look in GraphicsContext.cpp


#if !USE(SKIA)
void GraphicsContext::setPlatformFillGradient(Gradient*)
{
}

void GraphicsContext::setPlatformFillPattern(Pattern*)
{
}

void GraphicsContext::setPlatformStrokeGradient(Gradient*)
{
}

void GraphicsContext::setPlatformStrokePattern(Pattern*)
{
}
#endif

All of these seem to exist solely for skia. If we didn't make a (premature) copy of the gradient, but reached directly into m_state each time, I think we would (a) fix this bug, and (b) avoid this whole layer of indirection/copying.
Comment 7 Stephen White 2011-07-08 10:43:22 PDT
(In reply to comment #6)
> I agree this looks very invasive. Looking further up, I wonder why skia has this dual between graphicscontext->m_state (which has the gradient) and platformcontext which has the skia gradient. I notice the the webkit Gradient object itself holds a cache of the skia gradient, and it is correctly purged when addColorStop is called. If skia always went directly to m_state.fillGradient, I think we could skip all of these pushes.
> 
> Another clue that something funny is going on. Look in GraphicsContext.cpp
> 
> 
> #if !USE(SKIA)
> void GraphicsContext::setPlatformFillGradient(Gradient*)
> {
> }
> 
> void GraphicsContext::setPlatformFillPattern(Pattern*)
> {
> }
> 
> void GraphicsContext::setPlatformStrokeGradient(Gradient*)
> {
> }
> 
> void GraphicsContext::setPlatformStrokePattern(Pattern*)
> {
> }
> #endif
> 
> All of these seem to exist solely for skia. If we didn't make a (premature) copy of the gradient, but reached directly into m_state each time, I think we would (a) fix this bug, and (b) avoid this whole layer of indirection/copying.

I'm to blame for introducing these, in:

http://trac.webkit.org/changeset/46017

It was to refactor a bunch of cut-and-paste code, so that setupPaintForStroking() and setupPaintForFilling() could handle patterns and gradients, rather than having to cut-and-paste the same 5 lines of code we were using everywhere else for gradients and patterns (see the CL desc).

That may not be relevant anymore; I'm not sure.  But anything we come up with should be checked against the tests that were fixed in that CL, at least.
Comment 8 Mike Reed 2011-07-08 10:53:53 PDT
Ah, that helps. Certainly will explicitly check for regressions against those tests (and all of DRT).

I have a preliminary CL https://bugs.webkit.org/show_bug.cgi?id=64178 that is good in its own right, but will simplify a future CL (which I haven't posted yet) where I think we can address these gradient concerns w/o the extra calls proposed here.
Comment 9 James Robinson 2011-07-08 16:06:57 PDT
Comment on attachment 99773 [details]
patch

Too invasive.
Comment 10 Dongseong Hwang 2011-07-11 05:26:22 PDT
I found that we did not need to handle Pattern, because Pattern is mutable only due to Pattern::setPatternSpaceTransform() and setPatternSpaceTransform() already updates platformPattern.

I agree that this patch is too invasive. It is because SkGradientShader is immutable. We have to change platformGradient in GraphicsContext at every time that Gradient is modified. There is two approaches in order to change the platformGradient object.
1. Above approach.
2. Gradient has the callback for updating platformGradient in GraphicsContextSkia.

The second approach will be similar that DrawingBufferChromium uses WillPublishCallback class for managing a PlatformContextSkia object.
However, it will be more complex that a GradientSkia manages GraphicsContextSkia listners than a DrawingBufferChromium manages a PlatformContextSkia because several GraphicsContext objects can share one Gradient object and even one GraphicsContext can use one Gradient twice (i.e. fill and stroke).

I think two approaches are too invasive. It is why I chose the first invasive approach.

Recommend me better idea, please.
Comment 11 Mike Reed 2011-07-11 08:48:34 PDT
proposed alternate fix: https://bugs.webkit.org/show_bug.cgi?id=64281
Comment 12 Mike Reed 2011-07-11 11:53:26 PDT
https://bugs.webkit.org/show_bug.cgi?id=64281

This CL has landed. Can you confirm whether it fixes the issue for you?
Comment 13 Stephen White 2011-07-11 12:13:04 PDT
(In reply to comment #12)
> https://bugs.webkit.org/show_bug.cgi?id=64281
> 
> This CL has landed. Can you confirm whether it fixes the issue for you?

FYI, 2d.gradient.object.update seems to be passing on the canaries:

http://build.chromium.org/p/chromium.webkit/builders/Webkit%20Linux/builds/10413

I'll update the test expectations.
Comment 14 Dongseong Hwang 2011-07-11 18:20:52 PDT
OMG!

https://bugs.webkit.org/show_bug.cgi?id=64281 solved it.

I'm sorry for confusion.
Comment 15 Dongseong Hwang 2011-07-11 18:22:43 PDT

*** This bug has been marked as a duplicate of bug 64281 ***