Chromium Code Reviews| 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; |
| } |