use pixmaps for dst in sprites -- NO BITMAPS
BUG=skia: TBR=scroggo@google.com Review URL: https://codereview.chromium.org/1143173011
This commit is contained in:
parent
89d59883f3
commit
cb67414454
@ -654,6 +654,17 @@ public:
|
||||
bool extractAlpha(SkBitmap* dst, const SkPaint* paint, Allocator* allocator,
|
||||
SkIPoint* offset) const;
|
||||
|
||||
/**
|
||||
* If the pixels are available from this bitmap (w/o locking) return true, and fill out the
|
||||
* specified pixmap (if not null). If the pixels are not available (either because there are
|
||||
* none, or becuase accessing them would require locking or other machinary) return false and
|
||||
* ignore the pixmap parameter.
|
||||
*
|
||||
* Note: if this returns true, the results (in the pixmap) are only valid until the bitmap
|
||||
* is changed in anyway, in which case the results are invalid.
|
||||
*/
|
||||
bool peekPixels(SkPixmap*) const;
|
||||
|
||||
SkDEBUGCODE(void validate() const;)
|
||||
|
||||
class Allocator : public SkRefCnt {
|
||||
|
@ -1388,6 +1388,16 @@ bool SkBitmap::requestLock(SkAutoPixmapUnlock* result) const {
|
||||
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
|
||||
|
@ -128,7 +128,7 @@ public:
|
||||
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,
|
||||
|
@ -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 @@ void SkSpriteBlitter::blitMask(const SkMask&, const SkIRect& clip) {
|
||||
|
||||
// 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 @@ SkBlitter* SkBlitter::ChooseSprite(const SkBitmap& device, const SkPaint& paint,
|
||||
|
||||
SkSpriteBlitter* blitter;
|
||||
|
||||
switch (device.colorType()) {
|
||||
switch (dst.colorType()) {
|
||||
case kRGB_565_SkColorType:
|
||||
blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator);
|
||||
break;
|
||||
@ -68,7 +68,7 @@ SkBlitter* SkBlitter::ChooseSprite(const SkBitmap& device, const SkPaint& paint,
|
||||
}
|
||||
|
||||
if (blitter) {
|
||||
blitter->setup(device, left, top, paint);
|
||||
blitter->setup(dst, left, top, paint);
|
||||
}
|
||||
return blitter;
|
||||
}
|
||||
|
@ -1280,9 +1280,13 @@ void SkDraw::drawBitmap(const SkBitmap& bitmap, const SkMatrix& prematrix,
|
||||
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 @@ void SkDraw::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& ori
|
||||
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;
|
||||
|
@ -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 @@ class SkSpriteBlitter : public SkBlitter {
|
||||
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 @@ public:
|
||||
static SkSpriteBlitter* ChooseD32(const SkPixmap& source, const SkPaint&, SkTBlitterAllocator*);
|
||||
|
||||
protected:
|
||||
const SkBitmap* fDevice;
|
||||
SkPixmap fDst;
|
||||
const SkPixmap fSource;
|
||||
int fLeft, fTop;
|
||||
const SkPaint* fPaint;
|
||||
|
@ -15,12 +15,12 @@ public:
|
||||
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);
|
||||
|
@ -36,9 +36,9 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
|
||||
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 @@ public:
|
||||
|
||||
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 {
|
||||
|
@ -51,9 +51,9 @@ public:
|
||||
|
||||
// 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 @@ public:
|
||||
#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 @@ public:
|
||||
#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 @@ public:
|
||||
#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 @@ public:
|
||||
#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 @@ public:
|
||||
#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 @@ static void blitrow_d16_si8(uint16_t* SK_RESTRICT dst,
|
||||
#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 @@ static void blitrow_d16_si8(uint16_t* SK_RESTRICT dst,
|
||||
#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 @@ class Sprite_D16_S32_BlitRowProc : public SkSpriteBlitter {
|
||||
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 @@ public:
|
||||
}
|
||||
|
||||
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();
|
||||
|
@ -9,6 +9,31 @@
|
||||
#include "SkMallocPixelRef.h"
|
||||
#include "Test.h"
|
||||
|
||||
static void test_peekpixels(skiatest::Reporter* reporter) {
|
||||
const SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10);
|
||||
|
||||
SkPixmap pmap;
|
||||
SkBitmap bm;
|
||||
|
||||
// empty should return false
|
||||
REPORTER_ASSERT(reporter, !bm.peekPixels(NULL));
|
||||
REPORTER_ASSERT(reporter, !bm.peekPixels(&pmap));
|
||||
|
||||
// no pixels should return false
|
||||
bm.setInfo(SkImageInfo::MakeN32Premul(10, 10));
|
||||
REPORTER_ASSERT(reporter, !bm.peekPixels(NULL));
|
||||
REPORTER_ASSERT(reporter, !bm.peekPixels(&pmap));
|
||||
|
||||
// real pixels should return true
|
||||
bm.allocPixels(info);
|
||||
REPORTER_ASSERT(reporter, bm.peekPixels(NULL));
|
||||
REPORTER_ASSERT(reporter, bm.peekPixels(&pmap));
|
||||
REPORTER_ASSERT(reporter, pmap.info() == bm.info());
|
||||
REPORTER_ASSERT(reporter, pmap.addr() == bm.getPixels());
|
||||
REPORTER_ASSERT(reporter, pmap.rowBytes() == bm.rowBytes());
|
||||
REPORTER_ASSERT(reporter, pmap.ctable() == bm.getColorTable());
|
||||
}
|
||||
|
||||
// https://code.google.com/p/chromium/issues/detail?id=446164
|
||||
static void test_bigalloc(skiatest::Reporter* reporter) {
|
||||
const int width = 0x40000001;
|
||||
@ -95,4 +120,5 @@ DEF_TEST(Bitmap, reporter) {
|
||||
test_bigwidth(reporter);
|
||||
test_allocpixels(reporter);
|
||||
test_bigalloc(reporter);
|
||||
test_peekpixels(reporter);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user