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) Research In Motion Limited 2010. All rights reserved. 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) 27a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/filters/FEComposite.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "SkArithmeticMode.h" 30521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "SkXfermodeImageFilter.h" 31521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) 32a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/GraphicsContext.h" 33a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/cpu/arm/filters/FECompositeArithmeticNEON.h" 34a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/graphics/filters/SkiaImageFilterBuilder.h" 351e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/TextStream.h" 36591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "third_party/skia/include/core/SkDevice.h" 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "wtf/Uint8ClampedArray.h" 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)FEComposite::FEComposite(Filter* filter, const CompositeOperationType& type, float k1, float k2, float k3, float k4) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : FilterEffect(filter) 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_type(type) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_k1(k1) 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_k2(k2) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_k3(k3) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) , m_k4(k4) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)PassRefPtr<FEComposite> FEComposite::create(Filter* filter, const CompositeOperationType& type, float k1, float k2, float k3, float k4) 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return adoptRef(new FEComposite(filter, type, k1, k2, k3, k4)); 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)CompositeOperationType FEComposite::operation() const 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_type; 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FEComposite::setOperation(CompositeOperationType type) 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_type == type) 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_type = type; 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float FEComposite::k1() const 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_k1; 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FEComposite::setK1(float k1) 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_k1 == k1) 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_k1 = k1; 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float FEComposite::k2() const 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_k2; 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FEComposite::setK2(float k2) 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_k2 == k2) 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_k2 = k2; 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float FEComposite::k3() const 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_k3; 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FEComposite::setK3(float k3) 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_k3 == k3) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_k3 = k3; 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float FEComposite::k4() const 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_k4; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool FEComposite::setK4(float k4) 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_k4 == k4) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_k4 = k4; 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void FEComposite::correctFilterResultIfNeeded() 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_type != FECOMPOSITE_OPERATOR_ARITHMETIC) 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) forceValidPreMultipliedPixels(); 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <int b1, int b4> 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void computeArithmeticPixels(unsigned char* source, unsigned char* destination, int pixelArrayLength, 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float k1, float k2, float k3, float k4) 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float scaledK1; 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float scaledK4; 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (b1) 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scaledK1 = k1 / 255.0f; 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (b4) 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scaledK4 = k4 * 255.0f; 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (--pixelArrayLength >= 0) { 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char i1 = *source; 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char i2 = *destination; 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float result = k2 * i1 + k3 * i2; 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (b1) 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result += scaledK1 * i1 * i2; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (b4) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result += scaledK4; 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result <= 0) 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *destination = 0; 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (result >= 255) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *destination = 255; 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *destination = result; 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++source; 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++destination; 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// computeArithmeticPixelsUnclamped is a faster version of computeArithmeticPixels for the common case where clamping 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// is not necessary. This enables aggresive compiler optimizations such as auto-vectorization. 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template <int b1, int b4> 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void computeArithmeticPixelsUnclamped(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float scaledK1; 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float scaledK4; 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (b1) 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scaledK1 = k1 / 255.0f; 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (b4) 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scaledK4 = k4 * 255.0f; 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) while (--pixelArrayLength >= 0) { 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char i1 = *source; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned char i2 = *destination; 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float result = k2 * i1 + k3 * i2; 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (b1) 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result += scaledK1 * i1 * i2; 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (b4) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) result += scaledK4; 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *destination = result; 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++source; 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++destination; 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline void arithmeticSoftware(unsigned char* source, unsigned char* destination, int pixelArrayLength, float k1, float k2, float k3, float k4) 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float upperLimit = std::max(0.0f, k1) + std::max(0.0f, k2) + std::max(0.0f, k3) + k4; 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float lowerLimit = std::min(0.0f, k1) + std::min(0.0f, k2) + std::min(0.0f, k3) + k4; 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((k4 >= 0.0f && k4 <= 1.0f) && (upperLimit >= 0.0f && upperLimit <= 1.0f) && (lowerLimit >= 0.0f && lowerLimit <= 1.0f)) { 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (k4) { 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (k1) 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeArithmeticPixelsUnclamped<1, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4); 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeArithmeticPixelsUnclamped<0, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4); 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (k1) 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeArithmeticPixelsUnclamped<1, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeArithmeticPixelsUnclamped<0, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4); 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (k4) { 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (k1) 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeArithmeticPixels<1, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4); 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeArithmeticPixels<0, 1>(source, destination, pixelArrayLength, k1, k2, k3, k4); 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (k1) 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeArithmeticPixels<1, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4); 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) computeArithmeticPixels<0, 0>(source, destination, pixelArrayLength, k1, k2, k3, k4); 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)inline void FEComposite::platformArithmeticSoftware(Uint8ClampedArray* source, Uint8ClampedArray* destination, 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float k1, float k2, float k3, float k4) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int length = source->length(); 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(length == static_cast<int>(destination->length())); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The selection here eventually should happen dynamically. 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if HAVE(ARM_NEON_INTRINSICS) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(!(length & 0x3)); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformArithmeticNeon(source->data(), destination->data(), length, k1, k2, k3, k4); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) arithmeticSoftware(source->data(), destination->data(), length, k1, k2, k3, k4); 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 23409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)FloatRect FEComposite::determineAbsolutePaintRect(const FloatRect& originalRequestedRect) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 23609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect requestedRect = originalRequestedRect; 23709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (clipsToBounds()) 23809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) requestedRect.intersect(maxEffectRect()); 23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 24009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // We may be called multiple times if result is used more than once. Return 24109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // quickly if nothing new is required. 24209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (absolutePaintRect().contains(enclosingIntRect(requestedRect))) 24309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return requestedRect; 24409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 24509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // No mapPaintRect required for FEComposite. 24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect input1Rect = inputEffect(1)->determineAbsolutePaintRect(requestedRect); 24709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect affectedRect; 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (m_type) { 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_IN: 25009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // 'in' has output only in the intersection of both inputs. 25109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) affectedRect = intersection(input1Rect, inputEffect(0)->determineAbsolutePaintRect(input1Rect)); 25209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) break; 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_ATOP: 25409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // 'atop' has output only in the extents of the second input. 25509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Make sure first input knows where it needs to produce output. 25609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) inputEffect(0)->determineAbsolutePaintRect(input1Rect); 25709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) affectedRect = input1Rect; 25809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) break; 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_ARITHMETIC: 26009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (k4() > 0) { 26109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Make sure first input knows where it needs to produce output. 26209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) inputEffect(0)->determineAbsolutePaintRect(requestedRect); 26309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Arithmetic with non-zero k4 may influnce the complete filter primitive 26409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // region. So we can't optimize the paint region here. 26509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) affectedRect = requestedRect; 26609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) break; 26709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 26809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (k2() <= 0) { 26909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Input 0 does not appear where input 1 is not present. 27009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) FloatRect input0Rect = inputEffect(0)->determineAbsolutePaintRect(input1Rect); 27109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (k3() > 0) { 27209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) affectedRect = input1Rect; 27309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 27409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Just k1 is positive. Use intersection. 27509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) affectedRect = intersection(input1Rect, input0Rect); 27609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 27709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) break; 27809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 27909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // else fall through to use union 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Take the union of both input effects. 28209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) affectedRect = unionRect(input1Rect, inputEffect(0)->determineAbsolutePaintRect(requestedRect)); 28309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) break; 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 28509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 28609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) affectedRect.intersect(requestedRect); 28709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) addAbsolutePaintRect(affectedRect); 28809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return affectedRect; 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 29153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)void FEComposite::applySoftware() 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FilterEffect* in = inputEffect(0); 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FilterEffect* in2 = inputEffect(1); 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) { 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!dstPixelArray) 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePaintRect()); 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) RefPtr<Uint8ClampedArray> srcPixelArray = in->asPremultipliedImage(effectADrawingRect); 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePaintRect()); 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) in2->copyPremultipliedImage(dstPixelArray, effectBDrawingRect); 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) platformArithmeticSoftware(srcPixelArray.get(), dstPixelArray, m_k1, m_k2, m_k3, m_k4); 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ImageBuffer* resultImage = createImageBufferResult(); 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!resultImage) 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GraphicsContext* filterContext = resultImage->context(); 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 316926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ImageBuffer* imageBuffer = in->asImageBuffer(); 317926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ImageBuffer* imageBuffer2 = in2->asImageBuffer(); 318926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(imageBuffer); 319926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) ASSERT(imageBuffer2); 320926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (m_type) { 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_OVER: 3235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect())); 3245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect())); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_IN: { 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Applies only to the intersected region. 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IntRect destinationRect = in->absolutePaintRect(); 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationRect.intersect(in2->absolutePaintRect()); 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationRect.intersect(absolutePaintRect()); 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (destinationRect.isEmpty()) 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 333f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu FloatRect sourceRect(IntPoint(destinationRect.x() - in->absolutePaintRect().x(), 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationRect.y() - in->absolutePaintRect().y()), destinationRect.size()); 335f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu FloatRect source2Rect(IntPoint(destinationRect.x() - in2->absolutePaintRect().x(), 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) destinationRect.y() - in2->absolutePaintRect().y()), destinationRect.size()); 337197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch destinationRect.move(-absolutePaintRect().x(), -absolutePaintRect().y()); 338197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch filterContext->drawImageBuffer(imageBuffer2, destinationRect, &source2Rect); 339197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch filterContext->drawImageBuffer(imageBuffer, destinationRect, &sourceRect, CompositeSourceIn); 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_OUT: 3435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect())); 344f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect()), 0, CompositeDestinationOut); 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_ATOP: 3475267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect())); 348f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect()), 0, CompositeSourceAtop); 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_XOR: 3515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles) filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2->absolutePaintRect())); 352f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->absolutePaintRect()), 0, CompositeXOR); 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 359e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)SkXfermode::Mode toXfermode(CompositeOperationType mode) 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 36153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) switch (mode) { 362e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) case FECOMPOSITE_OPERATOR_OVER: 36353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return SkXfermode::kSrcOver_Mode; 364e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) case FECOMPOSITE_OPERATOR_IN: 36553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return SkXfermode::kSrcIn_Mode; 366e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) case FECOMPOSITE_OPERATOR_OUT: 36753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return SkXfermode::kSrcOut_Mode; 368e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) case FECOMPOSITE_OPERATOR_ATOP: 36953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return SkXfermode::kSrcATop_Mode; 370e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles) case FECOMPOSITE_OPERATOR_XOR: 37153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return SkXfermode::kXor_Mode; 37253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) default: 37353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) ASSERT_NOT_REACHED(); 37453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) return SkXfermode::kSrcOver_Mode; 37553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) } 37653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)} 37753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3783c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben MurdochPassRefPtr<SkImageFilter> FEComposite::createImageFilter(SkiaImageFilterBuilder* builder) 37953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles){ 380a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch return createImageFilterInternal(builder, true); 381a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch} 382a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch 383a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben MurdochPassRefPtr<SkImageFilter> FEComposite::createImageFilterWithoutValidation(SkiaImageFilterBuilder* builder) 384a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{ 385a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch return createImageFilterInternal(builder, false); 386a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch} 387a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch 388a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben MurdochPassRefPtr<SkImageFilter> FEComposite::createImageFilterInternal(SkiaImageFilterBuilder* builder, bool requiresPMColorValidation) 389a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch{ 390a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch RefPtr<SkImageFilter> foreground(builder->build(inputEffect(0), operatingColorSpace(), !mayProduceInvalidPreMultipliedPixels())); 391a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch RefPtr<SkImageFilter> background(builder->build(inputEffect(1), operatingColorSpace(), !mayProduceInvalidPreMultipliedPixels())); 3921e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles) SkImageFilter::CropRect cropRect = getCropRect(builder->cropOffset()); 39309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RefPtr<SkXfermode> mode; 39409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) 395a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch mode = adoptRef(SkArithmeticMode::Create(SkFloatToScalar(m_k1), SkFloatToScalar(m_k2), SkFloatToScalar(m_k3), SkFloatToScalar(m_k4), requiresPMColorValidation)); 39609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) else 39709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) mode = adoptRef(SkXfermode::Create(toXfermode(m_type))); 39810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch return adoptRef(SkXfermodeImageFilter::Create(mode.get(), background.get(), foreground.get(), &cropRect)); 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static TextStream& operator<<(TextStream& ts, const CompositeOperationType& type) 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (type) { 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_UNKNOWN: 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "UNKNOWN"; 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_OVER: 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "OVER"; 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_IN: 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "IN"; 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_OUT: 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "OUT"; 4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_ATOP: 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "ATOP"; 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_XOR: 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "XOR"; 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case FECOMPOSITE_OPERATOR_ARITHMETIC: 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "ARITHMETIC"; 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ts; 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)TextStream& FEComposite::externalRepresentation(TextStream& ts, int indent) const 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) writeIndent(ts, indent); 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "[feComposite"; 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) FilterEffect::externalRepresentation(ts); 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << " operation=\"" << m_type << "\""; 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_type == FECOMPOSITE_OPERATOR_ARITHMETIC) 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << " k1=\"" << m_k1 << "\" k2=\"" << m_k2 << "\" k3=\"" << m_k3 << "\" k4=\"" << m_k4 << "\""; 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ts << "]\n"; 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) inputEffect(0)->externalRepresentation(ts, indent + 1); 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) inputEffect(1)->externalRepresentation(ts, indent + 1); 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ts; 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 443c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 444