use pixmaps for dst in sprites -- NO BITMAPS
BUG=skia:
TBR=scroggo@google.com
Review URL: https://codereview.chromium.org/1143173011
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index cb4f1c6..dda6e39 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -1388,6 +1388,16 @@
return false;
}
+bool SkBitmap::peekPixels(SkPixmap* pmap) const {
+ if (fPixels) {
+ if (pmap) {
+ pmap->reset(fInfo, fPixels, fRowBytes, fColorTable);
+ }
+ return true;
+ }
+ return false;
+}
+
///////////////////////////////////////////////////////////////////////////////
#ifdef SK_DEBUG
diff --git a/src/core/SkBlitter.h b/src/core/SkBlitter.h
index 83e2e4e..695585a 100644
--- a/src/core/SkBlitter.h
+++ b/src/core/SkBlitter.h
@@ -128,7 +128,7 @@
SkTBlitterAllocator*,
bool drawCoverage = false);
- static SkBlitter* ChooseSprite(const SkBitmap& device,
+ static SkBlitter* ChooseSprite(const SkPixmap& dst,
const SkPaint&,
const SkPixmap& src,
int left, int top,
diff --git a/src/core/SkBlitter_Sprite.cpp b/src/core/SkBlitter_Sprite.cpp
index 46cd0a8..6dc5785 100644
--- a/src/core/SkBlitter_Sprite.cpp
+++ b/src/core/SkBlitter_Sprite.cpp
@@ -10,8 +10,8 @@
SkSpriteBlitter::SkSpriteBlitter(const SkPixmap& source) : fSource(source) {}
-void SkSpriteBlitter::setup(const SkBitmap& device, int left, int top, const SkPaint& paint) {
- fDevice = &device;
+void SkSpriteBlitter::setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) {
+ fDst = dst;
fLeft = left;
fTop = top;
fPaint = &paint;
@@ -40,7 +40,7 @@
// returning null means the caller will call SkBlitter::Choose() and
// have wrapped the source bitmap inside a shader
-SkBlitter* SkBlitter::ChooseSprite(const SkBitmap& device, const SkPaint& paint,
+SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint,
const SkPixmap& source, int left, int top, SkTBlitterAllocator* allocator) {
/* We currently ignore antialiasing and filtertype, meaning we will take our
special blitters regardless of these settings. Ignoring filtertype seems fine
@@ -55,7 +55,7 @@
SkSpriteBlitter* blitter;
- switch (device.colorType()) {
+ switch (dst.colorType()) {
case kRGB_565_SkColorType:
blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator);
break;
@@ -68,7 +68,7 @@
}
if (blitter) {
- blitter->setup(device, left, top, paint);
+ blitter->setup(dst, left, top, paint);
}
return blitter;
}
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 9188851..0ecc27d 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1280,9 +1280,13 @@
int ix = SkScalarRoundToInt(matrix.getTranslateX());
int iy = SkScalarRoundToInt(matrix.getTranslateY());
if (clipHandlesSprite(*fRC, ix, iy, pmap)) {
+ SkPixmap dstPM;
+ if (!fBitmap->peekPixels(&dstPM)) {
+ return;
+ }
SkTBlitterAllocator allocator;
// blitter will be owned by the allocator.
- SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, pmap, ix, iy, &allocator);
+ SkBlitter* blitter = SkBlitter::ChooseSprite(dstPM, paint, pmap, ix, iy, &allocator);
if (blitter) {
SkScan::FillIRect(SkIRect::MakeXYWH(ix, iy, pmap.width(), pmap.height()),
*fRC, blitter);
@@ -1337,9 +1341,13 @@
const SkPixmap& pmap = unlocker.pixmap();
if (NULL == paint.getColorFilter() && clipHandlesSprite(*fRC, x, y, pmap)) {
+ SkPixmap dstPM;
+ if (!fBitmap->peekPixels(&dstPM)) {
+ return;
+ }
SkTBlitterAllocator allocator;
// blitter will be owned by the allocator.
- SkBlitter* blitter = SkBlitter::ChooseSprite(*fBitmap, paint, pmap, x, y, &allocator);
+ SkBlitter* blitter = SkBlitter::ChooseSprite(dstPM, paint, pmap, x, y, &allocator);
if (blitter) {
SkScan::FillIRect(bounds, *fRC, blitter);
return;
diff --git a/src/core/SkSpriteBlitter.h b/src/core/SkSpriteBlitter.h
index 5cc483f..536c892 100644
--- a/src/core/SkSpriteBlitter.h
+++ b/src/core/SkSpriteBlitter.h
@@ -8,9 +8,8 @@
#ifndef SkSpriteBlitter_DEFINED
#define SkSpriteBlitter_DEFINED
-#include "SkBitmap.h"
-#include "SkBitmapProcShader.h"
#include "SkBlitter.h"
+#include "SkPixmap.h"
#include "SkShader.h"
#include "SkSmallAllocator.h"
@@ -20,7 +19,7 @@
public:
SkSpriteBlitter(const SkPixmap& source);
- virtual void setup(const SkBitmap& device, int left, int top, const SkPaint&);
+ virtual void setup(const SkPixmap& dst, int left, int top, const SkPaint&);
#ifdef SK_DEBUG
void blitH(int x, int y, int width) override;
@@ -33,7 +32,7 @@
static SkSpriteBlitter* ChooseD32(const SkPixmap& source, const SkPaint&, SkTBlitterAllocator*);
protected:
- const SkBitmap* fDevice;
+ SkPixmap fDst;
const SkPixmap fSource;
int fLeft, fTop;
const SkPaint* fPaint;
diff --git a/src/core/SkSpriteBlitterTemplate.h b/src/core/SkSpriteBlitterTemplate.h
index 3806dbc..36d3852 100644
--- a/src/core/SkSpriteBlitterTemplate.h
+++ b/src/core/SkSpriteBlitterTemplate.h
@@ -15,12 +15,12 @@
SkASSERT(width > 0 && height > 0);
int srcX = x - fLeft;
int srcY = y - fTop;
- SkSPRITE_DST_TYPE* SK_RESTRICT dst =fDevice->SkSPRITE_DST_GETADDR(x, y);
+ SkSPRITE_DST_TYPE* SK_RESTRICT dst =fDst.SkSPRITE_DST_GETADDR(x, y);
const SkSPRITE_SRC_TYPE* SK_RESTRICT src = fSource.SkSPRITE_SRC_GETADDR(srcX, srcY);
- size_t dstRB = fDevice->rowBytes();
+ size_t dstRB = fDst.rowBytes();
size_t srcRB = fSource.rowBytes();
- SkDEBUGCODE((void)fDevice->SkSPRITE_DST_GETADDR(x + width - 1, y + height - 1);)
+ SkDEBUGCODE((void)fDst.SkSPRITE_DST_GETADDR(x + width - 1, y + height - 1);)
SkDEBUGCODE((void)fSource.SkSPRITE_SRC_GETADDR(srcX + width - 1, srcY + height - 1);)
SkSPRITE_PREAMBLE(fSource, srcX, srcY);
diff --git a/src/core/SkSpriteBlitter_ARGB32.cpp b/src/core/SkSpriteBlitter_ARGB32.cpp
index 4138b72..962e2ac 100644
--- a/src/core/SkSpriteBlitter_ARGB32.cpp
+++ b/src/core/SkSpriteBlitter_ARGB32.cpp
@@ -36,9 +36,9 @@
void blitRect(int x, int y, int width, int height) override {
SkASSERT(width > 0 && height > 0);
- uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y);
+ uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y);
const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop);
- size_t dstRB = fDevice->rowBytes();
+ size_t dstRB = fDst.rowBytes();
size_t srcRB = fSource.rowBytes();
SkBlitRow::Proc32 proc = fProc32;
U8CPU alpha = fAlpha;
@@ -89,10 +89,10 @@
SkSafeUnref(fColorFilter);
}
- void setup(const SkBitmap& device, int left, int top, const SkPaint& paint) override {
- this->INHERITED::setup(device, left, top, paint);
+ void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override {
+ this->INHERITED::setup(dst, left, top, paint);
- int width = device.width();
+ int width = dst.width();
if (width > fBufferSize) {
fBufferSize = width;
delete[] fBuffer;
@@ -121,9 +121,9 @@
void blitRect(int x, int y, int width, int height) override {
SkASSERT(width > 0 && height > 0);
- uint32_t* SK_RESTRICT dst = fDevice->getAddr32(x, y);
+ uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y);
const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop);
- size_t dstRB = fDevice->rowBytes();
+ size_t dstRB = fDst.rowBytes();
size_t srcRB = fSource.rowBytes();
SkColorFilter* colorFilter = fColorFilter;
SkXfermode* xfermode = fXfermode;
@@ -167,9 +167,9 @@
void blitRect(int x, int y, int width, int height) override {
SkASSERT(width > 0 && height > 0);
- SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
+ SkPMColor* SK_RESTRICT dst = fDst.writable_addr32(x, y);
const SkPMColor16* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop);
- size_t dstRB = fDevice->rowBytes();
+ size_t dstRB = fDst.rowBytes();
size_t srcRB = fSource.rowBytes();
SkPMColor* SK_RESTRICT buffer = fBuffer;
SkColorFilter* colorFilter = fColorFilter;
@@ -213,9 +213,9 @@
void blitRect(int x, int y, int width, int height) override {
SkASSERT(width > 0 && height > 0);
- SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
+ SkPMColor* SK_RESTRICT dst = fDst.writable_addr32(x, y);
const SkPMColor16* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop);
- size_t dstRB = fDevice->rowBytes();
+ size_t dstRB = fDst.rowBytes();
size_t srcRB = fSource.rowBytes();
do {
@@ -241,9 +241,9 @@
void blitRect(int x, int y, int width, int height) override {
SkASSERT(width > 0 && height > 0);
- SkPMColor* SK_RESTRICT dst = fDevice->getAddr32(x, y);
+ SkPMColor* SK_RESTRICT dst = fDst.writable_addr32(x, y);
const SkPMColor16* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop);
- size_t dstRB = fDevice->rowBytes();
+ size_t dstRB = fDst.rowBytes();
size_t srcRB = fSource.rowBytes();
do {
diff --git a/src/core/SkSpriteBlitter_RGB16.cpp b/src/core/SkSpriteBlitter_RGB16.cpp
index ce4b2a9..677dbaa 100644
--- a/src/core/SkSpriteBlitter_RGB16.cpp
+++ b/src/core/SkSpriteBlitter_RGB16.cpp
@@ -51,9 +51,9 @@
// overrides
void blitRect(int x, int y, int width, int height) override {
- uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y);
+ uint16_t* SK_RESTRICT dst = fDst.writable_addr16(x, y);
const uint16_t* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop);
- size_t dstRB = fDevice->rowBytes();
+ size_t dstRB = fDst.rowBytes();
size_t srcRB = fSource.rowBytes();
while (--height >= 0) {
@@ -76,7 +76,7 @@
#define SkSPRITE_INIT fSrcAlpha = alpha;
#define SkSPRITE_DST_TYPE uint16_t
#define SkSPRITE_SRC_TYPE uint16_t
-#define SkSPRITE_DST_GETADDR getAddr16
+#define SkSPRITE_DST_GETADDR writable_addr16
#define SkSPRITE_SRC_GETADDR addr16
#define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha255To256(fSrcAlpha);
#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, src, scale)
@@ -98,7 +98,7 @@
#define SkSPRITE_INIT
#define SkSPRITE_DST_TYPE uint16_t
#define SkSPRITE_SRC_TYPE SkPMColor16
-#define SkSPRITE_DST_GETADDR getAddr16
+#define SkSPRITE_DST_GETADDR writable_addr16
#define SkSPRITE_SRC_GETADDR addr16
#define SkSPRITE_PREAMBLE(srcBM, x, y)
#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Opaque(dst, src)
@@ -119,7 +119,7 @@
#define SkSPRITE_INIT fSrcAlpha = alpha;
#define SkSPRITE_DST_TYPE uint16_t
#define SkSPRITE_SRC_TYPE uint16_t
-#define SkSPRITE_DST_GETADDR getAddr16
+#define SkSPRITE_DST_GETADDR writable_addr16
#define SkSPRITE_SRC_GETADDR addr16
#define SkSPRITE_PREAMBLE(srcBM, x, y) int scale = SkAlpha15To16(fSrcAlpha);
#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S4444_Blend(dst, src, scale)
@@ -135,7 +135,7 @@
#define SkSPRITE_INIT
#define SkSPRITE_DST_TYPE uint16_t
#define SkSPRITE_SRC_TYPE uint8_t
-#define SkSPRITE_DST_GETADDR getAddr16
+#define SkSPRITE_DST_GETADDR writable_addr16
#define SkSPRITE_SRC_GETADDR addr8
#define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.ctable()->readColors()
#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Opaque_Pixel(dst, ctable[src])
@@ -149,7 +149,7 @@
#define SkSPRITE_INIT fSrcAlpha = alpha;
#define SkSPRITE_DST_TYPE uint16_t
#define SkSPRITE_SRC_TYPE uint8_t
-#define SkSPRITE_DST_GETADDR getAddr16
+#define SkSPRITE_DST_GETADDR writable_addr16
#define SkSPRITE_SRC_GETADDR addr8
#define SkSPRITE_PREAMBLE(srcBM, x, y) const SkPMColor* ctable = srcBM.ctable()->readColors(); unsigned src_scale = SkAlpha255To256(fSrcAlpha);
#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S32A_Blend_Pixel(dst, ctable[src], src_scale)
@@ -227,7 +227,7 @@
#define SkSPRITE_INIT
#define SkSPRITE_DST_TYPE uint16_t
#define SkSPRITE_SRC_TYPE uint8_t
-#define SkSPRITE_DST_GETADDR getAddr16
+#define SkSPRITE_DST_GETADDR writable_addr16
#define SkSPRITE_SRC_GETADDR addr8
#define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.ctable()->read16BitCache()
#define SkSPRITE_BLIT_PIXEL(dst, src) *dst = ctable[src]
@@ -241,7 +241,7 @@
#define SkSPRITE_INIT fSrcAlpha = alpha;
#define SkSPRITE_DST_TYPE uint16_t
#define SkSPRITE_SRC_TYPE uint8_t
-#define SkSPRITE_DST_GETADDR getAddr16
+#define SkSPRITE_DST_GETADDR writable_addr16
#define SkSPRITE_SRC_GETADDR addr8
#define SkSPRITE_PREAMBLE(srcBM, x, y) const uint16_t* ctable = srcBM.ctable()->read16BitCache(); unsigned src_scale = SkAlpha255To256(fSrcAlpha);
#define SkSPRITE_BLIT_PIXEL(dst, src) D16_S16_Blend_Pixel(dst, ctable[src], src_scale)
@@ -255,8 +255,8 @@
public:
Sprite_D16_S32_BlitRowProc(const SkPixmap& source) : SkSpriteBlitter(source) {}
- void setup(const SkBitmap& device, int left, int top, const SkPaint& paint) override {
- this->INHERITED::setup(device, left, top, paint);
+ void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override {
+ this->INHERITED::setup(dst, left, top, paint);
unsigned flags = 0;
@@ -273,9 +273,9 @@
}
void blitRect(int x, int y, int width, int height) override {
- uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y);
+ uint16_t* SK_RESTRICT dst = fDst.writable_addr16(x, y);
const SkPMColor* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop);
- size_t dstRB = fDevice->rowBytes();
+ size_t dstRB = fDst.rowBytes();
size_t srcRB = fSource.rowBytes();
SkBlitRow::Proc16 proc = fProc;
U8CPU alpha = fPaint->getAlpha();