2012-11-16 20:34:37 +00:00
|
|
|
/*
|
|
|
|
* 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 "SkBitmap.h"
|
|
|
|
#include "SkBitmapHeap.h"
|
|
|
|
#include "SkColor.h"
|
|
|
|
#include "SkFlattenable.h"
|
2014-01-30 18:58:24 +00:00
|
|
|
#include "SkWriteBuffer.h"
|
2012-11-16 20:34:37 +00:00
|
|
|
#include "SkPictureFlat.h"
|
|
|
|
#include "SkRefCnt.h"
|
|
|
|
#include "SkShader.h"
|
|
|
|
#include "Test.h"
|
|
|
|
|
2014-11-12 17:19:02 +00:00
|
|
|
struct SimpleFlatController : public SkFlatController {
|
|
|
|
SimpleFlatController() : SkFlatController() {}
|
2014-11-12 18:09:10 +00:00
|
|
|
~SimpleFlatController() { fAllocations.freeAll(); }
|
2015-01-09 18:06:39 +00:00
|
|
|
void* allocThrow(size_t bytes) SK_OVERRIDE {
|
2014-11-12 18:09:10 +00:00
|
|
|
fAllocations.push(sk_malloc_throw(bytes));
|
|
|
|
return fAllocations.top();
|
|
|
|
}
|
2015-01-09 18:06:39 +00:00
|
|
|
void unalloc(void*) SK_OVERRIDE { }
|
2014-11-12 17:19:02 +00:00
|
|
|
void setBitmapStorage(SkBitmapHeap* h) { this->setBitmapHeap(h); }
|
2014-11-12 18:09:10 +00:00
|
|
|
private:
|
|
|
|
SkTDArray<void*> fAllocations;
|
2014-11-12 17:19:02 +00:00
|
|
|
};
|
|
|
|
|
2014-01-02 22:20:49 +00:00
|
|
|
struct SkShaderTraits {
|
2014-02-18 16:15:05 +00:00
|
|
|
static void Flatten(SkWriteBuffer& buffer, const SkShader& shader) {
|
2014-01-02 22:20:49 +00:00
|
|
|
buffer.writeFlattenable(&shader);
|
2012-11-16 20:34:37 +00:00
|
|
|
}
|
|
|
|
};
|
2014-01-02 22:20:49 +00:00
|
|
|
typedef SkFlatDictionary<SkShader, SkShaderTraits> FlatDictionary;
|
2012-11-16 20:34:37 +00:00
|
|
|
|
|
|
|
class SkBitmapHeapTester {
|
|
|
|
public:
|
|
|
|
static int32_t GetRefCount(const SkBitmapHeapEntry* entry) {
|
|
|
|
return entry->fRefCount;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-12-12 21:11:12 +00:00
|
|
|
DEF_TEST(BitmapHeap, reporter) {
|
2012-11-16 20:34:37 +00:00
|
|
|
// Create a bitmap shader.
|
|
|
|
SkBitmap bm;
|
2014-02-13 22:00:04 +00:00
|
|
|
bm.allocN32Pixels(2, 2);
|
2012-11-16 20:34:37 +00:00
|
|
|
bm.eraseColor(SK_ColorRED);
|
|
|
|
uint32_t* pixel = bm.getAddr32(1,0);
|
|
|
|
*pixel = SK_ColorBLUE;
|
|
|
|
|
|
|
|
SkShader* bitmapShader = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
|
|
|
|
SkShader::kRepeat_TileMode);
|
|
|
|
SkAutoTUnref<SkShader> aur(bitmapShader);
|
|
|
|
|
|
|
|
// Flatten, storing it in the bitmap heap.
|
|
|
|
SkBitmapHeap heap(1, 1);
|
2014-11-12 17:19:02 +00:00
|
|
|
SimpleFlatController controller;
|
2012-11-16 20:34:37 +00:00
|
|
|
controller.setBitmapStorage(&heap);
|
|
|
|
FlatDictionary dictionary(&controller);
|
|
|
|
|
|
|
|
// Dictionary and heap start off empty.
|
|
|
|
REPORTER_ASSERT(reporter, heap.count() == 0);
|
|
|
|
REPORTER_ASSERT(reporter, dictionary.count() == 0);
|
|
|
|
|
|
|
|
heap.deferAddingOwners();
|
|
|
|
int index = dictionary.find(*bitmapShader);
|
|
|
|
heap.endAddingOwnersDeferral(true);
|
|
|
|
|
|
|
|
// The dictionary and heap should now each have one entry.
|
|
|
|
REPORTER_ASSERT(reporter, 1 == index);
|
|
|
|
REPORTER_ASSERT(reporter, heap.count() == 1);
|
|
|
|
REPORTER_ASSERT(reporter, dictionary.count() == 1);
|
|
|
|
|
|
|
|
// The bitmap entry's refcount should be 1, then 0 after release.
|
|
|
|
SkBitmapHeapEntry* entry = heap.getEntry(0);
|
|
|
|
REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 1);
|
|
|
|
|
|
|
|
entry->releaseRef();
|
|
|
|
REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 0);
|
|
|
|
|
|
|
|
// Now clear out the heap, after which it should be empty.
|
|
|
|
heap.freeMemoryIfPossible(~0U);
|
|
|
|
REPORTER_ASSERT(reporter, heap.count() == 0);
|
|
|
|
|
|
|
|
// Now attempt to flatten the shader again.
|
|
|
|
heap.deferAddingOwners();
|
|
|
|
index = dictionary.find(*bitmapShader);
|
|
|
|
heap.endAddingOwnersDeferral(false);
|
|
|
|
|
|
|
|
// The dictionary should report the same index since the new entry is identical.
|
|
|
|
// The bitmap heap should contain the bitmap, but with no references.
|
|
|
|
REPORTER_ASSERT(reporter, 1 == index);
|
|
|
|
REPORTER_ASSERT(reporter, heap.count() == 1);
|
|
|
|
REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(heap.getEntry(0)) == 0);
|
|
|
|
}
|