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 the result is an exact copy, clone the gen ID. | 996 if (dst->pixelRef() && this->config() == dstConfig) { |
997 if (dst->pixelRef() && dst->pixelRef()->info() == fPixelRef->inf
o()) { | 997 // TODO(scroggo): fix issue 1742 |
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 | |
1017 SkBitmap tmpDst; | 1014 SkBitmap tmpDst; |
1018 tmpDst.setConfig(dstConfig, src->width(), src->height(), 0, | 1015 tmpDst.setConfig(dstConfig, src->width(), src->height(), 0, |
1019 src->alphaType()); | 1016 src->alphaType()); |
1020 | 1017 |
1021 // allocate colortable if srcConfig == kIndex8_Config | 1018 // allocate colortable if srcConfig == kIndex8_Config |
1022 SkColorTable* ctable = (dstConfig == kIndex8_Config) ? | 1019 SkColorTable* ctable = (dstConfig == kIndex8_Config) ? |
1023 new SkColorTable(*src->getColorTable()) : NULL; | 1020 new SkColorTable(*src->getColorTable()) : NULL; |
1024 SkAutoUnref au(ctable); | 1021 SkAutoUnref au(ctable); |
1025 if (!tmpDst.allocPixels(alloc, ctable)) { | 1022 if (!tmpDst.allocPixels(alloc, ctable)) { |
1026 return false; | 1023 return false; |
1027 } | 1024 } |
1028 | 1025 |
1029 if (!tmpDst.readyToDraw()) { | 1026 if (!tmpDst.readyToDraw()) { |
1030 // allocator/lock failed | 1027 // allocator/lock failed |
1031 return false; | 1028 return false; |
1032 } | 1029 } |
1033 | 1030 |
1034 // pixelRef must be non NULL or tmpDst.readyToDraw() would have | |
1035 // returned false. | |
1036 SkASSERT(tmpDst.pixelRef() != NULL); | |
1037 | |
1038 /* do memcpy for the same configs cases, else use drawing | 1031 /* do memcpy for the same configs cases, else use drawing |
1039 */ | 1032 */ |
1040 if (src->config() == dstConfig) { | 1033 if (src->config() == dstConfig) { |
1041 if (tmpDst.getSize() == src->getSize()) { | 1034 if (tmpDst.getSize() == src->getSize()) { |
1042 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); | 1035 memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize()); |
1043 SkPixelRef* pixelRef = tmpDst.pixelRef(); | 1036 SkPixelRef* pixelRef = tmpDst.pixelRef(); |
1044 | 1037 if (NULL != pixelRef && NULL != fPixelRef) { |
1045 // In order to reach this point, we know that the width, config and | 1038 // TODO(scroggo): fix issue 1742 |
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 SkASSERT(pixelRef->info() == fPixelRef->info()); | |
1053 pixelRef->cloneGenID(*fPixelRef); | 1039 pixelRef->cloneGenID(*fPixelRef); |
1054 } | 1040 } |
1055 } else { | 1041 } else { |
1056 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); | 1042 const char* srcP = reinterpret_cast<const char*>(src->getPixels()); |
1057 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); | 1043 char* dstP = reinterpret_cast<char*>(tmpDst.getPixels()); |
1058 // to be sure we don't read too much, only copy our logical pixels | 1044 // to be sure we don't read too much, only copy our logical pixels |
1059 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel(); | 1045 size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel(); |
1060 for (int y = 0; y < tmpDst.height(); y++) { | 1046 for (int y = 0; y < tmpDst.height(); y++) { |
1061 memcpy(dstP, srcP, bytesToCopy); | 1047 memcpy(dstP, srcP, bytesToCopy); |
1062 srcP += src->rowBytes(); | 1048 srcP += src->rowBytes(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 return false; | 1083 return false; |
1098 } | 1084 } |
1099 | 1085 |
1100 // If we have a PixelRef, and it supports deep copy, use it. | 1086 // If we have a PixelRef, and it supports deep copy, use it. |
1101 // Currently supported only by texture-backed bitmaps. | 1087 // Currently supported only by texture-backed bitmaps. |
1102 if (fPixelRef) { | 1088 if (fPixelRef) { |
1103 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); | 1089 SkPixelRef* pixelRef = fPixelRef->deepCopy(dstConfig); |
1104 if (pixelRef) { | 1090 if (pixelRef) { |
1105 uint32_t rowBytes; | 1091 uint32_t rowBytes; |
1106 if (dstConfig == fConfig) { | 1092 if (dstConfig == fConfig) { |
1107 // Since there is no subset to pass to deepCopy, and deepCopy | 1093 // TODO(scroggo): fix issue 1742 |
1108 // succeeded, the new pixel ref must be identical. | |
1109 SkASSERT(fPixelRef->info() == pixelRef->info()); | |
1110 pixelRef->cloneGenID(*fPixelRef); | 1094 pixelRef->cloneGenID(*fPixelRef); |
1111 // Use the same rowBytes as the original. | 1095 // Use the same rowBytes as the original. |
1112 rowBytes = fRowBytes; | 1096 rowBytes = fRowBytes; |
1113 } else { | 1097 } else { |
1114 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. | 1098 // With the new config, an appropriate fRowBytes will be compute
d by setConfig. |
1115 rowBytes = 0; | 1099 rowBytes = 0; |
1116 } | 1100 } |
1117 dst->setConfig(dstConfig, fWidth, fHeight, rowBytes); | 1101 dst->setConfig(dstConfig, fWidth, fHeight, rowBytes); |
1118 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); | 1102 dst->setPixelRef(pixelRef, fPixelRefOrigin)->unref(); |
1119 return true; | 1103 return true; |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1652 if (NULL != uri) { | 1636 if (NULL != uri) { |
1653 str->appendf(" uri:\"%s\"", uri); | 1637 str->appendf(" uri:\"%s\"", uri); |
1654 } else { | 1638 } else { |
1655 str->appendf(" pixelref:%p", pr); | 1639 str->appendf(" pixelref:%p", pr); |
1656 } | 1640 } |
1657 } | 1641 } |
1658 | 1642 |
1659 str->append(")"); | 1643 str->append(")"); |
1660 } | 1644 } |
1661 #endif | 1645 #endif |
OLD | NEW |