Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(141)

Unified Diff: src/core/SkCanvas.cpp

Issue 199413013: add new readPixels with direct memory parameters (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/core/SkCanvas.cpp
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 17e03c2373232bc2721c26f5bee1f246a3acbd1c..ef6a82d9bfc0747878f815c6db10d6683f32c719 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -667,6 +667,7 @@ SkBaseDevice* SkCanvas::setRootDevice(SkBaseDevice* device) {
return device;
}
+#ifdef SK_SUPPORT_LEGACY_READPIXELSCONFIG
bool SkCanvas::readPixels(SkBitmap* bitmap,
int x, int y,
Config8888 config8888) {
@@ -676,28 +677,95 @@ bool SkCanvas::readPixels(SkBitmap* bitmap,
}
return device->readPixels(bitmap, x, y, config8888);
}
+#endif
+
+bool SkCanvas::readPixels(SkBitmap* bitmap, int x, int y) {
+ if (kUnknown_SkColorType == bitmap->colorType() || bitmap->getTexture()) {
+ return false;
+ }
+
+ bool weAllocated = false;
+ if (NULL == bitmap->pixelRef()) {
+ if (!bitmap->allocPixels()) {
+ return false;
+ }
+ weAllocated = true;
+ }
+
+ SkBitmap bm(*bitmap);
+ bm.lockPixels();
+ if (bm.getPixels() && this->readPixels(bm.info(), bm.getPixels(), bm.rowBytes(), x, y)) {
+ return true;
+ }
+
+ if (weAllocated) {
+ bitmap->setPixelRef(NULL);
+ }
+ return false;
+}
bool SkCanvas::readPixels(const SkIRect& srcRect, SkBitmap* bitmap) {
- SkBaseDevice* device = this->getDevice();
- if (!device) {
+ SkIRect r = srcRect;
+ const SkISize size = this->getBaseLayerSize();
+ if (!r.intersect(0, 0, size.width(), size.height())) {
+ bitmap->reset();
return false;
}
- SkIRect bounds;
- bounds.set(0, 0, device->width(), device->height());
- if (!bounds.intersect(srcRect)) {
+ if (!bitmap->allocN32Pixels(r.width(), r.height())) {
+ // bitmap will already be reset.
+ return false;
+ }
+ if (!this->readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(), r.x(), r.y())) {
+ bitmap->reset();
return false;
}
+ return true;
+}
- SkBitmap tmp;
- tmp.setConfig(SkBitmap::kARGB_8888_Config, bounds.width(),
- bounds.height());
- if (this->readPixels(&tmp, bounds.fLeft, bounds.fTop)) {
- bitmap->swap(tmp);
- return true;
- } else {
+bool SkCanvas::readPixels(const SkImageInfo& origInfo, void* dstP, size_t rowBytes, int x, int y) {
+ switch (origInfo.colorType()) {
+ case kUnknown_SkColorType:
+ case kIndex_8_SkColorType:
+ return false;
+ default:
+ break;
+ }
+ if (NULL == dstP || rowBytes < origInfo.minRowBytes()) {
+ return false;
+ }
+ if (0 == origInfo.width() || 0 == origInfo.height()) {
+ return false;
+ }
+
+ SkBaseDevice* device = this->getDevice();
+ if (!device) {
+ return false;
+ }
+
+ const SkISize size = this->getBaseLayerSize();
+ SkIRect srcR = SkIRect::MakeXYWH(x, y, origInfo.width(), origInfo.height());
+ if (!srcR.intersect(0, 0, size.width(), size.height())) {
return false;
}
+
+ SkImageInfo info = origInfo;
+ // the intersect may have shrunk info's logical size
+ info.fWidth = srcR.width();
+ info.fHeight = srcR.height();
+
+ // if x or y are negative, then we have to adjust pixels
+ if (x > 0) {
+ x = 0;
+ }
+ if (y > 0) {
+ y = 0;
+ }
+ // here x,y are either 0 or negative
scroggo 2014/03/24 15:31:36 What's the use case for calling this function with
reed1 2014/03/24 15:53:05 We definitely support (in the public canvas versio
+ dstP = ((char*)dstP - y * rowBytes - x * info.bytesPerPixel());
+
+ // The device can assert that the requested area is always contained in its bounds
+ return device->readPixels(info, dstP, rowBytes, srcR.x(), srcR.y());
}
bool SkCanvas::writePixels(const SkBitmap& bitmap, int x, int y) {
@@ -1063,12 +1131,9 @@ SkAutoROCanvasPixels::SkAutoROCanvasPixels(SkCanvas* canvas) {
fAddr = canvas->peekPixels(&fInfo, &fRowBytes);
if (NULL == fAddr) {
fInfo = canvas->imageInfo();
- if (kUnknown_SkColorType == fInfo.colorType() ||
- !fBitmap.allocPixels(fInfo))
- {
+ if (kUnknown_SkColorType == fInfo.colorType() || !fBitmap.allocPixels(fInfo)) {
return; // failure, fAddr is NULL
}
- fBitmap.lockPixels();
if (!canvas->readPixels(&fBitmap, 0, 0)) {
return; // failure, fAddr is NULL
}

Powered by Google App Engine
This is Rietveld 408576698