blob: 3c3724edcafbf670d300db8df1f7ab0c00489dd1 [file] [log] [blame]
/*
* Copyright (C) 2010 University of Szeged
* Copyright (C) 2010 Zoltan Herczeg
* Copyright (C) 2018-2021 Apple, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "Color.h"
#include "FilterEffectApplier.h"
#include "LightSource.h"
namespace WebCore {
class FELighting;
class FELightingSoftwareApplier : public FilterEffectConcreteApplier<FELighting> {
using Base = FilterEffectConcreteApplier<FELighting>;
public:
using Base::Base;
bool apply(const Filter&, const FilterImageVector& inputs, FilterImage& result) override;
private:
static constexpr int cPixelSize = 4;
static constexpr int cAlphaChannelOffset = 3;
static constexpr uint8_t cOpaqueAlpha = static_cast<uint8_t>(0xFF);
// These factors and the normal coefficients come from the table under https://www.w3.org/TR/SVG/filters.html#feDiffuseLightingElement.
static constexpr float cFactor1div2 = -1 / 2.f;
static constexpr float cFactor1div3 = -1 / 3.f;
static constexpr float cFactor1div4 = -1 / 4.f;
static constexpr float cFactor2div3 = -2 / 3.f;
struct AlphaWindow {
uint8_t alpha[3][3] { };
// The implementations are lined up to make comparing indices easier.
uint8_t topLeft() const { return alpha[0][0]; }
uint8_t left() const { return alpha[1][0]; }
uint8_t bottomLeft() const { return alpha[2][0]; }
uint8_t top() const { return alpha[0][1]; }
uint8_t center() const { return alpha[1][1]; }
uint8_t bottom() const { return alpha[2][1]; }
void setTop(uint8_t value) { alpha[0][1] = value; }
void setCenter(uint8_t value) { alpha[1][1] = value; }
void setBottom(uint8_t value) { alpha[2][1] = value; }
void setTopRight(uint8_t value) { alpha[0][2] = value; }
void setRight(uint8_t value) { alpha[1][2] = value; }
void setBottomRight(uint8_t value) { alpha[2][2] = value; }
static void shiftRow(uint8_t alpha[3])
{
alpha[0] = alpha[1];
alpha[1] = alpha[2];
}
void shift()
{
shiftRow(alpha[0]);
shiftRow(alpha[1]);
shiftRow(alpha[2]);
}
};
struct LightingData {
// This structure contains only read-only (SMP safe) data
FELighting* effect;
FilterEffect::Type filterType;
Color lightingColor;
float surfaceScale;
float diffuseConstant;
float specularConstant;
float specularExponent;
const LightSource* lightSource;
const DestinationColorSpace* operatingColorSpace;
Uint8ClampedArray* pixels;
int widthMultipliedByPixelSize;
int width;
int height;
inline IntSize topLeftNormal(int offset) const;
inline IntSize topRowNormal(int offset) const;
inline IntSize topRightNormal(int offset) const;
inline IntSize leftColumnNormal(int offset) const;
inline IntSize interiorNormal(int offset, AlphaWindow&) const;
inline IntSize rightColumnNormal(int offset) const;
inline IntSize bottomLeftNormal(int offset) const;
inline IntSize bottomRowNormal(int offset) const;
inline IntSize bottomRightNormal(int offset) const;
};
struct ApplyParameters {
LightingData data;
LightSource::PaintingData paintingData;
int yStart;
int yEnd;
};
static void setPixelInternal(int offset, const LightingData&, const LightSource::PaintingData&, int x, int y, float factorX, float factorY, IntSize normal2DVector, float alpha);
static void setPixel(int offset, const LightingData&, const LightSource::PaintingData&, int x, int y, float factorX, float factorY, IntSize normal2DVector);
static void applyPlatformGenericPaint(const LightingData&, const LightSource::PaintingData&, int startY, int endY);
static void applyPlatformGenericWorker(ApplyParameters*);
static void applyPlatformGeneric(const LightingData&, const LightSource::PaintingData&);
static void applyPlatform(const LightingData&);
};
} // namespace WebCore