[chromium] Respect memory needed for RenderSurfaces when reserving contents textures
[WebKit-https.git] / Source / WebKit / chromium / tests / CCPrioritizedTextureTest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "cc/CCPrioritizedTexture.h"
28
29 #include "CCTiledLayerTestCommon.h"
30 #include "cc/CCPrioritizedTextureManager.h"
31 #include <gtest/gtest.h>
32
33 using namespace WebCore;
34 using namespace WebKitTests;
35 using namespace WTF;
36
37 namespace {
38
39 class CCPrioritizedTextureTest : public testing::Test {
40 public:
41     CCPrioritizedTextureTest()
42         : m_textureSize(256, 256)
43         , m_textureFormat(GraphicsContext3D::RGBA)
44     {
45     }
46
47     virtual ~CCPrioritizedTextureTest()
48     {
49     }
50
51     size_t texturesMemorySize(size_t textureCount)
52     {
53         return TextureManager::memoryUseBytes(m_textureSize, m_textureFormat) * textureCount;
54     }
55
56     PassOwnPtr<CCPrioritizedTextureManager> createManager(size_t maxTextures)
57     {
58         return CCPrioritizedTextureManager::create(texturesMemorySize(maxTextures), 1024);
59     }
60
61     bool validateTexture(OwnPtr<CCPrioritizedTexture>& texture, bool requestLate)
62     {
63 #if !ASSERT_DISABLED
64         texture->textureManager()->assertInvariants();
65 #endif
66         if (requestLate)
67             texture->requestLate();
68         bool success = texture->canAcquireBackingTexture();
69         if (success)
70             texture->acquireBackingTexture(allocator());
71         return success;
72     }
73
74     FakeTextureAllocator* allocator()
75     {
76        return &m_fakeTextureAllocator;
77     }
78
79 protected:
80     FakeTextureAllocator m_fakeTextureAllocator;
81     const IntSize m_textureSize;
82     const GC3Denum m_textureFormat;
83 };
84
85 TEST_F(CCPrioritizedTextureTest, requestTextureExceedingMaxLimit)
86 {
87     const size_t maxTextures = 8;
88     OwnPtr<CCPrioritizedTextureManager> textureManager = createManager(maxTextures);
89
90     // Create textures for double our memory limit.
91     OwnPtr<CCPrioritizedTexture> textures[maxTextures*2];
92
93     for (size_t i = 0; i < maxTextures*2; ++i)
94         textures[i] = textureManager->createTexture(m_textureSize, m_textureFormat);
95
96     // Set decreasing priorities
97     for (size_t i = 0; i < maxTextures*2; ++i)
98         textures[i]->setRequestPriority(100 + i);
99
100     // Only lower half should be available.
101     textureManager->prioritizeTextures(0);
102     EXPECT_TRUE(validateTexture(textures[0], false));
103     EXPECT_TRUE(validateTexture(textures[7], false));
104     EXPECT_FALSE(validateTexture(textures[8], false));
105     EXPECT_FALSE(validateTexture(textures[15], false));
106
107     // Set increasing priorities
108     for (size_t i = 0; i < maxTextures*2; ++i)
109         textures[i]->setRequestPriority(100 - i);
110
111     // Only upper half should be available.
112     textureManager->prioritizeTextures(0);
113     EXPECT_FALSE(validateTexture(textures[0], false));
114     EXPECT_FALSE(validateTexture(textures[7], false));
115     EXPECT_TRUE(validateTexture(textures[8], false));
116     EXPECT_TRUE(validateTexture(textures[15], false));
117
118     EXPECT_EQ(texturesMemorySize(maxTextures), textureManager->memoryAboveCutoffBytes());
119     EXPECT_LE(textureManager->memoryUseBytes(), textureManager->memoryAboveCutoffBytes());
120
121     textureManager->clearAllMemory(allocator());
122 }
123
124 TEST_F(CCPrioritizedTextureTest, changeMemoryLimits)
125 {
126     const size_t maxTextures = 8;
127     OwnPtr<CCPrioritizedTextureManager> textureManager = createManager(maxTextures);
128     OwnPtr<CCPrioritizedTexture> textures[maxTextures];
129
130     for (size_t i = 0; i < maxTextures; ++i)
131         textures[i] = textureManager->createTexture(m_textureSize, m_textureFormat);
132     for (size_t i = 0; i < maxTextures; ++i)
133         textures[i]->setRequestPriority(100 + i);
134
135     // Set max limit to 8 textures
136     textureManager->setMaxMemoryLimitBytes(texturesMemorySize(8));
137     textureManager->prioritizeTextures(0);
138     for (size_t i = 0; i < maxTextures; ++i)
139         validateTexture(textures[i], false);
140     textureManager->reduceMemory(allocator());
141
142     EXPECT_EQ(texturesMemorySize(8), textureManager->memoryAboveCutoffBytes());
143     EXPECT_LE(textureManager->memoryUseBytes(), textureManager->memoryAboveCutoffBytes());
144
145     // Set max limit to 5 textures
146     textureManager->setMaxMemoryLimitBytes(texturesMemorySize(5));
147     textureManager->prioritizeTextures(0);
148     for (size_t i = 0; i < maxTextures; ++i)
149         EXPECT_EQ(validateTexture(textures[i], false), i < 5);
150     textureManager->reduceMemory(allocator());
151
152     EXPECT_EQ(texturesMemorySize(5), textureManager->memoryAboveCutoffBytes());
153     EXPECT_LE(textureManager->memoryUseBytes(), textureManager->memoryAboveCutoffBytes());
154
155     // Set max limit to 4 textures
156     textureManager->setMaxMemoryLimitBytes(texturesMemorySize(4));
157     textureManager->prioritizeTextures(0);
158     for (size_t i = 0; i < maxTextures; ++i)
159         EXPECT_EQ(validateTexture(textures[i], false), i < 4);
160     textureManager->reduceMemory(allocator());
161
162     EXPECT_EQ(texturesMemorySize(4), textureManager->memoryAboveCutoffBytes());
163     EXPECT_LE(textureManager->memoryUseBytes(), textureManager->memoryAboveCutoffBytes());
164
165     textureManager->clearAllMemory(allocator());
166 }
167
168 TEST_F(CCPrioritizedTextureTest, textureManagerPartialUpdateTextures)
169 {
170     const size_t maxTextures = 4;
171     const size_t numTextures = 4;
172     OwnPtr<CCPrioritizedTextureManager> textureManager = createManager(maxTextures);
173     OwnPtr<CCPrioritizedTexture> textures[numTextures];
174     OwnPtr<CCPrioritizedTexture> moreTextures[numTextures];
175
176     for (size_t i = 0; i < numTextures; ++i) {
177         textures[i] = textureManager->createTexture(m_textureSize, m_textureFormat);
178         moreTextures[i] = textureManager->createTexture(m_textureSize, m_textureFormat);
179     }
180
181     for (size_t i = 0; i < numTextures; ++i)
182         textures[i]->setRequestPriority(200 + i);
183     textureManager->prioritizeTextures(0);
184
185     // Allocate textures which are currently high priority.
186     EXPECT_TRUE(validateTexture(textures[0], false));
187     EXPECT_TRUE(validateTexture(textures[1], false));
188     EXPECT_TRUE(validateTexture(textures[2], false));
189     EXPECT_TRUE(validateTexture(textures[3], false));
190
191     EXPECT_TRUE(textures[0]->haveBackingTexture());
192     EXPECT_TRUE(textures[1]->haveBackingTexture());
193     EXPECT_TRUE(textures[2]->haveBackingTexture());
194     EXPECT_TRUE(textures[3]->haveBackingTexture());
195
196     for (size_t i = 0; i < numTextures; ++i)
197         moreTextures[i]->setRequestPriority(100 + i);
198     textureManager->prioritizeTextures(0);
199
200     // Textures are now below cutoff.
201     EXPECT_FALSE(validateTexture(textures[0], false));
202     EXPECT_FALSE(validateTexture(textures[1], false));
203     EXPECT_FALSE(validateTexture(textures[2], false));
204     EXPECT_FALSE(validateTexture(textures[3], false));
205
206     // But they are still valid to use.
207     EXPECT_TRUE(textures[0]->haveBackingTexture());
208     EXPECT_TRUE(textures[1]->haveBackingTexture());
209     EXPECT_TRUE(textures[2]->haveBackingTexture());
210     EXPECT_TRUE(textures[3]->haveBackingTexture());
211
212     // Higher priority textures are finally needed.
213     EXPECT_TRUE(validateTexture(moreTextures[0], false));
214     EXPECT_TRUE(validateTexture(moreTextures[1], false));
215     EXPECT_TRUE(validateTexture(moreTextures[2], false));
216     EXPECT_TRUE(validateTexture(moreTextures[3], false));
217
218     // Lower priority have been fully evicted.
219     EXPECT_FALSE(textures[0]->haveBackingTexture());
220     EXPECT_FALSE(textures[1]->haveBackingTexture());
221     EXPECT_FALSE(textures[2]->haveBackingTexture());
222     EXPECT_FALSE(textures[3]->haveBackingTexture());
223
224     textureManager->clearAllMemory(allocator());
225 }
226
227 TEST_F(CCPrioritizedTextureTest, textureManagerPrioritiesAreEqual)
228 {
229     const size_t maxTextures = 16;
230     OwnPtr<CCPrioritizedTextureManager> textureManager = createManager(maxTextures);
231     OwnPtr<CCPrioritizedTexture> textures[maxTextures];
232
233     for (size_t i = 0; i < maxTextures; ++i)
234         textures[i] = textureManager->createTexture(m_textureSize, m_textureFormat);
235
236     // All 16 textures have the same priority except 2 higher priority.
237     for (size_t i = 0; i < maxTextures; ++i)
238         textures[i]->setRequestPriority(100);
239     textures[0]->setRequestPriority(99);
240     textures[1]->setRequestPriority(99);
241
242     // Set max limit to 8 textures
243     textureManager->setMaxMemoryLimitBytes(texturesMemorySize(8));
244     textureManager->prioritizeTextures(0);
245
246     // The two high priority textures should be available, others should not.
247     for (size_t i = 0; i < 2; ++i)
248         EXPECT_TRUE(validateTexture(textures[i], false));
249     for (size_t i = 2; i < maxTextures; ++i)
250         EXPECT_FALSE(validateTexture(textures[i], false));
251     EXPECT_EQ(texturesMemorySize(2), textureManager->memoryAboveCutoffBytes());
252     EXPECT_LE(textureManager->memoryUseBytes(), textureManager->memoryAboveCutoffBytes());
253
254     // Manually reserving textures should only succeed on the higher priority textures,
255     // and on remaining textures up to the memory limit.
256     for (size_t i = 0; i < 8; i++)
257         EXPECT_TRUE(validateTexture(textures[i], true));
258     for (size_t i = 9; i < maxTextures; i++)
259         EXPECT_FALSE(validateTexture(textures[i], true));
260     EXPECT_EQ(texturesMemorySize(8), textureManager->memoryAboveCutoffBytes());
261     EXPECT_LE(textureManager->memoryUseBytes(), textureManager->memoryAboveCutoffBytes());
262
263     textureManager->clearAllMemory(allocator());
264 }
265
266 TEST_F(CCPrioritizedTextureTest, textureManagerDestroyedFirst)
267 {
268     OwnPtr<CCPrioritizedTextureManager> textureManager = createManager(1);
269     OwnPtr<CCPrioritizedTexture> texture = textureManager->createTexture(m_textureSize, m_textureFormat);
270
271     // Texture is initially invalid, but it will become available.
272     EXPECT_FALSE(texture->haveBackingTexture());
273
274     texture->setRequestPriority(100);
275     textureManager->prioritizeTextures(0);
276
277     EXPECT_TRUE(validateTexture(texture, false));
278     EXPECT_TRUE(texture->canAcquireBackingTexture());
279     EXPECT_TRUE(texture->haveBackingTexture());
280
281     textureManager->clearAllMemory(allocator());
282     textureManager.clear();
283
284     EXPECT_FALSE(texture->canAcquireBackingTexture());
285     EXPECT_FALSE(texture->haveBackingTexture());
286 }
287
288 TEST_F(CCPrioritizedTextureTest, textureMovedToNewManager)
289 {
290     OwnPtr<CCPrioritizedTextureManager> textureManagerOne = createManager(1);
291     OwnPtr<CCPrioritizedTextureManager> textureManagerTwo = createManager(1);
292     OwnPtr<CCPrioritizedTexture> texture = textureManagerOne->createTexture(m_textureSize, m_textureFormat);
293
294     // Texture is initially invalid, but it will become available.
295     EXPECT_FALSE(texture->haveBackingTexture());
296
297     texture->setRequestPriority(100);
298     textureManagerOne->prioritizeTextures(0);
299
300     EXPECT_TRUE(validateTexture(texture, false));
301     EXPECT_TRUE(texture->canAcquireBackingTexture());
302     EXPECT_TRUE(texture->haveBackingTexture());
303
304     texture->setTextureManager(0);
305
306     textureManagerOne->clearAllMemory(allocator());
307     textureManagerOne.clear();
308
309     EXPECT_FALSE(texture->canAcquireBackingTexture());
310     EXPECT_FALSE(texture->haveBackingTexture());
311
312     texture->setTextureManager(textureManagerTwo.get());
313
314     textureManagerTwo->prioritizeTextures(0);
315
316     EXPECT_TRUE(validateTexture(texture, false));
317     EXPECT_TRUE(texture->canAcquireBackingTexture());
318     EXPECT_TRUE(texture->haveBackingTexture());
319
320     textureManagerTwo->clearAllMemory(allocator());
321 }
322
323 TEST_F(CCPrioritizedTextureTest, renderSurfacesReduceMemoryAvailableOutsideRootSurface)
324 {
325     const size_t maxTextures = 8;
326     OwnPtr<CCPrioritizedTextureManager> textureManager = createManager(maxTextures);
327
328     // Half of the memory is taken by surfaces.
329     const size_t renderSurfacesBytes = texturesMemorySize(4);
330
331     // Create textures to fill our memory limit.
332     OwnPtr<CCPrioritizedTexture> textures[maxTextures];
333
334     for (size_t i = 0; i < maxTextures; ++i)
335         textures[i] = textureManager->createTexture(m_textureSize, m_textureFormat);
336
337     // Set decreasing non-visible priorities outside root surface.
338     for (size_t i = 0; i < maxTextures; ++i)
339         textures[i]->setRequestPriority(100 + i);
340
341     // Only lower half should be available.
342     textureManager->prioritizeTextures(renderSurfacesBytes);
343     EXPECT_TRUE(validateTexture(textures[0], false));
344     EXPECT_TRUE(validateTexture(textures[3], false));
345     EXPECT_FALSE(validateTexture(textures[4], false));
346     EXPECT_FALSE(validateTexture(textures[7], false));
347
348     // Set increasing non-visible priorities outside root surface.
349     for (size_t i = 0; i < maxTextures; ++i)
350         textures[i]->setRequestPriority(100 - i);
351
352     // Only upper half should be available.
353     textureManager->prioritizeTextures(renderSurfacesBytes);
354     EXPECT_FALSE(validateTexture(textures[0], false));
355     EXPECT_FALSE(validateTexture(textures[3], false));
356     EXPECT_TRUE(validateTexture(textures[4], false));
357     EXPECT_TRUE(validateTexture(textures[7], false));
358
359     EXPECT_EQ(texturesMemorySize(4), textureManager->memoryAboveCutoffBytes());
360     EXPECT_EQ(texturesMemorySize(4), textureManager->memoryForRenderSurfacesBytes());
361     EXPECT_LE(textureManager->memoryUseBytes(), textureManager->memoryAboveCutoffBytes());
362
363     textureManager->clearAllMemory(allocator());
364 }
365
366 TEST_F(CCPrioritizedTextureTest, renderSurfacesReduceMemoryAvailableForRequestLate)
367 {
368     const size_t maxTextures = 8;
369     OwnPtr<CCPrioritizedTextureManager> textureManager = createManager(maxTextures);
370
371     // Half of the memory is taken by surfaces.
372     const size_t renderSurfacesBytes = texturesMemorySize(4);
373
374     // Create textures to fill our memory limit.
375     OwnPtr<CCPrioritizedTexture> textures[maxTextures];
376
377     for (size_t i = 0; i < maxTextures; ++i)
378         textures[i] = textureManager->createTexture(m_textureSize, m_textureFormat);
379
380     // Set equal priorities.
381     for (size_t i = 0; i < maxTextures; ++i)
382         textures[i]->setRequestPriority(100);
383
384     // The first four to be requested late will be available.
385     textureManager->prioritizeTextures(renderSurfacesBytes);
386     for (unsigned i = 0; i < maxTextures; ++i)
387         EXPECT_FALSE(validateTexture(textures[i], false));
388     for (unsigned i = 0; i < maxTextures; i += 2)
389         EXPECT_TRUE(validateTexture(textures[i], true));
390     for (unsigned i = 1; i < maxTextures; i += 2)
391         EXPECT_FALSE(validateTexture(textures[i], true));
392
393     EXPECT_EQ(texturesMemorySize(4), textureManager->memoryAboveCutoffBytes());
394     EXPECT_EQ(texturesMemorySize(4), textureManager->memoryForRenderSurfacesBytes());
395     EXPECT_LE(textureManager->memoryUseBytes(), textureManager->memoryAboveCutoffBytes());
396
397     textureManager->clearAllMemory(allocator());
398 }
399
400 TEST_F(CCPrioritizedTextureTest, whenRenderSurfaceNotAvailableTexturesAlsoNotAvailable)
401 {
402     const size_t maxTextures = 8;
403     OwnPtr<CCPrioritizedTextureManager> textureManager = createManager(maxTextures);
404
405     // Half of the memory is taken by surfaces.
406     const size_t renderSurfacesBytes = texturesMemorySize(4);
407
408     // Create textures to fill our memory limit.
409     OwnPtr<CCPrioritizedTexture> textures[maxTextures];
410
411     for (size_t i = 0; i < maxTextures; ++i)
412         textures[i] = textureManager->createTexture(m_textureSize, m_textureFormat);
413
414     // Set 6 visible textures in the root surface, and 2 in a child surface.
415     for (size_t i = 0; i < 6; ++i)
416         textures[i]->setRequestPriority(CCPriorityCalculator::visiblePriority(true));
417     for (size_t i = 6; i < 8; ++i)
418         textures[i]->setRequestPriority(CCPriorityCalculator::visiblePriority(false));
419
420     textureManager->prioritizeTextures(renderSurfacesBytes);
421
422     // Unable to requestLate textures in the child surface.
423     EXPECT_FALSE(validateTexture(textures[6], true));
424     EXPECT_FALSE(validateTexture(textures[7], true));
425
426     // Root surface textures are valid.
427     for (size_t i = 0; i < 6; ++i)
428         EXPECT_TRUE(validateTexture(textures[i], false));
429
430     EXPECT_EQ(texturesMemorySize(6), textureManager->memoryAboveCutoffBytes());
431     EXPECT_EQ(texturesMemorySize(2), textureManager->memoryForRenderSurfacesBytes());
432     EXPECT_LE(textureManager->memoryUseBytes(), textureManager->memoryAboveCutoffBytes());
433
434     textureManager->clearAllMemory(allocator());
435 }
436
437 } // namespace