Revert 279472 "Mojo: Add mojo_shell_tests to the Linux bots."
[chromium-blink-merge.git] / cc / resources / resource_update_controller_unittest.cc
blob0fb899d14612696e4d5077375bc5e3a3f21b3d1c
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/resource_update_controller.h"
7 #include "base/test/test_simple_task_runner.h"
8 #include "cc/resources/prioritized_resource_manager.h"
9 #include "cc/test/fake_output_surface.h"
10 #include "cc/test/fake_output_surface_client.h"
11 #include "cc/test/fake_proxy.h"
12 #include "cc/test/scheduler_test_common.h"
13 #include "cc/test/test_shared_bitmap_manager.h"
14 #include "cc/test/test_web_graphics_context_3d.h"
15 #include "cc/test/tiled_layer_test_common.h"
16 #include "cc/trees/single_thread_proxy.h" // For DebugScopedSetImplThread
17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/khronos/GLES2/gl2ext.h"
20 using testing::Test;
22 namespace cc {
23 namespace {
25 const int kFlushPeriodFull = 4;
26 const int kFlushPeriodPartial = kFlushPeriodFull;
28 class ResourceUpdateControllerTest;
30 class WebGraphicsContext3DForUploadTest : public TestWebGraphicsContext3D {
31 public:
32 explicit WebGraphicsContext3DForUploadTest(ResourceUpdateControllerTest* test)
33 : test_(test) {}
35 virtual void flush() OVERRIDE;
36 virtual void shallowFlushCHROMIUM() OVERRIDE;
37 virtual void texSubImage2D(GLenum target,
38 GLint level,
39 GLint xoffset,
40 GLint yoffset,
41 GLsizei width,
42 GLsizei height,
43 GLenum format,
44 GLenum type,
45 const void* pixels) OVERRIDE;
47 virtual void getQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* value)
48 OVERRIDE;
50 private:
51 ResourceUpdateControllerTest* test_;
54 class ResourceUpdateControllerTest : public Test {
55 public:
56 ResourceUpdateControllerTest()
57 : proxy_(),
58 queue_(make_scoped_ptr(new ResourceUpdateQueue)),
59 resource_manager_(PrioritizedResourceManager::Create(&proxy_)),
60 query_results_available_(0),
61 full_upload_count_expected_(0),
62 partial_count_expected_(0),
63 total_upload_count_expected_(0),
64 max_upload_count_per_update_(0),
65 num_consecutive_flushes_(0),
66 num_dangling_uploads_(0),
67 num_total_uploads_(0),
68 num_total_flushes_(0) {}
70 virtual ~ResourceUpdateControllerTest() {
71 DebugScopedSetImplThreadAndMainThreadBlocked
72 impl_thread_and_main_thread_blocked(&proxy_);
73 resource_manager_->ClearAllMemory(resource_provider_.get());
76 public:
77 void OnFlush() {
78 // Check for back-to-back flushes.
79 EXPECT_EQ(0, num_consecutive_flushes_) << "Back-to-back flushes detected.";
81 num_dangling_uploads_ = 0;
82 num_consecutive_flushes_++;
83 num_total_flushes_++;
86 void OnUpload() {
87 // Check for too many consecutive uploads
88 if (num_total_uploads_ < full_upload_count_expected_) {
89 EXPECT_LT(num_dangling_uploads_, kFlushPeriodFull)
90 << "Too many consecutive full uploads detected.";
91 } else {
92 EXPECT_LT(num_dangling_uploads_, kFlushPeriodPartial)
93 << "Too many consecutive partial uploads detected.";
96 num_consecutive_flushes_ = 0;
97 num_dangling_uploads_++;
98 num_total_uploads_++;
101 bool IsQueryResultAvailable() {
102 if (!query_results_available_)
103 return false;
105 query_results_available_--;
106 return true;
109 protected:
110 virtual void SetUp() {
111 bitmap_.allocN32Pixels(300, 150);
113 for (int i = 0; i < 4; i++) {
114 textures_[i] = PrioritizedResource::Create(resource_manager_.get(),
115 gfx::Size(300, 150),
116 RGBA_8888);
117 textures_[i]->
118 set_request_priority(PriorityCalculator::VisiblePriority(true));
120 resource_manager_->PrioritizeTextures();
122 output_surface_ = FakeOutputSurface::Create3d(
123 scoped_ptr<TestWebGraphicsContext3D>(
124 new WebGraphicsContext3DForUploadTest(this)));
125 CHECK(output_surface_->BindToClient(&output_surface_client_));
127 shared_bitmap_manager_.reset(new TestSharedBitmapManager());
128 resource_provider_ = ResourceProvider::Create(
129 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1,
130 false);
133 void AppendFullUploadsOfIndexedTextureToUpdateQueue(int count,
134 int texture_index) {
135 full_upload_count_expected_ += count;
136 total_upload_count_expected_ += count;
138 const gfx::Rect rect(0, 0, 300, 150);
139 const ResourceUpdate upload = ResourceUpdate::Create(
140 textures_[texture_index].get(), &bitmap_, rect, rect, gfx::Vector2d());
141 for (int i = 0; i < count; i++)
142 queue_->AppendFullUpload(upload);
145 void AppendFullUploadsToUpdateQueue(int count) {
146 AppendFullUploadsOfIndexedTextureToUpdateQueue(count, 0);
149 void AppendPartialUploadsOfIndexedTextureToUpdateQueue(int count,
150 int texture_index) {
151 partial_count_expected_ += count;
152 total_upload_count_expected_ += count;
154 const gfx::Rect rect(0, 0, 100, 100);
155 const ResourceUpdate upload = ResourceUpdate::Create(
156 textures_[texture_index].get(), &bitmap_, rect, rect, gfx::Vector2d());
157 for (int i = 0; i < count; i++)
158 queue_->AppendPartialUpload(upload);
161 void AppendPartialUploadsToUpdateQueue(int count) {
162 AppendPartialUploadsOfIndexedTextureToUpdateQueue(count, 0);
165 void SetMaxUploadCountPerUpdate(int count) {
166 max_upload_count_per_update_ = count;
169 void UpdateTextures() {
170 DebugScopedSetImplThreadAndMainThreadBlocked
171 impl_thread_and_main_thread_blocked(&proxy_);
172 scoped_ptr<ResourceUpdateController> update_controller =
173 ResourceUpdateController::Create(NULL,
174 proxy_.ImplThreadTaskRunner(),
175 queue_.Pass(),
176 resource_provider_.get());
177 update_controller->Finalize();
180 void MakeQueryResultAvailable() { query_results_available_++; }
182 protected:
183 // Classes required to interact and test the ResourceUpdateController
184 FakeProxy proxy_;
185 FakeOutputSurfaceClient output_surface_client_;
186 scoped_ptr<OutputSurface> output_surface_;
187 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_;
188 scoped_ptr<ResourceProvider> resource_provider_;
189 scoped_ptr<ResourceUpdateQueue> queue_;
190 scoped_ptr<PrioritizedResource> textures_[4];
191 scoped_ptr<PrioritizedResourceManager> resource_manager_;
192 SkBitmap bitmap_;
193 int query_results_available_;
195 // Properties / expectations of this test
196 int full_upload_count_expected_;
197 int partial_count_expected_;
198 int total_upload_count_expected_;
199 int max_upload_count_per_update_;
201 // Dynamic properties of this test
202 int num_consecutive_flushes_;
203 int num_dangling_uploads_;
204 int num_total_uploads_;
205 int num_total_flushes_;
208 void WebGraphicsContext3DForUploadTest::flush() { test_->OnFlush(); }
210 void WebGraphicsContext3DForUploadTest::shallowFlushCHROMIUM() {
211 test_->OnFlush();
214 void WebGraphicsContext3DForUploadTest::texSubImage2D(GLenum target,
215 GLint level,
216 GLint xoffset,
217 GLint yoffset,
218 GLsizei width,
219 GLsizei height,
220 GLenum format,
221 GLenum type,
222 const void* pixels) {
223 test_->OnUpload();
226 void WebGraphicsContext3DForUploadTest::getQueryObjectuivEXT(GLuint id,
227 GLenum pname,
228 GLuint* params) {
229 if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
230 *params = test_->IsQueryResultAvailable();
233 // ZERO UPLOADS TESTS
234 TEST_F(ResourceUpdateControllerTest, ZeroUploads) {
235 AppendFullUploadsToUpdateQueue(0);
236 AppendPartialUploadsToUpdateQueue(0);
237 UpdateTextures();
239 EXPECT_EQ(0, num_total_flushes_);
240 EXPECT_EQ(0, num_total_uploads_);
243 // ONE UPLOAD TESTS
244 TEST_F(ResourceUpdateControllerTest, OneFullUpload) {
245 AppendFullUploadsToUpdateQueue(1);
246 AppendPartialUploadsToUpdateQueue(0);
247 UpdateTextures();
249 EXPECT_EQ(1, num_total_flushes_);
250 EXPECT_EQ(1, num_total_uploads_);
251 EXPECT_EQ(0, num_dangling_uploads_)
252 << "Last upload wasn't followed by a flush.";
255 TEST_F(ResourceUpdateControllerTest, OnePartialUpload) {
256 AppendFullUploadsToUpdateQueue(0);
257 AppendPartialUploadsToUpdateQueue(1);
258 UpdateTextures();
260 EXPECT_EQ(1, num_total_flushes_);
261 EXPECT_EQ(1, num_total_uploads_);
262 EXPECT_EQ(0, num_dangling_uploads_)
263 << "Last upload wasn't followed by a flush.";
266 TEST_F(ResourceUpdateControllerTest, OneFullOnePartialUpload) {
267 AppendFullUploadsToUpdateQueue(1);
268 AppendPartialUploadsToUpdateQueue(1);
269 UpdateTextures();
271 EXPECT_EQ(1, num_total_flushes_);
272 EXPECT_EQ(2, num_total_uploads_);
273 EXPECT_EQ(0, num_dangling_uploads_)
274 << "Last upload wasn't followed by a flush.";
277 // This class of tests upload a number of textures that is a multiple
278 // of the flush period.
279 const int full_upload_flush_multipler = 7;
280 const int full_count = full_upload_flush_multipler * kFlushPeriodFull;
282 const int partial_upload_flush_multipler = 11;
283 const int partial_count =
284 partial_upload_flush_multipler * kFlushPeriodPartial;
286 TEST_F(ResourceUpdateControllerTest, ManyFullUploads) {
287 AppendFullUploadsToUpdateQueue(full_count);
288 AppendPartialUploadsToUpdateQueue(0);
289 UpdateTextures();
291 EXPECT_EQ(full_upload_flush_multipler, num_total_flushes_);
292 EXPECT_EQ(full_count, num_total_uploads_);
293 EXPECT_EQ(0, num_dangling_uploads_)
294 << "Last upload wasn't followed by a flush.";
297 TEST_F(ResourceUpdateControllerTest, ManyPartialUploads) {
298 AppendFullUploadsToUpdateQueue(0);
299 AppendPartialUploadsToUpdateQueue(partial_count);
300 UpdateTextures();
302 EXPECT_EQ(partial_upload_flush_multipler, num_total_flushes_);
303 EXPECT_EQ(partial_count, num_total_uploads_);
304 EXPECT_EQ(0, num_dangling_uploads_)
305 << "Last upload wasn't followed by a flush.";
308 TEST_F(ResourceUpdateControllerTest, ManyFullManyPartialUploads) {
309 AppendFullUploadsToUpdateQueue(full_count);
310 AppendPartialUploadsToUpdateQueue(partial_count);
311 UpdateTextures();
313 EXPECT_EQ(full_upload_flush_multipler + partial_upload_flush_multipler,
314 num_total_flushes_);
315 EXPECT_EQ(full_count + partial_count, num_total_uploads_);
316 EXPECT_EQ(0, num_dangling_uploads_)
317 << "Last upload wasn't followed by a flush.";
320 class FakeResourceUpdateControllerClient
321 : public ResourceUpdateControllerClient {
322 public:
323 FakeResourceUpdateControllerClient() { Reset(); }
324 void Reset() { ready_to_finalize_called_ = false; }
325 bool ReadyToFinalizeCalled() const { return ready_to_finalize_called_; }
327 virtual void ReadyToFinalizeTextureUpdates() OVERRIDE {
328 ready_to_finalize_called_ = true;
331 protected:
332 bool ready_to_finalize_called_;
335 class FakeResourceUpdateController : public ResourceUpdateController {
336 public:
337 static scoped_ptr<FakeResourceUpdateController> Create(
338 ResourceUpdateControllerClient* client,
339 base::TestSimpleTaskRunner* task_runner,
340 scoped_ptr<ResourceUpdateQueue> queue,
341 ResourceProvider* resource_provider) {
342 return make_scoped_ptr(new FakeResourceUpdateController(
343 client, task_runner, queue.Pass(), resource_provider));
346 void SetNow(base::TimeTicks time) { now_ = time; }
347 base::TimeTicks Now() const { return now_; }
348 void SetUpdateTextureTime(base::TimeDelta time) {
349 update_textures_time_ = time;
351 virtual base::TimeTicks UpdateMoreTexturesCompletionTime() OVERRIDE {
352 size_t total_updates =
353 resource_provider_->NumBlockingUploads() + update_more_textures_size_;
354 return now_ + total_updates * update_textures_time_;
356 void SetUpdateMoreTexturesSize(size_t size) {
357 update_more_textures_size_ = size;
359 virtual size_t UpdateMoreTexturesSize() const OVERRIDE {
360 return update_more_textures_size_;
363 protected:
364 FakeResourceUpdateController(ResourceUpdateControllerClient* client,
365 base::TestSimpleTaskRunner* task_runner,
366 scoped_ptr<ResourceUpdateQueue> queue,
367 ResourceProvider* resource_provider)
368 : ResourceUpdateController(
369 client, task_runner, queue.Pass(), resource_provider),
370 resource_provider_(resource_provider),
371 update_more_textures_size_(0) {}
373 ResourceProvider* resource_provider_;
374 base::TimeTicks now_;
375 base::TimeDelta update_textures_time_;
376 size_t update_more_textures_size_;
379 static void RunPendingTask(base::TestSimpleTaskRunner* task_runner,
380 FakeResourceUpdateController* controller) {
381 EXPECT_TRUE(task_runner->HasPendingTask());
382 controller->SetNow(controller->Now() + task_runner->NextPendingTaskDelay());
383 task_runner->RunPendingTasks();
386 TEST_F(ResourceUpdateControllerTest, UpdateMoreTextures) {
387 FakeResourceUpdateControllerClient client;
388 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
389 new base::TestSimpleTaskRunner;
391 SetMaxUploadCountPerUpdate(1);
392 AppendFullUploadsToUpdateQueue(3);
393 AppendPartialUploadsToUpdateQueue(0);
395 DebugScopedSetImplThreadAndMainThreadBlocked
396 impl_thread_and_main_thread_blocked(&proxy_);
397 scoped_ptr<FakeResourceUpdateController> controller(
398 FakeResourceUpdateController::Create(&client,
399 task_runner.get(),
400 queue_.Pass(),
401 resource_provider_.get()));
403 controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds(1));
404 controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
405 controller->SetUpdateMoreTexturesSize(1);
406 // Not enough time for any updates.
407 controller->PerformMoreUpdates(controller->Now() +
408 base::TimeDelta::FromMilliseconds(90));
409 EXPECT_FALSE(task_runner->HasPendingTask());
411 controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
412 controller->SetUpdateMoreTexturesSize(1);
413 // Only enough time for 1 update.
414 controller->PerformMoreUpdates(controller->Now() +
415 base::TimeDelta::FromMilliseconds(120));
416 EXPECT_FALSE(task_runner->HasPendingTask());
417 EXPECT_EQ(1, num_total_uploads_);
419 // Complete one upload.
420 MakeQueryResultAvailable();
422 controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
423 controller->SetUpdateMoreTexturesSize(1);
424 // Enough time for 2 updates.
425 controller->PerformMoreUpdates(controller->Now() +
426 base::TimeDelta::FromMilliseconds(220));
427 RunPendingTask(task_runner.get(), controller.get());
428 EXPECT_FALSE(task_runner->HasPendingTask());
429 EXPECT_TRUE(client.ReadyToFinalizeCalled());
430 EXPECT_EQ(3, num_total_uploads_);
433 TEST_F(ResourceUpdateControllerTest, NoMoreUpdates) {
434 FakeResourceUpdateControllerClient client;
435 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
436 new base::TestSimpleTaskRunner;
438 SetMaxUploadCountPerUpdate(1);
439 AppendFullUploadsToUpdateQueue(2);
440 AppendPartialUploadsToUpdateQueue(0);
442 DebugScopedSetImplThreadAndMainThreadBlocked
443 impl_thread_and_main_thread_blocked(&proxy_);
444 scoped_ptr<FakeResourceUpdateController> controller(
445 FakeResourceUpdateController::Create(&client,
446 task_runner.get(),
447 queue_.Pass(),
448 resource_provider_.get()));
450 controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds(1));
451 controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
452 controller->SetUpdateMoreTexturesSize(1);
453 // Enough time for 3 updates but only 2 necessary.
454 controller->PerformMoreUpdates(controller->Now() +
455 base::TimeDelta::FromMilliseconds(310));
456 RunPendingTask(task_runner.get(), controller.get());
457 EXPECT_FALSE(task_runner->HasPendingTask());
458 EXPECT_TRUE(client.ReadyToFinalizeCalled());
459 EXPECT_EQ(2, num_total_uploads_);
461 client.Reset();
462 controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(100));
463 controller->SetUpdateMoreTexturesSize(1);
464 // Enough time for updates but no more updates left.
465 controller->PerformMoreUpdates(controller->Now() +
466 base::TimeDelta::FromMilliseconds(310));
468 // ReadyToFinalizeTextureUpdates should only be called once.
469 EXPECT_FALSE(task_runner->HasPendingTask());
470 EXPECT_FALSE(client.ReadyToFinalizeCalled());
471 EXPECT_EQ(2, num_total_uploads_);
474 TEST_F(ResourceUpdateControllerTest, UpdatesCompleteInFiniteTime) {
475 FakeResourceUpdateControllerClient client;
476 scoped_refptr<base::TestSimpleTaskRunner> task_runner =
477 new base::TestSimpleTaskRunner;
479 SetMaxUploadCountPerUpdate(1);
480 AppendFullUploadsToUpdateQueue(2);
481 AppendPartialUploadsToUpdateQueue(0);
483 DebugScopedSetImplThreadAndMainThreadBlocked
484 impl_thread_and_main_thread_blocked(&proxy_);
485 scoped_ptr<FakeResourceUpdateController> controller(
486 FakeResourceUpdateController::Create(&client,
487 task_runner.get(),
488 queue_.Pass(),
489 resource_provider_.get()));
491 controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds(1));
492 controller->SetUpdateTextureTime(base::TimeDelta::FromMilliseconds(500));
493 controller->SetUpdateMoreTexturesSize(1);
495 for (int i = 0; i < 100; i++) {
496 if (client.ReadyToFinalizeCalled())
497 break;
499 // Not enough time for any updates.
500 controller->PerformMoreUpdates(controller->Now() +
501 base::TimeDelta::FromMilliseconds(400));
503 if (task_runner->HasPendingTask())
504 RunPendingTask(task_runner.get(), controller.get());
507 EXPECT_FALSE(task_runner->HasPendingTask());
508 EXPECT_TRUE(client.ReadyToFinalizeCalled());
509 EXPECT_EQ(2, num_total_uploads_);
512 } // namespace
513 } // namespace cc