aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBitmap.cpp75
-rw-r--r--src/core/SkPixelRef.cpp8
-rw-r--r--src/gpu/SkGrTexturePixelRef.cpp3
3 files changed, 59 insertions, 27 deletions
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index a5f7d57ad5..a9b9c99d9e 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -865,61 +865,82 @@ bool SkBitmap::copyTo(SkBitmap* dst, Config dstConfig, Allocator* alloc) const {
return false;
}
+ // if we have a texture, first get those pixels
+ SkBitmap tmpSrc;
+ const SkBitmap* src = this;
+
+ if (this->getTexture()) {
+ if (!fPixelRef->readPixels(&tmpSrc)) {
+ return false;
+ }
+ SkASSERT(tmpSrc.width() == this->width());
+ SkASSERT(tmpSrc.height() == this->height());
+
+ // did we get lucky and we can just return tmpSrc?
+ if (tmpSrc.config() == dstConfig && NULL == alloc) {
+ dst->swap(tmpSrc);
+ return true;
+ }
+
+ // fall through to the raster case
+ src = &tmpSrc;
+ }
+
// we lock this now, since we may need its colortable
- SkAutoLockPixels srclock(*this);
- if (!this->readyToDraw()) {
+ SkAutoLockPixels srclock(*src);
+ if (!src->readyToDraw()) {
return false;
}
-
- SkBitmap tmp;
- tmp.setConfig(dstConfig, this->width(), this->height());
-
+
+ SkBitmap tmpDst;
+ tmpDst.setConfig(dstConfig, src->width(), src->height());
+
// allocate colortable if srcConfig == kIndex8_Config
SkColorTable* ctable = (dstConfig == kIndex8_Config) ?
- new SkColorTable(*this->getColorTable()) : NULL;
+ new SkColorTable(*src->getColorTable()) : NULL;
SkAutoUnref au(ctable);
- if (!tmp.allocPixels(alloc, ctable)) {
+ if (!tmpDst.allocPixels(alloc, ctable)) {
return false;
}
-
- SkAutoLockPixels dstlock(tmp);
- if (!tmp.readyToDraw()) {
+
+ SkAutoLockPixels dstlock(tmpDst);
+ if (!tmpDst.readyToDraw()) {
// allocator/lock failed
return false;
}
-
+
/* do memcpy for the same configs cases, else use drawing
*/
- if (this->config() == dstConfig) {
- if (tmp.getSize() == this->getSize()) {
- memcpy(tmp.getPixels(), this->getPixels(), this->getSafeSize());
+ if (src->config() == dstConfig) {
+ if (tmpDst.getSize() == src->getSize()) {
+ memcpy(tmpDst.getPixels(), src->getPixels(), src->getSafeSize());
} else {
- const char* srcP = reinterpret_cast<const char*>(this->getPixels());
- char* dstP = reinterpret_cast<char*>(tmp.getPixels());
+ const char* srcP = reinterpret_cast<const char*>(src->getPixels());
+ char* dstP = reinterpret_cast<char*>(tmpDst.getPixels());
// to be sure we don't read too much, only copy our logical pixels
- size_t bytesToCopy = tmp.width() * tmp.bytesPerPixel();
- for (int y = 0; y < tmp.height(); y++) {
+ size_t bytesToCopy = tmpDst.width() * tmpDst.bytesPerPixel();
+ for (int y = 0; y < tmpDst.height(); y++) {
memcpy(dstP, srcP, bytesToCopy);
- srcP += this->rowBytes();
- dstP += tmp.rowBytes();
+ srcP += src->rowBytes();
+ dstP += tmpDst.rowBytes();
}
}
} else {
// if the src has alpha, we have to clear the dst first
- if (!this->isOpaque()) {
- tmp.eraseColor(0);
+ if (!src->isOpaque()) {
+ tmpDst.eraseColor(0);
}
- SkCanvas canvas(tmp);
+ SkCanvas canvas(tmpDst);
SkPaint paint;
paint.setDither(true);
- canvas.drawBitmap(*this, 0, 0, &paint);
+ canvas.drawBitmap(*src, 0, 0, &paint);
}
- tmp.setIsOpaque(this->isOpaque());
+ tmpDst.setIsOpaque(src->isOpaque());
- dst->swap(tmp);
+ dst->swap(tmpDst);
return true;
}
diff --git a/src/core/SkPixelRef.cpp b/src/core/SkPixelRef.cpp
index f558f52c2d..9b12226af2 100644
--- a/src/core/SkPixelRef.cpp
+++ b/src/core/SkPixelRef.cpp
@@ -79,6 +79,14 @@ void SkPixelRef::setImmutable() {
fIsImmutable = true;
}
+bool SkPixelRef::readPixels(SkBitmap* dst, const SkIRect* subset) {
+ return this->onReadPixels(dst, subset);
+}
+
+bool SkPixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
+ return false;
+}
+
///////////////////////////////////////////////////////////////////////////////
#define MAX_PAIR_COUNT 16
diff --git a/src/gpu/SkGrTexturePixelRef.cpp b/src/gpu/SkGrTexturePixelRef.cpp
index da9ac1a692..de19f1da32 100644
--- a/src/gpu/SkGrTexturePixelRef.cpp
+++ b/src/gpu/SkGrTexturePixelRef.cpp
@@ -27,4 +27,7 @@ SkGrTexturePixelRef::~SkGrTexturePixelRef() {
GrSafeUnref(fTexture);
}
+bool SkGrTexturePixelRef::onReadPixels(SkBitmap* dst, const SkIRect* subset) {
+ return false;
+}