Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / tests / SkResourceCacheTest.cpp
1 /*
2  * Copyright 2014 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 "Test.h"
9 #include "SkBitmapCache.h"
10 #include "SkCanvas.h"
11 #include "SkDiscardableMemoryPool.h"
12 #include "SkGraphics.h"
13 #include "SkResourceCache.h"
14
15 static const int kCanvasSize = 1;
16 static const int kBitmapSize = 16;
17 static const int kScale = 8;
18
19 static bool is_in_scaled_image_cache(const SkBitmap& orig,
20                                      SkScalar xScale,
21                                      SkScalar yScale) {
22     SkBitmap scaled;
23     float roundedImageWidth = SkScalarRoundToScalar(orig.width() * xScale);
24     float roundedImageHeight = SkScalarRoundToScalar(orig.height() * xScale);
25     return SkBitmapCache::Find(orig, roundedImageWidth, roundedImageHeight, &scaled);
26 }
27
28 // Draw a scaled bitmap, then return true iff it has been cached.
29 static bool test_scaled_image_cache_useage() {
30     SkAutoTUnref<SkCanvas> canvas(
31             SkCanvas::NewRasterN32(kCanvasSize, kCanvasSize));
32     SkBitmap bitmap;
33     bitmap.allocN32Pixels(kBitmapSize, kBitmapSize);
34     bitmap.eraseColor(0xFFFFFFFF);
35     SkScalar scale = SkIntToScalar(kScale);
36     SkScalar scaledSize = SkIntToScalar(kBitmapSize) * scale;
37     canvas->clipRect(SkRect::MakeLTRB(0, 0, scaledSize, scaledSize));
38     SkPaint paint;
39     paint.setFilterLevel(SkPaint::kHigh_FilterLevel);
40
41     canvas->drawBitmapRect(bitmap,
42                            SkRect::MakeLTRB(0, 0, scaledSize, scaledSize),
43                            &paint);
44
45     return is_in_scaled_image_cache(bitmap, scale, scale);
46 }
47
48 // http://crbug.com/389439
49 DEF_TEST(ResourceCache_SingleAllocationByteLimit, reporter) {
50     size_t originalByteLimit = SkGraphics::GetResourceCacheTotalByteLimit();
51     size_t originalAllocationLimit =
52         SkGraphics::GetResourceCacheSingleAllocationByteLimit();
53
54     size_t size = kBitmapSize * kScale * kBitmapSize * kScale
55         * SkColorTypeBytesPerPixel(kN32_SkColorType);
56
57     SkGraphics::SetResourceCacheTotalByteLimit(0);  // clear cache
58     SkGraphics::SetResourceCacheTotalByteLimit(2 * size);
59     SkGraphics::SetResourceCacheSingleAllocationByteLimit(0);  // No limit
60
61     REPORTER_ASSERT(reporter, test_scaled_image_cache_useage());
62
63     SkGraphics::SetResourceCacheTotalByteLimit(0);  // clear cache
64     SkGraphics::SetResourceCacheTotalByteLimit(2 * size);
65     SkGraphics::SetResourceCacheSingleAllocationByteLimit(size * 2);  // big enough
66
67     REPORTER_ASSERT(reporter, test_scaled_image_cache_useage());
68
69     SkGraphics::SetResourceCacheTotalByteLimit(0);  // clear cache
70     SkGraphics::SetResourceCacheTotalByteLimit(2 * size);
71     SkGraphics::SetResourceCacheSingleAllocationByteLimit(size / 2);  // too small
72
73     REPORTER_ASSERT(reporter, !test_scaled_image_cache_useage());
74
75     SkGraphics::SetResourceCacheSingleAllocationByteLimit(originalAllocationLimit);
76     SkGraphics::SetResourceCacheTotalByteLimit(originalByteLimit);
77 }
78
79 ////////////////////////////////////////////////////////////////////////////////////////
80
81 static void make_bitmap(SkBitmap* bitmap, const SkImageInfo& info, SkBitmap::Allocator* allocator) {
82     if (allocator) {
83         bitmap->setInfo(info);
84         allocator->allocPixelRef(bitmap, 0);
85     } else {
86         bitmap->allocPixels(info);
87     }
88 }
89
90 // http://skbug.com/2894
91 DEF_TEST(BitmapCache_add_rect, reporter) {
92     SkResourceCache::DiscardableFactory factory = SkResourceCache::GetDiscardableFactory();
93     SkBitmap::Allocator* allocator = SkBitmapCache::GetAllocator();
94
95     SkAutoTDelete<SkResourceCache> cache;
96     if (factory) {
97         cache.reset(SkNEW_ARGS(SkResourceCache, (factory)));
98     } else {
99         const size_t byteLimit = 100 * 1024;
100         cache.reset(SkNEW_ARGS(SkResourceCache, (byteLimit)));
101     }
102     SkBitmap cachedBitmap;
103     make_bitmap(&cachedBitmap, SkImageInfo::MakeN32Premul(5, 5), allocator);
104     cachedBitmap.setImmutable();
105
106     SkBitmap bm;
107     SkIRect rect = SkIRect::MakeWH(5, 5);
108
109     // Wrong subset size
110     REPORTER_ASSERT(reporter, !SkBitmapCache::Add(cachedBitmap.getGenerationID(), SkIRect::MakeWH(4, 6), cachedBitmap, cache));
111     REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
112     // Wrong offset value
113     REPORTER_ASSERT(reporter, !SkBitmapCache::Add(cachedBitmap.getGenerationID(), SkIRect::MakeXYWH(-1, 0, 5, 5), cachedBitmap, cache));
114     REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
115
116     // Should not be in the cache
117     REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
118
119     REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.getGenerationID(), rect, cachedBitmap, cache));
120     // Should be in the cache, we just added it
121     REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
122 }
123
124 #include "SkMipMap.h"
125
126 enum LockedState {
127     kNotLocked,
128     kLocked,
129 };
130
131 enum CachedState {
132     kNotInCache,
133     kInCache,
134 };
135
136 static void check_data(skiatest::Reporter* reporter, const SkCachedData* data,
137                        int refcnt, CachedState cacheState, LockedState lockedState) {
138     REPORTER_ASSERT(reporter, data->testing_only_getRefCnt() == refcnt);
139     REPORTER_ASSERT(reporter, data->testing_only_isInCache() == (kInCache == cacheState));
140     bool isLocked = (data->data() != NULL);
141     REPORTER_ASSERT(reporter, isLocked == (lockedState == kLocked));
142 }
143
144 static void test_mipmapcache(skiatest::Reporter* reporter, SkResourceCache* cache) {
145     cache->purgeAll();
146
147     SkBitmap src;
148     src.allocN32Pixels(5, 5);
149     src.setImmutable();
150
151     const SkMipMap* mipmap = SkMipMapCache::FindAndRef(src, cache);
152     REPORTER_ASSERT(reporter, NULL == mipmap);
153
154     mipmap = SkMipMapCache::AddAndRef(src, cache);
155     REPORTER_ASSERT(reporter, mipmap);
156     check_data(reporter, mipmap, 2, kInCache, kLocked);
157
158     mipmap->unref();
159     // tricky, since technically after this I'm no longer an owner, but since the cache is
160     // local, I know it won't get purged behind my back
161     check_data(reporter, mipmap, 1, kInCache, kNotLocked);
162
163     // find us again
164     mipmap = SkMipMapCache::FindAndRef(src, cache);
165     check_data(reporter, mipmap, 2, kInCache, kLocked);
166
167     cache->purgeAll();
168     check_data(reporter, mipmap, 1, kNotInCache, kLocked);
169
170     mipmap->unref();
171 }
172
173 DEF_TEST(BitmapCache_discarded_bitmap, reporter) {
174     SkResourceCache::DiscardableFactory factory = SkResourceCache::GetDiscardableFactory();
175     SkBitmap::Allocator* allocator = SkBitmapCache::GetAllocator();
176     
177     SkAutoTDelete<SkResourceCache> cache;
178     if (factory) {
179         cache.reset(SkNEW_ARGS(SkResourceCache, (factory)));
180     } else {
181         const size_t byteLimit = 100 * 1024;
182         cache.reset(SkNEW_ARGS(SkResourceCache, (byteLimit)));
183     }
184     SkBitmap cachedBitmap;
185     make_bitmap(&cachedBitmap, SkImageInfo::MakeN32Premul(5, 5), allocator);
186     cachedBitmap.setImmutable();
187     cachedBitmap.unlockPixels();
188
189     SkBitmap bm;
190     SkIRect rect = SkIRect::MakeWH(5, 5);
191
192     // Add a bitmap to the cache.
193     REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.getGenerationID(), rect, cachedBitmap, cache));
194     REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
195
196     // Finding more than once works fine.
197     REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
198     bm.unlockPixels();
199
200     // Drop the pixels in the bitmap.
201     if (factory) {
202         REPORTER_ASSERT(reporter, SkGetGlobalDiscardableMemoryPool()->getRAMUsed() > 0);
203         SkGetGlobalDiscardableMemoryPool()->dumpPool();
204         REPORTER_ASSERT(reporter, SkGetGlobalDiscardableMemoryPool()->getRAMUsed() == 0);
205
206         // The bitmap is not in the cache since it has been dropped.
207         REPORTER_ASSERT(reporter, !SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
208     }
209
210     make_bitmap(&cachedBitmap, SkImageInfo::MakeN32Premul(5, 5), allocator);
211     cachedBitmap.setImmutable();
212     cachedBitmap.unlockPixels();
213
214     // We can add the bitmap back to the cache and find it again.
215     REPORTER_ASSERT(reporter, SkBitmapCache::Add(cachedBitmap.getGenerationID(), rect, cachedBitmap, cache));
216     REPORTER_ASSERT(reporter, SkBitmapCache::Find(cachedBitmap.getGenerationID(), rect, &bm, cache));
217
218     test_mipmapcache(reporter, cache);
219 }