CustomFilterOperation.cpp [plain text]
#include "config.h"
#if ENABLE(CSS_SHADERS)
#include "CustomFilterOperation.h"
#include "CustomFilterParameter.h"
#include "CustomFilterProgram.h"
#include "FilterOperation.h"
#include <wtf/text/StringHash.h>
namespace WebCore {
bool customFilterParametersEqual(const CustomFilterParameterList& listA, const CustomFilterParameterList& listB)
{
if (listA.size() != listB.size())
return false;
for (size_t i = 0; i < listA.size(); ++i) {
if (listA.at(i).get() != listB.at(i).get()
&& *listA.at(i).get() != *listB.at(i).get())
return false;
}
return true;
}
#if !ASSERT_DISABLED
static bool checkCustomFilterParametersOrder(const CustomFilterParameterList& parameters)
{
for (unsigned i = 1; i < parameters.size(); ++i) {
if (!codePointCompareLessThan(parameters.at(i - 1)->name(), parameters.at(i)->name()))
return false;
}
return true;
}
#endif
void blendCustomFilterParameters(const CustomFilterParameterList& fromList, const CustomFilterParameterList& toList, double progress, CustomFilterParameterList& resultList)
{
ASSERT(checkCustomFilterParametersOrder(fromList));
ASSERT(checkCustomFilterParametersOrder(toList));
size_t fromListIndex = 0, toListIndex = 0;
while (fromListIndex < fromList.size() && toListIndex < toList.size()) {
CustomFilterParameter* paramFrom = fromList.at(fromListIndex).get();
CustomFilterParameter* paramTo = toList.at(toListIndex).get();
if (paramFrom->name() == paramTo->name()) {
resultList.append(paramTo->blend(paramFrom, progress));
++fromListIndex;
++toListIndex;
continue;
}
if (codePointCompareLessThan(paramFrom->name(), paramTo->name())) {
resultList.append(paramFrom);
++fromListIndex;
continue;
}
resultList.append(paramTo);
++toListIndex;
}
for (; fromListIndex < fromList.size(); ++fromListIndex)
resultList.append(fromList.at(fromListIndex));
for (; toListIndex < toList.size(); ++toListIndex)
resultList.append(toList.at(toListIndex));
ASSERT(checkCustomFilterParametersOrder(resultList));
}
CustomFilterOperation::CustomFilterOperation(PassRefPtr<CustomFilterProgram> program, const CustomFilterParameterList& sortedParameters, unsigned meshRows, unsigned meshColumns, MeshBoxType meshBoxType, MeshType meshType)
: FilterOperation(CUSTOM)
, m_program(program)
, m_parameters(sortedParameters)
, m_meshRows(meshRows)
, m_meshColumns(meshColumns)
, m_meshBoxType(meshBoxType)
, m_meshType(meshType)
{
ASSERT(checkCustomFilterParametersOrder(m_parameters));
}
CustomFilterOperation::~CustomFilterOperation()
{
}
PassRefPtr<FilterOperation> CustomFilterOperation::blend(const FilterOperation* from, double progress, bool blendToPassthrough)
{
if (blendToPassthrough || !from || !from->isSameType(*this))
return this;
const CustomFilterOperation* fromOp = static_cast<const CustomFilterOperation*>(from);
if (*m_program.get() != *fromOp->m_program.get()
|| m_meshRows != fromOp->m_meshRows
|| m_meshColumns != fromOp->m_meshColumns
|| m_meshBoxType != fromOp->m_meshBoxType
|| m_meshType != fromOp->m_meshType)
return this;
CustomFilterParameterList animatedParameters;
blendCustomFilterParameters(fromOp->m_parameters, m_parameters, progress, animatedParameters);
return CustomFilterOperation::create(m_program, animatedParameters, m_meshRows, m_meshColumns, m_meshBoxType, m_meshType);
}
}
#endif // ENABLE(CSS_SHADERS)