OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 The Android Open Source Project |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 | 9 |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
(...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
986 if (fPixelRef) { | 986 if (fPixelRef) { |
987 SkIRect subset; | 987 SkIRect subset; |
988 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, fWidth, fHeight); | 988 subset.setXYWH(fPixelRefOrigin.fX, fPixelRefOrigin.fY, fWidth, fHeight); |
989 if (fPixelRef->readPixels(&tmpSrc, &subset)) { | 989 if (fPixelRef->readPixels(&tmpSrc, &subset)) { |
990 SkASSERT(tmpSrc.width() == this->width()); | 990 SkASSERT(tmpSrc.width() == this->width()); |
991 SkASSERT(tmpSrc.height() == this->height()); | 991 SkASSERT(tmpSrc.height() == this->height()); |
992 | 992 |
993 // did we get lucky and we can just return tmpSrc? | 993 // did we get lucky and we can just return tmpSrc? |
994 if (tmpSrc.config() == dstConfig && NULL == alloc) { | 994 if (tmpSrc.config() == dstConfig && NULL == alloc) { |
995 dst->swap(tmpSrc); | 995 dst->swap(tmpSrc); |
996 if (dst->pixelRef() && this->config() == dstConfig) { | 996 // If the result is an exact copy, clone the gen ID. |
997 // TODO(scroggo): fix issue 1742 | 997 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf
o()) { |
998 dst->pixelRef()->cloneGenID(*fPixelRef); | 998 dst->pixelRef()->cloneGenID(*fPixelRef); |
999 } | 999 } |
1000 return true; | 1000 return true; |
1001 } | 1001 } |
1002 | 1002 |
1003 // fall through to the raster case | 1003 // fall through to the raster case |
1004 src = &tmpSrc; | 1004 src = &tmpSrc; |
1005 } | 1005 } |
1006 } | 1006 } |
1007 | 1007 |
1008 // we lock this now, since we may need its colortable | 1008 // we lock this now, since we may need its colortable |
1009 SkAutoLockPixels srclock(*src); | 1009 SkAutoLockPixels srclock(*src); |
1010 if (!src->readyToDraw()) { | 1010 if (!src->readyToDraw()) { |
1011 return false; | 1011 return false; |
1012 } | 1012 } |
1013 | 1013 |
| 1014 // The only way to be readyToDraw is if fPixelRef is non NULL. |
| 1015 SkASSERT(fPixelRef != NULL); |
| 1016 |
1014 SkBitmap tmpDst; | 1017 SkBitmap tmpDst; |
1015 tmpDst.setConfig(dstConfig, src->width(), src->height(), 0, | 1018 tmpDst.setConfig(dstConfig, src->width(), src->height(), 0, |
1016 src->alphaType()); | 1019 src->alphaType()); |
1017 | 1020 |
1018 // allocate colortable if srcConfig == kIndex8_Config | 1021 // allocate colortable if srcConfig == kIndex8_Config |
1019 SkColorTable* ctable = (dstConfig == kIndex8_Config) ? | 1022 SkColorTable* ctable = (dstConfig == kIndex8_Config) ? |
1020 new SkColorTable(*src->getColorTable()) : NULL; | 1023 new SkColorTable(*src->getColorTable()) : NULL; |
1021 SkAutoUnref au(ctable); | 1024 SkAutoUnref au(ctable); |
1022 if (!tmpDst.allocPixels(alloc, ctable)) { | 1025 if (!tmpDst.allocPixels(alloc, ctable)) { |
1023 return false; | 1026 return false; |
1024 } | 1027 } |
1025 | 1028 |
1026 if (!tmpDst.readyToDraw()) { | 1029 if (!tmpDst.readyToDraw()) { |
1027 // allocator/lock failed | 1030 // allocator/lock failed |
1028 return false; | 1031 return false; |
1029 } | 1032 } |
1030 | 1033 |
| 1034 // pixelRef must be non NULL or tmpDst.readyToDraw() would have |
| 1035 // returned false. |
| 1036 SkASSERT(tmpDst.pixelRef() != NULL); |
| 1037 |
1031 /* do memcpy for the same configs cases, else use drawing | 1038 /* do memcpy for the same configs cases, else use drawing |
1032 */ | 1039 */ |
1033 if (src->config() == dstConfig) { | 1040 if (src->config() == dstConfig) { |
1034 if (tmpDst.getSize() == src->getSize()) { | 1041 if (tmpDst.getSize() == src->getSize()) { |
1035 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); | 1042 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); |
1036 SkPixelRef* pixelRef = tmpDst.pixelRef(); | 1043 SkPixelRef* pixelRef = tmpDst.pixelRef(); |
1037 if (NULL != pixelRef && NULL != fPixelRef) { | 1044 |
1038 // TODO(scroggo): fix issue 1742 | 1045 // In order to reach this point, we know that the width, config and |
| 1046 // rowbytes of the SkPixelRefs are the same, but it is possible for |
| 1047 // the heights to differ, if this SkBitmap's height is a subset of |
| 1048 // fPixelRef. Only if the SkPixelRefs' heights match are we |
| 1049 // guaranteed that this is an exact copy, meaning we should clone |
| 1050 // the genID. |
| 1051 if (pixelRef->info().fHeight == fPixelRef->info().fHeight) { |
| 1052 // TODO: what to do if the two infos match, BUT |
| 1053 // fPixelRef is premul and pixelRef is opaque? |
| 1054 // skipping assert for now |
| 1055 // https://code.google.com/p/skia/issues/detail?id=2012 |
| 1056 // SkASSERT(pixelRef->info() == fPixelRef->info()); |
| 1057 SkASSERT(pixelRef->info().fWidth == fPixelRef->info().fWidth); |
| 1058 SkASSERT(pixelRef->info().fColorType == fPixelRef->info().fColor
Type); |
1039 pixelRef->cloneGenID(*fPixelRef); | 1059 pixelRef->cloneGenID(*fPixelRef); |
1040 } | 1060 } |
1041 } else { | 1061 } else { |
1042 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); | 1062 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); |
1043 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); | 1063 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); |
1044 // to be sure we don't read too much, only copy our logical pixels | 1064 // to be sure we don't read too much, only copy our logical pixels |
1045 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel(); | 1065 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel(); |
1046 for (int y = 0; y < tmpDst.height(); y++) { | 1066 for (int y = 0; y < tmpDst.height(); y++) { |
1047 memcpy(dstP, srcP, bytesToCopy); | 1067 memcpy(dstP, srcP, bytesToCopy); |
1048 srcP += src->rowBytes(); | 1068 srcP += src->rowBytes(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 return false; | 1103 return false; |
1084 } | 1104 } |
1085 | 1105 |
1086 // If we have a PixelRef, and it supports deep copy, use it. | 1106 // If we have a PixelRef, and it supports deep copy, use it. |
1087 // Currently supported only by texture-backed bitmaps. | 1107 // Currently supported only by texture-backed bitmaps. |
1088 if (fPixelRef) { | 1108 if (fPixelRef) { |
1089 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); | 1109 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); |
1090 if (pixelRef) { | 1110 if (pixelRef) { |
1091 uint32_t rowBytes; | 1111 uint32_t rowBytes; |
1092 if (dstConfig == fConfig) { | 1112 if (dstConfig == fConfig) { |
1093 // TODO(scroggo): fix issue 1742 | 1113 // Since there is no subset to pass to deepCopy, and deepCopy |
| 1114 // succeeded, the new pixel ref must be identical. |
| 1115 SkASSERT(fPixelRef->info() == pixelRef->info()); |
1094 pixelRef->cloneGenID(*fPixelRef); | 1116 pixelRef->cloneGenID(*fPixelRef); |
1095 // Use the same rowBytes as the original. | 1117 // Use the same rowBytes as the original. |
1096 rowBytes = fRowBytes; | 1118 rowBytes = fRowBytes; |
1097 } else { | 1119 } else { |
1098 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. | 1120 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. |
1099 rowBytes = 0; | 1121 rowBytes = 0; |
1100 } | 1122 } |
1101 dst->setConfig(dstConfig, fWidth, fHeight, rowBytes); | 1123 dst->setConfig(dstConfig, fWidth, fHeight, rowBytes); |
1102 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); | 1124 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); |
1103 return true; | 1125 return true; |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1636 if (NULL != uri) { | 1658 if (NULL != uri) { |
1637 str->appendf(" uri:\"%s\"", uri); | 1659 str->appendf(" uri:\"%s\"", uri); |
1638 } else { | 1660 } else { |
1639 str->appendf(" pixelref:%p", pr); | 1661 str->appendf(" pixelref:%p", pr); |
1640 } | 1662 } |
1641 } | 1663 } |
1642 | 1664 |
1643 str->append(")"); | 1665 str->append(")"); |
1644 } | 1666 } |
1645 #endif | 1667 #endif |
OLD | NEW |