Add SkChunkAlloc::unalloc() to undo the last allocation, useful if the caller wants to treat the allocats like temp memory (see PictureRecord)
Call unalloc if a paint (or other cached object) is already in our list for picture recording Use correct CompareType macro in SkCanvas::quickReject git-svn-id: http://skia.googlecode.com/svn/trunk@138 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
f459a4949d
commit
aefd2bc757
@ -46,6 +46,14 @@ public:
|
||||
return this->alloc(bytes, kThrow_AllocFailType);
|
||||
}
|
||||
|
||||
/** Call this to unalloc the most-recently allocated ptr by alloc(). On
|
||||
success, the number of bytes freed is returned, or 0 if the block could
|
||||
not be unallocated. This is a hint to the underlying allocator that
|
||||
the previous allocation may be reused, but the implementation is free
|
||||
to ignore this call (and return 0).
|
||||
*/
|
||||
size_t unalloc(void* ptr);
|
||||
|
||||
size_t totalCapacity() const { return fTotalCapacity; }
|
||||
|
||||
private:
|
||||
|
@ -299,12 +299,12 @@ void SampleWindow::afterChildren(SkCanvas* orig) {
|
||||
case kRaster_CanvasType:
|
||||
break;
|
||||
case kPicture_CanvasType:
|
||||
if (false) {
|
||||
if (true) {
|
||||
SkPicture* pict = new SkPicture(*fPicture);
|
||||
fPicture->unref();
|
||||
orig->drawPicture(*pict);
|
||||
pict->unref();
|
||||
} if (true) {
|
||||
} else if (true) {
|
||||
SkDynamicMemoryWStream ostream;
|
||||
fPicture->serialize(&ostream);
|
||||
fPicture->unref();
|
||||
|
@ -943,8 +943,8 @@ bool SkCanvas::quickRejectY(SkScalar top, SkScalar bottom, EdgeType et) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
SkScalarCompareType userT = SkScalarAs2sCompliment(top);
|
||||
SkScalarCompareType userB = SkScalarAs2sCompliment(bottom);
|
||||
SkScalarCompareType userT = SkScalarToCompareType(top);
|
||||
SkScalarCompareType userB = SkScalarToCompareType(bottom);
|
||||
|
||||
// check for invalid user Y coordinates (i.e. empty)
|
||||
if (userT >= userB) {
|
||||
|
@ -23,6 +23,10 @@ struct SkChunkAlloc::Block {
|
||||
char* fFreePtr;
|
||||
// data[] follows
|
||||
|
||||
char* startOfData() {
|
||||
return reinterpret_cast<char*>(this + 1);
|
||||
}
|
||||
|
||||
void freeChain() { // this can be null
|
||||
Block* block = this;
|
||||
while (block) {
|
||||
@ -89,7 +93,7 @@ SkChunkAlloc::Block* SkChunkAlloc::newBlock(size_t bytes, AllocFailType ftype) {
|
||||
if (block) {
|
||||
// block->fNext = fBlock;
|
||||
block->fFreeSize = size;
|
||||
block->fFreePtr = (char*)block + sizeof(Block);
|
||||
block->fFreePtr = block->startOfData();
|
||||
|
||||
fTotalCapacity += size;
|
||||
}
|
||||
@ -118,3 +122,18 @@ void* SkChunkAlloc::alloc(size_t bytes, AllocFailType ftype) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
size_t SkChunkAlloc::unalloc(void* ptr) {
|
||||
size_t bytes = 0;
|
||||
Block* block = fBlock;
|
||||
if (block) {
|
||||
char* cPtr = reinterpret_cast<char*>(ptr);
|
||||
char* start = block->startOfData();
|
||||
if (start <= cPtr && cPtr < block->fFreePtr) {
|
||||
bytes = block->fFreePtr - cPtr;
|
||||
block->fFreeSize += bytes;
|
||||
block->fFreePtr = cPtr;
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
@ -1278,50 +1278,143 @@ SkGlyphCache* SkPaint::detachCache(const SkMatrix* deviceMatrix) const
|
||||
|
||||
#include "SkStream.h"
|
||||
|
||||
static uintptr_t asint(const void* p) {
|
||||
return reinterpret_cast<uintptr_t>(p);
|
||||
}
|
||||
|
||||
union Scalar32 {
|
||||
SkScalar fScalar;
|
||||
uint32_t f32;
|
||||
};
|
||||
|
||||
static uint32_t* write_scalar(uint32_t* ptr, SkScalar value) {
|
||||
SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
|
||||
Scalar32 tmp;
|
||||
tmp.fScalar = value;
|
||||
*ptr = tmp.f32;
|
||||
return ptr + 1;
|
||||
}
|
||||
|
||||
static SkScalar read_scalar(const uint32_t*& ptr) {
|
||||
SkASSERT(sizeof(SkScalar) == sizeof(uint32_t));
|
||||
Scalar32 tmp;
|
||||
tmp.f32 = *ptr++;
|
||||
return tmp.fScalar;
|
||||
}
|
||||
|
||||
static uint32_t pack_4(unsigned a, unsigned b, unsigned c, unsigned d) {
|
||||
SkASSERT(a == (uint8_t)a);
|
||||
SkASSERT(b == (uint8_t)b);
|
||||
SkASSERT(c == (uint8_t)c);
|
||||
SkASSERT(d == (uint8_t)d);
|
||||
return (a << 24) | (b << 16) | (c << 8) | d;
|
||||
}
|
||||
|
||||
enum FlatFlags {
|
||||
kHasTypeface_FlatFlag = 0x01,
|
||||
kHasEffects_FlatFlag = 0x02
|
||||
};
|
||||
|
||||
// The size of a flat paint's POD fields
|
||||
static const uint32_t kPODPaintSize = 5 * sizeof(SkScalar) +
|
||||
1 * sizeof(SkColor) +
|
||||
1 * sizeof(uint16_t) +
|
||||
6 * sizeof(uint8_t);
|
||||
|
||||
/* To save space/time, we analyze the paint, and write a truncated version of
|
||||
it if there are not tricky elements like shaders, etc.
|
||||
*/
|
||||
void SkPaint::flatten(SkFlattenableWriteBuffer& buffer) const {
|
||||
buffer.writeTypeface(this->getTypeface());
|
||||
buffer.writeScalar(this->getTextSize());
|
||||
buffer.writeScalar(this->getTextScaleX());
|
||||
buffer.writeScalar(this->getTextSkewX());
|
||||
buffer.writeFlattenable(this->getPathEffect());
|
||||
buffer.writeFlattenable(this->getShader());
|
||||
buffer.writeFlattenable(this->getXfermode());
|
||||
buffer.writeFlattenable(this->getMaskFilter());
|
||||
buffer.writeFlattenable(this->getColorFilter());
|
||||
buffer.writeFlattenable(this->getRasterizer());
|
||||
buffer.writeFlattenable(this->getLooper());
|
||||
buffer.write32(this->getColor());
|
||||
buffer.writeScalar(this->getStrokeWidth());
|
||||
buffer.writeScalar(this->getStrokeMiter());
|
||||
buffer.write16(this->getFlags());
|
||||
buffer.write8(this->getTextAlign());
|
||||
buffer.write8(this->getStrokeCap());
|
||||
buffer.write8(this->getStrokeJoin());
|
||||
buffer.write8(this->getStyle());
|
||||
buffer.write8(this->getTextEncoding());
|
||||
uint8_t flatFlags = 0;
|
||||
if (this->getTypeface()) {
|
||||
flatFlags |= kHasTypeface_FlatFlag;
|
||||
}
|
||||
if (asint(this->getPathEffect()) |
|
||||
asint(this->getShader()) |
|
||||
asint(this->getXfermode()) |
|
||||
asint(this->getMaskFilter()) |
|
||||
asint(this->getColorFilter()) |
|
||||
asint(this->getRasterizer()) |
|
||||
asint(this->getLooper())) {
|
||||
flatFlags |= kHasEffects_FlatFlag;
|
||||
}
|
||||
|
||||
SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
|
||||
uint32_t* ptr = buffer.reserve(kPODPaintSize);
|
||||
|
||||
ptr = write_scalar(ptr, this->getTextSize());
|
||||
ptr = write_scalar(ptr, this->getTextScaleX());
|
||||
ptr = write_scalar(ptr, this->getTextSkewX());
|
||||
ptr = write_scalar(ptr, this->getStrokeWidth());
|
||||
ptr = write_scalar(ptr, this->getStrokeMiter());
|
||||
*ptr++ = this->getColor();
|
||||
*ptr++ = (this->getFlags() << 16) | (this->getTextAlign() << 8) | flatFlags;
|
||||
*ptr++ = pack_4(this->getStrokeCap(), this->getStrokeJoin(),
|
||||
this->getStyle(), this->getTextEncoding());
|
||||
|
||||
// now we're done with ptr and the (pre)reserved space. If we need to write
|
||||
// additional fields, use the buffer directly
|
||||
if (flatFlags & kHasTypeface_FlatFlag) {
|
||||
buffer.writeTypeface(this->getTypeface());
|
||||
}
|
||||
if (flatFlags & kHasEffects_FlatFlag) {
|
||||
buffer.writeFlattenable(this->getPathEffect());
|
||||
buffer.writeFlattenable(this->getShader());
|
||||
buffer.writeFlattenable(this->getXfermode());
|
||||
buffer.writeFlattenable(this->getMaskFilter());
|
||||
buffer.writeFlattenable(this->getColorFilter());
|
||||
buffer.writeFlattenable(this->getRasterizer());
|
||||
buffer.writeFlattenable(this->getLooper());
|
||||
}
|
||||
}
|
||||
|
||||
void SkPaint::unflatten(SkFlattenableReadBuffer& buffer) {
|
||||
this->setTypeface(buffer.readTypeface());
|
||||
this->setTextSize(buffer.readScalar());
|
||||
this->setTextScaleX(buffer.readScalar());
|
||||
this->setTextSkewX(buffer.readScalar());
|
||||
this->setPathEffect((SkPathEffect*) buffer.readFlattenable())->safeUnref();
|
||||
this->setShader((SkShader*) buffer.readFlattenable())->safeUnref();
|
||||
this->setXfermode((SkXfermode*) buffer.readFlattenable())->safeUnref();
|
||||
this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable())->safeUnref();
|
||||
this->setColorFilter((SkColorFilter*) buffer.readFlattenable())->safeUnref();
|
||||
this->setRasterizer((SkRasterizer*) buffer.readFlattenable())->safeUnref();
|
||||
this->setLooper((SkDrawLooper*) buffer.readFlattenable())->safeUnref();
|
||||
this->setColor(buffer.readU32());
|
||||
this->setStrokeWidth(buffer.readScalar());
|
||||
this->setStrokeMiter(buffer.readScalar());
|
||||
this->setFlags(buffer.readU16());
|
||||
this->setTextAlign((SkPaint::Align) buffer.readU8());
|
||||
this->setStrokeCap((SkPaint::Cap) buffer.readU8());
|
||||
this->setStrokeJoin((SkPaint::Join) buffer.readU8());
|
||||
this->setStyle((SkPaint::Style) buffer.readU8());
|
||||
this->setTextEncoding((SkPaint::TextEncoding) buffer.readU8());
|
||||
SkASSERT(SkAlign4(kPODPaintSize) == kPODPaintSize);
|
||||
const void* podData = buffer.skip(kPODPaintSize);
|
||||
const uint32_t* pod = reinterpret_cast<const uint32_t*>(podData);
|
||||
|
||||
// the order we read must match the order we wrote in flatten()
|
||||
this->setTextSize(read_scalar(pod));
|
||||
this->setTextScaleX(read_scalar(pod));
|
||||
this->setTextSkewX(read_scalar(pod));
|
||||
this->setStrokeWidth(read_scalar(pod));
|
||||
this->setStrokeMiter(read_scalar(pod));
|
||||
this->setColor(*pod++);
|
||||
|
||||
uint32_t tmp = *pod++;
|
||||
this->setFlags(tmp >> 16);
|
||||
this->setTextAlign(static_cast<Align>((tmp >> 8) & 0xFF));
|
||||
uint8_t flatFlags = tmp & 0xFF;
|
||||
|
||||
tmp = *pod++;
|
||||
this->setStrokeCap(static_cast<Cap>((tmp >> 24) & 0xFF));
|
||||
this->setStrokeJoin(static_cast<Join>((tmp >> 16) & 0xFF));
|
||||
this->setStyle(static_cast<Style>((tmp >> 8) & 0xFF));
|
||||
this->setTextEncoding(static_cast<TextEncoding>((tmp >> 0) & 0xFF));
|
||||
|
||||
if (flatFlags & kHasTypeface_FlatFlag) {
|
||||
this->setTypeface(buffer.readTypeface());
|
||||
} else {
|
||||
this->setTypeface(NULL);
|
||||
}
|
||||
|
||||
if (flatFlags & kHasEffects_FlatFlag) {
|
||||
this->setPathEffect((SkPathEffect*) buffer.readFlattenable())->safeUnref();
|
||||
this->setShader((SkShader*) buffer.readFlattenable())->safeUnref();
|
||||
this->setXfermode((SkXfermode*) buffer.readFlattenable())->safeUnref();
|
||||
this->setMaskFilter((SkMaskFilter*) buffer.readFlattenable())->safeUnref();
|
||||
this->setColorFilter((SkColorFilter*) buffer.readFlattenable())->safeUnref();
|
||||
this->setRasterizer((SkRasterizer*) buffer.readFlattenable())->safeUnref();
|
||||
this->setLooper((SkDrawLooper*) buffer.readFlattenable())->safeUnref();
|
||||
} else {
|
||||
this->setPathEffect(NULL);
|
||||
this->setShader(NULL);
|
||||
this->setXfermode(NULL);
|
||||
this->setMaskFilter(NULL);
|
||||
this->setColorFilter(NULL);
|
||||
this->setRasterizer(NULL);
|
||||
this->setLooper(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -514,8 +514,7 @@ int SkPictureRecord::find(SkTDArray<const SkFlatBitmap* >& bitmaps, const SkBitm
|
||||
int index = SkTSearch<SkFlatData>((const SkFlatData**) bitmaps.begin(),
|
||||
bitmaps.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
|
||||
if (index >= 0) {
|
||||
// SkBitmap bitmap;
|
||||
// flat->unflatten(&bitmap); // balance ref count
|
||||
(void)fHeap.unalloc(flat);
|
||||
return bitmaps[index]->index();
|
||||
}
|
||||
index = ~index;
|
||||
@ -529,8 +528,10 @@ int SkPictureRecord::find(SkTDArray<const SkFlatMatrix* >& matrices, const SkMat
|
||||
SkFlatMatrix* flat = SkFlatMatrix::Flatten(&fHeap, *matrix, fMatrixIndex);
|
||||
int index = SkTSearch<SkFlatData>((const SkFlatData**) matrices.begin(),
|
||||
matrices.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
|
||||
if (index >= 0)
|
||||
if (index >= 0) {
|
||||
(void)fHeap.unalloc(flat);
|
||||
return matrices[index]->index();
|
||||
}
|
||||
index = ~index;
|
||||
*matrices.insert(index) = flat;
|
||||
return fMatrixIndex++;
|
||||
@ -546,6 +547,7 @@ int SkPictureRecord::find(SkTDArray<const SkFlatPaint* >& paints, const SkPaint*
|
||||
int index = SkTSearch<SkFlatData>((const SkFlatData**) paints.begin(),
|
||||
paints.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
|
||||
if (index >= 0) {
|
||||
(void)fHeap.unalloc(flat);
|
||||
return paints[index]->index();
|
||||
}
|
||||
|
||||
@ -558,8 +560,10 @@ int SkPictureRecord::find(SkTDArray<const SkFlatRegion* >& regions, const SkRegi
|
||||
SkFlatRegion* flat = SkFlatRegion::Flatten(&fHeap, region, fRegionIndex);
|
||||
int index = SkTSearch<SkFlatData>((const SkFlatData**) regions.begin(),
|
||||
regions.count(), (SkFlatData*) flat, sizeof(flat), &SkFlatData::Compare);
|
||||
if (index >= 0)
|
||||
if (index >= 0) {
|
||||
(void)fHeap.unalloc(flat);
|
||||
return regions[index]->index();
|
||||
}
|
||||
index = ~index;
|
||||
*regions.insert(index) = flat;
|
||||
return fRegionIndex++;
|
||||
|
@ -68,6 +68,8 @@
|
||||
008C4D980F77DAEE0056981C /* SampleHairline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 008C4D970F77DAEE0056981C /* SampleHairline.cpp */; };
|
||||
009CC9190F65918A002185BE /* SampleFontScalerTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009CC9180F65918A002185BE /* SampleFontScalerTest.cpp */; };
|
||||
00A41E4B0EFC312F00C9CBEB /* SampleArc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */; };
|
||||
00FACE3C0F7D0E6600F8A7FF /* SkLargeBlock_malloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00FACE3B0F7D0E6600F8A7FF /* SkLargeBlock_malloc.cpp */; };
|
||||
00FACE680F7D23DD00F8A7FF /* SkWriter32_largeBlock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 00FACE5C0F7D209700F8A7FF /* SkWriter32_largeBlock.cpp */; };
|
||||
0156F80407C56A3000C6122B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0156F80307C56A3000C6122B /* Foundation.framework */; };
|
||||
01FC44D507BD3BB800D228F4 /* Quartz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01FC44D407BD3BB800D228F4 /* Quartz.framework */; };
|
||||
8D0C4E8D0486CD37000505A6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0867D6AAFE840B52C02AAC07 /* InfoPlist.strings */; };
|
||||
@ -184,6 +186,10 @@
|
||||
009CC9180F65918A002185BE /* SampleFontScalerTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleFontScalerTest.cpp; path = ../../samplecode/SampleFontScalerTest.cpp; sourceTree = SOURCE_ROOT; };
|
||||
00A41E4A0EFC312F00C9CBEB /* SampleArc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleArc.cpp; path = ../../samplecode/SampleArc.cpp; sourceTree = SOURCE_ROOT; };
|
||||
00D6B5CB0F72DC4300C466B9 /* SampleFuzz.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SampleFuzz.cpp; path = ../../samplecode/SampleFuzz.cpp; sourceTree = SOURCE_ROOT; };
|
||||
00FACE3B0F7D0E6600F8A7FF /* SkLargeBlock_malloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkLargeBlock_malloc.cpp; path = ../../src/utils/SkLargeBlock_malloc.cpp; sourceTree = SOURCE_ROOT; };
|
||||
00FACE3F0F7D167400F8A7FF /* SkLargeBlock_remap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkLargeBlock_remap.cpp; path = ../../src/utils/SkLargeBlock_remap.cpp; sourceTree = SOURCE_ROOT; };
|
||||
00FACE5C0F7D209700F8A7FF /* SkWriter32_largeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWriter32_largeBlock.cpp; path = ../../src/utils/SkWriter32_largeBlock.cpp; sourceTree = SOURCE_ROOT; };
|
||||
00FACE600F7D22CF00F8A7FF /* SkWriter32_noLargeBlock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SkWriter32_noLargeBlock.cpp; path = ../../src/utils/SkWriter32_noLargeBlock.cpp; sourceTree = SOURCE_ROOT; };
|
||||
0156F80307C56A3000C6122B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
|
||||
01FC44D407BD3BB800D228F4 /* Quartz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quartz.framework; path = /System/Library/Frameworks/Quartz.framework; sourceTree = "<absolute>"; };
|
||||
0867D6ABFE840B52C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
@ -331,6 +337,10 @@
|
||||
002884490EFAA35C0083E387 /* core.xcodeproj */,
|
||||
002884B40EFAB69F0083E387 /* maccore.xcodeproj */,
|
||||
00003C8C0EFC230E000FF73A /* effects.xcodeproj */,
|
||||
00FACE3B0F7D0E6600F8A7FF /* SkLargeBlock_malloc.cpp */,
|
||||
00FACE3F0F7D167400F8A7FF /* SkLargeBlock_remap.cpp */,
|
||||
00FACE5C0F7D209700F8A7FF /* SkWriter32_largeBlock.cpp */,
|
||||
00FACE600F7D22CF00F8A7FF /* SkWriter32_noLargeBlock.cpp */,
|
||||
);
|
||||
name = CICarbonSample;
|
||||
sourceTree = "<group>";
|
||||
@ -519,6 +529,8 @@
|
||||
007A7CB30F01658C00A2D6EE /* SamplePicture.cpp in Sources */,
|
||||
0041CE440F00A12400695E8C /* SampleLines.cpp in Sources */,
|
||||
008C4D980F77DAEE0056981C /* SampleHairline.cpp in Sources */,
|
||||
00FACE3C0F7D0E6600F8A7FF /* SkLargeBlock_malloc.cpp in Sources */,
|
||||
00FACE680F7D23DD00F8A7FF /* SkWriter32_largeBlock.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user