Bug 21883

Summary: [CAIRO] globalAlpha has to be stored and restored
Product: WebKit Reporter: Dirk Schulze <krit>
Component: New BugsAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: alp
Priority: P2 Keywords: Cairo
Version: 528+ (Nightly build)   
Hardware: PC   
OS: All   
URL: https://developer.mozilla.org/samples/canvas-tutorial/5_1_canvas_savestate.html
Attachments:
Description Flags
save/restore globalAlpha
none
save/restore globalAlpha
alp: review-
save/restore globalAlpha alp: review+

Description Dirk Schulze 2008-10-25 01:04:27 PDT
globalAlpha has to be stored and restored after calling save() or restore().
Comment 1 Dirk Schulze 2008-10-25 01:06:19 PDT
Created attachment 24673 [details]
save/restore globalAlpha

I added a stack (vector) to GraphicsContext to save and restore globalAlpha values on calling ctx.save() or ctx.restore().
Comment 2 Dirk Schulze 2008-10-27 23:39:01 PDT
Created attachment 24706 [details]
save/restore globalAlpha

there was a little bug in GraphicsContext::setAlpha()
Comment 3 Alp Toker 2008-10-28 07:17:26 PDT
(In reply to comment #2)
> Created an attachment (id=24706) [edit]
> save/restore globalAlpha
> 
> there was a little bug in GraphicsContext::setAlpha()
> 

GraphicsContext already keeps a stack with internal state (see GraphicsContext.cpp GraphicsContext::save() and GraphicsContextPrivate.h). I was thinking it might be better to add an 'alpha' field to that and let GraphicsContext do the work for us so we don't need to maintain our own stack of alpha values for GraphicsContextCairo. Could you take a look into that?
Comment 4 Dirk Schulze 2008-10-28 09:14:45 PDT
Created attachment 24717 [details]
save/restore globalAlpha

(In reply to comment #3)
> GraphicsContext already keeps a stack with internal state (see
> GraphicsContext.cpp GraphicsContext::save() and GraphicsContextPrivate.h). I
> was thinking it might be better to add an 'alpha' field to that and let
> GraphicsContext do the work for us so we don't need to maintain our own stack
> of alpha values for GraphicsContextCairo. Could you take a look into that?

I spoke to esedeidel via IRC as I implemented the current version of globalAlpha. And he didn't like the idea to change GraphicsContextPrivate.h. A globalAlpha variable is only needed on cairo and would waste space for other platforms.
Or we use #if PLATFORM(CAIRO).

This second patch uses the alternative. Only One patch should be reviewed.
Comment 5 Alp Toker 2008-10-28 18:56:49 PDT
Comment on attachment 24717 [details]
save/restore globalAlpha

This version of the patch looks pretty good. It makes sense to use the WebCore graphics state stack here rather than maintaining separate stacks that have to be maintained manually. Some comments..


>Index: WebCore/platform/graphics/GraphicsContextPrivate.h
>===================================================================
>--- WebCore/platform/graphics/GraphicsContextPrivate.h	(revision 37888)
>+++ WebCore/platform/graphics/GraphicsContextPrivate.h	(working copy)
>@@ -50,6 +50,9 @@ namespace WebCore {
>             : textDrawingMode(cTextFill)
>             , strokeStyle(SolidStroke)
>             , strokeThickness(0)

This would usually be '1.0f':

>+#if PLATFORM(CAIRO)
>+            , globalAlpha(1)
>+#endif


I think we'll still need to go through this code some time later and make sure we're using globalAlpha consistently everywhere it's needed, and to avoid creating temporary surfaces (which can be inefficient) where globalAlpha can just be multiplied with the pen color's alpha, but that doesn't really block this getting landed.

Going to wait for the build to get fixed before r+'ing and to give anyone else who's interested a chance to comment.
Comment 6 Alp Toker 2008-10-30 07:14:49 PDT
Comment on attachment 24706 [details]
save/restore globalAlpha

r-. Other patch you proposed is the way to go.
Comment 7 Alp Toker 2008-10-30 07:15:43 PDT
Comment on attachment 24717 [details]
save/restore globalAlpha

r=me

Will change the '0' to '1.0f'.
Comment 8 Alp Toker 2008-10-30 07:19:07 PDT
Landed in r38001.

Dirk: I did notice a performance issue we might want to look at.

   case SolidColorSpace:
        if (strokeColor().alpha()) {
            setColor(cr, strokeColor());
            if (m_common->state.globalAlpha < 1.0f) {
                cairo_push_group(cr);
                cairo_paint_with_alpha(cr, m_common->state.globalAlpha);
                cairo_pop_group_to_source(cr);
            }
            cairo_stroke(cr);
        }
        break;

^ Temporary groups are pretty expensive in Cairo IIRC, especially if they're not clipped. It would be better to just change setColor(cr, strokeColor()) to set the cairo color to the right alpha value and stroke etc. directly. Anyway, that's a different issue for a different bug, just thought I'd let you know.

Cheers