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/fetch/ResourceClient.h"
     34 #include "core/fetch/ResourcePtr.h"
     35 #include "core/fetch/ShaderResource.h"
     36 #include "core/rendering/style/StyleShader.h"
     37 #include "platform/graphics/filters/custom/CustomFilterProgram.h"
     38 #include "platform/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 
     92         // If we failed to create resources for the vertex shader or the
     93         // fragment shader, they won't be set here.
     94         // This can happen if the ResourceFetcher is no longer accepting fetch
     95         // requests because the page is being torn down.
     96         if (!m_vertexShader && !m_fragmentShader)
     97             return false;
     98 
     99         ASSERT(m_cachedVertexShader.get() || m_cachedFragmentShader.get());
    100         return (!m_cachedVertexShader.get() || m_isVertexShaderLoaded)
    101             && (!m_cachedFragmentShader.get() || m_isFragmentShaderLoaded);
    102     }
    103 
    104     virtual void willHaveClients()
    105     {
    106         if (m_vertexShader) {
    107             m_cachedVertexShader = m_vertexShader->resource();
    108             m_cachedVertexShader->addClient(this);
    109         }
    110         if (m_fragmentShader) {
    111             m_cachedFragmentShader = m_fragmentShader->resource();
    112             m_cachedFragmentShader->addClient(this);
    113         }
    114     }
    115 
    116     virtual void didRemoveLastClient()
    117     {
    118         if (m_cachedVertexShader.get()) {
    119             m_cachedVertexShader->removeClient(this);
    120             m_cachedVertexShader = 0;
    121             m_isVertexShaderLoaded = false;
    122         }
    123         if (m_cachedFragmentShader.get()) {
    124             m_cachedFragmentShader->removeClient(this);
    125             m_cachedFragmentShader = 0;
    126             m_isFragmentShaderLoaded = false;
    127         }
    128     }
    129 
    130     virtual void notifyFinished(Resource* resource)
    131     {
    132         if (resource->errorOccurred())
    133             return;
    134         // Note that m_cachedVertexShader might be equal to m_cachedFragmentShader and it would only get one event in that case.
    135         if (resource == m_cachedVertexShader.get())
    136             m_isVertexShaderLoaded = true;
    137         if (resource == m_cachedFragmentShader.get())
    138             m_isFragmentShaderLoaded = true;
    139         if (isLoaded())
    140             notifyClients();
    141     }
    142 
    143     bool hasPendingShaders() const
    144     {
    145         return (m_vertexShader && m_vertexShader->isPendingShader())
    146             || (m_fragmentShader && m_fragmentShader->isPendingShader());
    147     }
    148 
    149     // StyleCustomFilterProgramCache is responsible with updating the reference to the cache.
    150     void setCache(StyleCustomFilterProgramCache* cache) { m_cache = cache; }
    151     bool inCache() const { return m_cache; }
    152 
    153     KURL vertexShaderURL() const { return m_vertexShaderURL; }
    154     KURL fragmentShaderURL() const { return m_fragmentShaderURL; }
    155 
    156 private:
    157     StyleCustomFilterProgram(KURL vertexShaderURL, PassRefPtr<StyleShader> vertexShader, KURL fragmentShaderURL, PassRefPtr<StyleShader> fragmentShader,
    158         CustomFilterProgramType programType, const CustomFilterProgramMixSettings& mixSettings, CustomFilterMeshType meshType)
    159         : CustomFilterProgram(programType, mixSettings, meshType)
    160         , m_vertexShader(vertexShader)
    161         , m_fragmentShader(fragmentShader)
    162         , m_vertexShaderURL(vertexShaderURL)
    163         , m_fragmentShaderURL(fragmentShaderURL)
    164         , m_cache(0)
    165         , m_isVertexShaderLoaded(false)
    166         , m_isFragmentShaderLoaded(false)
    167     {
    168     }
    169 
    170     ~StyleCustomFilterProgram();
    171 
    172     RefPtr<StyleShader> m_vertexShader;
    173     RefPtr<StyleShader> m_fragmentShader;
    174 
    175     ResourcePtr<ShaderResource> m_cachedVertexShader;
    176     ResourcePtr<ShaderResource> m_cachedFragmentShader;
    177 
    178     // The URLs form the key of the StyleCustomFilterProgram in the cache and are used
    179     // to lookup the StyleCustomFilterProgram when it's removed from the cache.
    180     KURL m_vertexShaderURL;
    181     KURL m_fragmentShaderURL;
    182 
    183     // The Cache is responsible of invalidating this reference.
    184     StyleCustomFilterProgramCache* m_cache;
    185 
    186     bool m_isVertexShaderLoaded;
    187     bool m_isFragmentShaderLoaded;
    188 };
    189 
    190 } // namespace WebCore
    191 
    192 
    193 #endif // StyleCustomFilterProgram_h
    194