Index: src/core/SkBitmap_scroll.cpp |
diff --git a/src/core/SkBitmap_scroll.cpp b/src/core/SkBitmap_scroll.cpp |
index 54158c2bec1182de89fe612b0feb1d5c459ddf24..8c78bd9e94b20a35b7210e65fa57f393e8e075f5 100644 |
--- a/src/core/SkBitmap_scroll.cpp |
+++ b/src/core/SkBitmap_scroll.cpp |
@@ -8,9 +8,51 @@ |
#include "SkBitmap.h" |
#include "SkRegion.h" |
-bool SkBitmap::scrollRect(const SkIRect* subset, int dx, int dy, |
- SkRegion* inval) const |
-{ |
+static bool scroll_pixels(const SkPixmap& pmap, int dx, int dy) { |
+ const int shift = pmap.info().bytesPerPixel() >> 1; |
+ char* dst = (char*)pmap.writable_addr(); |
+ const char* src = dst; |
+ int rowBytes = (int)pmap.rowBytes(); // need rowBytes to be signed |
+ int width = pmap.width(); |
+ int height = pmap.height(); |
+ |
+ if (dy <= 0) { |
+ src -= dy * rowBytes; |
+ height += dy; |
+ } else { |
+ dst += dy * rowBytes; |
+ height -= dy; |
+ // now jump src/dst to the last scanline |
+ src += (height - 1) * rowBytes; |
+ dst += (height - 1) * rowBytes; |
+ // now invert rowbytes so we copy backwards in the loop |
+ rowBytes = -rowBytes; |
+ } |
+ |
+ if (dx <= 0) { |
+ src -= dx << shift; |
+ width += dx; |
+ } else { |
+ dst += dx << shift; |
+ width -= dx; |
+ } |
+ |
+ // If the X-translation would push it completely beyond the region, |
+ // then there's nothing to draw. |
+ if (width <= 0) { |
+ return false; |
+ } |
+ |
+ width <<= shift; // now width is the number of bytes to move per line |
+ while (--height >= 0) { |
+ memmove(dst, src, width); |
+ dst += rowBytes; |
+ src += rowBytes; |
+ } |
+ return true; |
+} |
+ |
+bool SkBitmap::scrollRect(const SkIRect* subset, int dx, int dy, SkRegion* inval) const { |
scroggo
2015/05/19 20:11:42
It appears that neither Android nor Chromium use t
reed1
2015/05/21 20:59:35
I'll try that in an (earlier?) CL.
|
if (this->isImmutable() || kUnknown_SkColorType == this->colorType()) { |
return false; |
} |
@@ -23,7 +65,6 @@ bool SkBitmap::scrollRect(const SkIRect* subset, int dx, int dy, |
tmp.scrollRect(NULL, dx, dy, inval); |
} |
- int shift = this->bytesPerPixel() >> 1; |
int width = this->width(); |
int height = this->height(); |
@@ -55,51 +96,12 @@ bool SkBitmap::scrollRect(const SkIRect* subset, int dx, int dy, |
inval->op(r, SkRegion::kDifference_Op); |
} |
- SkAutoLockPixels alp(*this); |
- // if we have no pixels, just return (inval is already updated) |
- // don't call readyToDraw(), since we don't require a colortable per se |
- if (this->getPixels() == NULL) { |
+ SkAutoBitmapLockResult result; |
+ if (!this->requestLock(&result)) { |
return true; |
} |
- |
- char* dst = (char*)this->getPixels(); |
- const char* src = dst; |
- int rowBytes = (int)this->rowBytes(); // need rowBytes to be signed |
- |
- if (dy <= 0) { |
- src -= dy * rowBytes; |
- height += dy; |
- } else { |
- dst += dy * rowBytes; |
- height -= dy; |
- // now jump src/dst to the last scanline |
- src += (height - 1) * rowBytes; |
- dst += (height - 1) * rowBytes; |
- // now invert rowbytes so we copy backwards in the loop |
- rowBytes = -rowBytes; |
+ if (scroll_pixels(result.pixmap(), dx, dy)) { |
+ this->notifyPixelsChanged(); |
} |
- |
- if (dx <= 0) { |
- src -= dx << shift; |
- width += dx; |
- } else { |
- dst += dx << shift; |
- width -= dx; |
- } |
- |
- // If the X-translation would push it completely beyond the region, |
- // then there's nothing to draw. |
- if (width <= 0) { |
- return true; |
- } |
- |
- width <<= shift; // now width is the number of bytes to move per line |
- while (--height >= 0) { |
- memmove(dst, src, width); |
- dst += rowBytes; |
- src += rowBytes; |
- } |
- |
- this->notifyPixelsChanged(); |
return true; |
} |