Title: [133242] trunk/Source/WebCore
Revision
133242
Author
[email protected]
Date
2012-11-01 17:03:31 -0700 (Thu, 01 Nov 2012)

Log Message

[CSS Shaders] CustomFilterOperation should be converted to ValidatedCustomFilterOperation before using it
https://bugs.webkit.org/show_bug.cgi?id=100533

Reviewed by Dean Jackson.

Added the code that converts a CustomFilterOperation to a ValidatedCustomFilterOperation.
Both the software path and the composited one will use this operation instead. There will be
no need to check the shader in platform code anymore.

No new tests, already covered by existing custom filter tests.

* platform/graphics/filters/ValidatedCustomFilterOperation.cpp:
(WebCore::ValidatedCustomFilterOperation::ValidatedCustomFilterOperation):
* platform/graphics/filters/ValidatedCustomFilterOperation.h:
(WebCore):
(WebCore::ValidatedCustomFilterOperation::create):
(ValidatedCustomFilterOperation):
(WebCore::ValidatedCustomFilterOperation::validatedProgram):
(WebCore::ValidatedCustomFilterOperation::parameters):
(WebCore::ValidatedCustomFilterOperation::meshRows):
(WebCore::ValidatedCustomFilterOperation::meshColumns):
(WebCore::ValidatedCustomFilterOperation::meshType):
(WebCore::ValidatedCustomFilterOperation::operator==):
* rendering/FilterEffectRenderer.cpp:
(WebCore::createCustomFilterEffect):
(WebCore::FilterEffectRenderer::build):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::ensureBacking):
(WebCore::RenderLayer::clearBacking):
(WebCore::RenderLayer::styleChanged): updateOrRemoveFilterClients needs to be called before the composited
layer is updated. Otherwise the composited layer will never see a loaded filter in the first call.
(WebCore):
(WebCore::RenderLayer::isCSSCustomFilterEnabled):
(WebCore::RenderLayer::computeFilterOperations):
(WebCore::RenderLayer::updateOrRemoveFilterClients): Split updateOrRemoveFilterEffect into 2 functions.
This one is supposed to add the clients needed to load network resources.
(WebCore::RenderLayer::updateOrRemoveFilterEffectRenderer): Figures out if a software fallback is needed
and creates a FilterEffectRenderer.
* rendering/RenderLayer.h:
(RenderLayer):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (133241 => 133242)


--- trunk/Source/WebCore/ChangeLog	2012-11-01 23:58:59 UTC (rev 133241)
+++ trunk/Source/WebCore/ChangeLog	2012-11-02 00:03:31 UTC (rev 133242)
@@ -1,3 +1,46 @@
+2012-11-01  Alexandru Chiculita  <[email protected]>
+
+        [CSS Shaders] CustomFilterOperation should be converted to ValidatedCustomFilterOperation before using it
+        https://bugs.webkit.org/show_bug.cgi?id=100533
+
+        Reviewed by Dean Jackson.
+
+        Added the code that converts a CustomFilterOperation to a ValidatedCustomFilterOperation.
+        Both the software path and the composited one will use this operation instead. There will be
+        no need to check the shader in platform code anymore.
+
+        No new tests, already covered by existing custom filter tests.
+
+        * platform/graphics/filters/ValidatedCustomFilterOperation.cpp:
+        (WebCore::ValidatedCustomFilterOperation::ValidatedCustomFilterOperation):
+        * platform/graphics/filters/ValidatedCustomFilterOperation.h:
+        (WebCore):
+        (WebCore::ValidatedCustomFilterOperation::create):
+        (ValidatedCustomFilterOperation):
+        (WebCore::ValidatedCustomFilterOperation::validatedProgram):
+        (WebCore::ValidatedCustomFilterOperation::parameters):
+        (WebCore::ValidatedCustomFilterOperation::meshRows):
+        (WebCore::ValidatedCustomFilterOperation::meshColumns):
+        (WebCore::ValidatedCustomFilterOperation::meshType):
+        (WebCore::ValidatedCustomFilterOperation::operator==):
+        * rendering/FilterEffectRenderer.cpp:
+        (WebCore::createCustomFilterEffect):
+        (WebCore::FilterEffectRenderer::build):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::ensureBacking):
+        (WebCore::RenderLayer::clearBacking):
+        (WebCore::RenderLayer::styleChanged): updateOrRemoveFilterClients needs to be called before the composited
+        layer is updated. Otherwise the composited layer will never see a loaded filter in the first call.
+        (WebCore):
+        (WebCore::RenderLayer::isCSSCustomFilterEnabled):
+        (WebCore::RenderLayer::computeFilterOperations):
+        (WebCore::RenderLayer::updateOrRemoveFilterClients): Split updateOrRemoveFilterEffect into 2 functions.
+        This one is supposed to add the clients needed to load network resources.
+        (WebCore::RenderLayer::updateOrRemoveFilterEffectRenderer): Figures out if a software fallback is needed 
+        and creates a FilterEffectRenderer.
+        * rendering/RenderLayer.h:
+        (RenderLayer):
+
 2012-11-01  Max Vujovic  <[email protected]>
 
         [CSS Shaders] Get rid of internal tex coord attribute

Modified: trunk/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.cpp (133241 => 133242)


--- trunk/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.cpp	2012-11-01 23:58:59 UTC (rev 133241)
+++ trunk/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.cpp	2012-11-02 00:03:31 UTC (rev 133242)
@@ -32,13 +32,21 @@
 #if ENABLE(CSS_SHADERS)
 #include "ValidatedCustomFilterOperation.h"
 
+#include "CustomFilterParameter.h"
+#include "CustomFilterValidatedProgram.h"
 #include "FractionalLayoutSize.h"
 #include <wtf/UnusedParam.h>
 
 namespace WebCore {
 
-ValidatedCustomFilterOperation::ValidatedCustomFilterOperation()
+ValidatedCustomFilterOperation::ValidatedCustomFilterOperation(PassRefPtr<CustomFilterValidatedProgram> validatedProgram, 
+    const CustomFilterParameterList& sortedParameters, unsigned meshRows, unsigned meshColumns, CustomFilterMeshType meshType)
     : FilterOperation(VALIDATED_CUSTOM)
+    , m_validatedProgram(validatedProgram)
+    , m_parameters(sortedParameters)
+    , m_meshRows(meshRows)
+    , m_meshColumns(meshColumns)
+    , m_meshType(meshType)
 {
 }
 

Modified: trunk/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.h (133241 => 133242)


--- trunk/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.h	2012-11-01 23:58:59 UTC (rev 133241)
+++ trunk/Source/WebCore/platform/graphics/filters/ValidatedCustomFilterOperation.h	2012-11-02 00:03:31 UTC (rev 133242)
@@ -31,16 +31,21 @@
 #define ValidatedCustomFilterOperation_h
 
 #if ENABLE(CSS_SHADERS)
+#include "CustomFilterConstants.h"
+#include "CustomFilterParameterList.h"
 #include "FilterOperation.h"
 #include "LayoutTypes.h"
 
 namespace WebCore {
 
+class CustomFilterValidatedProgram;
+
 class ValidatedCustomFilterOperation : public FilterOperation {
 public:
-    static PassRefPtr<ValidatedCustomFilterOperation> create()
+    static PassRefPtr<ValidatedCustomFilterOperation> create(PassRefPtr<CustomFilterValidatedProgram> validatedProgram, 
+        const CustomFilterParameterList& sortedParameters, unsigned meshRows, unsigned meshColumns, CustomFilterMeshType meshType)
     {
-        return adoptRef(new ValidatedCustomFilterOperation());
+        return adoptRef(new ValidatedCustomFilterOperation(validatedProgram, sortedParameters, meshRows, meshColumns, meshType));
     }
 
     virtual ~ValidatedCustomFilterOperation();
@@ -50,16 +55,40 @@
     virtual bool blendingNeedsRendererSize() const { return true; }
 
     virtual PassRefPtr<FilterOperation> blend(const FilterOperation* from, double progress, const LayoutSize&, bool blendToPassthrough = false);
+
+    CustomFilterValidatedProgram* validatedProgram() const { return m_validatedProgram.get(); }
+    const CustomFilterParameterList& parameters() const { return m_parameters; }
+
+    unsigned meshRows() const { return m_meshRows; }
+    unsigned meshColumns() const { return m_meshColumns; }
+
+    CustomFilterMeshType meshType() const { return m_meshType; }
+
 private:
     virtual bool operator==(const FilterOperation& o) const
     {
         if (!isSameType(o))
             return false;
 
-        return true;
+        const ValidatedCustomFilterOperation* other = static_cast<const ValidatedCustomFilterOperation*>(&o);
+        return m_validatedProgram.get() == other->m_validatedProgram.get()
+            && m_meshRows == other->m_meshRows
+            && m_meshColumns == other->m_meshColumns
+            && m_meshType == other->m_meshType
+            && m_parameters == other->m_parameters;
     }
 
-    ValidatedCustomFilterOperation();
+    ValidatedCustomFilterOperation(PassRefPtr<CustomFilterValidatedProgram>, const CustomFilterParameterList&, unsigned meshRows, unsigned meshColumns, CustomFilterMeshType);
+
+    RefPtr<CustomFilterValidatedProgram> m_validatedProgram;
+
+    CustomFilterParameterList m_parameters;
+    unsigned m_meshRows;
+    unsigned m_meshColumns;
+    CustomFilterMeshType m_meshType;
+    
+    // FIXME: Add CustomFilterMeshBoxType after 100782 is landed.
+    // https://bugs.webkit.org/show_bug.cgi?id=100890
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp (133241 => 133242)


--- trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp	2012-11-01 23:58:59 UTC (rev 133241)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp	2012-11-02 00:03:31 UTC (rev 133242)
@@ -43,13 +43,14 @@
 #include <wtf/MathExtras.h>
 
 #if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
+#include "CustomFilterConstants.h"
 #include "CustomFilterGlobalContext.h"
 #include "CustomFilterOperation.h"
 #include "CustomFilterProgram.h"
 #include "CustomFilterValidatedProgram.h"
 #include "FECustomFilter.h"
 #include "RenderView.h"
-#include "Settings.h"
+#include "ValidatedCustomFilterOperation.h"
 #endif
 
 #if ENABLE(SVG)
@@ -86,33 +87,18 @@
 }
 
 #if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
-static bool isCSSCustomFilterEnabled(Document* document)
+static PassRefPtr<FECustomFilter> createCustomFilterEffect(Filter* filter, Document* document, ValidatedCustomFilterOperation* operation)
 {
-    // We only want to enable shaders if WebGL is also enabled on this platform.
-    Settings* settings = document->settings();
-    return settings && settings->isCSSCustomFilterEnabled() && settings->webGLEnabled();
-}
-
-static PassRefPtr<FECustomFilter> createCustomFilterEffect(Filter* filter, Document* document, CustomFilterOperation* operation)
-{
-    if (!isCSSCustomFilterEnabled(document))
-        return 0;
-
-    RefPtr<CustomFilterProgram> program = operation->program();
-    if (!program->isLoaded())
-        return 0;
-
     CustomFilterGlobalContext* globalContext = document->renderView()->customFilterGlobalContext();
     globalContext->prepareContextIfNeeded(document->view()->hostWindow());
     if (!globalContext->context())
         return 0;
 
-    RefPtr<CustomFilterValidatedProgram> validatedProgram = globalContext->getValidatedProgram(program->programInfo());
-    if (!validatedProgram->isInitialized())
-        return 0;
-
-    return FECustomFilter::create(filter, globalContext->context(), validatedProgram.release(), operation->parameters(),
-        operation->meshRows(), operation->meshColumns(), operation->meshBoxType(), operation->meshType());
+    // FIXME: Use the right CustomFilterMeshBoxType when that will be available on the ValidatedCustomFilterOperation.
+    // Right now the implementation doesn't use that parameter anyway, so just pass the default MeshBoxTypeFilter.
+    // https://bugs.webkit.org/show_bug.cgi?id=100890
+    return FECustomFilter::create(filter, globalContext->context(), operation->validatedProgram(), operation->parameters(),
+        operation->meshRows(), operation->meshColumns(), MeshBoxTypeFilter, operation->meshType());
 }
 #endif
 
@@ -353,8 +339,13 @@
             break;
         }
 #if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
-        case FilterOperation::CUSTOM: {
-            CustomFilterOperation* customFilterOperation = static_cast<CustomFilterOperation*>(filterOperation);
+        case FilterOperation::CUSTOM:
+            // CUSTOM operations are always converted to VALIDATED_CUSTOM before getting here.
+            // The conversion happens in RenderLayer::computeFilterOperations.
+            ASSERT_NOT_REACHED();
+            break;
+        case FilterOperation::VALIDATED_CUSTOM: {
+            ValidatedCustomFilterOperation* customFilterOperation = static_cast<ValidatedCustomFilterOperation*>(filterOperation);
             effect = createCustomFilterEffect(this, document, customFilterOperation);
             if (effect)
                 m_hasCustomShaderFilter = true;

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (133241 => 133242)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2012-11-01 23:58:59 UTC (rev 133241)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2012-11-02 00:03:31 UTC (rev 133242)
@@ -110,8 +110,11 @@
 #include "SVGNames.h"
 #endif
 
-#if ENABLE(CSS_SHADERS)
-#include <CustomFilterOperation.h>
+#if ENABLE(CSS_SHADERS) && USE(3D_GRAPHICS)
+#include "CustomFilterGlobalContext.h"
+#include "CustomFilterOperation.h"
+#include "CustomFilterValidatedProgram.h"
+#include "ValidatedCustomFilterOperation.h"
 #endif
 
 #if PLATFORM(BLACKBERRY)
@@ -4505,7 +4508,7 @@
         compositor()->layerBecameComposited(this);
 
 #if ENABLE(CSS_FILTERS)
-        updateOrRemoveFilterEffect();
+        updateOrRemoveFilterEffectRenderer();
 #endif
 #if ENABLE(CSS_COMPOSITING)
         backing()->setBlendMode(m_blendMode);
@@ -4522,7 +4525,7 @@
 
 #if ENABLE(CSS_FILTERS)
     if (!layerBeingDestroyed)
-        updateOrRemoveFilterEffect();
+        updateOrRemoveFilterEffectRenderer();
 #else
     UNUSED_PARAM(layerBeingDestroyed);
 #endif
@@ -4941,6 +4944,9 @@
 #if ENABLE(CSS_COMPOSITING)
     updateBlendMode();
 #endif
+#if ENABLE(CSS_FILTERS)
+    updateOrRemoveFilterClients();
+#endif
 
 #if USE(ACCELERATED_COMPOSITING)
     if (compositor()->updateLayerCompositingState(this))
@@ -4956,7 +4962,7 @@
 #endif
 
 #if ENABLE(CSS_FILTERS)
-    updateOrRemoveFilterEffect();
+    updateOrRemoveFilterEffectRenderer();
 #if USE(ACCELERATED_COMPOSITING)
     bool backingDidCompositeLayers = isComposited() && backing()->canCompositeFilters();
     if (isComposited() && backingDidCompositeLayers && !backing()->canCompositeFilters()) {
@@ -5079,6 +5085,15 @@
     m_reflection->setStyle(newStyle.release());
 }
 
+#if ENABLE(CSS_SHADERS)
+bool RenderLayer::isCSSCustomFilterEnabled() const
+{
+    // We only want to enable shaders if WebGL is also enabled on this platform.
+    const Settings* settings = renderer()->document()->settings();
+    return settings && settings->isCSSCustomFilterEnabled() && settings->webGLEnabled();
+}
+#endif
+
 #if ENABLE(CSS_FILTERS)
 FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style)
 {
@@ -5089,17 +5104,33 @@
     if (!filters.hasCustomFilter())
         return filters;
 
+    if (!isCSSCustomFilterEnabled()) {
+        // CSS Custom filters should not parse at all in this case, but there might be
+        // remaining styles that were parsed when the flag was enabled. Reproduces in DumpRenderTree
+        // because it resets the flag while the previous test is still loaded.
+        return FilterOperations();
+    }
+
     FilterOperations outputFilters;
     for (size_t i = 0; i < filters.size(); ++i) {
         RefPtr<FilterOperation> filterOperation = filters.operations().at(i);
         if (filterOperation->getOperationType() == FilterOperation::CUSTOM) {
             // We have to wait until the program of CSS Shaders is loaded before setting it on the layer.
-            // Note that we will handle the loading of the shaders and repainting of the layer in updateOrRemoveFilterEffect.
+            // Note that we will handle the loading of the shaders and repainting of the layer in updateOrRemoveFilterClients.
             const CustomFilterOperation* customOperation = static_cast<const CustomFilterOperation*>(filterOperation.get());
-            if (!customOperation->program()->isLoaded())
+            RefPtr<CustomFilterProgram> program = customOperation->program();
+            if (!program->isLoaded())
                 continue;
-            // FIXME: Validate the shaders and convert the operation to a ValidatedCustomFilterOperation.
-            // https://bugs.webkit.org/show_bug.cgi?id=100533
+            
+            CustomFilterGlobalContext* globalContext = renderer()->view()->customFilterGlobalContext();
+            RefPtr<CustomFilterValidatedProgram> validatedProgram = globalContext->getValidatedProgram(program->programInfo());
+            if (!validatedProgram->isInitialized())
+                continue;
+
+            RefPtr<ValidatedCustomFilterOperation> validatedOperation = ValidatedCustomFilterOperation::create(validatedProgram.release(), 
+                customOperation->parameters(), customOperation->meshRows(), customOperation->meshColumns(), customOperation->meshType());
+            outputFilters.operations().append(validatedOperation.release());
+            continue;
         }
         outputFilters.operations().append(filterOperation.release());
     }
@@ -5107,7 +5138,7 @@
 #endif
 }
 
-void RenderLayer::updateOrRemoveFilterEffect()
+void RenderLayer::updateOrRemoveFilterClients()
 {
     if (!hasFilter()) {
         removeFilterInfoIfNeeded();
@@ -5127,7 +5158,13 @@
     else if (hasFilterInfo())
         filterInfo()->removeReferenceFilterClients();
 #endif
+}
 
+void RenderLayer::updateOrRemoveFilterEffectRenderer()
+{
+    // FilterEffectRenderer is only used to render the filters in software mode,
+    // so we always need to run updateOrRemoveFilterEffectRenderer after the composited
+    // mode might have changed for this layer.
     if (!paintsWithFilters()) {
         // Don't delete the whole filter info here, because we might use it
         // for loading CSS shader files.

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (133241 => 133242)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2012-11-01 23:58:59 UTC (rev 133241)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2012-11-02 00:03:31 UTC (rev 133242)
@@ -653,6 +653,10 @@
     bool containsDirtyOverlayScrollbars() const { return m_containsDirtyOverlayScrollbars; }
     void setContainsDirtyOverlayScrollbars(bool dirtyScrollbars) { m_containsDirtyOverlayScrollbars = dirtyScrollbars; }
 
+#if ENABLE(CSS_SHADERS)
+    bool isCSSCustomFilterEnabled() const;
+#endif
+
 #if ENABLE(CSS_FILTERS)
     FilterOperations computeFilterOperations(const RenderStyle*);
     bool paintsWithFilters() const;
@@ -843,7 +847,8 @@
     void setPaintingInsideReflection(bool b) { m_paintingInsideReflection = b; }
 
 #if ENABLE(CSS_FILTERS)
-    void updateOrRemoveFilterEffect();
+    void updateOrRemoveFilterClients();
+    void updateOrRemoveFilterEffectRenderer();
 #endif
 
     void parentClipRects(const RenderLayer* rootLayer, RenderRegion*, ClipRectsType, ClipRects&, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize, ShouldRespectOverflowClip = RespectOverflowClip) const;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to