| 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 |