Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / tests / GpuLayerCacheTest.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 #if SK_SUPPORT_GPU
9
10 #include "GrContext.h"
11 #include "GrContextFactory.h"
12 #include "GrLayerCache.h"
13 #include "SkPictureRecorder.h"
14 #include "Test.h"
15
16 class TestingAccess {
17 public:
18     static int NumLayers(GrLayerCache* cache) {
19         return cache->numLayers();
20     }
21     static void Purge(GrLayerCache* cache, uint32_t pictureID) {
22         cache->purge(pictureID);
23     }
24     static int Uses(GrCachedLayer* layer) {
25         return layer->uses();
26     }
27 };
28
29 // Add several layers to the cache
30 static void create_layers(skiatest::Reporter* reporter,
31                           GrLayerCache* cache,
32                           const SkPicture& picture,
33                           int numToAdd,
34                           int idOffset) {
35
36     for (int i = 0; i < numToAdd; ++i) {
37         GrCachedLayer* layer = cache->findLayerOrCreate(picture.uniqueID(), 
38                                                         idOffset+i+1, idOffset+i+2, 
39                                                         SkIRect::MakeEmpty(),
40                                                         SkMatrix::I(),
41                                                         NULL);
42         REPORTER_ASSERT(reporter, layer);
43         GrCachedLayer* temp = cache->findLayer(picture.uniqueID(), idOffset + i + 1,
44                                                SkIRect::MakeEmpty(), SkMatrix::I());
45         REPORTER_ASSERT(reporter, temp == layer);
46
47         REPORTER_ASSERT(reporter, TestingAccess::NumLayers(cache) == idOffset + i + 1);
48
49         REPORTER_ASSERT(reporter, picture.uniqueID() == layer->pictureID());
50         REPORTER_ASSERT(reporter, layer->start() == idOffset + i + 1);
51         REPORTER_ASSERT(reporter, layer->stop() == idOffset + i + 2);
52         REPORTER_ASSERT(reporter, NULL == layer->texture());
53         REPORTER_ASSERT(reporter, NULL == layer->paint());
54         REPORTER_ASSERT(reporter, !layer->isAtlased());
55     }
56
57     cache->trackPicture(&picture);
58 }
59
60 static void lock_layer(skiatest::Reporter* reporter,
61                        GrLayerCache* cache,
62                        GrCachedLayer* layer) {
63     // Make the layer 512x512 (so it can be atlased)
64     GrSurfaceDesc desc;
65     desc.fWidth = 512;
66     desc.fHeight = 512;
67     desc.fConfig = kSkia8888_GrPixelConfig;
68
69     bool needsRerendering;
70     bool inAtlas = cache->tryToAtlas(layer, desc, &needsRerendering);
71     if (!inAtlas) {
72         cache->lock(layer, desc, &needsRerendering);
73     }
74     REPORTER_ASSERT(reporter, needsRerendering);
75
76     cache->lock(layer, desc, &needsRerendering);
77     REPORTER_ASSERT(reporter, !needsRerendering);
78
79     REPORTER_ASSERT(reporter, layer->texture());
80     REPORTER_ASSERT(reporter, layer->locked());
81
82     cache->addUse(layer);
83
84     REPORTER_ASSERT(reporter, 1 == TestingAccess::Uses(layer));
85 }
86
87 // This test case exercises the public API of the GrLayerCache class.
88 // In particular it checks its interaction with the resource cache (w.r.t.
89 // locking & unlocking textures).
90 // TODO: need to add checks on VRAM usage!
91 DEF_GPUTEST(GpuLayerCache, reporter, factory) {
92     static const int kInitialNumLayers = 5;
93
94     for (int i= 0; i < GrContextFactory::kGLContextTypeCnt; ++i) {
95         GrContextFactory::GLContextType glCtxType = (GrContextFactory::GLContextType) i;
96
97         if (!GrContextFactory::IsRenderingGLContext(glCtxType)) {
98             continue;
99         }
100
101         GrContext* context = factory->get(glCtxType);
102
103         if (NULL == context) {
104             continue;
105         }
106
107         SkPictureRecorder recorder;
108         recorder.beginRecording(1, 1);
109         SkAutoTUnref<const SkPicture> picture(recorder.endRecording());
110
111         GrLayerCache cache(context);
112
113         create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
114
115         for (int i = 0; i < kInitialNumLayers; ++i) {
116             GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, 
117                                                    SkIRect::MakeEmpty(), SkMatrix::I());
118             REPORTER_ASSERT(reporter, layer);
119
120             lock_layer(reporter, &cache, layer);
121
122             // The first 4 layers should be in the atlas (and thus have non-empty
123             // rects)
124             if (i < 4) {
125                 REPORTER_ASSERT(reporter, layer->isAtlased());
126             } else {
127                 // The 5th layer couldn't fit in the atlas
128                 REPORTER_ASSERT(reporter, !layer->isAtlased());
129             }
130         }
131
132         // Unlock the textures
133         for (int i = 0; i < kInitialNumLayers; ++i) {
134             GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, 
135                                                    SkIRect::MakeEmpty(), SkMatrix::I());
136             REPORTER_ASSERT(reporter, layer);
137             cache.removeUse(layer);
138         }
139
140         for (int i = 0; i < kInitialNumLayers; ++i) {
141             GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i+1, 
142                                                    SkIRect::MakeEmpty(), SkMatrix::I());
143             REPORTER_ASSERT(reporter, layer);
144
145             // All the layers should be unlocked
146             REPORTER_ASSERT(reporter, !layer->locked());
147
148             // When hoisted layers aren't cached they are aggressively removed
149             // from the atlas
150 #if GR_CACHE_HOISTED_LAYERS
151             // The first 4 layers should still be in the atlas.
152             if (i < 4) {
153                 REPORTER_ASSERT(reporter, layer->texture());
154                 REPORTER_ASSERT(reporter, layer->isAtlased());
155             } else {
156 #endif
157                 // The final layer should not be atlased.
158                 REPORTER_ASSERT(reporter, NULL == layer->texture());
159                 REPORTER_ASSERT(reporter, !layer->isAtlased());
160 #if GR_CACHE_HOISTED_LAYERS
161             }
162 #endif
163         }
164
165         {
166             // Add an additional layer. Since all the layers are unlocked this 
167             // will force out the first atlased layer
168             create_layers(reporter, &cache, *picture, 1, kInitialNumLayers);
169             GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), 
170                                                    kInitialNumLayers+1, 
171                                                    SkIRect::MakeEmpty(), SkMatrix::I());
172             REPORTER_ASSERT(reporter, layer);
173
174             lock_layer(reporter, &cache, layer);
175             cache.removeUse(layer);
176         }
177
178         for (int i = 0; i < kInitialNumLayers+1; ++i) {
179             GrCachedLayer* layer = cache.findLayer(picture->uniqueID(), i + 1,
180                                                    SkIRect::MakeEmpty(), SkMatrix::I());
181 #if GR_CACHE_HOISTED_LAYERS
182             // 3 old layers plus the new one should be in the atlas.
183             if (1 == i || 2 == i || 3 == i || 5 == i) {
184                 REPORTER_ASSERT(reporter, layer);
185                 REPORTER_ASSERT(reporter, !layer->locked());
186                 REPORTER_ASSERT(reporter, layer->texture());
187                 REPORTER_ASSERT(reporter, layer->isAtlased());
188             } else if (4 == i) {
189 #endif
190                 // The one that was never atlased should still be around
191                 REPORTER_ASSERT(reporter, layer);
192
193                 REPORTER_ASSERT(reporter, NULL == layer->texture());
194                 REPORTER_ASSERT(reporter, !layer->isAtlased());
195 #if GR_CACHE_HOISTED_LAYERS
196             } else {
197                 // The one bumped out of the atlas (i.e., 0) should be gone
198                 REPORTER_ASSERT(reporter, NULL == layer);
199             }
200 #endif
201         }
202
203         //--------------------------------------------------------------------
204         // Free them all SkGpuDevice-style. This will not free up the
205         // atlas' texture but will eliminate all the layers.
206         TestingAccess::Purge(&cache, picture->uniqueID());
207
208         REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
209         // TODO: add VRAM/resource cache check here
210
211         //--------------------------------------------------------------------
212         // Test out the GrContext-style purge. This should remove all the layers
213         // and the atlas.
214         // Re-create the layers
215         create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
216
217         // Free them again GrContext-style. This should free up everything.
218         cache.freeAll();
219
220         REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
221         // TODO: add VRAM/resource cache check here
222
223         //--------------------------------------------------------------------
224         // Test out the MessageBus-style purge. This will not free the atlas
225         // but should eliminate the free-floating layers.
226         create_layers(reporter, &cache, *picture, kInitialNumLayers, 0);
227
228         picture.reset(NULL);
229         cache.processDeletedPictures();
230
231         REPORTER_ASSERT(reporter, TestingAccess::NumLayers(&cache) == 0);
232         // TODO: add VRAM/resource cache check here
233     }
234 }
235
236 #endif