Changeset 146529 in webkit


Ignore:
Timestamp:
Mar 21, 2013 3:17:44 PM (11 years ago)
Author:
Alexandru Chiculita
Message:

[CSS Shaders] Implement a StyleCustomFilterProgram cache
https://bugs.webkit.org/show_bug.cgi?id=112602

Reviewed by Dean Jackson.

Source/WebCore:

When the style is recalculated, the new computed RenderStyle is saved as the m_style of the
RenderObject, even if the style was not different.

In the case of Custom Filters, a new StyleCustomFilterProgram was created at all times, but the
actual equality check was done by comparing the pair of cached shaders from inside the StyleCustomFilterProgram.

Because of that the RenderLayer::styleChanged was not called when the new StyleCustomFilterProgram was created, so it
will end up still knowing only about the previous StyleCustomFilterProgram.

The RenderLayer sets itself as a client of the StyleCustomFilterProgram, so that it can repaint itself
when the program is loaded, but because RenderLayer::styleChanged is not called, it will not add itself as a client of the new
StyleCustomFilterProgram.

StyleCustomFilterProgram waits until the first client to load the programs, so in this case it will just remain unloaded.

There was no crash, but just an assert in debug mode. Also, as a visible side-effect some frames were rendered using blank shaders,
resulting in a pass-through filter.

The fix would be to actually make the RenderStyle::diff detect the change of the StyleCustomFilterProgram
using the pointer value and not the values. However, that will always invalidate the "filter" property because
of the StyleCustomFilterProgram that always gets created during the recalculation time.

I've added StyleCustomFilterProgramCache to cache all the instances of the StyleCustomFilterPrograms that a
StyleResolver allocates. This way, next time it will try to reuse previously allocated StyleCustomFilterPrograms.
The key of the cache is the CustomFilterProgramInfo, that combines the URLs to the shaders and a couple of other program settings.

StyleCustomFilterProgramCache is owned by the StyleResovler and StyleCustomFilterPrograms are responsible with
removing themselves from the cache when the last reference goes away.

This change makes the previous "platform level" program cache obsolete and I will remove that in a future patch.
https://bugs.webkit.org/show_bug.cgi?id=112844

Test: css3/filters/custom/custom-filter-reload.html

  • GNUmakefile.list.am:
  • Target.pri:
  • WebCore.gypi:
  • WebCore.vcproj/WebCore.vcproj:
  • WebCore.xcodeproj/project.pbxproj:
  • css/StyleResolver.cpp:

(WebCore::StyleResolver::lookupCustomFilterProgram): Lookup any similar programs in the cache. It will create a new pending
StyleCustomFilterProgram if there is no pre-cached version of the program.
if no program is found. loadPendingShaders is responsible for adding the program in the cache if it is actually going to be used.
(WebCore::StyleResolver::loadPendingShaders): At this point the program is final, so it's safe to add it to the cache.
(WebCore::StyleResolver::createCustomFilterOperationWithInlineSyntax):

  • css/StyleResolver.h:

(StyleResolver):

  • css/WebKitCSSShaderValue.cpp:

(WebCore::WebKitCSSShaderValue::completeURL): Factored out the function to compute the complete URL of the resource.
(WebCore::WebKitCSSShaderValue::cachedShader):

  • css/WebKitCSSShaderValue.h:

(WebCore::toWebKitCSSShaderValue):
(WebKitCSSShaderValue):

  • platform/graphics/filters/CustomFilterOperation.cpp:

(WebCore::CustomFilterOperation::blend):

  • platform/graphics/filters/CustomFilterOperation.h:

(WebCore::CustomFilterOperation::operator==): Removed. Programs should now compare by pointer. Kept it as
private to catch any potential use of it.

  • rendering/style/StyleCustomFilterProgram.cpp: Copied from Source/WebCore/css/WebKitCSSShaderValue.h.

(WebCore::StyleCustomFilterProgram::~StyleCustomFilterProgram): Destructor removes the program from the cache.

  • rendering/style/StyleCustomFilterProgram.h:

(WebCore::StyleCustomFilterProgram::setVertexShader): Added an assert to check that the shader is not in the
cache while the mutation happens. Otherwise the cache might have the wrong key.
(WebCore::StyleCustomFilterProgram::setFragmentShader): Ditto.
(WebCore::StyleCustomFilterProgram::isLoaded): Added more asserts to catch cases when the program is used with no clients.
(StyleCustomFilterProgram):
(WebCore::StyleCustomFilterProgram::hasPendingShaders):
(WebCore::StyleCustomFilterProgram::inCache):
(WebCore::StyleCustomFilterProgram::setCache): Function called when a program is added to / removed from the cache.
(WebCore::StyleCustomFilterProgram::vertexShaderURL): Added methods to store the KURL that we used as keys in the cache.
The same KURLs will be used to lookup and remove the filter at the end.
(WebCore::StyleCustomFilterProgram::setVertexShaderURL):
(WebCore::StyleCustomFilterProgram::fragmentShaderURL):
(WebCore::StyleCustomFilterProgram::setFragmentShaderURL):
(WebCore::StyleCustomFilterProgram::StyleCustomFilterProgram):

  • rendering/style/StyleCustomFilterProgramCache.cpp: Added.

(WebCore::StyleCustomFilterProgramCache::programCacheKey):
(WebCore::StyleCustomFilterProgramCache::StyleCustomFilterProgramCache):
(WebCore::StyleCustomFilterProgramCache::~StyleCustomFilterProgramCache): Destructor removes itself from all the
referenced StyleCustomFilterPrograms. This is to avoid issues with different destruction orders.
(WebCore::StyleCustomFilterProgramCache::lookup):
(WebCore::StyleCustomFilterProgramCache::add):
(WebCore::StyleCustomFilterProgramCache::remove):

  • rendering/style/StyleCustomFilterProgramCache.h:

(StyleCustomFilterProgramCache):

  • platform/graphics/texmap/coordinated/CoordinatedCustomFilterProgram.h:

(WebCore::CoordinatedCustomFilterProgram::operator==: Removed. Programs should now compare by pointer.

LayoutTests:

Added a new test to check for the case when the style is recalculated but the
filter property is not changed. All the other cases for the new StyleCustomFilterProgramCache
class should be tested by existing tests.

  • css3/filters/custom/custom-filter-reload-expected.txt: Added.
  • css3/filters/custom/custom-filter-reload.html: Added.
Location:
trunk
Files:
3 added
17 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r146525 r146529  
     12013-03-21  Alexandru Chiculita  <achicu@adobe.com>
     2
     3        [CSS Shaders] Implement a StyleCustomFilterProgram cache
     4        https://bugs.webkit.org/show_bug.cgi?id=112602
     5
     6        Reviewed by Dean Jackson.
     7
     8        Added a new test to check for the case when the style is recalculated but the
     9        filter property is not changed. All the other cases for the new StyleCustomFilterProgramCache
     10        class should be tested by existing tests.
     11
     12        * css3/filters/custom/custom-filter-reload-expected.txt: Added.
     13        * css3/filters/custom/custom-filter-reload.html: Added.
     14
    1152013-03-21  Jochen Eisinger  <jochen@chromium.org>
    216
  • trunk/Source/WebCore/ChangeLog

    r146527 r146529  
     12013-03-21  Alexandru Chiculita  <achicu@adobe.com>
     2
     3        [CSS Shaders] Implement a StyleCustomFilterProgram cache
     4        https://bugs.webkit.org/show_bug.cgi?id=112602
     5
     6        Reviewed by Dean Jackson.
     7
     8        When the style is recalculated, the new computed RenderStyle is saved as the m_style of the
     9        RenderObject, even if the style was not different.
     10
     11        In the case of Custom Filters, a new StyleCustomFilterProgram was created at all times, but the
     12        actual equality check was done by comparing the pair of cached shaders from inside the StyleCustomFilterProgram.
     13
     14        Because of that the RenderLayer::styleChanged was not called when the new StyleCustomFilterProgram was created, so it
     15        will end up still knowing only about the previous StyleCustomFilterProgram.
     16
     17        The RenderLayer sets itself as a client of the StyleCustomFilterProgram, so that it can repaint itself
     18        when the program is loaded, but because RenderLayer::styleChanged is not called, it will not add itself as a client of the new
     19        StyleCustomFilterProgram.
     20
     21        StyleCustomFilterProgram waits until the first client to load the programs, so in this case it will just remain unloaded.
     22
     23        There was no crash, but just an assert in debug mode. Also, as a visible side-effect some frames were rendered using blank shaders,
     24        resulting in a pass-through filter.
     25
     26        The fix would be to actually make the RenderStyle::diff detect the change of the StyleCustomFilterProgram
     27        using the pointer value and not the values. However, that will always invalidate the "filter" property because
     28        of the StyleCustomFilterProgram that always gets created during the recalculation time.
     29
     30        I've added StyleCustomFilterProgramCache to cache all the instances of the StyleCustomFilterPrograms that a
     31        StyleResolver allocates. This way, next time it will try to reuse previously allocated StyleCustomFilterPrograms.
     32        The key of the cache is the CustomFilterProgramInfo, that combines the URLs to the shaders and a couple of other program settings.
     33
     34        StyleCustomFilterProgramCache is owned by the StyleResovler and StyleCustomFilterPrograms are responsible with
     35        removing themselves from the cache when the last reference goes away.
     36
     37        This change makes the previous "platform level" program cache obsolete and I will remove that in a future patch.
     38        https://bugs.webkit.org/show_bug.cgi?id=112844
     39
     40        Test: css3/filters/custom/custom-filter-reload.html
     41
     42        * GNUmakefile.list.am:
     43        * Target.pri:
     44        * WebCore.gypi:
     45        * WebCore.vcproj/WebCore.vcproj:
     46        * WebCore.xcodeproj/project.pbxproj:
     47        * css/StyleResolver.cpp:
     48        (WebCore::StyleResolver::lookupCustomFilterProgram): Lookup any similar programs in the cache. It will create a new pending
     49        StyleCustomFilterProgram if there is no pre-cached version of the program.
     50        if no program is found. loadPendingShaders is responsible for adding the program in the cache if it is actually going to be used.
     51        (WebCore::StyleResolver::loadPendingShaders): At this point the program is final, so it's safe to add it to the cache.
     52        (WebCore::StyleResolver::createCustomFilterOperationWithInlineSyntax):
     53        * css/StyleResolver.h:
     54        (StyleResolver):
     55        * css/WebKitCSSShaderValue.cpp:
     56        (WebCore::WebKitCSSShaderValue::completeURL): Factored out the function to compute the complete URL of the resource.
     57        (WebCore::WebKitCSSShaderValue::cachedShader):
     58        * css/WebKitCSSShaderValue.h:
     59        (WebCore::toWebKitCSSShaderValue):
     60        (WebKitCSSShaderValue):
     61        * platform/graphics/filters/CustomFilterOperation.cpp:
     62        (WebCore::CustomFilterOperation::blend):
     63        * platform/graphics/filters/CustomFilterOperation.h:
     64        (WebCore::CustomFilterOperation::operator==): Removed. Programs should now compare by pointer. Kept it as
     65        private to catch any potential use of it.
     66        * rendering/style/StyleCustomFilterProgram.cpp: Copied from Source/WebCore/css/WebKitCSSShaderValue.h.
     67        (WebCore::StyleCustomFilterProgram::~StyleCustomFilterProgram): Destructor removes the program from the cache.
     68        * rendering/style/StyleCustomFilterProgram.h:
     69        (WebCore::StyleCustomFilterProgram::setVertexShader): Added an assert to check that the shader is not in the
     70        cache while the mutation happens. Otherwise the cache might have the wrong key.
     71        (WebCore::StyleCustomFilterProgram::setFragmentShader): Ditto.
     72        (WebCore::StyleCustomFilterProgram::isLoaded): Added more asserts to catch cases when the program is used with no clients.
     73        (StyleCustomFilterProgram):
     74        (WebCore::StyleCustomFilterProgram::hasPendingShaders):
     75        (WebCore::StyleCustomFilterProgram::inCache):
     76        (WebCore::StyleCustomFilterProgram::setCache): Function called when a program is added to / removed from the cache.
     77        (WebCore::StyleCustomFilterProgram::vertexShaderURL): Added methods to store the KURL that we used as keys in the cache.
     78        The same KURLs will be used to lookup and remove the filter at the end.
     79        (WebCore::StyleCustomFilterProgram::setVertexShaderURL):
     80        (WebCore::StyleCustomFilterProgram::fragmentShaderURL):
     81        (WebCore::StyleCustomFilterProgram::setFragmentShaderURL):
     82        (WebCore::StyleCustomFilterProgram::StyleCustomFilterProgram):
     83        * rendering/style/StyleCustomFilterProgramCache.cpp: Added.
     84        (WebCore::StyleCustomFilterProgramCache::programCacheKey):
     85        (WebCore::StyleCustomFilterProgramCache::StyleCustomFilterProgramCache):
     86        (WebCore::StyleCustomFilterProgramCache::~StyleCustomFilterProgramCache): Destructor removes itself from all the
     87        referenced StyleCustomFilterPrograms. This is to avoid issues with different destruction orders.
     88        (WebCore::StyleCustomFilterProgramCache::lookup):
     89        (WebCore::StyleCustomFilterProgramCache::add):
     90        (WebCore::StyleCustomFilterProgramCache::remove):
     91        * rendering/style/StyleCustomFilterProgramCache.h:
     92        (StyleCustomFilterProgramCache):
     93        * platform/graphics/texmap/coordinated/CoordinatedCustomFilterProgram.h:
     94        (WebCore::CoordinatedCustomFilterProgram::operator==: Removed. Programs should now compare by pointer.
     95
    1962013-03-21  Joshua Bell  <jsbell@chromium.org>
    297
  • trunk/Source/WebCore/GNUmakefile.list.am

    r146508 r146529  
    46644664        Source/WebCore/rendering/style/StyleCachedShader.cpp \
    46654665        Source/WebCore/rendering/style/StyleCachedShader.h \
     4666        Source/WebCore/rendering/style/StyleCustomFilterProgram.cpp \
    46664667        Source/WebCore/rendering/style/StyleCustomFilterProgram.h \
     4668        Source/WebCore/rendering/style/StyleCustomFilterProgramCache.cpp \
     4669        Source/WebCore/rendering/style/StyleCustomFilterProgramCache.h \
    46674670        Source/WebCore/rendering/style/StyleDashboardRegion.h \
    46684671        Source/WebCore/rendering/style/StyleDeprecatedFlexibleBoxData.cpp \
  • trunk/Source/WebCore/Target.pri

    r146508 r146529  
    12871287    rendering/style/StyleCachedImageSet.cpp \
    12881288    rendering/style/StyleCachedShader.cpp \
     1289    rendering/style/StyleCustomFilterProgram.cpp \
     1290    rendering/style/StyleCustomFilterProgramCache.cpp \
    12891291    rendering/style/StyleDeprecatedFlexibleBoxData.cpp \
    12901292    rendering/style/StyleFilterData.cpp \
     
    25842586    rendering/style/StyleCachedShader.h \
    25852587    rendering/style/StyleCustomFilterProgram.h \
     2588    rendering/style/StyleCustomFilterProgramCache.h \
    25862589    rendering/style/StyleDeprecatedFlexibleBoxData.h \
    25872590    rendering/style/StyleFilterData.h \
  • trunk/Source/WebCore/WebCore.gypi

    r146508 r146529  
    26572657            'rendering/style/StyleCachedShader.h',
    26582658            'rendering/style/StyleCachedShader.cpp',
     2659            'rendering/style/StyleCustomFilterProgramCache.cpp',
     2660            'rendering/style/StyleCustomFilterProgramCache.h',
     2661            'rendering/style/StyleCustomFilterProgram.cpp',
    26592662            'rendering/style/StyleCustomFilterProgram.h',
    26602663            'rendering/style/StyleDeprecatedFlexibleBoxData.cpp',
  • trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj

    r146508 r146529  
    4696946969                                </File>
    4697046970                                <File
     46971                                        RelativePath="..\rendering\style\StyleCustomFilterProgram.cpp"
     46972                                        >
     46973                                </File>
     46974                                <File
     46975                                        RelativePath="..\rendering\style\StyleCustomFilterProgramCache.h"
     46976                                        >
     46977                                </File>
     46978                                <File
     46979                                        RelativePath="..\rendering\style\StyleCustomFilterProgramCache.cpp"
     46980                                        >
     46981                                </File>
     46982                                <File
    4697146983                                        RelativePath="..\rendering\style\StyleDeprecatedFlexibleBoxData.cpp"
    4697246984                                        >
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r146508 r146529  
    15721572                50D88CB515BDFDAA001809F4 /* CustomFilterProgramInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50D88CB315BDFDAA001809F4 /* CustomFilterProgramInfo.cpp */; };
    15731573                50D88CB615BDFDAA001809F4 /* CustomFilterProgramInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 50D88CB415BDFDAA001809F4 /* CustomFilterProgramInfo.h */; };
     1574                50E18CD816F9285800C65486 /* StyleCustomFilterProgram.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E18CD516F9285800C65486 /* StyleCustomFilterProgram.cpp */; };
     1575                50E18CD916F9285800C65486 /* StyleCustomFilterProgramCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 50E18CD616F9285800C65486 /* StyleCustomFilterProgramCache.cpp */; };
     1576                50E18CDA16F9285800C65486 /* StyleCustomFilterProgramCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 50E18CD716F9285800C65486 /* StyleCustomFilterProgramCache.h */; };
    15741577                510184690B08602A004A825F /* CachedPage.h in Headers */ = {isa = PBXBuildFile; fileRef = 510184670B08602A004A825F /* CachedPage.h */; settings = {ATTRIBUTES = (Private, ); }; };
    15751578                5101846A0B08602A004A825F /* CachedPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 510184680B08602A004A825F /* CachedPage.cpp */; };
     
    90459048                50D88CB315BDFDAA001809F4 /* CustomFilterProgramInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CustomFilterProgramInfo.cpp; path = filters/CustomFilterProgramInfo.cpp; sourceTree = "<group>"; };
    90469049                50D88CB415BDFDAA001809F4 /* CustomFilterProgramInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CustomFilterProgramInfo.h; path = filters/CustomFilterProgramInfo.h; sourceTree = "<group>"; };
     9050                50E18CD516F9285800C65486 /* StyleCustomFilterProgram.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StyleCustomFilterProgram.cpp; path = style/StyleCustomFilterProgram.cpp; sourceTree = "<group>"; };
     9051                50E18CD616F9285800C65486 /* StyleCustomFilterProgramCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StyleCustomFilterProgramCache.cpp; path = style/StyleCustomFilterProgramCache.cpp; sourceTree = "<group>"; };
     9052                50E18CD716F9285800C65486 /* StyleCustomFilterProgramCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StyleCustomFilterProgramCache.h; path = style/StyleCustomFilterProgramCache.h; sourceTree = "<group>"; };
    90479053                510184670B08602A004A825F /* CachedPage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CachedPage.h; sourceTree = "<group>"; };
    90489054                510184680B08602A004A825F /* CachedPage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CachedPage.cpp; sourceTree = "<group>"; };
     
    2138921395                                5038BE2D1472AD230095E0D1 /* StyleCachedShader.cpp */,
    2139021396                                5038BE2E1472AD230095E0D1 /* StyleCachedShader.h */,
     21397                                50E18CD616F9285800C65486 /* StyleCustomFilterProgramCache.cpp */,
     21398                                50E18CD716F9285800C65486 /* StyleCustomFilterProgramCache.h */,
     21399                                50E18CD516F9285800C65486 /* StyleCustomFilterProgram.cpp */,
    2139121400                                503D0CAD14B5B0BA00F32F57 /* StyleCustomFilterProgram.h */,
    2139221401                                BC5EB67E0E81D4A700B25965 /* StyleDashboardRegion.h */,
     
    2675826767                                DAED203116F244480070EC0F /* PageConsole.h in Headers */,
    2675926768                                2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */,
     26769                                50E18CDA16F9285800C65486 /* StyleCustomFilterProgramCache.h in Headers */,
    2676026770                        );
    2676126771                        runOnlyForDeploymentPostprocessing = 0;
     
    2996429974                                DAED203016F2442B0070EC0F /* PageConsole.cpp in Sources */,
    2996529975                                E1BA003116FB92AC00BA7A35 /* ResourceHandleClient.cpp in Sources */,
     29976                                50E18CD816F9285800C65486 /* StyleCustomFilterProgram.cpp in Sources */,
     29977                                50E18CD916F9285800C65486 /* StyleCustomFilterProgramCache.cpp in Sources */,
    2996629978                        );
    2996729979                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/Source/WebCore/css/StyleResolver.cpp

    r146274 r146529  
    165165#include "CustomFilterOperation.h"
    166166#include "CustomFilterParameter.h"
     167#include "CustomFilterProgramInfo.h"
    167168#include "CustomFilterTransformParameter.h"
    168169#include "StyleCachedShader.h"
    169170#include "StyleCustomFilterProgram.h"
     171#include "StyleCustomFilterProgramCache.h"
    170172#include "StylePendingShader.h"
    171173#include "StyleShader.h"
     
    39423944}
    39433945
     3946PassRefPtr<CustomFilterProgram> StyleResolver::lookupCustomFilterProgram(WebKitCSSShaderValue* vertexShader, WebKitCSSShaderValue* fragmentShader,
     3947    CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
     3948{
     3949    CachedResourceLoader* cachedResourceLoader = m_state.document()->cachedResourceLoader();
     3950    KURL vertexShaderURL = vertexShader ? vertexShader->completeURL(cachedResourceLoader) : KURL();
     3951    KURL fragmentShaderURL = fragmentShader ? fragmentShader->completeURL(cachedResourceLoader) : KURL();
     3952    RefPtr<StyleCustomFilterProgram> program;
     3953    if (m_customFilterProgramCache)
     3954        program = m_customFilterProgramCache->lookup(CustomFilterProgramInfo(vertexShaderURL, fragmentShaderURL, programType, mixSettings, meshType));
     3955    if (!program) {
     3956        // Create a new StyleCustomFilterProgram that will be resolved during the loadPendingShaders and added to the cache.
     3957        program = StyleCustomFilterProgram::create(vertexShaderURL, vertexShader ? styleShader(vertexShader) : 0,
     3958            fragmentShaderURL, fragmentShader ? styleShader(fragmentShader) : 0, programType, mixSettings, meshType);
     3959    }
     3960    return program.release();
     3961}
     3962
    39443963void StyleResolver::loadPendingShaders()
    39453964{
     
    39563975            ASSERT(customFilter->program());
    39573976            StyleCustomFilterProgram* program = static_cast<StyleCustomFilterProgram*>(customFilter->program());
    3958             if (program->vertexShader() && program->vertexShader()->isPendingShader()) {
    3959                 WebKitCSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->vertexShader())->cssShaderValue();
    3960                 program->setVertexShader(shaderValue->cachedShader(cachedResourceLoader));
    3961             }
    3962             if (program->fragmentShader() && program->fragmentShader()->isPendingShader()) {
    3963                 WebKitCSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->fragmentShader())->cssShaderValue();
    3964                 program->setFragmentShader(shaderValue->cachedShader(cachedResourceLoader));
     3977            // Note that the StylePendingShaders could be already resolved to StyleCachedShaders. That's because the rule was matched before.
     3978            // However, the StyleCustomFilterProgram that was initially created could have been removed from the cache in the meanwhile,
     3979            // meaning that we get a new StyleCustomFilterProgram here that is not yet in the cache, but already has loaded StyleShaders.
     3980            if (!program->hasPendingShaders() && program->inCache())
     3981                continue;
     3982            if (!m_customFilterProgramCache)
     3983                m_customFilterProgramCache = adoptPtr(new StyleCustomFilterProgramCache());
     3984            RefPtr<StyleCustomFilterProgram> styleProgram = m_customFilterProgramCache->lookup(program);
     3985            if (styleProgram.get())
     3986                customFilter->setProgram(styleProgram.release());
     3987            else {
     3988                if (program->vertexShader() && program->vertexShader()->isPendingShader()) {
     3989                    WebKitCSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->vertexShader())->cssShaderValue();
     3990                    program->setVertexShader(shaderValue->cachedShader(cachedResourceLoader));
     3991                }
     3992                if (program->fragmentShader() && program->fragmentShader()->isPendingShader()) {
     3993                    WebKitCSSShaderValue* shaderValue = static_cast<StylePendingShader*>(program->fragmentShader())->cssShaderValue();
     3994                    program->setFragmentShader(shaderValue->cachedShader(cachedResourceLoader));
     3995                }
     3996                m_customFilterProgramCache->add(program);
    39653997            }
    39663998        }
     
    41064138    ASSERT(shadersListLength);
    41074139
    4108     RefPtr<StyleShader> vertexShader = styleShader(shadersList->itemWithoutBoundsCheck(0));
    4109     RefPtr<StyleShader> fragmentShader;
     4140    WebKitCSSShaderValue* vertexShader = toWebKitCSSShaderValue(shadersList->itemWithoutBoundsCheck(0));
     4141    WebKitCSSShaderValue* fragmentShader = 0;
    41104142    CustomFilterProgramType programType = PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE;
    41114143    CustomFilterProgramMixSettings mixSettings;
     
    41134145    if (shadersListLength > 1) {
    41144146        CSSValue* fragmentShaderOrMixFunction = shadersList->itemWithoutBoundsCheck(1);
    4115 
    41164147        if (fragmentShaderOrMixFunction->isWebKitCSSMixFunctionValue()) {
    41174148            WebKitCSSMixFunctionValue* mixFunction = static_cast<WebKitCSSMixFunctionValue*>(fragmentShaderOrMixFunction);
     
    41194150
    41204151            ASSERT(mixFunction->length());
    4121             fragmentShader = styleShader(iterator.value());
     4152            fragmentShader = toWebKitCSSShaderValue(iterator.value());
    41224153            iterator.advance();
    41234154
     
    41354166        } else {
    41364167            programType = PROGRAM_TYPE_NO_ELEMENT_TEXTURE;
    4137             fragmentShader = styleShader(fragmentShaderOrMixFunction);
    4138         }
    4139     }
     4168            fragmentShader = toWebKitCSSShaderValue(fragmentShaderOrMixFunction);
     4169        }
     4170    }
     4171
     4172    if (!vertexShader && !fragmentShader)
     4173        return 0;
    41404174   
    41414175    unsigned meshRows = 1;
     
    41934227    if (parametersValue && !parseCustomFilterParameterList(parametersValue, parameterList))
    41944228        return 0;
    4195    
    4196     RefPtr<StyleCustomFilterProgram> program = StyleCustomFilterProgram::create(vertexShader.release(), fragmentShader.release(), programType, mixSettings, meshType);
     4229
     4230    RefPtr<CustomFilterProgram> program = lookupCustomFilterProgram(vertexShader, fragmentShader, programType, mixSettings, meshType);
    41974231    return CustomFilterOperation::create(program.release(), parameterList, meshRows, meshColumns, meshType);
    41984232}
  • trunk/Source/WebCore/css/StyleResolver.h

    r145885 r146529  
    4444#include "WebKitCSSSVGDocumentValue.h"
    4545#endif
     46#if ENABLE(CSS_SHADERS)
     47#include "CustomFilterConstants.h"
     48#endif
    4649#include <wtf/HashMap.h>
    4750#include <wtf/HashSet.h>
     
    7376class CustomFilterParameter;
    7477class CustomFilterParameterList;
     78class CustomFilterProgram;
     79struct CustomFilterProgramMixSettings;
    7580class Document;
    7681class Element;
     
    8893class Settings;
    8994class StaticCSSRuleList;
     95class StyleCustomFilterProgramCache;
    9096class StyleBuilder;
    9197class StyleScopeResolver;
     
    318324    PassRefPtr<CustomFilterOperation> createCustomFilterOperation(WebKitCSSFilterValue*);
    319325    void loadPendingShaders();
     326    PassRefPtr<CustomFilterProgram> lookupCustomFilterProgram(WebKitCSSShaderValue* vertexShader, WebKitCSSShaderValue* fragmentShader,
     327        CustomFilterProgramType, const CustomFilterProgramMixSettings&, CustomFilterMeshType);
    320328#endif
    321329#if ENABLE(SVG)
     
    632640    State m_state;
    633641
     642#if ENABLE(CSS_SHADERS)
     643    OwnPtr<StyleCustomFilterProgramCache> m_customFilterProgramCache;
     644#endif
     645
    634646    friend class StyleBuilder;
    635647    friend bool operator==(const MatchedProperties&, const MatchedProperties&);
  • trunk/Source/WebCore/css/WebKitCSSShaderValue.cpp

    r143028 r146529  
    3838#include "CachedResourceRequestInitiators.h"
    3939#include "Document.h"
     40#include "KURL.h"
    4041#include "StyleCachedShader.h"
    4142#include "StylePendingShader.h"
     
    5556}
    5657
     58KURL WebKitCSSShaderValue::completeURL(CachedResourceLoader* loader) const
     59{
     60    return loader->document()->completeURL(m_url);
     61}
     62
    5763StyleCachedShader* WebKitCSSShaderValue::cachedShader(CachedResourceLoader* loader)
    5864{
     
    6268        m_accessedShader = true;
    6369
    64         CachedResourceRequest request(ResourceRequest(loader->document()->completeURL(m_url)));
     70        CachedResourceRequest request(ResourceRequest(completeURL(loader)));
    6571        request.setInitiator(cachedResourceRequestInitiators().css);
    6672        if (CachedResourceHandle<CachedShader> cachedShader = loader->requestShader(request))
  • trunk/Source/WebCore/css/WebKitCSSShaderValue.h

    r143028 r146529  
    3838
    3939class CachedResourceLoader;
     40class KURL;
    4041class StyleCachedShader;
    4142class StyleShader;
     
    4950    void setFormat(const String& format) { m_format = format; }
    5051
     52    KURL completeURL(CachedResourceLoader*) const;
    5153    StyleCachedShader* cachedShader(CachedResourceLoader*);
    5254    StyleShader* cachedOrPendingShader();
     
    6769};
    6870
     71// This will catch anyone doing an unnecessary cast.
     72WebKitCSSShaderValue* toWebKitCSSShaderValue(const WebKitCSSShaderValue*);
     73
     74inline WebKitCSSShaderValue* toWebKitCSSShaderValue(CSSValue* value)
     75{
     76    return value->isWebKitCSSShaderValue() ? static_cast<WebKitCSSShaderValue*>(value) : 0;
     77}
     78
    6979} // namespace WebCore
    7080
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterOperation.cpp

    r137754 r146529  
    6464   
    6565    const CustomFilterOperation* fromOp = static_cast<const CustomFilterOperation*>(from);
    66     if (*m_program.get() != *fromOp->m_program.get()
     66    if (m_program.get() != fromOp->m_program.get()
    6767        || m_meshRows != fromOp->m_meshRows
    6868        || m_meshColumns != fromOp->m_meshColumns
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterOperation.h

    r137754 r146529  
    7777
    7878        const CustomFilterOperation* other = static_cast<const CustomFilterOperation*>(&o);
    79         return *m_program.get() == *other->m_program.get()
     79        return m_program.get() == other->m_program.get()
    8080            && m_meshRows == other->m_meshRows
    8181            && m_meshColumns == other->m_meshColumns
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterProgram.cpp

    r132903 r146529  
    8787}
    8888
    89 bool CustomFilterProgram::operator==(const CustomFilterProgram& o) const
    90 {
    91     return m_programType == o.m_programType
    92         && (m_programType != PROGRAM_TYPE_BLENDS_ELEMENT_TEXTURE || m_mixSettings == o.m_mixSettings)
    93         && m_meshType == o.m_meshType;
    94 }
    95 
    9689} // namespace WebCore
    9790#endif // ENABLE(CSS_SHADERS)
  • trunk/Source/WebCore/platform/graphics/filters/CustomFilterProgram.h

    r132903 r146529  
    6464    CustomFilterMeshType meshType() const { return m_meshType; }
    6565
    66     virtual bool operator==(const CustomFilterProgram&) const;
    67     bool operator!=(const CustomFilterProgram& o) const { return !(*this == o); }
    6866protected:
    6967    // StyleCustomFilterProgram can notify the clients that the cached resources are
     
    7876
    7977private:
     78    // CustomFilterPrograms are unique combinations of shaders and can be
     79    // compared using just the pointer value instead.
     80    // These will catch anyone doing a value equal comparison.
     81    bool operator==(const CustomFilterProgram&) const;
     82    bool operator!=(const CustomFilterProgram&) const;
     83
    8084    typedef HashCountedSet<CustomFilterProgramClient*> CustomFilterProgramClientList;
    8185    CustomFilterProgramClientList m_clients;
  • trunk/Source/WebCore/platform/graphics/texmap/coordinated/CoordinatedCustomFilterProgram.h

    r141543 r146529  
    4242    virtual bool isLoaded() const OVERRIDE { return true; }
    4343
    44     virtual bool operator==(const CustomFilterProgram& o) const OVERRIDE
    45     {
    46         // We don't use the != operator because that would recursively call this method.
    47         if (!CustomFilterProgram::operator==(o))
    48             return false;
    49 
    50         // The following cast is ugly, but CoordinatedCustomFilterProgram is the single implementation of CustomFilterProgram on UI Process.
    51         const CoordinatedCustomFilterProgram* other = static_cast<const CoordinatedCustomFilterProgram*>(&o);
    52         return m_vertexShaderString == other->vertexShaderString() && m_fragmentShaderString == other->fragmentShaderString();
    53     }
    54 
    5544protected:
    5645    virtual String vertexShaderString() const OVERRIDE { return m_vertexShaderString; }
  • trunk/Source/WebCore/rendering/style/StyleCustomFilterProgram.cpp

    r146528 r146529  
    11/*
    2  * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
     2 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828 */
    2929
    30 #ifndef WebKitCSSShaderValue_h
    31 #define WebKitCSSShaderValue_h
     30#include "config.h"
    3231
    3332#if ENABLE(CSS_SHADERS)
    3433
    35 #include "CSSValue.h"
     34#include "StyleCustomFilterProgram.h"
     35
     36#include "StyleCustomFilterProgramCache.h"
    3637
    3738namespace WebCore {
    3839
    39 class CachedResourceLoader;
    40 class StyleCachedShader;
    41 class StyleShader;
    42 
    43 class WebKitCSSShaderValue : public CSSValue {
    44 public:
    45     static PassRefPtr<WebKitCSSShaderValue> create(const String& url) { return adoptRef(new WebKitCSSShaderValue(url)); }
    46     ~WebKitCSSShaderValue();
    47 
    48     const String& format() const { return m_format; }
    49     void setFormat(const String& format) { m_format = format; }
    50 
    51     StyleCachedShader* cachedShader(CachedResourceLoader*);
    52     StyleShader* cachedOrPendingShader();
    53 
    54     String customCssText() const;
    55 
    56     bool equals(const WebKitCSSShaderValue&) const;
    57 
    58     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
    59 
    60 private:
    61     WebKitCSSShaderValue(const String& url);
    62 
    63     String m_url;
    64     String m_format;
    65     RefPtr<StyleShader> m_shader;
    66     bool m_accessedShader;
    67 };
     40StyleCustomFilterProgram::~StyleCustomFilterProgram()
     41{
     42    if (m_cache)
     43        m_cache->remove(this);
     44}
    6845
    6946} // namespace WebCore
     
    7148#endif // ENABLE(CSS_SHADERS)
    7249
    73 #endif // WebKitCSSShaderValue_h
  • trunk/Source/WebCore/rendering/style/StyleCustomFilterProgram.h

    r144565 r146529  
    3636#include "CachedShader.h"
    3737#include "CustomFilterProgram.h"
     38#include "KURL.h"
    3839#include "StyleShader.h"
    3940#include <wtf/FastAllocBase.h>
     
    4344// CSS Shaders
    4445
     46class StyleCustomFilterProgramCache;
     47
    4548class StyleCustomFilterProgram : public CustomFilterProgram, public CachedResourceClient {
    4649    WTF_MAKE_FAST_ALLOCATED;
    4750public:
    48     static PassRefPtr<StyleCustomFilterProgram> create(PassRefPtr<StyleShader> vertexShader, PassRefPtr<StyleShader> fragmentShader, CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
     51    static PassRefPtr<StyleCustomFilterProgram> create(KURL vertexShaderURL, PassRefPtr<StyleShader> vertexShader,
     52        KURL fragmentShaderURL, PassRefPtr<StyleShader> fragmentShader, CustomFilterProgramType programType,
     53        const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
    4954    {
    50         return adoptRef(new StyleCustomFilterProgram(vertexShader, fragmentShader, programType, mixSettings, meshType));
     55        return adoptRef(new StyleCustomFilterProgram(vertexShaderURL, vertexShader, fragmentShaderURL, fragmentShader, programType, mixSettings, meshType));
    5156    }
    5257   
    53     void setVertexShader(PassRefPtr<StyleShader> shader) { m_vertexShader = shader; }
     58    void setVertexShader(PassRefPtr<StyleShader> shader)
     59    {
     60        // The shader is immutable while in the cache.
     61        ASSERT(!m_cache);
     62        m_vertexShader = shader;
     63    }
    5464    StyleShader* vertexShader() const { return m_vertexShader.get(); }
    5565   
    56     void setFragmentShader(PassRefPtr<StyleShader> shader) { m_fragmentShader = shader; }
     66    void setFragmentShader(PassRefPtr<StyleShader> shader)
     67    {
     68        // The shader is immutable while in the cache.
     69        ASSERT(!m_cache);
     70        m_fragmentShader = shader;
     71    }
    5772    StyleShader* fragmentShader() const { return m_fragmentShader.get(); }
    5873   
     
    7388        // Do not use the CachedResource:isLoaded method here, because it actually means !isLoading(),
    7489        // so missing and canceled resources will have isLoaded set to true, even if they are not loaded yet.
     90        ASSERT(!m_vertexShader || m_vertexShader->isCachedShader());
     91        ASSERT(!m_fragmentShader || m_fragmentShader->isCachedShader());
     92        ASSERT(m_cachedVertexShader.get() || m_cachedFragmentShader.get());
    7593        return (!m_cachedVertexShader.get() || m_isVertexShaderLoaded)
    7694            && (!m_cachedFragmentShader.get() || m_isFragmentShaderLoaded);
     
    115133            notifyClients();
    116134    }
    117    
    118     CachedShader* cachedVertexShader() const { return m_vertexShader ? m_vertexShader->cachedShader() : 0; }
    119     CachedShader* cachedFragmentShader() const { return m_fragmentShader ? m_fragmentShader->cachedShader() : 0; }
    120    
    121     virtual bool operator==(const CustomFilterProgram& o) const
     135
     136    bool hasPendingShaders() const
    122137    {
    123         // We don't use the != operator because that would recursively call this method.
    124         if (!CustomFilterProgram::operator==(o))
    125             return false;
    126 
    127         // The following cast is ugly, but StyleCustomFilterProgram is the single implementation of CustomFilterProgram.
    128         const StyleCustomFilterProgram* other = static_cast<const StyleCustomFilterProgram*>(&o);
    129         return cachedVertexShader() == other->cachedVertexShader() && cachedFragmentShader() == other->cachedFragmentShader();
     138        return (m_vertexShader && m_vertexShader->isPendingShader())
     139            || (m_fragmentShader && m_fragmentShader->isPendingShader());
    130140    }
    131141
     142    // StyleCustomFilterProgramCache is responsible with updating the reference to the cache.
     143    void setCache(StyleCustomFilterProgramCache* cache) { m_cache = cache; }
     144    bool inCache() const { return m_cache; }
     145   
     146    KURL vertexShaderURL() const { return m_vertexShaderURL; }
     147    KURL fragmentShaderURL() const { return m_fragmentShaderURL; }
     148
    132149private:
    133     StyleCustomFilterProgram(PassRefPtr<StyleShader> vertexShader, PassRefPtr<StyleShader> fragmentShader, CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
     150    StyleCustomFilterProgram(KURL vertexShaderURL, PassRefPtr<StyleShader> vertexShader, KURL fragmentShaderURL, PassRefPtr<StyleShader> fragmentShader,
     151        CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
    134152        : CustomFilterProgram(programType, mixSettings, meshType)
    135153        , m_vertexShader(vertexShader)
    136154        , m_fragmentShader(fragmentShader)
     155        , m_vertexShaderURL(vertexShaderURL)
     156        , m_fragmentShaderURL(fragmentShaderURL)
     157        , m_cache(0)
    137158        , m_isVertexShaderLoaded(false)
    138159        , m_isFragmentShaderLoaded(false)
    139160    {
    140161    }
     162
     163    ~StyleCustomFilterProgram();
    141164   
    142165    RefPtr<StyleShader> m_vertexShader;
    143166    RefPtr<StyleShader> m_fragmentShader;
    144    
     167
    145168    CachedResourceHandle<CachedShader> m_cachedVertexShader;
    146169    CachedResourceHandle<CachedShader> m_cachedFragmentShader;
     170
     171    // The URLs form the key of the StyleCustomFilterProgram in the cache and are used
     172    // to lookup the StyleCustomFilterProgram when it's removed from the cache.
     173    KURL m_vertexShaderURL;
     174    KURL m_fragmentShaderURL;
     175
     176    // The Cache is responsible of invalidating this reference.
     177    StyleCustomFilterProgramCache* m_cache;
    147178   
    148179    bool m_isVertexShaderLoaded;
  • trunk/Source/WebCore/rendering/style/StyleCustomFilterProgramCache.h

    r146528 r146529  
    11/*
    2  * Copyright (C) 2011 Adobe Systems Incorporated. All rights reserved.
     2 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2828 */
    2929
    30 #ifndef WebKitCSSShaderValue_h
    31 #define WebKitCSSShaderValue_h
     30#ifndef StyleCustomFilterProgramCache_h
     31#define StyleCustomFilterProgramCache_h
    3232
    3333#if ENABLE(CSS_SHADERS)
    34 
    35 #include "CSSValue.h"
     34#include "CustomFilterProgramInfo.h"
     35#include <wtf/FastAllocBase.h>
     36#include <wtf/HashMap.h>
    3637
    3738namespace WebCore {
    3839
    39 class CachedResourceLoader;
    40 class StyleCachedShader;
    41 class StyleShader;
     40class StyleCustomFilterProgram;
     41class CustomFilterProgramInfo;
    4242
    43 class WebKitCSSShaderValue : public CSSValue {
     43class StyleCustomFilterProgramCache {
     44    WTF_MAKE_FAST_ALLOCATED;
    4445public:
    45     static PassRefPtr<WebKitCSSShaderValue> create(const String& url) { return adoptRef(new WebKitCSSShaderValue(url)); }
    46     ~WebKitCSSShaderValue();
     46    StyleCustomFilterProgramCache();
     47    ~StyleCustomFilterProgramCache();
    4748
    48     const String& format() const { return m_format; }
    49     void setFormat(const String& format) { m_format = format; }
     49    // Lookups a StyleCustomFilterProgram that has similar parameters with the specified program.
     50    StyleCustomFilterProgram* lookup(StyleCustomFilterProgram*) const;
     51    StyleCustomFilterProgram* lookup(const CustomFilterProgramInfo&) const;
    5052
    51     StyleCachedShader* cachedShader(CachedResourceLoader*);
    52     StyleShader* cachedOrPendingShader();
    53 
    54     String customCssText() const;
    55 
    56     bool equals(const WebKitCSSShaderValue&) const;
    57 
    58     void reportDescendantMemoryUsage(MemoryObjectInfo*) const;
     53    void add(StyleCustomFilterProgram*);
     54    void remove(StyleCustomFilterProgram*);
    5955
    6056private:
    61     WebKitCSSShaderValue(const String& url);
    62 
    63     String m_url;
    64     String m_format;
    65     RefPtr<StyleShader> m_shader;
    66     bool m_accessedShader;
     57    typedef HashMap<CustomFilterProgramInfo, StyleCustomFilterProgram*> CacheMap;
     58    CacheMap m_cache;
    6759};
    6860
     
    7163#endif // ENABLE(CSS_SHADERS)
    7264
    73 #endif // WebKitCSSShaderValue_h
     65#endif // StyleCustomFilterProgramCache_h
Note: See TracChangeset for help on using the changeset viewer.