695832f2d49020755147146da4eb315c3f16c68d
[WebKit-https.git] / Source / WebKit / chromium / tests / CCTextureUpdateControllerTest.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/CCTextureUpdateController.h"
28
29 #include "CCSchedulerTestCommon.h"
30 #include "CCTiledLayerTestCommon.h"
31 #include "FakeWebCompositorOutputSurface.h"
32 #include "FakeWebGraphicsContext3D.h"
33 #include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread
34 #include <public/WebCompositor.h>
35 #include <public/WebThread.h>
36
37 #include <gtest/gtest.h>
38 #include <wtf/RefPtr.h>
39
40 using namespace WebCore;
41 using namespace WebKit;
42 using namespace WebKitTests;
43 using testing::Test;
44
45
46 namespace {
47
48 const int kFlushPeriodFull = 4;
49 const int kFlushPeriodPartial = kFlushPeriodFull;
50
51 class CCTextureUpdateControllerTest;
52
53 class WebGraphicsContext3DForUploadTest : public FakeWebGraphicsContext3D {
54 public:
55     WebGraphicsContext3DForUploadTest(CCTextureUpdateControllerTest *test)
56         : m_test(test)
57         , m_supportShallowFlush(true)
58     { }
59
60     virtual void flush(void);
61     virtual void shallowFlushCHROMIUM(void);
62     virtual GrGLInterface* onCreateGrGLInterface() { return 0; }
63
64     virtual WebString getString(WGC3Denum name)
65     {
66         if (m_supportShallowFlush)
67             return WebString("GL_CHROMIUM_shallow_flush");
68         return WebString("");
69     }
70
71 private:
72     CCTextureUpdateControllerTest* m_test;
73     bool m_supportShallowFlush;
74 };
75
76
77 class TextureUploaderForUploadTest : public FakeTextureUploader {
78 public:
79     TextureUploaderForUploadTest(CCTextureUpdateControllerTest *test) : m_test(test) { }
80
81     virtual void beginUploads() OVERRIDE;
82     virtual void endUploads() OVERRIDE;
83     virtual void uploadTexture(WebCore::CCResourceProvider*, Parameters) OVERRIDE;
84
85 private:
86     CCTextureUpdateControllerTest* m_test;
87 };
88
89 class TextureForUploadTest : public LayerTextureUpdater::Texture {
90 public:
91     TextureForUploadTest() : LayerTextureUpdater::Texture(adoptPtr<CCPrioritizedTexture>(0)) { }
92     virtual void updateRect(CCResourceProvider*, const IntRect& sourceRect, const IntRect& destRect) { }
93 };
94
95
96 class CCTextureUpdateControllerTest : public Test {
97 public:
98     CCTextureUpdateControllerTest()
99     : m_queue(adoptPtr(new CCTextureUpdateQueue))
100     , m_uploader(this)
101     , m_fullUploadCountExpected(0)
102     , m_partialCountExpected(0)
103     , m_totalUploadCountExpected(0)
104     , m_maxUploadCountPerUpdate(0)
105     , m_numBeginUploads(0)
106     , m_numEndUploads(0)
107     , m_numConsecutiveFlushes(0)
108     , m_numDanglingUploads(0)
109     , m_numTotalUploads(0)
110     , m_numTotalFlushes(0)
111     , m_numPreviousUploads(0)
112     , m_numPreviousFlushes(0)
113     { }
114
115 public:
116     void onFlush()
117     {
118         // Check for back-to-back flushes.
119         EXPECT_EQ(0, m_numConsecutiveFlushes) << "Back-to-back flushes detected.";
120
121         // Check for premature flushes
122         if (m_numPreviousUploads != m_maxUploadCountPerUpdate) {
123             if (m_numTotalUploads < m_fullUploadCountExpected)
124                 EXPECT_GE(m_numDanglingUploads, kFlushPeriodFull) << "Premature flush detected in full uploads.";
125             else if (m_numTotalUploads > m_fullUploadCountExpected && m_numTotalUploads < m_totalUploadCountExpected)
126                 EXPECT_GE(m_numDanglingUploads, kFlushPeriodPartial) << "Premature flush detected in partial uploads.";
127         }
128
129         m_numDanglingUploads = 0;
130         m_numConsecutiveFlushes++;
131         m_numTotalFlushes++;
132         m_numPreviousFlushes++;
133     }
134
135     void onBeginUploads()
136     {
137         m_numPreviousFlushes = 0;
138         m_numPreviousUploads = 0;
139         m_numBeginUploads++;
140     }
141
142     void onUpload()
143     {
144         // Check for too many consecutive uploads
145         if (m_numTotalUploads < m_fullUploadCountExpected)
146             EXPECT_LT(m_numDanglingUploads, kFlushPeriodFull) << "Too many consecutive full uploads detected.";
147         else
148             EXPECT_LT(m_numDanglingUploads, kFlushPeriodPartial) << "Too many consecutive partial uploads detected.";
149
150         m_numConsecutiveFlushes = 0;
151         m_numDanglingUploads++;
152         m_numTotalUploads++;
153         m_numPreviousUploads++;
154     }
155
156     void onEndUploads()
157     {
158         EXPECT_EQ(0, m_numDanglingUploads) << "Last upload wasn't followed by a flush.";
159
160         // Note: The m_numTotalUploads != m_fullUploadCountExpected comparison
161         // allows for the quota not to be hit in the case where we are trasitioning
162         // from full uploads to partial uploads.
163         if (m_numTotalUploads != m_totalUploadCountExpected && m_numTotalUploads != m_fullUploadCountExpected) {
164             EXPECT_EQ(m_maxUploadCountPerUpdate, m_numPreviousUploads)
165                 << "endUpload() was called when there are textures to upload, but the upload quota hasn't been filled.";
166         }
167
168         m_numEndUploads++;
169     }
170
171 protected:
172     virtual void SetUp()
173     {
174         OwnPtr<WebThread> thread;
175         WebCompositor::initialize(thread.get());
176
177         m_context = FakeWebCompositorOutputSurface::create(adoptPtr(new WebGraphicsContext3DForUploadTest(this)));
178         DebugScopedSetImplThread implThread;
179         m_resourceProvider = CCResourceProvider::create(m_context.get());
180     }
181
182     virtual void TearDown()
183     {
184         WebCompositor::shutdown();
185     }
186
187     void appendFullUploadsToUpdateQueue(int count)
188     {
189         m_fullUploadCountExpected += count;
190         m_totalUploadCountExpected += count;
191
192         const IntRect rect(0, 0, 300, 150);
193         const TextureUploader::Parameters upload = { &m_texture, rect, rect };
194         for (int i = 0; i < count; i++)
195             m_queue->appendFullUpload(upload);
196     }
197
198     void appendPartialUploadsToUpdateQueue(int count)
199     {
200         m_partialCountExpected += count;
201         m_totalUploadCountExpected += count;
202
203         const IntRect rect(0, 0, 100, 100);
204         const TextureUploader::Parameters upload = { &m_texture, rect, rect };
205         for (int i = 0; i < count; i++)
206             m_queue->appendPartialUpload(upload);
207     }
208
209     void setMaxUploadCountPerUpdate(int count)
210     {
211         m_maxUploadCountPerUpdate = count;
212     }
213
214 protected:
215     // Classes required to interact and test the CCTextureUpdateController
216     OwnPtr<CCGraphicsContext> m_context;
217     OwnPtr<CCResourceProvider> m_resourceProvider;
218     OwnPtr<CCTextureUpdateQueue> m_queue;
219     TextureForUploadTest m_texture;
220     FakeTextureCopier m_copier;
221     TextureUploaderForUploadTest m_uploader;
222
223     // Properties / expectations of this test
224     int m_fullUploadCountExpected;
225     int m_partialCountExpected;
226     int m_totalUploadCountExpected;
227     int m_maxUploadCountPerUpdate;
228
229     // Dynamic properties of this test
230     int m_numBeginUploads;
231     int m_numEndUploads;
232     int m_numConsecutiveFlushes;
233     int m_numDanglingUploads;
234     int m_numTotalUploads;
235     int m_numTotalFlushes;
236     int m_numPreviousUploads;
237     int m_numPreviousFlushes;
238 };
239
240 void WebGraphicsContext3DForUploadTest::flush(void)
241 {
242     m_test->onFlush();
243 }
244
245 void WebGraphicsContext3DForUploadTest::shallowFlushCHROMIUM(void)
246 {
247     m_test->onFlush();
248 }
249
250 void TextureUploaderForUploadTest::beginUploads()
251 {
252     m_test->onBeginUploads();
253 }
254
255 void TextureUploaderForUploadTest::endUploads()
256 {
257     m_test->onEndUploads();
258 }
259
260 void TextureUploaderForUploadTest::uploadTexture(WebCore::CCResourceProvider*, Parameters)
261 {
262     m_test->onUpload();
263 }
264
265
266 // ZERO UPLOADS TESTS
267 TEST_F(CCTextureUpdateControllerTest, ZeroUploads)
268 {
269     appendFullUploadsToUpdateQueue(0);
270     appendPartialUploadsToUpdateQueue(0);
271     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
272
273     EXPECT_EQ(0, m_numBeginUploads);
274     EXPECT_EQ(0, m_numEndUploads);
275     EXPECT_EQ(0, m_numPreviousFlushes);
276     EXPECT_EQ(0, m_numPreviousUploads);
277 }
278
279
280 // ONE UPLOAD TESTS
281 TEST_F(CCTextureUpdateControllerTest, OneFullUpload)
282 {
283     appendFullUploadsToUpdateQueue(1);
284     appendPartialUploadsToUpdateQueue(0);
285     DebugScopedSetImplThread implThread;
286     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
287
288     EXPECT_EQ(1, m_numBeginUploads);
289     EXPECT_EQ(1, m_numEndUploads);
290     EXPECT_EQ(1, m_numPreviousFlushes);
291     EXPECT_EQ(1, m_numPreviousUploads);
292 }
293
294 TEST_F(CCTextureUpdateControllerTest, OnePartialUpload)
295 {
296     appendFullUploadsToUpdateQueue(0);
297     appendPartialUploadsToUpdateQueue(1);
298     DebugScopedSetImplThread implThread;
299     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
300
301     EXPECT_EQ(1, m_numBeginUploads);
302     EXPECT_EQ(1, m_numEndUploads);
303     EXPECT_EQ(1, m_numPreviousFlushes);
304     EXPECT_EQ(1, m_numPreviousUploads);
305 }
306
307 TEST_F(CCTextureUpdateControllerTest, OneFullOnePartialUpload)
308 {
309     appendFullUploadsToUpdateQueue(1);
310     appendPartialUploadsToUpdateQueue(1);
311     DebugScopedSetImplThread implThread;
312     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
313
314     // We expect the full uploads to be followed by a flush
315     // before the partial uploads begin.
316     EXPECT_EQ(1, m_numBeginUploads);
317     EXPECT_EQ(1, m_numEndUploads);
318     EXPECT_EQ(2, m_numPreviousFlushes);
319     EXPECT_EQ(2, m_numPreviousUploads);
320 }
321
322
323 // NO REMAINDER TESTS
324 // This class of tests upload a number of textures that is a multiple of the flush period.
325 const int fullUploadFlushMultipler = 7;
326 const int fullNoRemainderCount = fullUploadFlushMultipler * kFlushPeriodFull;
327
328 const int partialUploadFlushMultipler = 11;
329 const int partialNoRemainderCount = partialUploadFlushMultipler * kFlushPeriodPartial;
330
331 TEST_F(CCTextureUpdateControllerTest, ManyFullUploadsNoRemainder)
332 {
333     appendFullUploadsToUpdateQueue(fullNoRemainderCount);
334     appendPartialUploadsToUpdateQueue(0);
335     DebugScopedSetImplThread implThread;
336     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
337
338     EXPECT_EQ(1, m_numBeginUploads);
339     EXPECT_EQ(1, m_numEndUploads);
340     EXPECT_EQ(fullUploadFlushMultipler, m_numPreviousFlushes);
341     EXPECT_EQ(fullNoRemainderCount, m_numPreviousUploads);
342 }
343
344 TEST_F(CCTextureUpdateControllerTest, ManyPartialUploadsNoRemainder)
345 {
346     appendFullUploadsToUpdateQueue(0);
347     appendPartialUploadsToUpdateQueue(partialNoRemainderCount);
348     DebugScopedSetImplThread implThread;
349     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
350
351     EXPECT_EQ(1, m_numBeginUploads);
352     EXPECT_EQ(1, m_numEndUploads);
353     EXPECT_EQ(partialUploadFlushMultipler, m_numPreviousFlushes);
354     EXPECT_EQ(partialNoRemainderCount, m_numPreviousUploads);
355 }
356
357 TEST_F(CCTextureUpdateControllerTest, ManyFullManyPartialUploadsNoRemainder)
358 {
359     appendFullUploadsToUpdateQueue(fullNoRemainderCount);
360     appendPartialUploadsToUpdateQueue(partialNoRemainderCount);
361     DebugScopedSetImplThread implThread;
362     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
363
364     EXPECT_EQ(1, m_numBeginUploads);
365     EXPECT_EQ(1, m_numEndUploads);
366     EXPECT_EQ(fullUploadFlushMultipler + partialUploadFlushMultipler, m_numPreviousFlushes);
367     EXPECT_EQ(fullNoRemainderCount + partialNoRemainderCount, m_numPreviousUploads);
368 }
369
370
371 // MIN/MAX REMAINDER TESTS
372 // This class of tests mix and match uploading 1 more and 1 less texture
373 // than a multiple of the flush period.
374
375 const int fullMinRemainderCount = fullNoRemainderCount + 1;
376 const int fullMaxRemainderCount = fullNoRemainderCount - 1;
377 const int partialMinRemainderCount = partialNoRemainderCount + 1;
378 const int partialMaxRemainderCount = partialNoRemainderCount - 1;
379
380 TEST_F(CCTextureUpdateControllerTest, ManyFullAndPartialMinRemainder)
381 {
382     appendFullUploadsToUpdateQueue(fullMinRemainderCount);
383     appendPartialUploadsToUpdateQueue(partialMinRemainderCount);
384     DebugScopedSetImplThread implThread;
385     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
386
387     EXPECT_EQ(1, m_numBeginUploads);
388     EXPECT_EQ(1, m_numEndUploads);
389     EXPECT_EQ(fullUploadFlushMultipler + partialUploadFlushMultipler + 2, m_numPreviousFlushes);
390     EXPECT_EQ(fullMinRemainderCount + partialMinRemainderCount, m_numPreviousUploads);
391 }
392
393 TEST_F(CCTextureUpdateControllerTest, ManyFullAndPartialUploadsMaxRemainder)
394 {
395     appendFullUploadsToUpdateQueue(fullMaxRemainderCount);
396     appendPartialUploadsToUpdateQueue(partialMaxRemainderCount);
397     DebugScopedSetImplThread implThread;
398     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
399
400     EXPECT_EQ(1, m_numBeginUploads);
401     EXPECT_EQ(1, m_numEndUploads);
402     EXPECT_EQ(fullUploadFlushMultipler + partialUploadFlushMultipler, m_numPreviousFlushes);
403     EXPECT_EQ(fullMaxRemainderCount + partialMaxRemainderCount, m_numPreviousUploads);
404 }
405
406 TEST_F(CCTextureUpdateControllerTest, ManyFullMinRemainderManyPartialMaxRemainder)
407 {
408     appendFullUploadsToUpdateQueue(fullMinRemainderCount);
409     appendPartialUploadsToUpdateQueue(partialMaxRemainderCount);
410     DebugScopedSetImplThread implThread;
411     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
412
413     EXPECT_EQ(1, m_numBeginUploads);
414     EXPECT_EQ(1, m_numEndUploads);
415     EXPECT_EQ((fullUploadFlushMultipler+1) + partialUploadFlushMultipler, m_numPreviousFlushes);
416     EXPECT_EQ(fullMinRemainderCount + partialMaxRemainderCount, m_numPreviousUploads);
417 }
418
419 TEST_F(CCTextureUpdateControllerTest, ManyFullMaxRemainderManyPartialMinRemainder)
420 {
421     appendFullUploadsToUpdateQueue(fullMaxRemainderCount);
422     appendPartialUploadsToUpdateQueue(partialMinRemainderCount);
423     DebugScopedSetImplThread implThread;
424     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
425
426     EXPECT_EQ(1, m_numBeginUploads);
427     EXPECT_EQ(1, m_numEndUploads);
428     EXPECT_EQ(fullUploadFlushMultipler + (partialUploadFlushMultipler+1), m_numPreviousFlushes);
429     EXPECT_EQ(fullMaxRemainderCount + partialMinRemainderCount, m_numPreviousUploads);
430 }
431
432
433 // MULTIPLE UPDATE TESTS
434 // These tests attempt to upload too many textures at once, requiring
435 // multiple calls to update().
436
437 int expectedFlushes(int uploads, int flushPeriod)
438 {
439     return (uploads + flushPeriod - 1) / flushPeriod;
440 }
441
442 TEST_F(CCTextureUpdateControllerTest, TripleUpdateFinalUpdateFullAndPartial)
443 {
444     const int kMaxUploadsPerUpdate = 40;
445     const int kFullUploads = 100;
446     const int kPartialUploads = 20;
447
448     int expectedPreviousFlushes = 0;
449     int expectedPreviousUploads = 0;
450
451     setMaxUploadCountPerUpdate(kMaxUploadsPerUpdate);
452     appendFullUploadsToUpdateQueue(kFullUploads);
453     appendPartialUploadsToUpdateQueue(kPartialUploads);
454
455     // First update (40 full)
456     DebugScopedSetImplThread implThread;
457     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
458
459     EXPECT_EQ(1, m_numBeginUploads);
460     EXPECT_EQ(1, m_numEndUploads);
461
462     expectedPreviousFlushes = expectedFlushes(kMaxUploadsPerUpdate, kFlushPeriodFull);
463     EXPECT_EQ(expectedPreviousFlushes, m_numPreviousFlushes);
464
465     expectedPreviousUploads = kMaxUploadsPerUpdate;
466     EXPECT_EQ(expectedPreviousUploads, m_numPreviousUploads);
467
468     // Second update (40 full)
469     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
470
471     EXPECT_EQ(2, m_numBeginUploads);
472     EXPECT_EQ(2, m_numEndUploads);
473
474     expectedPreviousFlushes = expectedFlushes(kMaxUploadsPerUpdate, kFlushPeriodFull);
475     EXPECT_EQ(expectedPreviousFlushes, m_numPreviousFlushes);
476
477     expectedPreviousUploads = kMaxUploadsPerUpdate;
478     EXPECT_EQ(expectedPreviousUploads, m_numPreviousUploads);
479
480     // Third update (20 full, 20 partial)
481     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
482
483     EXPECT_EQ(3, m_numBeginUploads);
484     EXPECT_EQ(3, m_numEndUploads);
485
486     expectedPreviousFlushes = expectedFlushes(kFullUploads-kMaxUploadsPerUpdate*2, kFlushPeriodFull) +
487                               expectedFlushes(kPartialUploads, kFlushPeriodPartial);
488     EXPECT_EQ(expectedPreviousFlushes, m_numPreviousFlushes);
489
490     expectedPreviousUploads = (kFullUploads-kMaxUploadsPerUpdate*2)+kPartialUploads;
491     EXPECT_EQ(expectedPreviousUploads, m_numPreviousUploads);
492
493     // Final sanity checks
494     EXPECT_EQ(kFullUploads + kPartialUploads, m_numTotalUploads);
495 }
496
497 TEST_F(CCTextureUpdateControllerTest, TripleUpdateFinalUpdateAllPartial)
498 {
499     const int kMaxUploadsPerUpdate = 40;
500     const int kFullUploads = 70;
501     const int kPartialUploads = 30;
502
503     int expectedPreviousFlushes = 0;
504     int expectedPreviousUploads = 0;
505
506     setMaxUploadCountPerUpdate(kMaxUploadsPerUpdate);
507     appendFullUploadsToUpdateQueue(kFullUploads);
508     appendPartialUploadsToUpdateQueue(kPartialUploads);
509
510     // First update (40 full)
511     DebugScopedSetImplThread implThread;
512     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
513
514     EXPECT_EQ(1, m_numBeginUploads);
515     EXPECT_EQ(1, m_numEndUploads);
516
517     expectedPreviousFlushes = expectedFlushes(kMaxUploadsPerUpdate, kFlushPeriodFull);
518     EXPECT_EQ(expectedPreviousFlushes, m_numPreviousFlushes);
519
520     expectedPreviousUploads = kMaxUploadsPerUpdate;
521     EXPECT_EQ(expectedPreviousUploads, m_numPreviousUploads);
522
523     // Second update (30 full, optionally 10 partial)
524     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
525
526     EXPECT_EQ(2, m_numBeginUploads);
527     EXPECT_EQ(2, m_numEndUploads);
528     EXPECT_LE(m_numPreviousUploads, kMaxUploadsPerUpdate);
529     // Be lenient on the exact number of flushes here, as the number of flushes
530     // will depend on whether some partial uploads were performed.
531     // onFlush(), onUpload(), and onEndUpload() will do basic flush checks for us anyway.
532
533     // Third update (30 partial OR 20 partial if 10 partial uploaded in second update)
534     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
535
536     EXPECT_EQ(3, m_numBeginUploads);
537     EXPECT_EQ(3, m_numEndUploads);
538     EXPECT_LE(m_numPreviousUploads, kMaxUploadsPerUpdate);
539     // Be lenient on the exact number of flushes here as well.
540
541     // Final sanity checks
542     EXPECT_EQ(kFullUploads + kPartialUploads, m_numTotalUploads);
543 }
544
545 class FakeCCTextureUpdateController : public WebCore::CCTextureUpdateController {
546 public:
547     static PassOwnPtr<FakeCCTextureUpdateController> create(WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
548     {
549         return adoptPtr(new FakeCCTextureUpdateController(thread, queue, resourceProvider, copier, uploader));
550     }
551
552     void setMonotonicTimeNow(double time) { m_monotonicTimeNow = time; }
553     virtual double monotonicTimeNow() const OVERRIDE { return m_monotonicTimeNow; }
554     void setUpdateMoreTexturesTime(double time) { m_updateMoreTexturesTime = time; }
555     virtual double updateMoreTexturesTime() const OVERRIDE { return m_updateMoreTexturesTime; }
556     void setUpdateMoreTexturesSize(size_t size) { m_updateMoreTexturesSize = size; }
557     virtual size_t updateMoreTexturesSize() const OVERRIDE { return m_updateMoreTexturesSize; }
558
559 protected:
560     FakeCCTextureUpdateController(WebCore::CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopier* copier, TextureUploader* uploader)
561         : WebCore::CCTextureUpdateController(thread, queue, resourceProvider, copier, uploader)
562         , m_monotonicTimeNow(0)
563         , m_updateMoreTexturesTime(0)
564         , m_updateMoreTexturesSize(0) { }
565
566     double m_monotonicTimeNow;
567     double m_updateMoreTexturesTime;
568     size_t m_updateMoreTexturesSize;
569 };
570
571 TEST_F(CCTextureUpdateControllerTest, UpdateMoreTextures)
572 {
573     FakeCCThread thread;
574
575     setMaxUploadCountPerUpdate(1);
576     appendFullUploadsToUpdateQueue(3);
577     appendPartialUploadsToUpdateQueue(0);
578
579     DebugScopedSetImplThread implThread;
580     OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader));
581
582     controller->setMonotonicTimeNow(0);
583     controller->setUpdateMoreTexturesTime(0.1);
584     controller->setUpdateMoreTexturesSize(1);
585     // Not enough time for any updates.
586     controller->updateMoreTextures(0.09);
587     EXPECT_FALSE(thread.hasPendingTask());
588     EXPECT_EQ(0, m_numBeginUploads);
589     EXPECT_EQ(0, m_numEndUploads);
590
591     thread.reset();
592     controller->setMonotonicTimeNow(0);
593     controller->setUpdateMoreTexturesTime(0.1);
594     controller->setUpdateMoreTexturesSize(1);
595     // Only enough time for 1 update.
596     controller->updateMoreTextures(0.12);
597     EXPECT_TRUE(thread.hasPendingTask());
598     controller->setMonotonicTimeNow(thread.pendingDelayMs() / 1000.0);
599     thread.runPendingTask();
600     EXPECT_EQ(1, m_numBeginUploads);
601     EXPECT_EQ(1, m_numEndUploads);
602     EXPECT_EQ(1, m_numTotalUploads);
603
604     thread.reset();
605     controller->setMonotonicTimeNow(0);
606     controller->setUpdateMoreTexturesTime(0.1);
607     controller->setUpdateMoreTexturesSize(1);
608     // Enough time for 2 updates.
609     controller->updateMoreTextures(0.22);
610     EXPECT_TRUE(thread.hasPendingTask());
611     controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0);
612     thread.runPendingTask();
613     EXPECT_EQ(3, m_numBeginUploads);
614     EXPECT_EQ(3, m_numEndUploads);
615     EXPECT_EQ(3, m_numTotalUploads);
616 }
617
618 TEST_F(CCTextureUpdateControllerTest, NoMoreUpdates)
619 {
620     FakeCCThread thread;
621
622     setMaxUploadCountPerUpdate(1);
623     appendFullUploadsToUpdateQueue(2);
624     appendPartialUploadsToUpdateQueue(0);
625
626     DebugScopedSetImplThread implThread;
627     OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader));
628
629     controller->setMonotonicTimeNow(0);
630     controller->setUpdateMoreTexturesTime(0.1);
631     controller->setUpdateMoreTexturesSize(1);
632     // Enough time for 3 updates but only 2 necessary.
633     controller->updateMoreTextures(0.31);
634     EXPECT_TRUE(thread.hasPendingTask());
635     controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0);
636     thread.runPendingTask();
637     EXPECT_TRUE(thread.hasPendingTask());
638     controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0);
639     thread.runPendingTask();
640     EXPECT_EQ(2, m_numBeginUploads);
641     EXPECT_EQ(2, m_numEndUploads);
642     EXPECT_EQ(2, m_numTotalUploads);
643
644     thread.reset();
645     controller->setMonotonicTimeNow(0);
646     controller->setUpdateMoreTexturesTime(0.1);
647     controller->setUpdateMoreTexturesSize(1);
648     // Enough time for updates but no more updates left.
649     controller->updateMoreTextures(0.31);
650     EXPECT_FALSE(thread.hasPendingTask());
651     EXPECT_EQ(2, m_numBeginUploads);
652     EXPECT_EQ(2, m_numEndUploads);
653     EXPECT_EQ(2, m_numTotalUploads);
654 }
655
656 TEST_F(CCTextureUpdateControllerTest, UpdatesCompleteInFiniteTime)
657 {
658     FakeCCThread thread;
659
660     setMaxUploadCountPerUpdate(1);
661     appendFullUploadsToUpdateQueue(2);
662     appendPartialUploadsToUpdateQueue(0);
663
664     DebugScopedSetImplThread implThread;
665     OwnPtr<FakeCCTextureUpdateController> controller(FakeCCTextureUpdateController::create(&thread, m_queue.release(), m_resourceProvider.get(), &m_copier, &m_uploader));
666
667     controller->setMonotonicTimeNow(0);
668     controller->setUpdateMoreTexturesTime(0.5);
669     controller->setUpdateMoreTexturesSize(1);
670
671     for (int i = 0; i < 100; i++) {
672         if (!controller->hasMoreUpdates())
673             break;
674
675         // Not enough time for any updates.
676         controller->updateMoreTextures(0.4);
677
678         if (thread.hasPendingTask()) {
679             controller->setMonotonicTimeNow(controller->monotonicTimeNow() + thread.pendingDelayMs() / 1000.0);
680             thread.runPendingTask();
681         }
682     }
683
684     EXPECT_EQ(2, m_numBeginUploads);
685     EXPECT_EQ(2, m_numEndUploads);
686     EXPECT_EQ(2, m_numTotalUploads);
687 }
688
689 } // namespace