Bug 99887 - [CSS Shaders] Changing the blend mode in CSS doesn't update the custom filter rendering
Summary: [CSS Shaders] Changing the blend mode in CSS doesn't update the custom filter...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Layout and Rendering (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Max Vujovic
URL:
Keywords:
Depends on:
Blocks: 71392
  Show dependency treegraph
 
Reported: 2012-10-19 16:40 PDT by Max Vujovic
Modified: 2012-10-23 14:24 PDT (History)
5 users (show)

See Also:


Attachments
Patch (11.70 KB, patch)
2012-10-22 11:27 PDT, Max Vujovic
no flags Details | Formatted Diff | Diff
Patch (10.92 KB, patch)
2012-10-22 14:24 PDT, Max Vujovic
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Max Vujovic 2012-10-19 16:40:59 PDT
Suppose an element initially has the style:
-webkit-filter: custom(none mix(url(shader.fs) normal source-atop));

Then, we change the blend mode from "normal" to "multiply":
-webkit-filter: custom(none mix(url(shader.fs) multiply source-atop));

The element's appearance should change, but it doesn't.

I've got a patch coming up for this.
Comment 1 Max Vujovic 2012-10-22 11:27:56 PDT
Created attachment 169946 [details]
Patch

I'd like some feedback on the use of setTimeout(..., 0) in the test. In DRT, I want to make sure we render the custom filter with its original style once, and then we change the style. I'm not sure about the best way to do this in DRT.
Comment 2 Alexandru Chiculita 2012-10-22 13:10:17 PDT
Comment on attachment 169946 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=169946&action=review

Looks good, Max!

> LayoutTests/css3/filters/custom/custom-filter-change-blend-mode.html:28
> +            document.getElementById("shaded").style.webkitFilter = "custom(none mix(url('../resources/mix-color.fs') normal source-atop), mix_color 0 1 0 1)";

I would use a class name instead, just to keep the CSS code out of JS.

> Source/WebCore/ChangeLog:8
> +        Before this patch, WebKit would not rerender a custom filter when its blend mode changed.

What about using repaint instead of rerender?

> Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp:94
> +    if (m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE && m_mixSettings != o.m_mixSettings)
> +        return false;
> +
> +    return m_programType == o.m_programType;
> +}

nit: It looks like you could combine these two in the same line.

return (m_programType == o.m_programType) && (m_programType != PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE || m_mixSettings == o.m_mixSettings);

> Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp:100
> +    if (m_programType == PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE && m_mixSettings != o.m_mixSettings)
> +        return false;
>  

Ditto.

> Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h:61
> +    bool operator!=(const CustomFilterProgramMixSettings& o) const
> +    {
> +        return !(*this == o);
> +    }

If you do the previous refactorings, you wouldn't need this one anymore.
Comment 3 Max Vujovic 2012-10-22 14:24:11 PDT
Created attachment 169984 [details]
Patch
Comment 4 Max Vujovic 2012-10-22 14:31:12 PDT
Comment on attachment 169946 [details]
Patch

Thanks for the review, Alex!

Regarding the test, I changed it to trigger a style resolution with "targetElement.clientWidth" instead of using setTimeout. A repaint test would have also worked, but this way we can keep it a ref test. Thanks for the tip!

View in context: https://bugs.webkit.org/attachment.cgi?id=169946&action=review

>> LayoutTests/css3/filters/custom/custom-filter-change-blend-mode.html:28
>> +            document.getElementById("shaded").style.webkitFilter = "custom(none mix(url('../resources/mix-color.fs') normal source-atop), mix_color 0 1 0 1)";
> 
> I would use a class name instead, just to keep the CSS code out of JS.

Done. Looks much better.

>> Source/WebCore/ChangeLog:8
>> +        Before this patch, WebKit would not rerender a custom filter when its blend mode changed.
> 
> What about using repaint instead of rerender?

In the patch I just posted, I've changed this to be more even specific:
"Before this patch, WebKit would not recompute an element's style when just its custom filter blend mode changed."

>> Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp:94
>> +}
> 
> nit: It looks like you could combine these two in the same line.
> 
> return (m_programType == o.m_programType) && (m_programType != PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE || m_mixSettings == o.m_mixSettings);

Done.

>> Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.cpp:100
>>  
> 
> Ditto.

Done.

>> Source/WebCore/platform/graphics/filters/CustomFilterProgramInfo.h:61
>> +    }
> 
> If you do the previous refactorings, you wouldn't need this one anymore.

Yup, I removed it.
Comment 5 Dirk Schulze 2012-10-23 13:51:36 PDT
Comment on attachment 169984 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=169984&action=review

> LayoutTests/css3/filters/custom/custom-filter-change-blend-mode.html:47
> +    .multiply {
> +        -webkit-filter: custom(none mix(url('../resources/mix-color.fs') multiply source-atop), mix_color 0 1 0 1);
> +    }
> +    .normal {
> +        -webkit-filter: custom(none mix(url('../resources/mix-color.fs') normal source-atop), mix_color 0 1 0 1);
> +    }

Your description writes that just changing blend mode does not trigger repaint. In this case you set the whole property with all values. How can you make sure that just the blend mode is responsible for the repaint? Is there a way to set just the blend mode explicitly?
Comment 6 Max Vujovic 2012-10-23 14:03:45 PDT
Thanks for looking at this, Dirk.

(In reply to comment #5)
> (From update of attachment 169984 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=169984&action=review
> 
> > LayoutTests/css3/filters/custom/custom-filter-change-blend-mode.html:47
> > +    .multiply {
> > +        -webkit-filter: custom(none mix(url('../resources/mix-color.fs') multiply source-atop), mix_color 0 1 0 1);
> > +    }
> > +    .normal {
> > +        -webkit-filter: custom(none mix(url('../resources/mix-color.fs') normal source-atop), mix_color 0 1 0 1);
> > +    }
> 
> Your description writes that just changing blend mode does not trigger repaint. In this case you set the whole property with all values. 

Right, I'm just make sure all the new values are the same as the old values, except the blend mode.

> How can you make sure that just the blend mode is responsible for the repaint?

CustomFilterOperation's equals operator provides the answer:
"""
    virtual bool operator==(const FilterOperation& o) const
    {
        if (!isSameType(o))
            return false;

        const CustomFilterOperation* other = static_cast<const CustomFilterOperation*>(&o);
        return *m_program.get() == *other->m_program.get()
               && m_meshRows == other->m_meshRows
               && m_meshColumns == other->m_meshColumns
               && m_meshBoxType == other->m_meshBoxType
               && m_meshType == other->m_meshType
               && customFilterParametersEqual(m_parameters, other->m_parameters);
    }
"""

When we change only the blend mode, every condition matches between the old CustomFilterOperation and the new CustomFilterOperation except the first one, which compares the CustomFilterProgram.

With this patch, CustomFilterProgram's equals operator considers the mix settings.

> Is there a way to set just the blend mode explicitly?

Unfortunately no. We haven't defined a CSSOM for the mix function yet.
Comment 7 Dirk Schulze 2012-10-23 14:14:18 PDT
Comment on attachment 169984 [details]
Patch

I see. r=me then. :)
Comment 8 Max Vujovic 2012-10-23 14:14:41 PDT
(In reply to comment #7)
> (From update of attachment 169984 [details])
> I see. r=me then. :)

Thanks! :)
Comment 9 WebKit Review Bot 2012-10-23 14:24:21 PDT
Comment on attachment 169984 [details]
Patch

Clearing flags on attachment: 169984

Committed r132266: <http://trac.webkit.org/changeset/132266>
Comment 10 WebKit Review Bot 2012-10-23 14:24:25 PDT
All reviewed patches have been landed.  Closing bug.