diff options
Diffstat (limited to 'chromium/third_party/WebKit/Source/platform/graphics/filters/FELighting.cpp')
-rw-r--r-- | chromium/third_party/WebKit/Source/platform/graphics/filters/FELighting.cpp | 93 |
1 files changed, 43 insertions, 50 deletions
diff --git a/chromium/third_party/WebKit/Source/platform/graphics/filters/FELighting.cpp b/chromium/third_party/WebKit/Source/platform/graphics/filters/FELighting.cpp index 92efec12059..8e6bc1818ac 100644 --- a/chromium/third_party/WebKit/Source/platform/graphics/filters/FELighting.cpp +++ b/chromium/third_party/WebKit/Source/platform/graphics/filters/FELighting.cpp @@ -29,7 +29,6 @@ #include "platform/graphics/filters/FELighting.h" #include "SkLightingImageFilter.h" -#include "platform/graphics/cpu/arm/filters/FELightingNEON.h" #include "platform/graphics/filters/DistantLightSource.h" #include "platform/graphics/filters/ParallelJobs.h" #include "platform/graphics/filters/SkiaImageFilterBuilder.h" @@ -45,14 +44,22 @@ FELighting::FELighting(Filter* filter, LightingType lightingType, const Color& l , m_lightSource(lightSource) , m_lightingColor(lightingColor) , m_surfaceScale(surfaceScale) - , m_diffuseConstant(diffuseConstant) - , m_specularConstant(specularConstant) - , m_specularExponent(specularExponent) + , m_diffuseConstant(std::max(diffuseConstant, 0.0f)) + , m_specularConstant(std::max(specularConstant, 0.0f)) + , m_specularExponent(std::min(std::max(specularExponent, 1.0f), 128.0f)) , m_kernelUnitLengthX(kernelUnitLengthX) , m_kernelUnitLengthY(kernelUnitLengthY) { } +FloatRect FELighting::mapPaintRect(const FloatRect& rect, bool) +{ + FloatRect result = rect; + // The areas affected need to be a pixel bigger to accommodate the Sobel kernel. + result.inflate(1); + return result; +} + const static int cPixelSize = 4; const static int cAlphaChannelOffset = 3; const static unsigned char cOpaqueAlpha = static_cast<unsigned char>(0xff); @@ -179,7 +186,7 @@ inline void FELighting::LightingData::bottomRight(int offset, IntPoint& normalVe inline void FELighting::inlineSetPixel(int offset, LightingData& data, LightSource::PaintingData& paintingData, int lightX, int lightY, float factorX, float factorY, IntPoint& normal2DVector) { - m_lightSource->updatePaintingData(paintingData, lightX, lightY, static_cast<float>(data.pixels->item(offset + cAlphaChannelOffset)) * data.surfaceScale); + data.lightSource->updatePaintingData(paintingData, lightX, lightY, static_cast<float>(data.pixels->item(offset + cAlphaChannelOffset)) * data.surfaceScale); float lightStrength; if (!normal2DVector.x() && !normal2DVector.y()) { @@ -286,12 +293,21 @@ inline void FELighting::platformApplyGeneric(LightingData& data, LightSource::Pa inline void FELighting::platformApply(LightingData& data, LightSource::PaintingData& paintingData) { - // The selection here eventually should happen dynamically on some platforms. -#if CPU(ARM_NEON) && CPU(ARM_TRADITIONAL) && COMPILER(GCC) - platformApplyNeon(data, paintingData); -#else platformApplyGeneric(data, paintingData); -#endif +} + +void FELighting::getTransform(FloatPoint3D* scale, FloatSize* offset) const +{ + FloatRect initialEffectRect = effectBoundaries(); + FloatRect absoluteEffectRect = filter()->mapLocalRectToAbsoluteRect(initialEffectRect); + FloatPoint absoluteLocation(absolutePaintRect().location()); + FloatSize positionOffset(absoluteLocation - absoluteEffectRect.location()); + offset->setWidth(positionOffset.width()); + offset->setHeight(positionOffset.height()); + scale->setX(initialEffectRect.width() > 0.0f && initialEffectRect.width() > 0.0f ? absoluteEffectRect.width() / initialEffectRect.width() : 1.0f); + scale->setY(initialEffectRect.height() > 0.0f && initialEffectRect.height() > 0.0f ? absoluteEffectRect.height() / initialEffectRect.height() : 1.0f); + // X and Y scale should be the same, but, if not, do a best effort by averaging the 2 for Z scale + scale->setZ(0.5f * (scale->x() + scale->y())); } bool FELighting::drawLighting(Uint8ClampedArray* pixels, int width, int height) @@ -312,8 +328,14 @@ bool FELighting::drawLighting(Uint8ClampedArray* pixels, int width, int height) data.widthMultipliedByPixelSize = width * cPixelSize; data.widthDecreasedByOne = width - 1; data.heightDecreasedByOne = height - 1; - paintingData.colorVector = FloatPoint3D(m_lightingColor.red(), m_lightingColor.green(), m_lightingColor.blue()); - m_lightSource->initPaintingData(paintingData); + FloatPoint3D worldScale; + FloatSize originOffset; + getTransform(&worldScale, &originOffset); + RefPtr<LightSource> lightSource = m_lightSource->create(worldScale, originOffset); + data.lightSource = lightSource.get(); + Color lightColor = adaptColorToOperatingColorSpace(m_lightingColor); + paintingData.colorVector = FloatPoint3D(lightColor.red(), lightColor.green(), lightColor.blue()); + data.lightSource->initPaintingData(paintingData); // Top/Left corner. IntPoint normalVector; @@ -413,7 +435,8 @@ void FELighting::applySoftware() PassRefPtr<SkImageFilter> FELighting::createImageFilter(SkiaImageFilterBuilder* builder) { SkImageFilter::CropRect rect = getCropRect(builder ? builder->cropOffset() : FloatSize()); - RefPtr<SkImageFilter> input(builder ? builder->build(inputEffect(0), operatingColorSpace()) : 0); + Color lightColor = adaptColorToOperatingColorSpace(m_lightingColor); + RefPtr<SkImageFilter> input(builder ? builder->build(inputEffect(0), operatingColorSpace()) : nullptr); switch (m_lightSource->type()) { case LS_DISTANT: { DistantLightSource* distantLightSource = static_cast<DistantLightSource*>(m_lightSource.get()); @@ -423,16 +446,16 @@ PassRefPtr<SkImageFilter> FELighting::createImageFilter(SkiaImageFilterBuilder* sinf(azimuthRad) * cosf(elevationRad), sinf(elevationRad)); if (m_specularConstant > 0) - return adoptRef(SkLightingImageFilter::CreateDistantLitSpecular(direction, m_lightingColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input.get(), &rect)); - return adoptRef(SkLightingImageFilter::CreateDistantLitDiffuse(direction, m_lightingColor.rgb(), m_surfaceScale, m_diffuseConstant, input.get(), &rect)); + return adoptRef(SkLightingImageFilter::CreateDistantLitSpecular(direction, lightColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input.get(), &rect)); + return adoptRef(SkLightingImageFilter::CreateDistantLitDiffuse(direction, lightColor.rgb(), m_surfaceScale, m_diffuseConstant, input.get(), &rect)); } case LS_POINT: { PointLightSource* pointLightSource = static_cast<PointLightSource*>(m_lightSource.get()); FloatPoint3D position = pointLightSource->position(); SkPoint3 skPosition(position.x(), position.y(), position.z()); if (m_specularConstant > 0) - return adoptRef(SkLightingImageFilter::CreatePointLitSpecular(skPosition, m_lightingColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input.get(), &rect)); - return adoptRef(SkLightingImageFilter::CreatePointLitDiffuse(skPosition, m_lightingColor.rgb(), m_surfaceScale, m_diffuseConstant, input.get(), &rect)); + return adoptRef(SkLightingImageFilter::CreatePointLitSpecular(skPosition, lightColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input.get(), &rect)); + return adoptRef(SkLightingImageFilter::CreatePointLitDiffuse(skPosition, lightColor.rgb(), m_surfaceScale, m_diffuseConstant, input.get(), &rect)); } case LS_SPOT: { SpotLightSource* spotLightSource = static_cast<SpotLightSource*>(m_lightSource.get()); @@ -443,43 +466,13 @@ PassRefPtr<SkImageFilter> FELighting::createImageFilter(SkiaImageFilterBuilder* if (!limitingConeAngle || limitingConeAngle > 90 || limitingConeAngle < -90) limitingConeAngle = 90; if (m_specularConstant > 0) - return adoptRef(SkLightingImageFilter::CreateSpotLitSpecular(location, target, specularExponent, limitingConeAngle, m_lightingColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input.get(), &rect)); - return adoptRef(SkLightingImageFilter::CreateSpotLitDiffuse(location, target, specularExponent, limitingConeAngle, m_lightingColor.rgb(), m_surfaceScale, m_diffuseConstant, input.get(), &rect)); + return adoptRef(SkLightingImageFilter::CreateSpotLitSpecular(location, target, specularExponent, limitingConeAngle, lightColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input.get(), &rect)); + return adoptRef(SkLightingImageFilter::CreateSpotLitDiffuse(location, target, specularExponent, limitingConeAngle, lightColor.rgb(), m_surfaceScale, m_diffuseConstant, input.get(), &rect)); } default: ASSERT_NOT_REACHED(); - return 0; + return nullptr; } } -bool FELighting::applySkia() -{ - // For now, only use the skia implementation for accelerated rendering. - if (!filter()->isAccelerated()) - return false; - - ImageBuffer* resultImage = createImageBufferResult(); - if (!resultImage) - return false; - - FilterEffect* in = inputEffect(0); - - IntRect drawingRegion = drawingRegionOfInputImage(in->absolutePaintRect()); - - setIsAlphaImage(in->isAlphaImage()); - - RefPtr<Image> image = in->asImageBuffer()->copyImage(DontCopyBackingStore); - RefPtr<NativeImageSkia> nativeImage = image->nativeImageForCurrentFrame(); - if (!nativeImage) - return false; - - GraphicsContext* dstContext = resultImage->context(); - - SkPaint paint; - RefPtr<SkImageFilter> filter = createImageFilter(0); - paint.setImageFilter(filter.get()); - dstContext->drawBitmap(nativeImage->bitmap(), drawingRegion.location().x(), drawingRegion.location().y(), &paint); - return true; -} - } // namespace WebCore |