Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: Source/platform/graphics/filters/FEBlend.cpp

Issue 416093002: Use GraphicContext::drawImageBuffer in FEBlend (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Rebase; Merge rebaselines. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/platform/graphics/ImageBuffer.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2 * Copyright (C) 2004, 2005, 2006, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org> 3 * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org> 4 * Copyright (C) 2005 Eric Seidel <eric@webkit.org>
5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org> 5 * Copyright (C) 2009 Dirk Schulze <krit@webkit.org>
6 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies) 6 * Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
7 * Copyright (C) 2013 Google Inc. All rights reserved. 7 * Copyright (C) 2013 Google Inc. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 13 matching lines...) Expand all
24 24
25 #include "config.h" 25 #include "config.h"
26 #include "platform/graphics/filters/FEBlend.h" 26 #include "platform/graphics/filters/FEBlend.h"
27 27
28 #include "SkBitmapSource.h" 28 #include "SkBitmapSource.h"
29 #include "SkXfermodeImageFilter.h" 29 #include "SkXfermodeImageFilter.h"
30 #include "platform/graphics/GraphicsContext.h" 30 #include "platform/graphics/GraphicsContext.h"
31 #include "platform/graphics/cpu/arm/filters/FEBlendNEON.h" 31 #include "platform/graphics/cpu/arm/filters/FEBlendNEON.h"
32 #include "platform/graphics/filters/SkiaImageFilterBuilder.h" 32 #include "platform/graphics/filters/SkiaImageFilterBuilder.h"
33 #include "platform/graphics/skia/NativeImageSkia.h" 33 #include "platform/graphics/skia/NativeImageSkia.h"
34 #include "platform/graphics/skia/SkiaUtils.h"
34 #include "platform/text/TextStream.h" 35 #include "platform/text/TextStream.h"
35 #include "wtf/Uint8ClampedArray.h" 36 #include "wtf/Uint8ClampedArray.h"
36 37
37 typedef unsigned char (*BlendType)(unsigned char colorA, unsigned char colorB, u nsigned char alphaA, unsigned char alphaB); 38 typedef unsigned char (*BlendType)(unsigned char colorA, unsigned char colorB, u nsigned char alphaA, unsigned char alphaB);
38 39
39 namespace blink { 40 namespace blink {
40 41
41 FEBlend::FEBlend(Filter* filter, BlendModeType mode) 42 FEBlend::FEBlend(Filter* filter, BlendModeType mode)
42 : FilterEffect(filter) 43 : FilterEffect(filter)
43 , m_mode(mode) 44 , m_mode(mode)
(...skipping 11 matching lines...) Expand all
55 } 56 }
56 57
57 bool FEBlend::setBlendMode(BlendModeType mode) 58 bool FEBlend::setBlendMode(BlendModeType mode)
58 { 59 {
59 if (m_mode == mode) 60 if (m_mode == mode)
60 return false; 61 return false;
61 m_mode = mode; 62 m_mode = mode;
62 return true; 63 return true;
63 } 64 }
64 65
65 static inline unsigned char fastDivideBy255(uint16_t value) 66 static WebBlendMode toWebBlendMode(BlendModeType mode)
66 { 67 {
67 // This is an approximate algorithm for division by 255, but it gives accura te results for 16bit values. 68 switch (mode) {
68 uint16_t quotient = value >> 8; 69 case FEBLEND_MODE_NORMAL:
69 uint16_t remainder = value - (quotient * 255) + 1; 70 return WebBlendModeNormal;
70 return quotient + (remainder >> 8); 71 case FEBLEND_MODE_MULTIPLY:
71 } 72 return WebBlendModeMultiply;
72 73 case FEBLEND_MODE_SCREEN:
73 inline unsigned char feBlendNormal(unsigned char colorA, unsigned char colorB, u nsigned char alphaA, unsigned char) 74 return WebBlendModeScreen;
74 { 75 case FEBLEND_MODE_DARKEN:
75 return fastDivideBy255((255 - alphaA) * colorB + colorA * 255); 76 return WebBlendModeDarken;
76 } 77 case FEBLEND_MODE_LIGHTEN:
77 78 return WebBlendModeLighten;
78 inline unsigned char feBlendMultiply(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB) 79 default:
79 { 80 ASSERT_NOT_REACHED();
80 return fastDivideBy255((255 - alphaA) * colorB + (255 - alphaB + colorB) * c olorA); 81 return WebBlendModeNormal;
81 }
82
83 inline unsigned char feBlendScreen(unsigned char colorA, unsigned char colorB, u nsigned char, unsigned char)
84 {
85 return fastDivideBy255((colorB + colorA) * 255 - colorA * colorB);
86 }
87
88 inline unsigned char feBlendDarken(unsigned char colorA, unsigned char colorB, u nsigned char alphaA, unsigned char alphaB)
89 {
90 return fastDivideBy255(std::min((255 - alphaA) * colorB + colorA * 255, (255 - alphaB) * colorA + colorB * 255));
91 }
92
93 inline unsigned char feBlendLighten(unsigned char colorA, unsigned char colorB, unsigned char alphaA, unsigned char alphaB)
94 {
95 return fastDivideBy255(std::max((255 - alphaA) * colorB + colorA * 255, (255 - alphaB) * colorA + colorB * 255));
96 }
97
98 inline unsigned char feBlendUnknown(unsigned char, unsigned char, unsigned char, unsigned char)
99 {
100 return 0;
101 }
102
103 template<BlendType BlendFunction>
104 static void platformApply(unsigned char* sourcePixelA, unsigned char* sourcePixe lB,
105 unsigned char* destinationPixel, unsigned pixelArrayLe ngth)
106 {
107 unsigned len = pixelArrayLength / 4;
108 for (unsigned pixelOffset = 0; pixelOffset < len; pixelOffset++) {
109 unsigned char alphaA = sourcePixelA[3];
110 unsigned char alphaB = sourcePixelB[3];
111 destinationPixel[0] = BlendFunction(sourcePixelA[0], sourcePixelB[0], al phaA, alphaB);
112 destinationPixel[1] = BlendFunction(sourcePixelA[1], sourcePixelB[1], al phaA, alphaB);
113 destinationPixel[2] = BlendFunction(sourcePixelA[2], sourcePixelB[2], al phaA, alphaB);
114 destinationPixel[3] = 255 - fastDivideBy255((255 - alphaA) * (255 - alph aB));
115 sourcePixelA += 4;
116 sourcePixelB += 4;
117 destinationPixel += 4;
118 } 82 }
119 } 83 }
120 84
121 void FEBlend::platformApplyGeneric(unsigned char* sourcePixelA, unsigned char* s ourcePixelB,
122 unsigned char* destinationPixel, unsigned pix elArrayLength)
123 {
124 switch (m_mode) {
125 case FEBLEND_MODE_NORMAL:
126 platformApply<feBlendNormal>(sourcePixelA, sourcePixelB, destinationPixe l, pixelArrayLength);
127 break;
128 case FEBLEND_MODE_MULTIPLY:
129 platformApply<feBlendMultiply>(sourcePixelA, sourcePixelB, destinationPi xel, pixelArrayLength);
130 break;
131 case FEBLEND_MODE_SCREEN:
132 platformApply<feBlendScreen>(sourcePixelA, sourcePixelB, destinationPixe l, pixelArrayLength);
133 break;
134 case FEBLEND_MODE_DARKEN:
135 platformApply<feBlendDarken>(sourcePixelA, sourcePixelB, destinationPixe l, pixelArrayLength);
136 break;
137 case FEBLEND_MODE_LIGHTEN:
138 platformApply<feBlendLighten>(sourcePixelA, sourcePixelB, destinationPix el, pixelArrayLength);
139 break;
140 case FEBLEND_MODE_UNKNOWN:
141 platformApply<feBlendUnknown>(sourcePixelA, sourcePixelB, destinationPix el, pixelArrayLength);
142 break;
143 }
144 }
145
146 void FEBlend::applySoftware() 85 void FEBlend::applySoftware()
147 { 86 {
148 FilterEffect* in = inputEffect(0); 87 FilterEffect* in = inputEffect(0);
149 FilterEffect* in2 = inputEffect(1); 88 FilterEffect* in2 = inputEffect(1);
150 89
151 ASSERT(m_mode > FEBLEND_MODE_UNKNOWN); 90 ASSERT(m_mode > FEBLEND_MODE_UNKNOWN && m_mode <= FEBLEND_MODE_LIGHTEN);
152 ASSERT(m_mode <= FEBLEND_MODE_LIGHTEN);
153 91
92 #if HAVE(ARM_NEON_INTRINSICS)
154 Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult(); 93 Uint8ClampedArray* dstPixelArray = createPremultipliedImageResult();
155 if (!dstPixelArray) 94 if (!dstPixelArray)
156 return; 95 return;
157 96
158 IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePai ntRect()); 97 IntRect effectADrawingRect = requestedRegionOfInputImageData(in->absolutePai ntRect());
159 RefPtr<Uint8ClampedArray> srcPixelArrayA = in->asPremultipliedImage(effectAD rawingRect); 98 RefPtr<Uint8ClampedArray> srcPixelArrayA = in->asPremultipliedImage(effectAD rawingRect);
160 99
161 IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePa intRect()); 100 IntRect effectBDrawingRect = requestedRegionOfInputImageData(in2->absolutePa intRect());
162 RefPtr<Uint8ClampedArray> srcPixelArrayB = in2->asPremultipliedImage(effectB DrawingRect); 101 RefPtr<Uint8ClampedArray> srcPixelArrayB = in2->asPremultipliedImage(effectB DrawingRect);
163 102
164 unsigned pixelArrayLength = srcPixelArrayA->length(); 103 unsigned pixelArrayLength = srcPixelArrayA->length();
165 ASSERT(pixelArrayLength == srcPixelArrayB->length()); 104 ASSERT(pixelArrayLength == srcPixelArrayB->length());
166 105
167 #if HAVE(ARM_NEON_INTRINSICS)
168 if (pixelArrayLength >= 8) { 106 if (pixelArrayLength >= 8) {
169 platformApplyNEON(srcPixelArrayA->data(), srcPixelArrayB->data(), dstPix elArray->data(), pixelArrayLength); 107 platformApplyNEON(srcPixelArrayA->data(), srcPixelArrayB->data(), dstPix elArray->data(), pixelArrayLength);
170 } 108 } else {
171 else { // If there is just one pixel we expand it to two. 109 // If there is just one pixel we expand it to two.
172 ASSERT(pixelArrayLength > 0); 110 ASSERT(pixelArrayLength > 0);
173 uint32_t sourceA[2] = {0, 0}; 111 uint32_t sourceA[2] = {0, 0};
174 uint32_t sourceBAndDest[2] = {0, 0}; 112 uint32_t sourceBAndDest[2] = {0, 0};
175 113
176 sourceA[0] = reinterpret_cast<uint32_t*>(srcPixelArrayA->data())[0]; 114 sourceA[0] = reinterpret_cast<uint32_t*>(srcPixelArrayA->data())[0];
177 sourceBAndDest[0] = reinterpret_cast<uint32_t*>(srcPixelArrayB->data())[ 0]; 115 sourceBAndDest[0] = reinterpret_cast<uint32_t*>(srcPixelArrayB->data())[ 0];
178 platformApplyNEON(reinterpret_cast<uint8_t*>(sourceA), reinterpret_cast< uint8_t*>(sourceBAndDest), reinterpret_cast<uint8_t*>(sourceBAndDest), 8); 116 platformApplyNEON(reinterpret_cast<uint8_t*>(sourceA), reinterpret_cast< uint8_t*>(sourceBAndDest), reinterpret_cast<uint8_t*>(sourceBAndDest), 8);
179 reinterpret_cast<uint32_t*>(dstPixelArray->data())[0] = sourceBAndDest[0 ]; 117 reinterpret_cast<uint32_t*>(dstPixelArray->data())[0] = sourceBAndDest[0 ];
180 } 118 }
181 #else 119 #else
182 platformApplyGeneric(srcPixelArrayA->data(), srcPixelArrayB->data(), dstPixe lArray->data(), pixelArrayLength); 120 ImageBuffer* resultImage = createImageBufferResult();
121 if (!resultImage)
122 return;
123 GraphicsContext* filterContext = resultImage->context();
124
125 ImageBuffer* imageBuffer = in->asImageBuffer();
126 ImageBuffer* imageBuffer2 = in2->asImageBuffer();
127 ASSERT(imageBuffer);
128 ASSERT(imageBuffer2);
129
130 WebBlendMode blendMode = toWebBlendMode(m_mode);
131 filterContext->drawImageBuffer(imageBuffer2, drawingRegionOfInputImage(in2-> absolutePaintRect()));
132 filterContext->drawImageBuffer(imageBuffer, drawingRegionOfInputImage(in->ab solutePaintRect()), 0, CompositeSourceOver, blendMode);
183 #endif 133 #endif
184 } 134 }
185 135
186 static SkXfermode::Mode toSkiaMode(BlendModeType mode)
187 {
188 switch (mode) {
189 case FEBLEND_MODE_NORMAL:
190 return SkXfermode::kSrcOver_Mode;
191 case FEBLEND_MODE_MULTIPLY:
192 return SkXfermode::kMultiply_Mode;
193 case FEBLEND_MODE_SCREEN:
194 return SkXfermode::kScreen_Mode;
195 case FEBLEND_MODE_DARKEN:
196 return SkXfermode::kDarken_Mode;
197 case FEBLEND_MODE_LIGHTEN:
198 return SkXfermode::kLighten_Mode;
199 default:
200 return SkXfermode::kSrcOver_Mode;
201 }
202 }
203
204 PassRefPtr<SkImageFilter> FEBlend::createImageFilter(SkiaImageFilterBuilder* bui lder) 136 PassRefPtr<SkImageFilter> FEBlend::createImageFilter(SkiaImageFilterBuilder* bui lder)
205 { 137 {
206 RefPtr<SkImageFilter> foreground(builder->build(inputEffect(0), operatingCol orSpace())); 138 RefPtr<SkImageFilter> foreground(builder->build(inputEffect(0), operatingCol orSpace()));
207 RefPtr<SkImageFilter> background(builder->build(inputEffect(1), operatingCol orSpace())); 139 RefPtr<SkImageFilter> background(builder->build(inputEffect(1), operatingCol orSpace()));
208 SkAutoTUnref<SkXfermode> mode(SkXfermode::Create(toSkiaMode(m_mode))); 140 RefPtr<SkXfermode> mode(WebCoreCompositeToSkiaComposite(CompositeSourceOver, toWebBlendMode(m_mode)));
209 SkImageFilter::CropRect cropRect = getCropRect(builder->cropOffset()); 141 SkImageFilter::CropRect cropRect = getCropRect(builder->cropOffset());
210 return adoptRef(SkXfermodeImageFilter::Create(mode, background.get(), foregr ound.get(), &cropRect)); 142 return adoptRef(SkXfermodeImageFilter::Create(mode.get(), background.get(), foreground.get(), &cropRect));
211 } 143 }
212 144
213 static TextStream& operator<<(TextStream& ts, const BlendModeType& type) 145 static TextStream& operator<<(TextStream& ts, const BlendModeType& type)
214 { 146 {
215 switch (type) { 147 switch (type) {
216 case FEBLEND_MODE_UNKNOWN: 148 case FEBLEND_MODE_UNKNOWN:
217 ts << "unknown"; 149 ts << "unknown";
218 break; 150 break;
219 case FEBLEND_MODE_NORMAL: 151 case FEBLEND_MODE_NORMAL:
220 ts << "normal"; 152 ts << "normal";
(...skipping 19 matching lines...) Expand all
240 writeIndent(ts, indent); 172 writeIndent(ts, indent);
241 ts << "[feBlend"; 173 ts << "[feBlend";
242 FilterEffect::externalRepresentation(ts); 174 FilterEffect::externalRepresentation(ts);
243 ts << " mode=\"" << m_mode << "\"]\n"; 175 ts << " mode=\"" << m_mode << "\"]\n";
244 inputEffect(0)->externalRepresentation(ts, indent + 1); 176 inputEffect(0)->externalRepresentation(ts, indent + 1);
245 inputEffect(1)->externalRepresentation(ts, indent + 1); 177 inputEffect(1)->externalRepresentation(ts, indent + 1);
246 return ts; 178 return ts;
247 } 179 }
248 180
249 } // namespace blink 181 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/graphics/ImageBuffer.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698