Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2012 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkBitmap.h"
      9 #include "SkBitmapHeap.h"
     10 #include "SkColor.h"
     11 #include "SkFlattenable.h"
     12 #include "SkWriteBuffer.h"
     13 #include "SkPictureFlat.h"
     14 #include "SkRefCnt.h"
     15 #include "SkShader.h"
     16 #include "Test.h"
     17 
     18 struct SimpleFlatController : public SkFlatController {
     19     SimpleFlatController() : SkFlatController() {}
     20     ~SimpleFlatController() { fAllocations.freeAll(); }
     21     void* allocThrow(size_t bytes) override {
     22         fAllocations.push(sk_malloc_throw(bytes));
     23         return fAllocations.top();
     24     }
     25     void unalloc(void*) override { }
     26     void setBitmapStorage(SkBitmapHeap* h) { this->setBitmapHeap(h); }
     27 private:
     28     SkTDArray<void*> fAllocations;
     29 };
     30 
     31 struct SkShaderTraits {
     32     static void Flatten(SkWriteBuffer& buffer, const SkShader& shader) {
     33         buffer.writeFlattenable(&shader);
     34     }
     35 };
     36 typedef SkFlatDictionary<SkShader, SkShaderTraits> FlatDictionary;
     37 
     38 class SkBitmapHeapTester {
     39 public:
     40     static int32_t GetRefCount(const SkBitmapHeapEntry* entry) {
     41         return entry->fRefCount;
     42     }
     43 };
     44 
     45 DEF_TEST(BitmapHeap, reporter) {
     46     // Create a bitmap shader.
     47     SkBitmap bm;
     48     bm.allocN32Pixels(2, 2);
     49     bm.eraseColor(SK_ColorRED);
     50     uint32_t* pixel = bm.getAddr32(1,0);
     51     *pixel = SK_ColorBLUE;
     52 
     53     SkShader* bitmapShader = SkShader::CreateBitmapShader(bm, SkShader::kRepeat_TileMode,
     54                                                           SkShader::kRepeat_TileMode);
     55     SkAutoTUnref<SkShader> aur(bitmapShader);
     56 
     57     // Flatten, storing it in the bitmap heap.
     58     SkBitmapHeap heap(1, 1);
     59     SimpleFlatController controller;
     60     controller.setBitmapStorage(&heap);
     61     FlatDictionary dictionary(&controller);
     62 
     63     // Dictionary and heap start off empty.
     64     REPORTER_ASSERT(reporter, heap.count() == 0);
     65     REPORTER_ASSERT(reporter, dictionary.count() == 0);
     66 
     67     heap.deferAddingOwners();
     68     int index = dictionary.find(*bitmapShader);
     69     heap.endAddingOwnersDeferral(true);
     70 
     71     // The dictionary and heap should now each have one entry.
     72     REPORTER_ASSERT(reporter, 1 == index);
     73     REPORTER_ASSERT(reporter, heap.count() == 1);
     74     REPORTER_ASSERT(reporter, dictionary.count() == 1);
     75 
     76     // The bitmap entry's refcount should be 1, then 0 after release.
     77     SkBitmapHeapEntry* entry = heap.getEntry(0);
     78     REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 1);
     79 
     80     entry->releaseRef();
     81     REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(entry) == 0);
     82 
     83     // Now clear out the heap, after which it should be empty.
     84     heap.freeMemoryIfPossible(~0U);
     85     REPORTER_ASSERT(reporter, heap.count() == 0);
     86 
     87     // Now attempt to flatten the shader again.
     88     heap.deferAddingOwners();
     89     index = dictionary.find(*bitmapShader);
     90     heap.endAddingOwnersDeferral(false);
     91 
     92     // The dictionary should report the same index since the new entry is identical.
     93     // The bitmap heap should contain the bitmap, but with no references.
     94     REPORTER_ASSERT(reporter, 1 == index);
     95     REPORTER_ASSERT(reporter, heap.count() == 1);
     96     REPORTER_ASSERT(reporter, SkBitmapHeapTester::GetRefCount(heap.getEntry(0)) == 0);
     97 }
     98