More cleanup: streamline paths and bitmaps.

SkBitmapHeap is still used---now exclusively---by pipe.

BUG=skia:

Review URL: https://codereview.chromium.org/715413002
This commit is contained in:
mtklein 2014-11-12 10:24:55 -08:00 committed by Commit bot
parent 391e318b3d
commit 71a2363707
7 changed files with 39 additions and 232 deletions

View File

@ -127,8 +127,6 @@
'<(skia_src_path)/core/SkPaintPriv.h',
'<(skia_src_path)/core/SkPath.cpp',
'<(skia_src_path)/core/SkPathEffect.cpp',
'<(skia_src_path)/core/SkPathHeap.cpp',
'<(skia_src_path)/core/SkPathHeap.h',
'<(skia_src_path)/core/SkPathMeasure.cpp',
'<(skia_src_path)/core/SkPathRef.cpp',
'<(skia_src_path)/core/SkPicture.cpp',

View File

@ -1,95 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkPathHeap.h"
#include "SkPath.h"
#include "SkStream.h"
#include "SkReadBuffer.h"
#include "SkTSearch.h"
#include "SkWriteBuffer.h"
#include <new>
#define kPathCount 64
SkPathHeap::SkPathHeap() : fHeap(kPathCount * sizeof(SkPath)) {
}
SkPathHeap::SkPathHeap(SkReadBuffer& buffer)
: fHeap(kPathCount * sizeof(SkPath)) {
const int count = buffer.readInt();
fPaths.setCount(count);
SkPath** ptr = fPaths.begin();
SkPath* p = (SkPath*)fHeap.allocThrow(count * sizeof(SkPath));
for (int i = 0; i < count; i++) {
new (p) SkPath;
buffer.readPath(p);
*ptr++ = p; // record the pointer
p++; // move to the next storage location
}
}
SkPathHeap::~SkPathHeap() {
SkPath** iter = fPaths.begin();
SkPath** stop = fPaths.end();
while (iter < stop) {
(*iter)->~SkPath();
iter++;
}
}
int SkPathHeap::append(const SkPath& path) {
SkPath* p = (SkPath*)fHeap.allocThrow(sizeof(SkPath));
new (p) SkPath(path);
*fPaths.append() = p;
return fPaths.count();
}
SkPathHeap::LookupEntry::LookupEntry(const SkPath& path)
: fGenerationID(path.getGenerationID()), fStorageSlot(0) {
}
SkPathHeap::LookupEntry* SkPathHeap::addIfNotPresent(const SkPath& path) {
LookupEntry searchKey(path);
int index = SkTSearch<const LookupEntry, LookupEntry::Less>(
fLookupTable.begin(),
fLookupTable.count(),
searchKey,
sizeof(LookupEntry));
if (index < 0) {
index = ~index;
*fLookupTable.insert(index) = LookupEntry(path);
}
return &fLookupTable[index];;
}
int SkPathHeap::insert(const SkPath& path) {
SkPathHeap::LookupEntry* entry = this->addIfNotPresent(path);
if (entry->storageSlot() > 0) {
return entry->storageSlot();
}
int newSlot = this->append(path);
SkASSERT(newSlot > 0);
entry->setStorageSlot(newSlot);
return newSlot;
}
void SkPathHeap::flatten(SkWriteBuffer& buffer) const {
int count = fPaths.count();
buffer.writeInt(count);
SkPath* const* iter = fPaths.begin();
SkPath* const* stop = fPaths.end();
while (iter < stop) {
buffer.writePath(**iter);
iter++;
}
}

View File

@ -1,76 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkPathHeap_DEFINED
#define SkPathHeap_DEFINED
#include "SkRefCnt.h"
#include "SkChunkAlloc.h"
#include "SkTDArray.h"
class SkPath;
class SkReadBuffer;
class SkWriteBuffer;
class SkPathHeap : public SkRefCnt {
public:
SK_DECLARE_INST_COUNT(SkPathHeap)
SkPathHeap();
SkPathHeap(SkReadBuffer&);
virtual ~SkPathHeap();
/** Copy the path into the heap, and return the new total number of paths.
Thus, the returned value will be index+1, where index is the index of
this newly added (copied) path.
*/
int append(const SkPath&);
/** Add the specified path to the heap using its gen ID to de-duplicate.
Returns the path's index in the heap + 1.
*/
int insert(const SkPath&);
// called during picture-playback
int count() const { return fPaths.count(); }
const SkPath& operator[](int index) const {
return *fPaths[index];
}
void flatten(SkWriteBuffer&) const;
private:
// we store the paths in the heap (placement new)
SkChunkAlloc fHeap;
// we just store ptrs into fHeap here
SkTDArray<SkPath*> fPaths;
class LookupEntry {
public:
LookupEntry(const SkPath& path);
int storageSlot() const { return fStorageSlot; }
void setStorageSlot(int storageSlot) { fStorageSlot = storageSlot; }
static bool Less(const LookupEntry& a, const LookupEntry& b) {
return a.fGenerationID < b.fGenerationID;
}
private:
uint32_t fGenerationID; // the SkPath's generation ID
// the path's index in the heap + 1. It is 0 if the path is not yet in the heap.
int fStorageSlot;
};
SkTDArray<LookupEntry> fLookupTable;
SkPathHeap::LookupEntry* addIfNotPresent(const SkPath& path);
typedef SkRefCnt INHERITED;
};
#endif

View File

@ -30,10 +30,8 @@ SkPictureData::SkPictureData(const SkPictInfo& info)
void SkPictureData::initForPlayback() const {
// ensure that the paths bounds are pre-computed
if (fPathHeap.get()) {
for (int i = 0; i < fPathHeap->count(); i++) {
(*fPathHeap.get())[i].updateBoundsCache();
}
for (int i = 0; i < fPaths->count(); i++) {
(*fPaths)[i].updateBoundsCache();
}
}
@ -48,11 +46,9 @@ SkPictureData::SkPictureData(const SkPictureRecord& record,
fContentInfo.set(record.fContentInfo);
fBitmaps = record.fBitmapHeap->extractBitmaps();
fPaints = SkTRefArray<SkPaint>::Create(record.fPaints.begin(), record.fPaints.count());
fBitmapHeap.reset(SkSafeRef(record.fBitmapHeap));
fPathHeap.reset(SkSafeRef(record.pathHeap()));
fBitmaps = SkTRefArray<SkBitmap>::Create(record.fBitmaps.begin(), record.fBitmaps.count());
fPaints = SkTRefArray<SkPaint> ::Create(record.fPaints .begin(), record.fPaints .count());
fPaths = SkTRefArray<SkPath> ::Create(record.fPaths .begin(), record.fPaths .count());
this->initForPlayback();
@ -80,6 +76,7 @@ SkPictureData::SkPictureData(const SkPictureRecord& record,
void SkPictureData::init() {
fBitmaps = NULL;
fPaints = NULL;
fPaths = NULL;
fPictureRefs = NULL;
fPictureCount = 0;
fTextBlobRefs = NULL;
@ -93,6 +90,7 @@ SkPictureData::~SkPictureData() {
SkSafeUnref(fBitmaps);
SkSafeUnref(fPaints);
SkSafeUnref(fPaths);
for (int i = 0; i < fPictureCount; i++) {
fPictureRefs[i]->unref();
@ -210,9 +208,12 @@ void SkPictureData::flattenToBuffer(SkWriteBuffer& buffer) const {
}
}
if ((n = SafeCount(fPathHeap.get())) > 0) {
if ((n = SafeCount(fPaths)) > 0) {
write_tag_size(buffer, SK_PICT_PATH_BUFFER_TAG, n);
fPathHeap->flatten(buffer);
buffer.writeInt(n);
for (int i = 0; i < n; i++) {
buffer.writePath((*fPaths)[i]);
}
}
if (fTextBlobCount > 0) {
@ -441,9 +442,12 @@ bool SkPictureData::parseBufferTag(SkReadBuffer& buffer,
} break;
case SK_PICT_PATH_BUFFER_TAG:
if (size > 0) {
fPathHeap.reset(SkNEW_ARGS(SkPathHeap, (buffer)));
}
break;
const int count = buffer.readInt();
fPaths = SkTRefArray<SkPath>::Create(count);
for (int i = 0; i < count; i++) {
buffer.readPath(&fPaths->writableAt(i));
}
} break;
case SK_PICT_TEXTBLOB_BUFFER_TAG: {
if (!buffer.validate((0 == fTextBlobCount) && (NULL == fTextBlobRefs))) {
return false;

View File

@ -9,7 +9,6 @@
#define SkPictureData_DEFINED
#include "SkBitmap.h"
#include "SkPathHeap.h"
#include "SkPicture.h"
#include "SkPictureContentInfo.h"
#include "SkPictureFlat.h"
@ -85,18 +84,12 @@ protected:
public:
const SkBitmap& getBitmap(SkReader32* reader) const {
const int index = reader->readInt();
if (SkBitmapHeap::INVALID_SLOT == index) {
#ifdef SK_DEBUG
SkDebugf("An invalid bitmap was recorded!\n");
#endif
return fBadBitmap;
}
return (*fBitmaps)[index];
}
const SkPath& getPath(SkReader32* reader) const {
int index = reader->readInt() - 1;
return (*fPathHeap.get())[index];
return (*fPaths)[index];
}
const SkPicture* getPicture(SkReader32* reader) const {
@ -149,15 +142,12 @@ private:
// bitmap allows playback to draw nothing and move on.
SkBitmap fBadBitmap;
SkAutoTUnref<SkBitmapHeap> fBitmapHeap;
SkTRefArray<SkBitmap>* fBitmaps;
SkTRefArray<SkPaint>* fPaints;
SkTRefArray<SkPaint>* fPaints;
SkTRefArray<SkPath>* fPaths;
SkData* fOpData; // opcodes and parameters
SkAutoTUnref<const SkPathHeap> fPathHeap; // reference counted
const SkPicture** fPictureRefs;
int fPictureCount;
const SkTextBlob** fTextBlobRefs;

View File

@ -31,16 +31,12 @@ static const uint32_t kSaveLayerWithBoundsSize = 4 * kUInt32Size + sizeof(SkRect
SkPictureRecord::SkPictureRecord(const SkISize& dimensions, uint32_t flags)
: INHERITED(dimensions.width(), dimensions.height())
, fRecordFlags(flags) {
fBitmapHeap = SkNEW(SkBitmapHeap);
fFirstSavedLayerIndex = kNoSavedLayerIndex;
fInitialSaveCount = kNoInitialSave;
, fFirstSavedLayerIndex(kNoSavedLayerIndex)
, fRecordFlags(flags)
, fInitialSaveCount(kNoInitialSave) {
}
SkPictureRecord::~SkPictureRecord() {
SkSafeUnref(fBitmapHeap);
fPictureRefs.unrefAll();
fTextBlobRefs.unrefAll();
}
@ -905,13 +901,16 @@ SkSurface* SkPictureRecord::onNewSurface(const SkImageInfo& info, const SkSurfac
}
int SkPictureRecord::addBitmap(const SkBitmap& bitmap) {
const int index = fBitmapHeap->insert(bitmap);
// In debug builds, a bad return value from insert() will crash, allowing for debugging. In
// release builds, the invalid value will be recorded so that the reader will know that there
// was a problem.
SkASSERT(index != SkBitmapHeap::INVALID_SLOT);
this->addInt(index);
return index;
if (bitmap.isImmutable()) {
fBitmaps.push_back(bitmap);
} else {
SkBitmap copy;
bitmap.copyTo(&copy);
copy.setImmutable();
fBitmaps.push_back(copy);
}
this->addInt(fBitmaps.count()-1); // Unlike the rest, bitmap indicies are 0-based.
return fBitmaps.count();
}
void SkPictureRecord::addMatrix(const SkMatrix& matrix) {
@ -930,14 +929,8 @@ void SkPictureRecord::addPaintPtr(const SkPaint* paint) {
}
int SkPictureRecord::addPathToHeap(const SkPath& path) {
if (NULL == fPathHeap) {
fPathHeap.reset(SkNEW(SkPathHeap));
}
#ifdef SK_DEDUP_PICTURE_PATHS
return fPathHeap->insert(path);
#else
return fPathHeap->append(path);
#endif
fPaths.push_back(path);
return fPaths.count();
}
void SkPictureRecord::addPath(const SkPath& path) {

View File

@ -10,7 +10,6 @@
#include "SkCanvas.h"
#include "SkFlattenable.h"
#include "SkPathHeap.h"
#include "SkPicture.h"
#include "SkPictureData.h"
#include "SkTemplates.h"
@ -82,10 +81,6 @@ public:
return fWriter.snapshotAsData();
}
const SkPathHeap* pathHeap() const {
return fPathHeap.get();
}
const SkPictureContentInfo& contentInfo() const {
return fContentInfo;
}
@ -236,14 +231,12 @@ protected:
void recordSaveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags);
void recordRestore(bool fillInSkips = true);
// Allocated in the constructor and managed by this class.
SkBitmapHeap* fBitmapHeap;
private:
SkPictureContentInfo fContentInfo;
SkAutoTUnref<SkPathHeap> fPathHeap;
SkTArray<SkPaint> fPaints;
SkTArray<SkBitmap> fBitmaps;
SkTArray<SkPaint> fPaints;
SkTArray<SkPath> fPaths;
SkWriter32 fWriter;