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;