OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2008 The Android Open Source Project | 2 * Copyright 2008 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 "SkAtomics.h" | 8 #include "SkAtomics.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 return (fPixelRef) ? fPixelRef->getGenerationID() : 0; | 417 return (fPixelRef) ? fPixelRef->getGenerationID() : 0; |
418 } | 418 } |
419 | 419 |
420 void SkBitmap::notifyPixelsChanged() const { | 420 void SkBitmap::notifyPixelsChanged() const { |
421 SkASSERT(!this->isImmutable()); | 421 SkASSERT(!this->isImmutable()); |
422 if (fPixelRef) { | 422 if (fPixelRef) { |
423 fPixelRef->notifyPixelsChanged(); | 423 fPixelRef->notifyPixelsChanged(); |
424 } | 424 } |
425 } | 425 } |
426 | 426 |
427 GrTexture* SkBitmap::getTexture() const { | |
428 return fPixelRef ? fPixelRef->getTexture() : nullptr; | |
429 } | |
430 | |
431 /////////////////////////////////////////////////////////////////////////////// | 427 /////////////////////////////////////////////////////////////////////////////// |
432 | 428 |
433 /** We explicitly use the same allocator for our pixels that SkMask does, | 429 /** We explicitly use the same allocator for our pixels that SkMask does, |
434 so that we can freely assign memory allocated by one class to the other. | 430 so that we can freely assign memory allocated by one class to the other. |
435 */ | 431 */ |
436 bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst, | 432 bool SkBitmap::HeapAllocator::allocPixelRef(SkBitmap* dst, |
437 SkColorTable* ctable) { | 433 SkColorTable* ctable) { |
438 const SkImageInfo info = dst->info(); | 434 const SkImageInfo info = dst->info(); |
439 if (kUnknown_SkColorType == info.colorType()) { | 435 if (kUnknown_SkColorType == info.colorType()) { |
440 // SkDebugf("unsupported config for info %d\n", dst->config()); | 436 // SkDebugf("unsupported config for info %d\n", dst->config()); |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
733 if (nullptr == result || nullptr == fPixelRef) { | 729 if (nullptr == result || nullptr == fPixelRef) { |
734 return false; // no src pixels | 730 return false; // no src pixels |
735 } | 731 } |
736 | 732 |
737 SkIRect srcRect, r; | 733 SkIRect srcRect, r; |
738 srcRect.set(0, 0, this->width(), this->height()); | 734 srcRect.set(0, 0, this->width(), this->height()); |
739 if (!r.intersect(srcRect, subset)) { | 735 if (!r.intersect(srcRect, subset)) { |
740 return false; // r is empty (i.e. no intersection) | 736 return false; // r is empty (i.e. no intersection) |
741 } | 737 } |
742 | 738 |
743 if (fPixelRef->getTexture() != nullptr) { | |
744 // Do a deep copy | |
745 SkPixelRef* pixelRef = fPixelRef->deepCopy(this->colorType(), this->colo
rSpace(), &subset); | |
746 if (pixelRef != nullptr) { | |
747 SkBitmap dst; | |
748 dst.setInfo(this->info().makeWH(subset.width(), subset.height())); | |
749 dst.setIsVolatile(this->isVolatile()); | |
750 dst.setPixelRef(pixelRef)->unref(); | |
751 SkDEBUGCODE(dst.validate()); | |
752 result->swap(dst); | |
753 return true; | |
754 } | |
755 } | |
756 | |
757 // If the upper left of the rectangle was outside the bounds of this SkBitma
p, we should have | 739 // If the upper left of the rectangle was outside the bounds of this SkBitma
p, we should have |
758 // exited above. | 740 // exited above. |
759 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width(
))); | 741 SkASSERT(static_cast<unsigned>(r.fLeft) < static_cast<unsigned>(this->width(
))); |
760 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height(
))); | 742 SkASSERT(static_cast<unsigned>(r.fTop) < static_cast<unsigned>(this->height(
))); |
761 | 743 |
762 SkBitmap dst; | 744 SkBitmap dst; |
763 dst.setInfo(this->info().makeWH(r.width(), r.height()), this->rowBytes()); | 745 dst.setInfo(this->info().makeWH(r.width(), r.height()), this->rowBytes()); |
764 dst.setIsVolatile(this->isVolatile()); | 746 dst.setIsVolatile(this->isVolatile()); |
765 | 747 |
766 if (fPixelRef) { | 748 if (fPixelRef) { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
902 SkPixelRef* dstPixelRef = tmpDst.pixelRef(); | 884 SkPixelRef* dstPixelRef = tmpDst.pixelRef(); |
903 if (dstPixelRef->info() == fPixelRef->info()) { | 885 if (dstPixelRef->info() == fPixelRef->info()) { |
904 dstPixelRef->cloneGenID(*fPixelRef); | 886 dstPixelRef->cloneGenID(*fPixelRef); |
905 } | 887 } |
906 } | 888 } |
907 | 889 |
908 dst->swap(tmpDst); | 890 dst->swap(tmpDst); |
909 return true; | 891 return true; |
910 } | 892 } |
911 | 893 |
| 894 // TODO: can we merge this with copyTo? |
912 bool SkBitmap::deepCopyTo(SkBitmap* dst) const { | 895 bool SkBitmap::deepCopyTo(SkBitmap* dst) const { |
913 const SkColorType dstCT = this->colorType(); | 896 const SkColorType dstCT = this->colorType(); |
914 SkColorSpace* dstCS = this->colorSpace(); | |
915 | 897 |
916 if (!this->canCopyTo(dstCT)) { | 898 if (!this->canCopyTo(dstCT)) { |
917 return false; | 899 return false; |
918 } | 900 } |
919 | 901 return this->copyTo(dst, dstCT, nullptr); |
920 // If we have a PixelRef, and it supports deep copy, use it. | |
921 // Currently supported only by texture-backed bitmaps. | |
922 if (fPixelRef) { | |
923 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstCT, dstCS, nullptr); | |
924 if (pixelRef) { | |
925 uint32_t rowBytes; | |
926 if (this->colorType() == dstCT && this->colorSpace() == dstCS) { | |
927 // Since there is no subset to pass to deepCopy, and deepCopy | |
928 // succeeded, the new pixel ref must be identical. | |
929 SkASSERT(fPixelRef->info() == pixelRef->info()); | |
930 pixelRef->cloneGenID(*fPixelRef); | |
931 // Use the same rowBytes as the original. | |
932 rowBytes = fRowBytes; | |
933 } else { | |
934 // With the new config, an appropriate fRowBytes will be compute
d by setInfo. | |
935 rowBytes = 0; | |
936 } | |
937 | |
938 const SkImageInfo info = fInfo.makeColorType(dstCT); | |
939 if (!dst->setInfo(info, rowBytes)) { | |
940 return false; | |
941 } | |
942 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); | |
943 return true; | |
944 } | |
945 } | |
946 | |
947 if (this->getTexture()) { | |
948 return false; | |
949 } else { | |
950 return this->copyTo(dst, dstCT, nullptr); | |
951 } | |
952 } | 902 } |
953 | 903 |
954 /////////////////////////////////////////////////////////////////////////////// | 904 /////////////////////////////////////////////////////////////////////////////// |
955 | 905 |
956 static void rect_memset(uint8_t* array, U8CPU value, SkISize size, size_t rowByt
es) { | 906 static void rect_memset(uint8_t* array, U8CPU value, SkISize size, size_t rowByt
es) { |
957 for (int y = 0; y < size.height(); ++y) { | 907 for (int y = 0; y < size.height(); ++y) { |
958 memset(array, value, size.width()); | 908 memset(array, value, size.width()); |
959 array += rowBytes; | 909 array += rowBytes; |
960 } | 910 } |
961 } | 911 } |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 /////////////////////////////////////////////////////////////////////////////// | 1299 /////////////////////////////////////////////////////////////////////////////// |
1350 | 1300 |
1351 #ifdef SK_DEBUG | 1301 #ifdef SK_DEBUG |
1352 void SkImageInfo::validate() const { | 1302 void SkImageInfo::validate() const { |
1353 SkASSERT(fWidth >= 0); | 1303 SkASSERT(fWidth >= 0); |
1354 SkASSERT(fHeight >= 0); | 1304 SkASSERT(fHeight >= 0); |
1355 SkASSERT(SkColorTypeIsValid(fColorType)); | 1305 SkASSERT(SkColorTypeIsValid(fColorType)); |
1356 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); | 1306 SkASSERT(SkAlphaTypeIsValid(fAlphaType)); |
1357 } | 1307 } |
1358 #endif | 1308 #endif |
OLD | NEW |