Remove SkBitmapHeap and SkBitmapHeapReader. They're unused.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1938033002

Review-Url: https://codereview.chromium.org/1938033002
This commit is contained in:
brianosman 2016-05-03 06:07:38 -07:00 committed by Commit bot
parent db1adf5989
commit 444f1ba1b7
10 changed files with 13 additions and 778 deletions

View File

@ -33,8 +33,6 @@
'<(skia_src_path)/core/SkBitmapController.cpp',
'<(skia_src_path)/core/SkBitmapDevice.cpp',
'<(skia_src_path)/core/SkBitmapFilter.h',
'<(skia_src_path)/core/SkBitmapHeap.cpp',
'<(skia_src_path)/core/SkBitmapHeap.h',
'<(skia_src_path)/core/SkBitmapProcShader.cpp',
'<(skia_src_path)/core/SkBitmapProcShader.h',
'<(skia_src_path)/core/SkBitmapProcState.cpp',

View File

@ -19,7 +19,6 @@
#include "../private/SkTHash.h"
class SkBitmap;
class SkBitmapHeap;
class SkFactorySet;
class SkFlattenable;
class SkRefCntSet;
@ -79,15 +78,6 @@ public:
SkRefCntSet* getTypefaceRecorder() const { return fTFSet; }
SkRefCntSet* setTypefaceRecorder(SkRefCntSet*);
/**
* Set an SkBitmapHeap to store bitmaps rather than flattening.
*
* Incompatible with an SkPixelSerializer. If an SkPixelSerializer is set,
* setting an SkBitmapHeap will set the SkPixelSerializer to NULL in release
* and crash in debug.
*/
void setBitmapHeap(SkBitmapHeap*);
/**
* Set an SkPixelSerializer to store an encoded representation of pixels,
* e.g. SkBitmaps.
@ -95,9 +85,6 @@ public:
* Calls ref() on the serializer.
*
* TODO: Encode SkImage pixels as well.
*
* Incompatible with the SkBitmapHeap. If an encoder is set fBitmapHeap will
* be set to NULL in release and crash in debug.
*/
void setPixelSerializer(SkPixelSerializer*);
SkPixelSerializer* getPixelSerializer() const { return fPixelSerializer; }
@ -107,7 +94,6 @@ private:
SkFactorySet* fFactorySet;
SkWriter32 fWriter;
SkBitmapHeap* fBitmapHeap;
SkRefCntSet* fTFSet;
SkAutoTUnref<SkPixelSerializer> fPixelSerializer;

View File

@ -1,391 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkBitmapHeap.h"
#include "SkBitmap.h"
#include "SkTSearch.h"
SkBitmapHeapEntry::SkBitmapHeapEntry()
: fSlot(-1)
, fRefCount(0)
, fBytesAllocated(0) {
}
SkBitmapHeapEntry::~SkBitmapHeapEntry() {
SkASSERT(0 == fRefCount);
}
void SkBitmapHeapEntry::addReferences(int count) {
if (0 == fRefCount) {
// If there are no current owners then the heap manager
// will be the only one able to modify it, so it does not
// need to be an atomic operation.
fRefCount = count;
} else {
sk_atomic_add(&fRefCount, count);
}
}
///////////////////////////////////////////////////////////////////////////////
static bool operator<(const SkIPoint& a, const SkIPoint& b) {
return *(const int64_t*)&a < *(const int64_t*)&b;
}
static bool operator>(const SkIPoint& a, const SkIPoint& b) {
return *(const int64_t*)&a > *(const int64_t*)&b;
}
bool SkBitmapHeap::LookupEntry::Less(const SkBitmapHeap::LookupEntry& a,
const SkBitmapHeap::LookupEntry& b) {
if (a.fGenerationId < b.fGenerationId) {
return true;
} else if (a.fGenerationId > b.fGenerationId) {
return false;
} else if (a.fPixelOrigin < b.fPixelOrigin) {
return true;
} else if (a.fPixelOrigin > b.fPixelOrigin) {
return false;
} else if (a.fWidth < b.fWidth) {
return true;
} else if (a.fWidth > b.fWidth) {
return false;
} else if (a.fHeight < b.fHeight) {
return true;
}
return false;
}
///////////////////////////////////////////////////////////////////////////////
SkBitmapHeap::SkBitmapHeap(int32_t preferredSize, int32_t ownerCount)
: INHERITED()
, fExternalStorage(nullptr)
, fMostRecentlyUsed(nullptr)
, fLeastRecentlyUsed(nullptr)
, fPreferredCount(preferredSize)
, fOwnerCount(ownerCount)
, fBytesAllocated(0)
, fDeferAddingOwners(false) {
}
SkBitmapHeap::SkBitmapHeap(ExternalStorage* storage, int32_t preferredSize)
: INHERITED()
, fExternalStorage(storage)
, fMostRecentlyUsed(nullptr)
, fLeastRecentlyUsed(nullptr)
, fPreferredCount(preferredSize)
, fOwnerCount(IGNORE_OWNERS)
, fBytesAllocated(0)
, fDeferAddingOwners(false) {
SkSafeRef(storage);
}
SkBitmapHeap::~SkBitmapHeap() {
SkDEBUGCODE(
for (int i = 0; i < fStorage.count(); i++) {
bool unused = false;
for (int j = 0; j < fUnusedSlots.count(); j++) {
if (fUnusedSlots[j] == fStorage[i]->fSlot) {
unused = true;
break;
}
}
if (!unused) {
fBytesAllocated -= fStorage[i]->fBytesAllocated;
}
}
fBytesAllocated -= (fStorage.count() * sizeof(SkBitmapHeapEntry));
)
SkASSERT(0 == fBytesAllocated);
fStorage.deleteAll();
SkSafeUnref(fExternalStorage);
fLookupTable.deleteAll();
}
void SkBitmapHeap::removeFromLRU(SkBitmapHeap::LookupEntry* entry) {
if (fMostRecentlyUsed == entry) {
fMostRecentlyUsed = entry->fLessRecentlyUsed;
if (nullptr == fMostRecentlyUsed) {
SkASSERT(fLeastRecentlyUsed == entry);
fLeastRecentlyUsed = nullptr;
} else {
fMostRecentlyUsed->fMoreRecentlyUsed = nullptr;
}
} else {
// Remove entry from its prior place, and make sure to cover the hole.
if (fLeastRecentlyUsed == entry) {
SkASSERT(entry->fMoreRecentlyUsed != nullptr);
fLeastRecentlyUsed = entry->fMoreRecentlyUsed;
}
// Since we have already considered the case where entry is the most recently used, it must
// have a more recently used at this point.
SkASSERT(entry->fMoreRecentlyUsed != nullptr);
entry->fMoreRecentlyUsed->fLessRecentlyUsed = entry->fLessRecentlyUsed;
if (entry->fLessRecentlyUsed != nullptr) {
SkASSERT(fLeastRecentlyUsed != entry);
entry->fLessRecentlyUsed->fMoreRecentlyUsed = entry->fMoreRecentlyUsed;
}
}
entry->fMoreRecentlyUsed = nullptr;
}
void SkBitmapHeap::appendToLRU(SkBitmapHeap::LookupEntry* entry) {
if (fMostRecentlyUsed != nullptr) {
SkASSERT(nullptr == fMostRecentlyUsed->fMoreRecentlyUsed);
fMostRecentlyUsed->fMoreRecentlyUsed = entry;
entry->fLessRecentlyUsed = fMostRecentlyUsed;
}
fMostRecentlyUsed = entry;
if (nullptr == fLeastRecentlyUsed) {
fLeastRecentlyUsed = entry;
}
}
// iterate through our LRU cache and try to find an entry to evict
SkBitmapHeap::LookupEntry* SkBitmapHeap::findEntryToReplace(const SkBitmap& replacement) {
SkASSERT(fPreferredCount != UNLIMITED_SIZE);
SkASSERT(fStorage.count() >= fPreferredCount);
SkBitmapHeap::LookupEntry* iter = fLeastRecentlyUsed;
while (iter != nullptr) {
SkBitmapHeapEntry* heapEntry = fStorage[iter->fStorageSlot];
if (heapEntry->fRefCount > 0) {
// If the least recently used bitmap has not been unreferenced
// by its owner, then according to our LRU specifications a more
// recently used one can not have used all its references yet either.
return nullptr;
}
if (replacement.getGenerationID() == iter->fGenerationId) {
// Do not replace a bitmap with a new one using the same
// pixel ref. Instead look for a different one that will
// potentially free up more space.
iter = iter->fMoreRecentlyUsed;
} else {
return iter;
}
}
return nullptr;
}
size_t SkBitmapHeap::freeMemoryIfPossible(size_t bytesToFree) {
if (UNLIMITED_SIZE == fPreferredCount) {
return 0;
}
LookupEntry* iter = fLeastRecentlyUsed;
size_t origBytesAllocated = fBytesAllocated;
// Purge starting from LRU until a non-evictable bitmap is found or until
// everything is evicted.
while (iter != nullptr) {
SkBitmapHeapEntry* heapEntry = fStorage[iter->fStorageSlot];
if (heapEntry->fRefCount > 0) {
break;
}
LookupEntry* next = iter->fMoreRecentlyUsed;
this->removeEntryFromLookupTable(iter);
// Free the pixel memory. removeEntryFromLookupTable already reduced
// fBytesAllocated properly.
heapEntry->fBitmap.reset();
// Add to list of unused slots which can be reused in the future.
fUnusedSlots.push(heapEntry->fSlot);
iter = next;
if (origBytesAllocated - fBytesAllocated >= bytesToFree) {
break;
}
}
if (fLeastRecentlyUsed != iter) {
// There was at least one eviction.
fLeastRecentlyUsed = iter;
if (nullptr == fLeastRecentlyUsed) {
// Everything was evicted
fMostRecentlyUsed = nullptr;
fBytesAllocated -= (fStorage.count() * sizeof(SkBitmapHeapEntry));
fStorage.deleteAll();
fUnusedSlots.reset();
SkASSERT(0 == fBytesAllocated);
} else {
fLeastRecentlyUsed->fLessRecentlyUsed = nullptr;
}
}
return origBytesAllocated - fBytesAllocated;
}
int SkBitmapHeap::findInLookupTable(const LookupEntry& indexEntry, SkBitmapHeapEntry** entry) {
int index = SkTSearch<const LookupEntry, LookupEntry::Less>(
(const LookupEntry**)fLookupTable.begin(),
fLookupTable.count(),
&indexEntry, sizeof(void*));
if (index < 0) {
// insert ourselves into the bitmapIndex
index = ~index;
*fLookupTable.insert(index) = new LookupEntry(indexEntry);
} else if (entry != nullptr) {
// populate the entry if needed
*entry = fStorage[fLookupTable[index]->fStorageSlot];
}
return index;
}
bool SkBitmapHeap::copyBitmap(const SkBitmap& originalBitmap, SkBitmap& copiedBitmap) {
SkASSERT(!fExternalStorage);
// If the bitmap is mutable, we need to do a deep copy, since the
// caller may modify it afterwards.
if (originalBitmap.isImmutable()) {
copiedBitmap = originalBitmap;
// TODO if we have the pixel ref in the heap we could pass it here to avoid a potential deep copy
// else if (sharedPixelRef != nullptr) {
// copiedBitmap = orig;
// copiedBitmap.setPixelRef(sharedPixelRef, originalBitmap.pixelRefOffset());
} else if (originalBitmap.empty()) {
copiedBitmap.reset();
} else if (!originalBitmap.deepCopyTo(&copiedBitmap)) {
return false;
}
copiedBitmap.setImmutable();
return true;
}
int SkBitmapHeap::removeEntryFromLookupTable(LookupEntry* entry) {
// remove the bitmap index for the deleted entry
SkDEBUGCODE(int count = fLookupTable.count();)
int index = this->findInLookupTable(*entry, nullptr);
// Verify that findInLookupTable found an existing entry rather than adding
// a new entry to the lookup table.
SkASSERT(count == fLookupTable.count());
fBytesAllocated -= fStorage[entry->fStorageSlot]->fBytesAllocated;
delete fLookupTable[index];
fLookupTable.remove(index);
return index;
}
int32_t SkBitmapHeap::insert(const SkBitmap& originalBitmap) {
SkBitmapHeapEntry* entry = nullptr;
int searchIndex = this->findInLookupTable(LookupEntry(originalBitmap), &entry);
if (entry) {
// Already had a copy of the bitmap in the heap.
if (fOwnerCount != IGNORE_OWNERS) {
if (fDeferAddingOwners) {
*fDeferredEntries.append() = entry->fSlot;
} else {
entry->addReferences(fOwnerCount);
}
}
if (fPreferredCount != UNLIMITED_SIZE) {
LookupEntry* lookupEntry = fLookupTable[searchIndex];
if (lookupEntry != fMostRecentlyUsed) {
this->removeFromLRU(lookupEntry);
this->appendToLRU(lookupEntry);
}
}
return entry->fSlot;
}
// decide if we need to evict an existing heap entry or create a new one
if (fPreferredCount != UNLIMITED_SIZE && fStorage.count() >= fPreferredCount) {
// iterate through our LRU cache and try to find an entry to evict
LookupEntry* lookupEntry = this->findEntryToReplace(originalBitmap);
if (lookupEntry != nullptr) {
// we found an entry to evict
entry = fStorage[lookupEntry->fStorageSlot];
// Remove it from the LRU. The new entry will be added to the LRU later.
this->removeFromLRU(lookupEntry);
int index = this->removeEntryFromLookupTable(lookupEntry);
// update the current search index now that we have removed one
if (index < searchIndex) {
searchIndex--;
}
}
}
// if we didn't have an entry yet we need to create one
if (!entry) {
if (fPreferredCount != UNLIMITED_SIZE && fUnusedSlots.count() > 0) {
int slot;
fUnusedSlots.pop(&slot);
entry = fStorage[slot];
} else {
entry = new SkBitmapHeapEntry;
fStorage.append(1, &entry);
entry->fSlot = fStorage.count() - 1;
fBytesAllocated += sizeof(SkBitmapHeapEntry);
}
}
// create a copy of the bitmap
bool copySucceeded;
if (fExternalStorage) {
copySucceeded = fExternalStorage->insert(originalBitmap, entry->fSlot);
} else {
copySucceeded = copyBitmap(originalBitmap, entry->fBitmap);
}
// if the copy failed then we must abort
if (!copySucceeded) {
// delete the index
delete fLookupTable[searchIndex];
fLookupTable.remove(searchIndex);
// If entry is the last slot in storage, it is safe to delete it.
if (fStorage.count() - 1 == entry->fSlot) {
// free the slot
fStorage.remove(entry->fSlot);
fBytesAllocated -= sizeof(SkBitmapHeapEntry);
delete entry;
} else {
fUnusedSlots.push(entry->fSlot);
}
return INVALID_SLOT;
}
// update the index with the appropriate slot in the heap
fLookupTable[searchIndex]->fStorageSlot = entry->fSlot;
// compute the space taken by this entry
// TODO if there is a shared pixel ref don't count it
// If the SkBitmap does not share an SkPixelRef with an SkBitmap already
// in the SharedHeap, also include the size of its pixels.
entry->fBytesAllocated = originalBitmap.getSize();
// add the bytes from this entry to the total count
fBytesAllocated += entry->fBytesAllocated;
if (fOwnerCount != IGNORE_OWNERS) {
if (fDeferAddingOwners) {
*fDeferredEntries.append() = entry->fSlot;
} else {
entry->addReferences(fOwnerCount);
}
}
if (fPreferredCount != UNLIMITED_SIZE) {
this->appendToLRU(fLookupTable[searchIndex]);
}
return entry->fSlot;
}
void SkBitmapHeap::deferAddingOwners() {
fDeferAddingOwners = true;
}
void SkBitmapHeap::endAddingOwnersDeferral(bool add) {
if (add) {
for (int i = 0; i < fDeferredEntries.count(); i++) {
SkASSERT(fOwnerCount != IGNORE_OWNERS);
SkBitmapHeapEntry* heapEntry = this->getEntry(fDeferredEntries[i]);
SkASSERT(heapEntry != nullptr);
heapEntry->addReferences(fOwnerCount);
}
}
fDeferAddingOwners = false;
fDeferredEntries.reset();
}

View File

@ -1,299 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef SkBitmapHeap_DEFINED
#define SkBitmapHeap_DEFINED
#include "SkAtomics.h"
#include "SkBitmap.h"
#include "SkPoint.h"
#include "SkRefCnt.h"
#include "SkTDArray.h"
#include "SkTypes.h"
/**
* SkBitmapHeapEntry provides users of SkBitmapHeap (using internal storage) with a means to...
* (1) get access a bitmap in the heap
* (2) indicate they are done with bitmap by releasing their reference (if they were an owner).
*/
class SkBitmapHeapEntry : SkNoncopyable {
public:
~SkBitmapHeapEntry();
int32_t getSlot() { return fSlot; }
SkBitmap* getBitmap() { return &fBitmap; }
void releaseRef() {
sk_atomic_dec(&fRefCount);
}
private:
SkBitmapHeapEntry();
void addReferences(int count);
int32_t fSlot;
int32_t fRefCount;
SkBitmap fBitmap;
// Keep track of the bytes allocated for this bitmap. When replacing the
// bitmap or removing this HeapEntry we know how much memory has been
// reclaimed.
size_t fBytesAllocated;
friend class SkBitmapHeap;
friend class SkBitmapHeapTester;
};
class SkBitmapHeapReader : public SkRefCnt {
public:
SkBitmapHeapReader() : INHERITED() {}
virtual SkBitmap* getBitmap(int32_t slot) const = 0;
virtual void releaseRef(int32_t slot) = 0;
private:
typedef SkRefCnt INHERITED;
};
/**
* TODO: stores immutable bitmaps into a heap
*/
class SkBitmapHeap : public SkBitmapHeapReader {
public:
class ExternalStorage : public SkRefCnt {
public:
virtual bool insert(const SkBitmap& bitmap, int32_t slot) = 0;
private:
typedef SkRefCnt INHERITED;
};
static const int32_t UNLIMITED_SIZE = -1;
static const int32_t IGNORE_OWNERS = -1;
static const int32_t INVALID_SLOT = -1;
/**
* Constructs a heap that is responsible for allocating and managing its own storage. In the
* case where we choose to allow the heap to grow indefinitely (i.e. UNLIMITED_SIZE) we
* guarantee that once allocated in the heap a bitmap's index in the heap is immutable.
* Otherwise we guarantee the bitmaps placement in the heap until its owner count goes to zero.
*
* @param preferredSize Specifies the preferred maximum number of bitmaps to store. This is
* not a hard limit as it can grow larger if the number of bitmaps in the heap with active
* owners exceeds this limit.
* @param ownerCount The number of owners to assign to each inserted bitmap. NOTE: while a
* bitmap in the heap has a least one owner it can't be removed.
*/
SkBitmapHeap(int32_t preferredSize = UNLIMITED_SIZE, int32_t ownerCount = IGNORE_OWNERS);
/**
* Constructs a heap that defers the responsibility of storing the bitmaps to an external
* function. This is especially useful if the bitmaps will be used in a separate process as the
* external storage can ensure the data is properly shuttled to the appropriate processes.
*
* Our LRU implementation assumes that inserts into the external storage are consumed in the
* order that they are inserted (i.e. SkPipe). This ensures that we don't need to query the
* external storage to see if a slot in the heap is eligible to be overwritten.
*
* @param externalStorage The class responsible for storing the bitmaps inserted into the heap
* @param heapSize The maximum size of the heap. Because of the sequential limitation imposed
* by our LRU implementation we can guarantee that the heap will never grow beyond this size.
*/
SkBitmapHeap(ExternalStorage* externalStorage, int32_t heapSize = UNLIMITED_SIZE);
virtual ~SkBitmapHeap();
/**
* Retrieves the bitmap from the specified slot in the heap
*
* @return The bitmap located at that slot or nullptr if external storage is being used.
*/
SkBitmap* getBitmap(int32_t slot) const override {
SkASSERT(fExternalStorage == nullptr);
SkBitmapHeapEntry* entry = getEntry(slot);
if (entry) {
return &entry->fBitmap;
}
return nullptr;
}
/**
* Retrieves the bitmap from the specified slot in the heap
*
* @return The bitmap located at that slot or nullptr if external storage is being used.
*/
void releaseRef(int32_t slot) override {
SkASSERT(fExternalStorage == nullptr);
if (fOwnerCount != IGNORE_OWNERS) {
SkBitmapHeapEntry* entry = getEntry(slot);
if (entry) {
entry->releaseRef();
}
}
}
/**
* Inserts a bitmap into the heap. The stored version of bitmap is guaranteed to be immutable
* and is not dependent on the lifecycle of the provided bitmap.
*
* @param bitmap the bitmap to be inserted into the heap
* @return the slot in the heap where the bitmap is stored or INVALID_SLOT if the bitmap could
* not be added to the heap. If it was added the slot will remain valid...
* (1) indefinitely if no owner count has been specified.
* (2) until all owners have called releaseRef on the appropriate SkBitmapHeapEntry*
*/
int32_t insert(const SkBitmap& bitmap);
/**
* Retrieves an entry from the heap at a given slot.
*
* @param slot the slot in the heap where a bitmap was stored.
* @return a SkBitmapHeapEntry that wraps the bitmap or nullptr if external storage is used.
*/
SkBitmapHeapEntry* getEntry(int32_t slot) const {
SkASSERT(slot <= fStorage.count());
if (fExternalStorage != nullptr) {
return nullptr;
}
return fStorage[slot];
}
/**
* Returns a count of the number of items currently in the heap
*/
int count() const {
SkASSERT(fExternalStorage != nullptr ||
fStorage.count() - fUnusedSlots.count() == fLookupTable.count());
return fLookupTable.count();
}
/**
* Returns the total number of bytes allocated by the bitmaps in the heap
*/
size_t bytesAllocated() const {
return fBytesAllocated;
}
/**
* Attempt to reduce the storage allocated.
* @param bytesToFree minimum number of bytes that should be attempted to
* be freed.
* @return number of bytes actually freed.
*/
size_t freeMemoryIfPossible(size_t bytesToFree);
/**
* Defer any increments of owner counts until endAddingOwnersDeferral is called. So if an
* existing SkBitmap is inserted into the SkBitmapHeap, its corresponding SkBitmapHeapEntry will
* not have addReferences called on it, and the client does not need to make a corresponding
* call to releaseRef. Only meaningful if this SkBitmapHeap was created with an owner count not
* equal to IGNORE_OWNERS.
*/
void deferAddingOwners();
/**
* Resume adding references when duplicate SkBitmaps are inserted.
* @param add If true, add references to the SkBitmapHeapEntrys whose SkBitmaps were re-inserted
* while deferring.
*/
void endAddingOwnersDeferral(bool add);
private:
struct LookupEntry {
LookupEntry(const SkBitmap& bm)
: fGenerationId(bm.getGenerationID())
, fPixelOrigin(bm.pixelRefOrigin())
, fWidth(bm.width())
, fHeight(bm.height())
, fMoreRecentlyUsed(nullptr)
, fLessRecentlyUsed(nullptr){}
const uint32_t fGenerationId; // SkPixelRef GenerationID.
const SkIPoint fPixelOrigin;
const uint32_t fWidth;
const uint32_t fHeight;
// TODO: Generalize the LRU caching mechanism
LookupEntry* fMoreRecentlyUsed;
LookupEntry* fLessRecentlyUsed;
uint32_t fStorageSlot; // slot of corresponding bitmap in fStorage.
/**
* Compare two LookupEntry pointers for sorting and searching.
*/
static bool Less(const LookupEntry& a, const LookupEntry& b);
};
/**
* Remove the entry from the lookup table. Also deletes the entry pointed
* to by the table. Therefore, if a pointer to that one was passed in, the
* pointer should no longer be used, since the object to which it points has
* been deleted.
* @return The index in the lookup table of the entry before removal.
*/
int removeEntryFromLookupTable(LookupEntry*);
/**
* Searches for the bitmap in the lookup table and returns the bitmaps index within the table.
* If the bitmap was not already in the table it is added.
*
* @param key The key to search the lookup table, created from a bitmap.
* @param entry A pointer to a SkBitmapHeapEntry* that if non-null AND the bitmap is found
* in the lookup table is populated with the entry from the heap storage.
*/
int findInLookupTable(const LookupEntry& key, SkBitmapHeapEntry** entry);
LookupEntry* findEntryToReplace(const SkBitmap& replacement);
bool copyBitmap(const SkBitmap& originalBitmap, SkBitmap& copiedBitmap);
/**
* Remove a LookupEntry from the LRU, in preparation for either deleting or appending as most
* recent. Points the LookupEntry's old neighbors at each other, and sets fLeastRecentlyUsed
* (if there is still an entry left). Sets LookupEntry's fMoreRecentlyUsed to nullptr and leaves
* its fLessRecentlyUsed unmodified.
*/
void removeFromLRU(LookupEntry* entry);
/**
* Append a LookupEntry to the end of the LRU cache, marking it as the most
* recently used. Assumes that the LookupEntry is already in fLookupTable,
* but is not in the LRU cache. If it is in the cache, removeFromLRU should
* be called first.
*/
void appendToLRU(LookupEntry*);
// searchable index that maps to entries in the heap
SkTDArray<LookupEntry*> fLookupTable;
// heap storage
SkTDArray<SkBitmapHeapEntry*> fStorage;
// Used to mark slots in fStorage as deleted without actually deleting
// the slot so as not to mess up the numbering.
SkTDArray<int> fUnusedSlots;
ExternalStorage* fExternalStorage;
LookupEntry* fMostRecentlyUsed;
LookupEntry* fLeastRecentlyUsed;
const int32_t fPreferredCount;
const int32_t fOwnerCount;
size_t fBytesAllocated;
bool fDeferAddingOwners;
SkTDArray<int> fDeferredEntries;
typedef SkBitmapHeapReader INHERITED;
};
#endif // SkBitmapHeap_DEFINED

View File

@ -153,10 +153,6 @@ private:
bool parseBufferTag(SkReadBuffer&, uint32_t tag, uint32_t size);
void flattenToBuffer(SkWriteBuffer&) const;
// Only used by getBitmap() if the passed in index is SkBitmapHeap::INVALID_SLOT. This empty
// bitmap allows playback to draw nothing and move on.
SkBitmap fBadBitmap;
SkTArray<SkBitmap> fBitmaps;
SkTArray<SkPaint> fPaints;
SkTArray<SkPath> fPaths;

View File

@ -8,7 +8,6 @@
#define SkPictureFlat_DEFINED
#include "SkBitmapHeap.h"
#include "SkChecksum.h"
#include "SkChunkAlloc.h"
#include "SkReadBuffer.h"

View File

@ -27,7 +27,6 @@ SkReadBuffer::SkReadBuffer() {
fVersion = 0;
fMemoryPtr = nullptr;
fBitmapStorage = nullptr;
fTFArray = nullptr;
fTFCount = 0;
@ -45,7 +44,6 @@ SkReadBuffer::SkReadBuffer(const void* data, size_t size) {
fReader.setMemory(data, size);
fMemoryPtr = nullptr;
fBitmapStorage = nullptr;
fTFArray = nullptr;
fTFCount = 0;
@ -65,7 +63,6 @@ SkReadBuffer::SkReadBuffer(SkStream* stream) {
stream->read(fMemoryPtr, length);
fReader.setMemory(fMemoryPtr, length);
fBitmapStorage = nullptr;
fTFArray = nullptr;
fTFCount = 0;
@ -79,7 +76,6 @@ SkReadBuffer::SkReadBuffer(SkStream* stream) {
SkReadBuffer::~SkReadBuffer() {
sk_free(fMemoryPtr);
SkSafeUnref(fBitmapStorage);
}
bool SkReadBuffer::readBool() {
@ -186,25 +182,15 @@ uint32_t SkReadBuffer::getArrayCount() {
bool SkReadBuffer::readBitmap(SkBitmap* bitmap) {
const int width = this->readInt();
const int height = this->readInt();
// The writer stored a boolean value to determine whether an SkBitmapHeap was used during
// writing.
// writing. That feature is deprecated.
if (this->readBool()) {
// An SkBitmapHeap was used for writing. Read the index from the stream and find the
// corresponding SkBitmap in fBitmapStorage.
const uint32_t index = this->readUInt();
this->readUInt(); // bitmap generation ID (see SkWriteBuffer::writeBitmap)
if (fBitmapStorage) {
*bitmap = *fBitmapStorage->getBitmap(index);
fBitmapStorage->releaseRef(index);
return true;
} else {
// The bitmap was stored in a heap, but there is no way to access it. Set an error and
// fall through to use a place holder bitmap.
SkErrorInternals::SetError(kParseError_SkError, "SkWriteBuffer::writeBitmap "
"stored the SkBitmap in an SkBitmapHeap, but "
"SkReadBuffer has no SkBitmapHeapReader to "
"retrieve the SkBitmap.");
}
this->readUInt(); // Bitmap index
this->readUInt(); // Bitmap generation ID
SkErrorInternals::SetError(kParseError_SkError, "SkWriteBuffer::writeBitmap "
"stored the SkBitmap in an SkBitmapHeap, but "
"that feature is no longer supported.");
} else {
// The writer stored false, meaning the SkBitmap was not stored in an SkBitmapHeap.
const size_t length = this->readUInt();

View File

@ -8,7 +8,6 @@
#ifndef SkReadBuffer_DEFINED
#define SkReadBuffer_DEFINED
#include "SkBitmapHeap.h"
#include "SkColorFilter.h"
#include "SkData.h"
#include "SkDrawLooper.h"
@ -176,10 +175,6 @@ public:
virtual SkTypeface* readTypeface();
void setBitmapStorage(SkBitmapHeapReader* bitmapStorage) {
SkRefCnt_SafeAssign(fBitmapStorage, bitmapStorage);
}
void setTypefaceArray(SkTypeface* array[], int count) {
fTFArray = array;
fTFCount = count;
@ -255,7 +250,6 @@ private:
void* fMemoryPtr;
SkBitmapHeapReader* fBitmapStorage;
SkTypeface** fTFArray;
int fTFCount;

View File

@ -9,7 +9,6 @@
#define SkValidatingReadBuffer_DEFINED
#include "SkRefCnt.h"
#include "SkBitmapHeap.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
#include "SkPath.h"

View File

@ -7,7 +7,6 @@
#include "SkWriteBuffer.h"
#include "SkBitmap.h"
#include "SkBitmapHeap.h"
#include "SkData.h"
#include "SkPixelRef.h"
#include "SkPtrRecorder.h"
@ -17,7 +16,6 @@
SkWriteBuffer::SkWriteBuffer(uint32_t flags)
: fFlags(flags)
, fFactorySet(nullptr)
, fBitmapHeap(nullptr)
, fTFSet(nullptr) {
}
@ -25,13 +23,11 @@ SkWriteBuffer::SkWriteBuffer(void* storage, size_t storageSize, uint32_t flags)
: fFlags(flags)
, fFactorySet(nullptr)
, fWriter(storage, storageSize)
, fBitmapHeap(nullptr)
, fTFSet(nullptr) {
}
SkWriteBuffer::~SkWriteBuffer() {
SkSafeUnref(fFactorySet);
SkSafeUnref(fBitmapHeap);
SkSafeUnref(fTFSet);
}
@ -139,32 +135,15 @@ void SkWriteBuffer::writeBitmap(const SkBitmap& bitmap) {
this->writeInt(bitmap.width());
this->writeInt(bitmap.height());
// Record information about the bitmap in one of three ways, in order of priority:
// 1. If there is an SkBitmapHeap, store it in the heap. The client can avoid serializing the
// bitmap entirely or serialize it later as desired. A boolean value of true will be written
// to the stream to signify that a heap was used.
// 2. If there is a function for encoding bitmaps, use it to write an encoded version of the
// Record information about the bitmap in one of two ways, in order of priority:
// 1. If there is a function for encoding bitmaps, use it to write an encoded version of the
// bitmap. After writing a boolean value of false, signifying that a heap was not used, write
// the size of the encoded data. A non-zero size signifies that encoded data was written.
// 3. Call SkBitmap::flatten. After writing a boolean value of false, signifying that a heap was
// 2. Call SkBitmap::flatten. After writing a boolean value of false, signifying that a heap was
// not used, write a zero to signify that the data was not encoded.
bool useBitmapHeap = fBitmapHeap != nullptr;
// Write a bool: true if the SkBitmapHeap is to be used, in which case the reader must use an
// SkBitmapHeapReader to read the SkBitmap. False if the bitmap was serialized another way.
this->writeBool(useBitmapHeap);
if (useBitmapHeap) {
SkASSERT(nullptr == fPixelSerializer);
int32_t slot = fBitmapHeap->insert(bitmap);
fWriter.write32(slot);
// crbug.com/155875
// The generation ID is not required information. We write it to prevent collisions
// in SkFlatDictionary. It is possible to get a collision when a previously
// unflattened (i.e. stale) instance of a similar flattenable is in the dictionary
// and the instance currently being written is re-using the same slot from the
// bitmap heap.
fWriter.write32(bitmap.getGenerationID());
return;
}
// Write a bool to indicate that we did not use an SkBitmapHeap. That feature is deprecated.
this->writeBool(false);
SkPixelRef* pixelRef = bitmap.pixelRef();
if (pixelRef) {
@ -183,7 +162,6 @@ void SkWriteBuffer::writeBitmap(const SkBitmap& bitmap) {
// see if the caller wants to manually encode
SkAutoPixmapUnlock result;
if (fPixelSerializer && bitmap.requestLock(&result)) {
SkASSERT(nullptr == fBitmapHeap);
SkAutoDataUnref data(fPixelSerializer->encode(result.pixmap()));
if (data.get() != nullptr) {
// if we have to "encode" the bitmap, then we assume there is no
@ -229,21 +207,10 @@ SkRefCntSet* SkWriteBuffer::setTypefaceRecorder(SkRefCntSet* rec) {
return rec;
}
void SkWriteBuffer::setBitmapHeap(SkBitmapHeap* bitmapHeap) {
SkRefCnt_SafeAssign(fBitmapHeap, bitmapHeap);
if (bitmapHeap != nullptr) {
SkASSERT(nullptr == fPixelSerializer);
fPixelSerializer.reset(nullptr);
}
}
void SkWriteBuffer::setPixelSerializer(SkPixelSerializer* serializer) {
fPixelSerializer.reset(serializer);
if (serializer) {
serializer->ref();
SkASSERT(nullptr == fBitmapHeap);
SkSafeUnref(fBitmapHeap);
fBitmapHeap = nullptr;
}
}