Home | History | Annotate | Download | only in style
      1 /*
      2  * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1. Redistributions of source code must retain the above
      9  *    copyright notice, this list of conditions and the following
     10  *    disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above
     12  *    copyright notice, this list of conditions and the following
     13  *    disclaimer in the documentation and/or other materials
     14  *    provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AS IS AND ANY
     17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
     20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
     21  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     25  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
     26  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 
     30 #ifndef StyleCustomFilterProgram_h
     31 #define StyleCustomFilterProgram_h
     32 
     33 #include "core/loader/cache/ResourceClient.h"
     34 #include "core/loader/cache/ResourcePtr.h"
     35 #include "core/loader/cache/ShaderResource.h"
     36 #include "core/platform/graphics/filters/custom/CustomFilterProgram.h"
     37 #include "core/rendering/style/StyleShader.h"
     38 #include "weborigin/KURL.h"
     39 #include "wtf/FastAllocBase.h"
     40 
     41 namespace WebCore {
     42 
     43 // CSS Shaders
     44 
     45 class StyleCustomFilterProgramCache;
     46 
     47 class StyleCustomFilterProgram : public CustomFilterProgram, public ResourceClient {
     48     WTF_MAKE_FAST_ALLOCATED;
     49 public:
     50     static PassRefPtr<StyleCustomFilterProgram> create(KURL vertexShaderURL, PassRefPtr<StyleShader> vertexShader,
     51         KURL fragmentShaderURL, PassRefPtr<StyleShader> fragmentShader, CustomFilterProgramType programType,
     52         const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
     53     {
     54         return adoptRef(new StyleCustomFilterProgram(vertexShaderURL, vertexShader, fragmentShaderURL, fragmentShader, programType, mixSettings, meshType));
     55     }
     56 
     57     void setVertexShader(PassRefPtr<StyleShader> shader)
     58     {
     59         // The shader is immutable while in the cache.
     60         ASSERT(!m_cache);
     61         m_vertexShader = shader;
     62     }
     63     StyleShader* vertexShader() const { return m_vertexShader.get(); }
     64 
     65     void setFragmentShader(PassRefPtr<StyleShader> shader)
     66     {
     67         // The shader is immutable while in the cache.
     68         ASSERT(!m_cache);
     69         m_fragmentShader = shader;
     70     }
     71     StyleShader* fragmentShader() const { return m_fragmentShader.get(); }
     72 
     73     virtual String vertexShaderString() const
     74     {
     75         ASSERT(isLoaded());
     76         return m_cachedVertexShader.get() ? m_cachedVertexShader->shaderString() : String();
     77     }
     78 
     79     virtual String fragmentShaderString() const
     80     {
     81         ASSERT(isLoaded());
     82         return m_cachedFragmentShader.get() ? m_cachedFragmentShader->shaderString() : String();
     83     }
     84 
     85     virtual bool isLoaded() const
     86     {
     87         // Do not use the Resource:isLoaded method here, because it actually means !isLoading(),
     88         // so missing and canceled resources will have isLoaded set to true, even if they are not loaded yet.
     89         ASSERT(!m_vertexShader || m_vertexShader->isShaderResource());
     90         ASSERT(!m_fragmentShader || m_fragmentShader->isShaderResource());
     91         ASSERT(m_cachedVertexShader.get() || m_cachedFragmentShader.get());
     92         return (!m_cachedVertexShader.get() || m_isVertexShaderLoaded)
     93             && (!m_cachedFragmentShader.get() || m_isFragmentShaderLoaded);
     94     }
     95 
     96     virtual void willHaveClients()
     97     {
     98         if (m_vertexShader) {
     99             m_cachedVertexShader = m_vertexShader->resource();
    100             m_cachedVertexShader->addClient(this);
    101         }
    102         if (m_fragmentShader) {
    103             m_cachedFragmentShader = m_fragmentShader->resource();
    104             m_cachedFragmentShader->addClient(this);
    105         }
    106     }
    107 
    108     virtual void didRemoveLastClient()
    109     {
    110         if (m_cachedVertexShader.get()) {
    111             m_cachedVertexShader->removeClient(this);
    112             m_cachedVertexShader = 0;
    113             m_isVertexShaderLoaded = false;
    114         }
    115         if (m_cachedFragmentShader.get()) {
    116             m_cachedFragmentShader->removeClient(this);
    117             m_cachedFragmentShader = 0;
    118             m_isFragmentShaderLoaded = false;
    119         }
    120     }
    121 
    122     virtual void notifyFinished(Resource* resource)
    123     {
    124         if (resource->errorOccurred())
    125             return;
    126         // Note that m_cachedVertexShader might be equal to m_cachedFragmentShader and it would only get one event in that case.
    127         if (resource == m_cachedVertexShader.get())
    128             m_isVertexShaderLoaded = true;
    129         if (resource == m_cachedFragmentShader.get())
    130             m_isFragmentShaderLoaded = true;
    131         if (isLoaded())
    132             notifyClients();
    133     }
    134 
    135     bool hasPendingShaders() const
    136     {
    137         return (m_vertexShader && m_vertexShader->isPendingShader())
    138             || (m_fragmentShader && m_fragmentShader->isPendingShader());
    139     }
    140 
    141     // StyleCustomFilterProgramCache is responsible with updating the reference to the cache.
    142     void setCache(StyleCustomFilterProgramCache* cache) { m_cache = cache; }
    143     bool inCache() const { return m_cache; }
    144 
    145     KURL vertexShaderURL() const { return m_vertexShaderURL; }
    146     KURL fragmentShaderURL() const { return m_fragmentShaderURL; }
    147 
    148 private:
    149     StyleCustomFilterProgram(KURL vertexShaderURL, PassRefPtr<StyleShader> vertexShader, KURL fragmentShaderURL, PassRefPtr<StyleShader> fragmentShader,
    150         CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
    151         : CustomFilterProgram(programType, mixSettings, meshType)
    152         , m_vertexShader(vertexShader)
    153         , m_fragmentShader(fragmentShader)
    154         , m_vertexShaderURL(vertexShaderURL)
    155         , m_fragmentShaderURL(fragmentShaderURL)
    156         , m_cache(0)
    157         , m_isVertexShaderLoaded(false)
    158         , m_isFragmentShaderLoaded(false)
    159     {
    160     }
    161 
    162     ~StyleCustomFilterProgram();
    163 
    164     RefPtr<StyleShader> m_vertexShader;
    165     RefPtr<StyleShader> m_fragmentShader;
    166 
    167     ResourcePtr<ShaderResource> m_cachedVertexShader;
    168     ResourcePtr<ShaderResource> m_cachedFragmentShader;
    169 
    170     // The URLs form the key of the StyleCustomFilterProgram in the cache and are used
    171     // to lookup the StyleCustomFilterProgram when it's removed from the cache.
    172     KURL m_vertexShaderURL;
    173     KURL m_fragmentShaderURL;
    174 
    175     // The Cache is responsible of invalidating this reference.
    176     StyleCustomFilterProgramCache* m_cache;
    177 
    178     bool m_isVertexShaderLoaded;
    179     bool m_isFragmentShaderLoaded;
    180 };
    181 
    182 } // namespace WebCore
    183 
    184 
    185 #endif // StyleCustomFilterProgram_h
    186