8e9a8812bf6ead1a3db4f6feeb71d42bd4aacac7
[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 "FakeWebGraphicsContext3D.h"
32 #include "GraphicsContext3DPrivate.h"
33 #include "WebCompositor.h"
34 #include "cc/CCSingleThreadProxy.h" // For DebugScopedSetImplThread
35 #include "platform/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 = CCGraphicsContext::create3D(
178                     adoptPtr(new WebGraphicsContext3DForUploadTest(this)));
179         DebugScopedSetImplThread implThread;
180         m_resourceProvider = CCResourceProvider::create(m_context.get());
181     }
182
183     virtual void TearDown()
184     {
185         WebCompositor::shutdown();
186     }
187
188     void appendFullUploadsToUpdateQueue(int count)
189     {
190         m_fullUploadCountExpected += count;
191         m_totalUploadCountExpected += count;
192
193         const IntRect rect(0, 0, 300, 150);
194         const TextureUploader::Parameters upload = { &m_texture, rect, rect };
195         for (int i = 0; i < count; i++)
196             m_queue->appendFullUpload(upload);
197     }
198
199     void appendPartialUploadsToUpdateQueue(int count)
200     {
201         m_partialCountExpected += count;
202         m_totalUploadCountExpected += count;
203
204         const IntRect rect(0, 0, 100, 100);
205         const TextureUploader::Parameters upload = { &m_texture, rect, rect };
206         for (int i = 0; i < count; i++)
207             m_queue->appendPartialUpload(upload);
208     }
209
210     void setMaxUploadCountPerUpdate(int count)
211     {
212         m_maxUploadCountPerUpdate = count;
213     }
214
215 protected:
216     // Classes required to interact and test the CCTextureUpdateController
217     OwnPtr<CCGraphicsContext> m_context;
218     OwnPtr<CCResourceProvider> m_resourceProvider;
219     OwnPtr<CCTextureUpdateQueue> m_queue;
220     TextureForUploadTest m_texture;
221     FakeTextureCopier m_copier;
222     TextureUploaderForUploadTest m_uploader;
223
224     // Properties / expectations of this test
225     int m_fullUploadCountExpected;
226     int m_partialCountExpected;
227     int m_totalUploadCountExpected;
228     int m_maxUploadCountPerUpdate;
229
230     // Dynamic properties of this test
231     int m_numBeginUploads;
232     int m_numEndUploads;
233     int m_numConsecutiveFlushes;
234     int m_numDanglingUploads;
235     int m_numTotalUploads;
236     int m_numTotalFlushes;
237     int m_numPreviousUploads;
238     int m_numPreviousFlushes;
239 };
240
241 void WebGraphicsContext3DForUploadTest::flush(void)
242 {
243     m_test->onFlush();
244 }
245
246 void WebGraphicsContext3DForUploadTest::shallowFlushCHROMIUM(void)
247 {
248     m_test->onFlush();
249 }
250
251 void TextureUploaderForUploadTest::beginUploads()
252 {
253     m_test->onBeginUploads();
254 }
255
256 void TextureUploaderForUploadTest::endUploads()
257 {
258     m_test->onEndUploads();
259 }
260
261 void TextureUploaderForUploadTest::uploadTexture(WebCore::CCResourceProvider*, Parameters)
262 {
263     m_test->onUpload();
264 }
265
266
267 // ZERO UPLOADS TESTS
268 TEST_F(CCTextureUpdateControllerTest, ZeroUploads)
269 {
270     appendFullUploadsToUpdateQueue(0);
271     appendPartialUploadsToUpdateQueue(0);
272     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
273
274     EXPECT_EQ(0, m_numBeginUploads);
275     EXPECT_EQ(0, m_numEndUploads);
276     EXPECT_EQ(0, m_numPreviousFlushes);
277     EXPECT_EQ(0, m_numPreviousUploads);
278 }
279
280
281 // ONE UPLOAD TESTS
282 TEST_F(CCTextureUpdateControllerTest, OneFullUpload)
283 {
284     appendFullUploadsToUpdateQueue(1);
285     appendPartialUploadsToUpdateQueue(0);
286     DebugScopedSetImplThread implThread;
287     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
288
289     EXPECT_EQ(1, m_numBeginUploads);
290     EXPECT_EQ(1, m_numEndUploads);
291     EXPECT_EQ(1, m_numPreviousFlushes);
292     EXPECT_EQ(1, m_numPreviousUploads);
293 }
294
295 TEST_F(CCTextureUpdateControllerTest, OnePartialUpload)
296 {
297     appendFullUploadsToUpdateQueue(0);
298     appendPartialUploadsToUpdateQueue(1);
299     DebugScopedSetImplThread implThread;
300     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
301
302     EXPECT_EQ(1, m_numBeginUploads);
303     EXPECT_EQ(1, m_numEndUploads);
304     EXPECT_EQ(1, m_numPreviousFlushes);
305     EXPECT_EQ(1, m_numPreviousUploads);
306 }
307
308 TEST_F(CCTextureUpdateControllerTest, OneFullOnePartialUpload)
309 {
310     appendFullUploadsToUpdateQueue(1);
311     appendPartialUploadsToUpdateQueue(1);
312     DebugScopedSetImplThread implThread;
313     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
314
315     // We expect the full uploads to be followed by a flush
316     // before the partial uploads begin.
317     EXPECT_EQ(1, m_numBeginUploads);
318     EXPECT_EQ(1, m_numEndUploads);
319     EXPECT_EQ(2, m_numPreviousFlushes);
320     EXPECT_EQ(2, m_numPreviousUploads);
321 }
322
323
324 // NO REMAINDER TESTS
325 // This class of tests upload a number of textures that is a multiple of the flush period.
326 const int fullUploadFlushMultipler = 7;
327 const int fullNoRemainderCount = fullUploadFlushMultipler * kFlushPeriodFull;
328
329 const int partialUploadFlushMultipler = 11;
330 const int partialNoRemainderCount = partialUploadFlushMultipler * kFlushPeriodPartial;
331
332 TEST_F(CCTextureUpdateControllerTest, ManyFullUploadsNoRemainder)
333 {
334     appendFullUploadsToUpdateQueue(fullNoRemainderCount);
335     appendPartialUploadsToUpdateQueue(0);
336     DebugScopedSetImplThread implThread;
337     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
338
339     EXPECT_EQ(1, m_numBeginUploads);
340     EXPECT_EQ(1, m_numEndUploads);
341     EXPECT_EQ(fullUploadFlushMultipler, m_numPreviousFlushes);
342     EXPECT_EQ(fullNoRemainderCount, m_numPreviousUploads);
343 }
344
345 TEST_F(CCTextureUpdateControllerTest, ManyPartialUploadsNoRemainder)
346 {
347     appendFullUploadsToUpdateQueue(0);
348     appendPartialUploadsToUpdateQueue(partialNoRemainderCount);
349     DebugScopedSetImplThread implThread;
350     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
351
352     EXPECT_EQ(1, m_numBeginUploads);
353     EXPECT_EQ(1, m_numEndUploads);
354     EXPECT_EQ(partialUploadFlushMultipler, m_numPreviousFlushes);
355     EXPECT_EQ(partialNoRemainderCount, m_numPreviousUploads);
356 }
357
358 TEST_F(CCTextureUpdateControllerTest, ManyFullManyPartialUploadsNoRemainder)
359 {
360     appendFullUploadsToUpdateQueue(fullNoRemainderCount);
361     appendPartialUploadsToUpdateQueue(partialNoRemainderCount);
362     DebugScopedSetImplThread implThread;
363     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
364
365     EXPECT_EQ(1, m_numBeginUploads);
366     EXPECT_EQ(1, m_numEndUploads);
367     EXPECT_EQ(fullUploadFlushMultipler + partialUploadFlushMultipler, m_numPreviousFlushes);
368     EXPECT_EQ(fullNoRemainderCount + partialNoRemainderCount, m_numPreviousUploads);
369 }
370
371
372 // MIN/MAX REMAINDER TESTS
373 // This class of tests mix and match uploading 1 more and 1 less texture
374 // than a multiple of the flush period.
375
376 const int fullMinRemainderCount = fullNoRemainderCount + 1;
377 const int fullMaxRemainderCount = fullNoRemainderCount - 1;
378 const int partialMinRemainderCount = partialNoRemainderCount + 1;
379 const int partialMaxRemainderCount = partialNoRemainderCount - 1;
380
381 TEST_F(CCTextureUpdateControllerTest, ManyFullAndPartialMinRemainder)
382 {
383     appendFullUploadsToUpdateQueue(fullMinRemainderCount);
384     appendPartialUploadsToUpdateQueue(partialMinRemainderCount);
385     DebugScopedSetImplThread implThread;
386     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
387
388     EXPECT_EQ(1, m_numBeginUploads);
389     EXPECT_EQ(1, m_numEndUploads);
390     EXPECT_EQ(fullUploadFlushMultipler + partialUploadFlushMultipler + 2, m_numPreviousFlushes);
391     EXPECT_EQ(fullMinRemainderCount + partialMinRemainderCount, m_numPreviousUploads);
392 }
393
394 TEST_F(CCTextureUpdateControllerTest, ManyFullAndPartialUploadsMaxRemainder)
395 {
396     appendFullUploadsToUpdateQueue(fullMaxRemainderCount);
397     appendPartialUploadsToUpdateQueue(partialMaxRemainderCount);
398     DebugScopedSetImplThread implThread;
399     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
400
401     EXPECT_EQ(1, m_numBeginUploads);
402     EXPECT_EQ(1, m_numEndUploads);
403     EXPECT_EQ(fullUploadFlushMultipler + partialUploadFlushMultipler, m_numPreviousFlushes);
404     EXPECT_EQ(fullMaxRemainderCount + partialMaxRemainderCount, m_numPreviousUploads);
405 }
406
407 TEST_F(CCTextureUpdateControllerTest, ManyFullMinRemainderManyPartialMaxRemainder)
408 {
409     appendFullUploadsToUpdateQueue(fullMinRemainderCount);
410     appendPartialUploadsToUpdateQueue(partialMaxRemainderCount);
411     DebugScopedSetImplThread implThread;
412     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
413
414     EXPECT_EQ(1, m_numBeginUploads);
415     EXPECT_EQ(1, m_numEndUploads);
416     EXPECT_EQ((fullUploadFlushMultipler+1) + partialUploadFlushMultipler, m_numPreviousFlushes);
417     EXPECT_EQ(fullMinRemainderCount + partialMaxRemainderCount, m_numPreviousUploads);
418 }
419
420 TEST_F(CCTextureUpdateControllerTest, ManyFullMaxRemainderManyPartialMinRemainder)
421 {
422     appendFullUploadsToUpdateQueue(fullMaxRemainderCount);
423     appendPartialUploadsToUpdateQueue(partialMinRemainderCount);
424     DebugScopedSetImplThread implThread;
425     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), m_totalUploadCountExpected);
426
427     EXPECT_EQ(1, m_numBeginUploads);
428     EXPECT_EQ(1, m_numEndUploads);
429     EXPECT_EQ(fullUploadFlushMultipler + (partialUploadFlushMultipler+1), m_numPreviousFlushes);
430     EXPECT_EQ(fullMaxRemainderCount + partialMinRemainderCount, m_numPreviousUploads);
431 }
432
433
434 // MULTIPLE UPDATE TESTS
435 // These tests attempt to upload too many textures at once, requiring
436 // multiple calls to update().
437
438 int expectedFlushes(int uploads, int flushPeriod)
439 {
440     return (uploads + flushPeriod - 1) / flushPeriod;
441 }
442
443 TEST_F(CCTextureUpdateControllerTest, TripleUpdateFinalUpdateFullAndPartial)
444 {
445     const int kMaxUploadsPerUpdate = 40;
446     const int kFullUploads = 100;
447     const int kPartialUploads = 20;
448
449     int expectedPreviousFlushes = 0;
450     int expectedPreviousUploads = 0;
451
452     setMaxUploadCountPerUpdate(kMaxUploadsPerUpdate);
453     appendFullUploadsToUpdateQueue(kFullUploads);
454     appendPartialUploadsToUpdateQueue(kPartialUploads);
455
456     // First update (40 full)
457     DebugScopedSetImplThread implThread;
458     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
459
460     EXPECT_EQ(1, m_numBeginUploads);
461     EXPECT_EQ(1, m_numEndUploads);
462
463     expectedPreviousFlushes = expectedFlushes(kMaxUploadsPerUpdate, kFlushPeriodFull);
464     EXPECT_EQ(expectedPreviousFlushes, m_numPreviousFlushes);
465
466     expectedPreviousUploads = kMaxUploadsPerUpdate;
467     EXPECT_EQ(expectedPreviousUploads, m_numPreviousUploads);
468
469     // Second update (40 full)
470     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
471
472     EXPECT_EQ(2, m_numBeginUploads);
473     EXPECT_EQ(2, m_numEndUploads);
474
475     expectedPreviousFlushes = expectedFlushes(kMaxUploadsPerUpdate, kFlushPeriodFull);
476     EXPECT_EQ(expectedPreviousFlushes, m_numPreviousFlushes);
477
478     expectedPreviousUploads = kMaxUploadsPerUpdate;
479     EXPECT_EQ(expectedPreviousUploads, m_numPreviousUploads);
480
481     // Third update (20 full, 20 partial)
482     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
483
484     EXPECT_EQ(3, m_numBeginUploads);
485     EXPECT_EQ(3, m_numEndUploads);
486
487     expectedPreviousFlushes = expectedFlushes(kFullUploads-kMaxUploadsPerUpdate*2, kFlushPeriodFull) +
488                               expectedFlushes(kPartialUploads, kFlushPeriodPartial);
489     EXPECT_EQ(expectedPreviousFlushes, m_numPreviousFlushes);
490
491     expectedPreviousUploads = (kFullUploads-kMaxUploadsPerUpdate*2)+kPartialUploads;
492     EXPECT_EQ(expectedPreviousUploads, m_numPreviousUploads);
493
494     // Final sanity checks
495     EXPECT_EQ(kFullUploads + kPartialUploads, m_numTotalUploads);
496 }
497
498 TEST_F(CCTextureUpdateControllerTest, TripleUpdateFinalUpdateAllPartial)
499 {
500     const int kMaxUploadsPerUpdate = 40;
501     const int kFullUploads = 70;
502     const int kPartialUploads = 30;
503
504     int expectedPreviousFlushes = 0;
505     int expectedPreviousUploads = 0;
506
507     setMaxUploadCountPerUpdate(kMaxUploadsPerUpdate);
508     appendFullUploadsToUpdateQueue(kFullUploads);
509     appendPartialUploadsToUpdateQueue(kPartialUploads);
510
511     // First update (40 full)
512     DebugScopedSetImplThread implThread;
513     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
514
515     EXPECT_EQ(1, m_numBeginUploads);
516     EXPECT_EQ(1, m_numEndUploads);
517
518     expectedPreviousFlushes = expectedFlushes(kMaxUploadsPerUpdate, kFlushPeriodFull);
519     EXPECT_EQ(expectedPreviousFlushes, m_numPreviousFlushes);
520
521     expectedPreviousUploads = kMaxUploadsPerUpdate;
522     EXPECT_EQ(expectedPreviousUploads, m_numPreviousUploads);
523
524     // Second update (30 full, optionally 10 partial)
525     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
526
527     EXPECT_EQ(2, m_numBeginUploads);
528     EXPECT_EQ(2, m_numEndUploads);
529     EXPECT_LE(m_numPreviousUploads, kMaxUploadsPerUpdate);
530     // Be lenient on the exact number of flushes here, as the number of flushes
531     // will depend on whether some partial uploads were performed.
532     // onFlush(), onUpload(), and onEndUpload() will do basic flush checks for us anyway.
533
534     // Third update (30 partial OR 20 partial if 10 partial uploaded in second update)
535     CCTextureUpdateController::updateTextures(m_resourceProvider.get(), &m_copier, &m_uploader, m_queue.get(), kMaxUploadsPerUpdate);
536
537     EXPECT_EQ(3, m_numBeginUploads);
538     EXPECT_EQ(3, m_numEndUploads);
539     EXPECT_LE(m_numPreviousUploads, kMaxUploadsPerUpdate);
540     // Be lenient on the exact number of flushes here as well.
541
542     // Final sanity checks
543     EXPECT_EQ(kFullUploads + kPartialUploads, m_numTotalUploads);
544 }
545
546 } // namespace