15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) 753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/cpu/arm/filters/FEBlendNEON.h" 2853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/filters/FEBlend.h" 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/GraphicsContext.h" 3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/filters/Filter.h" 3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/text/TextStream.h" 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderTreeAsText.h" 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/Uint8ClampedArray.h" 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "SkBitmapSource.h" 38e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#include "SkXfermodeImageFilter.h" 3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/filters/SkiaImageFilterBuilder.h" 4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/skia/NativeImageSkia.h" 4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef unsigned char (*BlendType)(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB); 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FEBlend::FEBlend(Filter* filter, BlendModeType mode) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : FilterEffect(filter) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_mode(mode) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<FEBlend> FEBlend::create(Filter* filter, BlendModeType mode) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new FEBlend(filter, mode)); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)BlendModeType FEBlend::blendMode() const 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_mode; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FEBlend::setBlendMode(BlendModeType mode) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_mode == mode) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_mode = mode; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline unsigned char fastDivideBy255(uint16_t value) 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This is an approximate algorithm for division by 255, but it gives accurate results for 16bit values. 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t quotient = value >> 8; 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint16_t remainder = value - (quotient * 255) + 1; 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return quotient + (remainder >> 8); 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline unsigned char feBlendNormal(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char) 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fastDivideBy255((255 - alphaA) * colorB + colorA * 255); 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline unsigned char feBlendMultiply(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB) 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fastDivideBy255((255 - alphaA) * colorB + (255 - alphaB + colorB) * colorA); 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline unsigned char feBlendScreen(unsigned char colorA, unsigned char colorB, unsigned char, unsigned char) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fastDivideBy255((colorB + colorA) * 255 - colorA * colorB); 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline unsigned char feBlendDarken(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB) 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fastDivideBy255(std::min((255 - alphaA) * colorB + colorA * 255, (255 - alphaB) * colorA + colorB * 255)); 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline unsigned char feBlendLighten(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB) 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fastDivideBy255(std::max((255 - alphaA) * colorB + colorA * 255, (255 - alphaB) * colorA + colorB * 255)); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline unsigned char feBlendUnknown(unsigned char, unsigned char, unsigned char, unsigned char) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<BlendType BlendFunction> 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static void platformApply(unsigned char* sourcePixelA, unsigned char* sourcePixelB, 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char* destinationPixel, unsigned pixelArrayLength) 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned len = pixelArrayLength / 4; 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (unsigned pixelOffset = 0; pixelOffset < len; pixelOffset++) { 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char alphaA = sourcePixelA[3]; 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char alphaB = sourcePixelB[3]; 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationPixel[0] = BlendFunction(sourcePixelA[0], sourcePixelB[0], alphaA, alphaB); 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationPixel[1] = BlendFunction(sourcePixelA[1], sourcePixelB[1], alphaA, alphaB); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationPixel[2] = BlendFunction(sourcePixelA[2], sourcePixelB[2], alphaA, alphaB); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationPixel[3] = 255 - fastDivideBy255((255 - alphaA) * (255 - alphaB)); 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sourcePixelA += 4; 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sourcePixelB += 4; 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationPixel += 4; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FEBlend::platformApplyGeneric(unsigned char* sourcePixelA, unsigned char* sourcePixelB, 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char* destinationPixel, unsigned pixelArrayLength) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (m_mode) { 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_NORMAL: 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformApply<feBlendNormal>(sourcePixelA, sourcePixelB, destinationPixel, pixelArrayLength); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_MULTIPLY: 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformApply<feBlendMultiply>(sourcePixelA, sourcePixelB, destinationPixel, pixelArrayLength); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_SCREEN: 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformApply<feBlendScreen>(sourcePixelA, sourcePixelB, destinationPixel, pixelArrayLength); 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_DARKEN: 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformApply<feBlendDarken>(sourcePixelA, sourcePixelB, destinationPixel, pixelArrayLength); 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_LIGHTEN: 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformApply<feBlendLighten>(sourcePixelA, sourcePixelB, destinationPixel, pixelArrayLength); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_UNKNOWN: 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformApply<feBlendUnknown>(sourcePixelA, sourcePixelB, destinationPixel, pixelArrayLength); 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 15153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void FEBlend::applySoftware() 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FilterEffect* in = inputEffect(0); 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FilterEffect* in2 = inputEffect(1); 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_mode > FEBLEND_MODE_UNKNOWN); 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(m_mode <= FEBLEND_MODE_LIGHTEN); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!dstPixelArray) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<Uint8ClampedArray> srcPixelArrayA = in->asPremultipliedImage(effectADrawingRect); 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<Uint8ClampedArray> srcPixelArrayB = in2->asPremultipliedImage(effectBDrawingRect); 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned pixelArrayLength = srcPixelArrayA->length(); 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(pixelArrayLength == srcPixelArrayB->length()); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if HAVE(ARM_NEON_INTRINSICS) 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pixelArrayLength >= 8) 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformApplyNEON(srcPixelArrayA->data(), srcPixelArrayB->data(), dstPixelArray->data(), pixelArrayLength); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else { // If there is just one pixel we expand it to two. 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(pixelArrayLength > 0); 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t sourceA[2] = {0, 0}; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) uint32_t sourceBAndDest[2] = {0, 0}; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sourceA[0] = reinterpret_cast<uint32_t*>(srcPixelArrayA->data())[0]; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) sourceBAndDest[0] = reinterpret_cast<uint32_t*>(srcPixelArrayB->data())[0]; 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformApplyNEON(reinterpret_cast<uint8_t*>(sourceA), reinterpret_cast<uint8_t*>(sourceBAndDest), reinterpret_cast<uint8_t*>(sourceBAndDest), 8); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) reinterpret_cast<uint32_t*>(dstPixelArray->data())[0] = sourceBAndDest[0]; 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformApplyGeneric(srcPixelArrayA->data(), srcPixelArrayB->data(), dstPixelArray->data(), pixelArrayLength); 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 190e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochstatic SkXfermode::Mode toSkiaMode(BlendModeType mode) 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 19253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) switch (mode) { 19353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case FEBLEND_MODE_NORMAL: 194e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return SkXfermode::kSrcOver_Mode; 19553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case FEBLEND_MODE_MULTIPLY: 196e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return SkXfermode::kMultiply_Mode; 19753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case FEBLEND_MODE_SCREEN: 198e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return SkXfermode::kScreen_Mode; 19953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case FEBLEND_MODE_DARKEN: 200e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return SkXfermode::kDarken_Mode; 20153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) case FEBLEND_MODE_LIGHTEN: 202e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return SkXfermode::kLighten_Mode; 20353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) default: 204e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return SkXfermode::kSrcOver_Mode; 20553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 20653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 20753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 20853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool FEBlend::applySkia() 20953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 21053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) // For now, only use the skia implementation for accelerated rendering. 21153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (filter()->renderingMode() != Accelerated) 21253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return false; 21353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 21453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FilterEffect* in = inputEffect(0); 21553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) FilterEffect* in2 = inputEffect(1); 21653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 21753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!in || !in2) 21853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return false; 21953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 22053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ImageBuffer* resultImage = createImageBufferResult(); 22153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!resultImage) 22253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return false; 22353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 22453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RefPtr<Image> foreground = in->asImageBuffer()->copyImage(DontCopyBackingStore); 22553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RefPtr<Image> background = in2->asImageBuffer()->copyImage(DontCopyBackingStore); 22653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 22753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RefPtr<NativeImageSkia> foregroundNativeImage = foreground->nativeImageForCurrentFrame(); 22853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) RefPtr<NativeImageSkia> backgroundNativeImage = background->nativeImageForCurrentFrame(); 22953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 23053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) if (!foregroundNativeImage || !backgroundNativeImage) 23153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return false; 23253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 23353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkBitmap foregroundBitmap = foregroundNativeImage->bitmap(); 23453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkBitmap backgroundBitmap = backgroundNativeImage->bitmap(); 23553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 23653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkAutoTUnref<SkImageFilter> backgroundSource(new SkBitmapSource(backgroundBitmap)); 237e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(toSkiaMode(m_mode))); 238e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch SkAutoTUnref<SkImageFilter> blend(new SkXfermodeImageFilter(mode, backgroundSource)); 23953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) SkPaint paint; 24053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) paint.setImageFilter(blend); 24153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) resultImage->context()->drawBitmap(foregroundBitmap, 0, 0, &paint); 24253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return true; 24353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 24453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 245e6d4491e48613634a83c1957c72759da80987961Ben MurdochPassRefPtr<SkImageFilter> FEBlend::createImageFilter(SkiaImageFilterBuilder* builder) 24653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 247e6d4491e48613634a83c1957c72759da80987961Ben Murdoch RefPtr<SkImageFilter> foreground(builder->build(inputEffect(0), operatingColorSpace())); 248e6d4491e48613634a83c1957c72759da80987961Ben Murdoch RefPtr<SkImageFilter> background(builder->build(inputEffect(1), operatingColorSpace())); 249e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(toSkiaMode(m_mode))); 250e6d4491e48613634a83c1957c72759da80987961Ben Murdoch return adoptRef(new SkXfermodeImageFilter(mode, background.get(), foreground.get())); 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static TextStream& operator<<(TextStream& ts, const BlendModeType& type) 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (type) { 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_UNKNOWN: 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "UNKNOWN"; 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_NORMAL: 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "NORMAL"; 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_MULTIPLY: 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "MULTIPLY"; 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_SCREEN: 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "SCREEN"; 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_DARKEN: 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "DARKEN"; 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FEBLEND_MODE_LIGHTEN: 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "LIGHTEN"; 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ts; 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TextStream& FEBlend::externalRepresentation(TextStream& ts, int indent) const 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writeIndent(ts, indent); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "[feBlend"; 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FilterEffect::externalRepresentation(ts); 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << " mode=\"" << m_mode << "\"]\n"; 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) inputEffect(0)->externalRepresentation(ts, indent + 1); 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) inputEffect(1)->externalRepresentation(ts, indent + 1); 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ts; 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore 290