OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkImageFilter.h" | 8 #include "SkImageFilter.h" |
9 #include "SkImageFilterCacheKey.h" | 9 #include "SkImageFilterCacheKey.h" |
10 | 10 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 do { | 116 do { |
117 id = sk_atomic_inc(&gImageFilterUniqueID) + 1; | 117 id = sk_atomic_inc(&gImageFilterUniqueID) + 1; |
118 } while (0 == id); | 118 } while (0 == id); |
119 return id; | 119 return id; |
120 } | 120 } |
121 | 121 |
122 void SkImageFilter::Common::allocInputs(int count) { | 122 void SkImageFilter::Common::allocInputs(int count) { |
123 fInputs.reset(count); | 123 fInputs.reset(count); |
124 } | 124 } |
125 | 125 |
126 void SkImageFilter::Common::detachInputs(SkImageFilter** inputs) { | |
127 for (int i = 0; i < fInputs.count(); ++i) { | |
128 inputs[i] = fInputs[i].release(); | |
129 } | |
130 } | |
131 | |
132 bool SkImageFilter::Common::unflatten(SkReadBuffer& buffer, int expectedCount) { | 126 bool SkImageFilter::Common::unflatten(SkReadBuffer& buffer, int expectedCount) { |
133 const int count = buffer.readInt(); | 127 const int count = buffer.readInt(); |
134 if (!buffer.validate(count >= 0)) { | 128 if (!buffer.validate(count >= 0)) { |
135 return false; | 129 return false; |
136 } | 130 } |
137 if (!buffer.validate(expectedCount < 0 || count == expectedCount)) { | 131 if (!buffer.validate(expectedCount < 0 || count == expectedCount)) { |
138 return false; | 132 return false; |
139 } | 133 } |
140 | 134 |
141 SkFUZZF(("allocInputs: %d\n", count)); | 135 SkFUZZF(("allocInputs: %d\n", count)); |
(...skipping 16 matching lines...) Expand all Loading... |
158 fCropRect = CropRect(rect, flags); | 152 fCropRect = CropRect(rect, flags); |
159 if (buffer.isVersionLT(SkReadBuffer::kImageFilterNoUniqueID_Version)) { | 153 if (buffer.isVersionLT(SkReadBuffer::kImageFilterNoUniqueID_Version)) { |
160 | 154 |
161 (void) buffer.readUInt(); | 155 (void) buffer.readUInt(); |
162 } | 156 } |
163 return buffer.isValid(); | 157 return buffer.isValid(); |
164 } | 158 } |
165 | 159 |
166 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 160 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
167 | 161 |
| 162 void SkImageFilter::init(sk_sp<SkImageFilter>* inputs, |
| 163 int inputCount, |
| 164 const CropRect* cropRect) { |
| 165 fCropRect = cropRect ? *cropRect : CropRect(SkRect(), 0x0); |
| 166 |
| 167 fInputs.reset(inputCount); |
| 168 |
| 169 for (int i = 0; i < inputCount; ++i) { |
| 170 if (!inputs[i] || inputs[i]->usesSrcInput()) { |
| 171 fUsesSrcInput = true; |
| 172 } |
| 173 fInputs[i] = inputs[i]; |
| 174 } |
| 175 } |
| 176 |
168 SkImageFilter::SkImageFilter(sk_sp<SkImageFilter>* inputs, | 177 SkImageFilter::SkImageFilter(sk_sp<SkImageFilter>* inputs, |
169 int inputCount, | 178 int inputCount, |
170 const CropRect* cropRect) | 179 const CropRect* cropRect) |
171 : fInputCount(inputCount), | 180 : fUsesSrcInput(false) |
172 fInputs(new SkImageFilter*[inputCount]), | 181 , fUniqueID(next_image_filter_unique_id()) { |
173 fUsesSrcInput(false), | 182 this->init(inputs, inputCount, cropRect); |
174 fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)), | |
175 fUniqueID(next_image_filter_unique_id()) { | |
176 for (int i = 0; i < inputCount; ++i) { | |
177 if (nullptr == inputs[i] || inputs[i]->usesSrcInput()) { | |
178 fUsesSrcInput = true; | |
179 } | |
180 fInputs[i] = SkSafeRef(inputs[i].get()); | |
181 } | |
182 } | |
183 | |
184 SkImageFilter::SkImageFilter(int inputCount, SkImageFilter** inputs, const CropR
ect* cropRect) | |
185 : fInputCount(inputCount), | |
186 fInputs(new SkImageFilter*[inputCount]), | |
187 fUsesSrcInput(false), | |
188 fCropRect(cropRect ? *cropRect : CropRect(SkRect(), 0x0)), | |
189 fUniqueID(next_image_filter_unique_id()) { | |
190 for (int i = 0; i < inputCount; ++i) { | |
191 if (nullptr == inputs[i] || inputs[i]->usesSrcInput()) { | |
192 fUsesSrcInput = true; | |
193 } | |
194 fInputs[i] = SkSafeRef(inputs[i]); | |
195 } | |
196 } | 183 } |
197 | 184 |
198 SkImageFilter::~SkImageFilter() { | 185 SkImageFilter::~SkImageFilter() { |
199 for (int i = 0; i < fInputCount; i++) { | |
200 SkSafeUnref(fInputs[i]); | |
201 } | |
202 delete[] fInputs; | |
203 Cache::Get()->purgeByKeys(fCacheKeys.begin(), fCacheKeys.count()); | 186 Cache::Get()->purgeByKeys(fCacheKeys.begin(), fCacheKeys.count()); |
204 } | 187 } |
205 | 188 |
206 SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer) | 189 SkImageFilter::SkImageFilter(int inputCount, SkReadBuffer& buffer) |
207 : fUsesSrcInput(false) | 190 : fUsesSrcInput(false) |
208 , fUniqueID(next_image_filter_unique_id()) { | 191 , fCropRect(SkRect(), 0x0) |
| 192 , fUniqueID(next_image_filter_unique_id()) { |
209 Common common; | 193 Common common; |
210 if (common.unflatten(buffer, inputCount)) { | 194 if (common.unflatten(buffer, inputCount)) { |
211 fCropRect = common.cropRect(); | 195 this->init(common.inputs(), common.inputCount(), &common.cropRect()); |
212 fInputCount = common.inputCount(); | |
213 fInputs = new SkImageFilter* [fInputCount]; | |
214 common.detachInputs(fInputs); | |
215 for (int i = 0; i < fInputCount; ++i) { | |
216 if (nullptr == fInputs[i] || fInputs[i]->usesSrcInput()) { | |
217 fUsesSrcInput = true; | |
218 } | |
219 } | |
220 } else { | |
221 fInputCount = 0; | |
222 fInputs = nullptr; | |
223 } | 196 } |
224 } | 197 } |
225 | 198 |
226 void SkImageFilter::flatten(SkWriteBuffer& buffer) const { | 199 void SkImageFilter::flatten(SkWriteBuffer& buffer) const { |
227 buffer.writeInt(fInputCount); | 200 buffer.writeInt(fInputs.count()); |
228 for (int i = 0; i < fInputCount; i++) { | 201 for (int i = 0; i < fInputs.count(); i++) { |
229 SkImageFilter* input = this->getInput(i); | 202 SkImageFilter* input = this->getInput(i); |
230 buffer.writeBool(input != nullptr); | 203 buffer.writeBool(input != nullptr); |
231 if (input != nullptr) { | 204 if (input != nullptr) { |
232 buffer.writeFlattenable(input); | 205 buffer.writeFlattenable(input); |
233 } | 206 } |
234 } | 207 } |
235 buffer.writeRect(fCropRect.rect()); | 208 buffer.writeRect(fCropRect.rect()); |
236 buffer.writeUInt(fCropRect.flags()); | 209 buffer.writeUInt(fCropRect.flags()); |
237 } | 210 } |
238 | 211 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 } else { | 304 } else { |
332 SkIRect bounds = this->onFilterBounds(src, ctm, direction); | 305 SkIRect bounds = this->onFilterBounds(src, ctm, direction); |
333 bounds = this->onFilterNodeBounds(bounds, ctm, direction); | 306 bounds = this->onFilterNodeBounds(bounds, ctm, direction); |
334 SkIRect dst; | 307 SkIRect dst; |
335 this->getCropRect().applyTo(bounds, ctm, this->affectsTransparentBlack()
, &dst); | 308 this->getCropRect().applyTo(bounds, ctm, this->affectsTransparentBlack()
, &dst); |
336 return dst; | 309 return dst; |
337 } | 310 } |
338 } | 311 } |
339 | 312 |
340 SkRect SkImageFilter::computeFastBounds(const SkRect& src) const { | 313 SkRect SkImageFilter::computeFastBounds(const SkRect& src) const { |
341 if (0 == fInputCount) { | 314 if (0 == this->countInputs()) { |
342 return src; | 315 return src; |
343 } | 316 } |
344 SkRect combinedBounds = this->getInput(0) ? this->getInput(0)->computeFastBo
unds(src) : src; | 317 SkRect combinedBounds = this->getInput(0) ? this->getInput(0)->computeFastBo
unds(src) : src; |
345 for (int i = 1; i < fInputCount; i++) { | 318 for (int i = 1; i < this->countInputs(); i++) { |
346 SkImageFilter* input = this->getInput(i); | 319 SkImageFilter* input = this->getInput(i); |
347 if (input) { | 320 if (input) { |
348 combinedBounds.join(input->computeFastBounds(src)); | 321 combinedBounds.join(input->computeFastBounds(src)); |
349 } else { | 322 } else { |
350 combinedBounds.join(src); | 323 combinedBounds.join(src); |
351 } | 324 } |
352 } | 325 } |
353 return combinedBounds; | 326 return combinedBounds; |
354 } | 327 } |
355 | 328 |
356 bool SkImageFilter::canComputeFastBounds() const { | 329 bool SkImageFilter::canComputeFastBounds() const { |
357 if (this->affectsTransparentBlack()) { | 330 if (this->affectsTransparentBlack()) { |
358 return false; | 331 return false; |
359 } | 332 } |
360 for (int i = 0; i < fInputCount; i++) { | 333 for (int i = 0; i < this->countInputs(); i++) { |
361 SkImageFilter* input = this->getInput(i); | 334 SkImageFilter* input = this->getInput(i); |
362 if (input && !input->canComputeFastBounds()) { | 335 if (input && !input->canComputeFastBounds()) { |
363 return false; | 336 return false; |
364 } | 337 } |
365 } | 338 } |
366 return true; | 339 return true; |
367 } | 340 } |
368 | 341 |
369 bool SkImageFilter::onFilterImageDeprecated(Proxy*, const SkBitmap&, const Conte
xt&, | 342 bool SkImageFilter::onFilterImageDeprecated(Proxy*, const SkBitmap&, const Conte
xt&, |
370 SkBitmap*, SkIPoint*) const { | 343 SkBitmap*, SkIPoint*) const { |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 bounds->width(), bounds->height(), | 498 bounds->width(), bounds->height(), |
526 srcOffset->x() - bounds->x(), | 499 srcOffset->x() - bounds->x(), |
527 srcOffset->y() - bounds->y())); | 500 srcOffset->y() - bounds->y())); |
528 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); | 501 *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); |
529 return img; | 502 return img; |
530 } | 503 } |
531 } | 504 } |
532 | 505 |
533 SkIRect SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, | 506 SkIRect SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, |
534 MapDirection direction) const { | 507 MapDirection direction) const { |
535 if (fInputCount < 1) { | 508 if (this->countInputs() < 1) { |
536 return src; | 509 return src; |
537 } | 510 } |
538 | 511 |
539 SkIRect totalBounds; | 512 SkIRect totalBounds; |
540 for (int i = 0; i < fInputCount; ++i) { | 513 for (int i = 0; i < this->countInputs(); ++i) { |
541 SkImageFilter* filter = this->getInput(i); | 514 SkImageFilter* filter = this->getInput(i); |
542 SkIRect rect = filter ? filter->filterBounds(src, ctm, direction) : src; | 515 SkIRect rect = filter ? filter->filterBounds(src, ctm, direction) : src; |
543 if (0 == i) { | 516 if (0 == i) { |
544 totalBounds = rect; | 517 totalBounds = rect; |
545 } else { | 518 } else { |
546 totalBounds.join(rect); | 519 totalBounds.join(rect); |
547 } | 520 } |
548 } | 521 } |
549 | 522 |
550 return totalBounds; | 523 return totalBounds; |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 dev = SkBitmapDevice::Create(cinfo.fInfo, surfaceProps); | 776 dev = SkBitmapDevice::Create(cinfo.fInfo, surfaceProps); |
804 } | 777 } |
805 return dev; | 778 return dev; |
806 } | 779 } |
807 | 780 |
808 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, | 781 bool SkImageFilter::DeviceProxy::filterImage(const SkImageFilter* filter, const
SkBitmap& src, |
809 const SkImageFilter::Context& ctx, | 782 const SkImageFilter::Context& ctx, |
810 SkBitmap* result, SkIPoint* offset) { | 783 SkBitmap* result, SkIPoint* offset) { |
811 return fDevice->filterImage(filter, src, ctx, result, offset); | 784 return fDevice->filterImage(filter, src, ctx, result, offset); |
812 } | 785 } |
OLD | NEW |