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. 4 5 #include "cc/output/gl_renderer.h" 6 7 #include <set> 8 9 #include "cc/base/math_util.h" 10 #include "cc/output/compositor_frame_metadata.h" 11 #include "cc/resources/prioritized_resource_manager.h" 12 #include "cc/resources/resource_provider.h" 13 #include "cc/test/fake_impl_proxy.h" 14 #include "cc/test/fake_layer_tree_host_impl.h" 15 #include "cc/test/fake_output_surface.h" 16 #include "cc/test/fake_output_surface_client.h" 17 #include "cc/test/fake_renderer_client.h" 18 #include "cc/test/mock_quad_culler.h" 19 #include "cc/test/pixel_test.h" 20 #include "cc/test/render_pass_test_common.h" 21 #include "cc/test/render_pass_test_utils.h" 22 #include "cc/test/test_shared_bitmap_manager.h" 23 #include "cc/test/test_web_graphics_context_3d.h" 24 #include "gpu/GLES2/gl2extchromium.h" 25 #include "gpu/command_buffer/client/context_support.h" 26 #include "testing/gmock/include/gmock/gmock.h" 27 #include "testing/gtest/include/gtest/gtest.h" 28 #include "third_party/khronos/GLES2/gl2.h" 29 #include "third_party/skia/include/core/SkImageFilter.h" 30 #include "third_party/skia/include/core/SkMatrix.h" 31 #include "third_party/skia/include/effects/SkColorFilterImageFilter.h" 32 #include "third_party/skia/include/effects/SkColorMatrixFilter.h" 33 #include "ui/gfx/transform.h" 34 35 using testing::_; 36 using testing::AnyNumber; 37 using testing::Args; 38 using testing::AtLeast; 39 using testing::ElementsAre; 40 using testing::Expectation; 41 using testing::InSequence; 42 using testing::Mock; 43 using testing::Return; 44 using testing::StrictMock; 45 46 namespace cc { 47 48 class GLRendererTest : public testing::Test { 49 protected: 50 RenderPass* root_render_pass() { return render_passes_in_draw_order_.back(); } 51 52 RenderPassList render_passes_in_draw_order_; 53 }; 54 55 #define EXPECT_PROGRAM_VALID(program_binding) \ 56 do { \ 57 EXPECT_TRUE((program_binding)->program()); \ 58 EXPECT_TRUE((program_binding)->initialized()); \ 59 } while (false) 60 61 // Explicitly named to be a friend in GLRenderer for shader access. 62 class GLRendererShaderPixelTest : public GLRendererPixelTest { 63 public: 64 void TestShaders() { 65 ASSERT_FALSE(renderer()->IsContextLost()); 66 EXPECT_PROGRAM_VALID(renderer()->GetTileCheckerboardProgram()); 67 EXPECT_PROGRAM_VALID(renderer()->GetDebugBorderProgram()); 68 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgram()); 69 EXPECT_PROGRAM_VALID(renderer()->GetSolidColorProgramAA()); 70 TestShadersWithTexCoordPrecision(TexCoordPrecisionMedium); 71 TestShadersWithTexCoordPrecision(TexCoordPrecisionHigh); 72 ASSERT_FALSE(renderer()->IsContextLost()); 73 } 74 75 void TestShadersWithTexCoordPrecision(TexCoordPrecision precision) { 76 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgram(precision)); 77 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassProgramAA(precision)); 78 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgram(precision)); 79 EXPECT_PROGRAM_VALID(renderer()->GetRenderPassMaskProgramAA(precision)); 80 EXPECT_PROGRAM_VALID( 81 renderer()->GetRenderPassColorMatrixProgram(precision)); 82 EXPECT_PROGRAM_VALID( 83 renderer()->GetRenderPassMaskColorMatrixProgramAA(precision)); 84 EXPECT_PROGRAM_VALID( 85 renderer()->GetRenderPassColorMatrixProgramAA(precision)); 86 EXPECT_PROGRAM_VALID( 87 renderer()->GetRenderPassMaskColorMatrixProgram(precision)); 88 EXPECT_PROGRAM_VALID(renderer()->GetTextureProgram(precision)); 89 EXPECT_PROGRAM_VALID( 90 renderer()->GetNonPremultipliedTextureProgram(precision)); 91 EXPECT_PROGRAM_VALID(renderer()->GetTextureBackgroundProgram(precision)); 92 EXPECT_PROGRAM_VALID( 93 renderer()->GetNonPremultipliedTextureBackgroundProgram(precision)); 94 EXPECT_PROGRAM_VALID(renderer()->GetTextureIOSurfaceProgram(precision)); 95 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVProgram(precision)); 96 EXPECT_PROGRAM_VALID(renderer()->GetVideoYUVAProgram(precision)); 97 // This is unlikely to be ever true in tests due to usage of osmesa. 98 if (renderer()->Capabilities().using_egl_image) 99 EXPECT_PROGRAM_VALID(renderer()->GetVideoStreamTextureProgram(precision)); 100 else 101 EXPECT_FALSE(renderer()->GetVideoStreamTextureProgram(precision)); 102 TestShadersWithSamplerType(precision, SamplerType2D); 103 TestShadersWithSamplerType(precision, SamplerType2DRect); 104 // This is unlikely to be ever true in tests due to usage of osmesa. 105 if (renderer()->Capabilities().using_egl_image) 106 TestShadersWithSamplerType(precision, SamplerTypeExternalOES); 107 } 108 109 void TestShadersWithSamplerType(TexCoordPrecision precision, 110 SamplerType sampler) { 111 EXPECT_PROGRAM_VALID(renderer()->GetTileProgram(precision, sampler)); 112 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramOpaque(precision, sampler)); 113 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramAA(precision, sampler)); 114 EXPECT_PROGRAM_VALID(renderer()->GetTileProgramSwizzle(precision, sampler)); 115 EXPECT_PROGRAM_VALID( 116 renderer()->GetTileProgramSwizzleOpaque(precision, sampler)); 117 EXPECT_PROGRAM_VALID( 118 renderer()->GetTileProgramSwizzleAA(precision, sampler)); 119 } 120 }; 121 122 namespace { 123 124 #if !defined(OS_ANDROID) 125 TEST_F(GLRendererShaderPixelTest, AllShadersCompile) { TestShaders(); } 126 #endif 127 128 class FakeRendererGL : public GLRenderer { 129 public: 130 FakeRendererGL(RendererClient* client, 131 const LayerTreeSettings* settings, 132 OutputSurface* output_surface, 133 ResourceProvider* resource_provider) 134 : GLRenderer(client, 135 settings, 136 output_surface, 137 resource_provider, 138 NULL, 139 0) {} 140 141 // GLRenderer methods. 142 143 // Changing visibility to public. 144 using GLRenderer::IsBackbufferDiscarded; 145 using GLRenderer::DoDrawQuad; 146 using GLRenderer::BeginDrawingFrame; 147 using GLRenderer::FinishDrawingQuadList; 148 using GLRenderer::stencil_enabled; 149 }; 150 151 class GLRendererWithDefaultHarnessTest : public GLRendererTest { 152 protected: 153 GLRendererWithDefaultHarnessTest() { 154 output_surface_ = 155 FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()).Pass(); 156 CHECK(output_surface_->BindToClient(&output_surface_client_)); 157 158 shared_bitmap_manager_.reset(new TestSharedBitmapManager()); 159 resource_provider_ = 160 ResourceProvider::Create( 161 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, 162 false).Pass(); 163 renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_, 164 &settings_, 165 output_surface_.get(), 166 resource_provider_.get())); 167 } 168 169 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); } 170 171 LayerTreeSettings settings_; 172 FakeOutputSurfaceClient output_surface_client_; 173 scoped_ptr<FakeOutputSurface> output_surface_; 174 FakeRendererClient renderer_client_; 175 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; 176 scoped_ptr<ResourceProvider> resource_provider_; 177 scoped_ptr<FakeRendererGL> renderer_; 178 }; 179 180 // Closing the namespace here so that GLRendererShaderTest can take advantage 181 // of the friend relationship with GLRenderer and all of the mock classes 182 // declared above it. 183 } // namespace 184 185 class GLRendererShaderTest : public GLRendererTest { 186 protected: 187 GLRendererShaderTest() { 188 output_surface_ = FakeOutputSurface::Create3d().Pass(); 189 CHECK(output_surface_->BindToClient(&output_surface_client_)); 190 191 shared_bitmap_manager_.reset(new TestSharedBitmapManager()); 192 resource_provider_ = 193 ResourceProvider::Create( 194 output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, 195 false).Pass(); 196 renderer_.reset(new FakeRendererGL(&renderer_client_, 197 &settings_, 198 output_surface_.get(), 199 resource_provider_.get())); 200 } 201 202 void TestRenderPassProgram(TexCoordPrecision precision) { 203 EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_[precision]); 204 EXPECT_EQ(renderer_->render_pass_program_[precision].program(), 205 renderer_->program_shadow_); 206 } 207 208 void TestRenderPassColorMatrixProgram(TexCoordPrecision precision) { 209 EXPECT_PROGRAM_VALID( 210 &renderer_->render_pass_color_matrix_program_[precision]); 211 EXPECT_EQ(renderer_->render_pass_color_matrix_program_[precision].program(), 212 renderer_->program_shadow_); 213 } 214 215 void TestRenderPassMaskProgram(TexCoordPrecision precision) { 216 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_[precision]); 217 EXPECT_EQ(renderer_->render_pass_mask_program_[precision].program(), 218 renderer_->program_shadow_); 219 } 220 221 void TestRenderPassMaskColorMatrixProgram(TexCoordPrecision precision) { 222 EXPECT_PROGRAM_VALID( 223 &renderer_->render_pass_mask_color_matrix_program_[precision]); 224 EXPECT_EQ( 225 renderer_->render_pass_mask_color_matrix_program_[precision].program(), 226 renderer_->program_shadow_); 227 } 228 229 void TestRenderPassProgramAA(TexCoordPrecision precision) { 230 EXPECT_PROGRAM_VALID(&renderer_->render_pass_program_aa_[precision]); 231 EXPECT_EQ(renderer_->render_pass_program_aa_[precision].program(), 232 renderer_->program_shadow_); 233 } 234 235 void TestRenderPassColorMatrixProgramAA(TexCoordPrecision precision) { 236 EXPECT_PROGRAM_VALID( 237 &renderer_->render_pass_color_matrix_program_aa_[precision]); 238 EXPECT_EQ( 239 renderer_->render_pass_color_matrix_program_aa_[precision].program(), 240 renderer_->program_shadow_); 241 } 242 243 void TestRenderPassMaskProgramAA(TexCoordPrecision precision) { 244 EXPECT_PROGRAM_VALID(&renderer_->render_pass_mask_program_aa_[precision]); 245 EXPECT_EQ(renderer_->render_pass_mask_program_aa_[precision].program(), 246 renderer_->program_shadow_); 247 } 248 249 void TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecision precision) { 250 EXPECT_PROGRAM_VALID( 251 &renderer_->render_pass_mask_color_matrix_program_aa_[precision]); 252 EXPECT_EQ(renderer_->render_pass_mask_color_matrix_program_aa_[precision] 253 .program(), 254 renderer_->program_shadow_); 255 } 256 257 void TestSolidColorProgramAA() { 258 EXPECT_PROGRAM_VALID(&renderer_->solid_color_program_aa_); 259 EXPECT_EQ(renderer_->solid_color_program_aa_.program(), 260 renderer_->program_shadow_); 261 } 262 263 LayerTreeSettings settings_; 264 FakeOutputSurfaceClient output_surface_client_; 265 scoped_ptr<FakeOutputSurface> output_surface_; 266 FakeRendererClient renderer_client_; 267 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; 268 scoped_ptr<ResourceProvider> resource_provider_; 269 scoped_ptr<FakeRendererGL> renderer_; 270 }; 271 272 namespace { 273 274 // Test GLRenderer DiscardBackbuffer functionality: 275 // Suggest discarding framebuffer when one exists and the renderer is not 276 // visible. 277 // Expected: it is discarded and damage tracker is reset. 278 TEST_F( 279 GLRendererWithDefaultHarnessTest, 280 SuggestBackbufferNoShouldDiscardBackbufferAndDamageRootLayerIfNotVisible) { 281 renderer_->SetVisible(false); 282 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count()); 283 EXPECT_TRUE(renderer_->IsBackbufferDiscarded()); 284 } 285 286 // Test GLRenderer DiscardBackbuffer functionality: 287 // Suggest discarding framebuffer when one exists and the renderer is visible. 288 // Expected: the allocation is ignored. 289 TEST_F(GLRendererWithDefaultHarnessTest, 290 SuggestBackbufferNoDoNothingWhenVisible) { 291 renderer_->SetVisible(true); 292 EXPECT_EQ(0, renderer_client_.set_full_root_layer_damage_count()); 293 EXPECT_FALSE(renderer_->IsBackbufferDiscarded()); 294 } 295 296 // Test GLRenderer DiscardBackbuffer functionality: 297 // Suggest discarding framebuffer when one does not exist. 298 // Expected: it does nothing. 299 TEST_F(GLRendererWithDefaultHarnessTest, 300 SuggestBackbufferNoWhenItDoesntExistShouldDoNothing) { 301 renderer_->SetVisible(false); 302 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count()); 303 EXPECT_TRUE(renderer_->IsBackbufferDiscarded()); 304 305 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count()); 306 EXPECT_TRUE(renderer_->IsBackbufferDiscarded()); 307 } 308 309 // Test GLRenderer DiscardBackbuffer functionality: 310 // Begin drawing a frame while a framebuffer is discarded. 311 // Expected: will recreate framebuffer. 312 TEST_F(GLRendererWithDefaultHarnessTest, 313 DiscardedBackbufferIsRecreatedForScopeDuration) { 314 gfx::Rect viewport_rect(1, 1); 315 renderer_->SetVisible(false); 316 EXPECT_TRUE(renderer_->IsBackbufferDiscarded()); 317 EXPECT_EQ(1, renderer_client_.set_full_root_layer_damage_count()); 318 319 AddRenderPass(&render_passes_in_draw_order_, 320 RenderPass::Id(1, 0), 321 viewport_rect, 322 gfx::Transform()); 323 324 renderer_->SetVisible(true); 325 renderer_->DrawFrame(&render_passes_in_draw_order_, 326 1.f, 327 viewport_rect, 328 viewport_rect, 329 false); 330 EXPECT_FALSE(renderer_->IsBackbufferDiscarded()); 331 332 SwapBuffers(); 333 EXPECT_EQ(1u, output_surface_->num_sent_frames()); 334 } 335 336 TEST_F(GLRendererWithDefaultHarnessTest, ExternalStencil) { 337 gfx::Rect viewport_rect(1, 1); 338 EXPECT_FALSE(renderer_->stencil_enabled()); 339 340 output_surface_->set_has_external_stencil_test(true); 341 342 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 343 RenderPass::Id(1, 0), 344 viewport_rect, 345 gfx::Transform()); 346 root_pass->has_transparent_background = false; 347 348 renderer_->DrawFrame(&render_passes_in_draw_order_, 349 1.f, 350 viewport_rect, 351 viewport_rect, 352 false); 353 EXPECT_TRUE(renderer_->stencil_enabled()); 354 } 355 356 class ForbidSynchronousCallContext : public TestWebGraphicsContext3D { 357 public: 358 ForbidSynchronousCallContext() {} 359 360 virtual void getAttachedShaders(GLuint program, 361 GLsizei max_count, 362 GLsizei* count, 363 GLuint* shaders) OVERRIDE { 364 ADD_FAILURE(); 365 } 366 virtual GLint getAttribLocation(GLuint program, const GLchar* name) OVERRIDE { 367 ADD_FAILURE(); 368 return 0; 369 } 370 virtual void getBooleanv(GLenum pname, GLboolean* value) OVERRIDE { 371 ADD_FAILURE(); 372 } 373 virtual void getBufferParameteriv(GLenum target, 374 GLenum pname, 375 GLint* value) OVERRIDE { 376 ADD_FAILURE(); 377 } 378 virtual GLenum getError() OVERRIDE { 379 ADD_FAILURE(); 380 return GL_NO_ERROR; 381 } 382 virtual void getFloatv(GLenum pname, GLfloat* value) OVERRIDE { 383 ADD_FAILURE(); 384 } 385 virtual void getFramebufferAttachmentParameteriv(GLenum target, 386 GLenum attachment, 387 GLenum pname, 388 GLint* value) OVERRIDE { 389 ADD_FAILURE(); 390 } 391 virtual void getIntegerv(GLenum pname, GLint* value) OVERRIDE { 392 if (pname == GL_MAX_TEXTURE_SIZE) { 393 // MAX_TEXTURE_SIZE is cached client side, so it's OK to query. 394 *value = 1024; 395 } else { 396 ADD_FAILURE(); 397 } 398 } 399 400 // We allow querying the shader compilation and program link status in debug 401 // mode, but not release. 402 virtual void getProgramiv(GLuint program, 403 GLenum pname, 404 GLint* value) OVERRIDE { 405 #ifndef NDEBUG 406 *value = 1; 407 #else 408 ADD_FAILURE(); 409 #endif 410 } 411 412 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE { 413 #ifndef NDEBUG 414 *value = 1; 415 #else 416 ADD_FAILURE(); 417 #endif 418 } 419 420 virtual void getRenderbufferParameteriv(GLenum target, 421 GLenum pname, 422 GLint* value) OVERRIDE { 423 ADD_FAILURE(); 424 } 425 426 virtual void getShaderPrecisionFormat(GLenum shadertype, 427 GLenum precisiontype, 428 GLint* range, 429 GLint* precision) OVERRIDE { 430 ADD_FAILURE(); 431 } 432 virtual void getTexParameterfv(GLenum target, 433 GLenum pname, 434 GLfloat* value) OVERRIDE { 435 ADD_FAILURE(); 436 } 437 virtual void getTexParameteriv(GLenum target, 438 GLenum pname, 439 GLint* value) OVERRIDE { 440 ADD_FAILURE(); 441 } 442 virtual void getUniformfv(GLuint program, 443 GLint location, 444 GLfloat* value) OVERRIDE { 445 ADD_FAILURE(); 446 } 447 virtual void getUniformiv(GLuint program, 448 GLint location, 449 GLint* value) OVERRIDE { 450 ADD_FAILURE(); 451 } 452 virtual GLint getUniformLocation(GLuint program, 453 const GLchar* name) OVERRIDE { 454 ADD_FAILURE(); 455 return 0; 456 } 457 virtual void getVertexAttribfv(GLuint index, 458 GLenum pname, 459 GLfloat* value) OVERRIDE { 460 ADD_FAILURE(); 461 } 462 virtual void getVertexAttribiv(GLuint index, 463 GLenum pname, 464 GLint* value) OVERRIDE { 465 ADD_FAILURE(); 466 } 467 virtual GLsizeiptr getVertexAttribOffset(GLuint index, 468 GLenum pname) OVERRIDE { 469 ADD_FAILURE(); 470 return 0; 471 } 472 }; 473 TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) { 474 FakeOutputSurfaceClient output_surface_client; 475 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 476 scoped_ptr<TestWebGraphicsContext3D>(new ForbidSynchronousCallContext))); 477 CHECK(output_surface->BindToClient(&output_surface_client)); 478 479 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 480 new TestSharedBitmapManager()); 481 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 482 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 483 484 LayerTreeSettings settings; 485 FakeRendererClient renderer_client; 486 FakeRendererGL renderer(&renderer_client, 487 &settings, 488 output_surface.get(), 489 resource_provider.get()); 490 } 491 492 class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D { 493 public: 494 LoseContextOnFirstGetContext() {} 495 496 virtual void getProgramiv(GLuint program, 497 GLenum pname, 498 GLint* value) OVERRIDE { 499 context_lost_ = true; 500 *value = 0; 501 } 502 503 virtual void getShaderiv(GLuint shader, GLenum pname, GLint* value) OVERRIDE { 504 context_lost_ = true; 505 *value = 0; 506 } 507 }; 508 509 TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) { 510 FakeOutputSurfaceClient output_surface_client; 511 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 512 scoped_ptr<TestWebGraphicsContext3D>(new LoseContextOnFirstGetContext))); 513 CHECK(output_surface->BindToClient(&output_surface_client)); 514 515 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 516 new TestSharedBitmapManager()); 517 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 518 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 519 520 LayerTreeSettings settings; 521 FakeRendererClient renderer_client; 522 FakeRendererGL renderer(&renderer_client, 523 &settings, 524 output_surface.get(), 525 resource_provider.get()); 526 } 527 528 class ClearCountingContext : public TestWebGraphicsContext3D { 529 public: 530 ClearCountingContext() { test_capabilities_.gpu.discard_framebuffer = true; } 531 532 MOCK_METHOD3(discardFramebufferEXT, 533 void(GLenum target, 534 GLsizei numAttachments, 535 const GLenum* attachments)); 536 MOCK_METHOD1(clear, void(GLbitfield mask)); 537 }; 538 539 TEST_F(GLRendererTest, OpaqueBackground) { 540 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext); 541 ClearCountingContext* context = context_owned.get(); 542 543 FakeOutputSurfaceClient output_surface_client; 544 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 545 context_owned.PassAs<TestWebGraphicsContext3D>())); 546 CHECK(output_surface->BindToClient(&output_surface_client)); 547 548 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 549 new TestSharedBitmapManager()); 550 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 551 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 552 553 LayerTreeSettings settings; 554 FakeRendererClient renderer_client; 555 FakeRendererGL renderer(&renderer_client, 556 &settings, 557 output_surface.get(), 558 resource_provider.get()); 559 560 gfx::Rect viewport_rect(1, 1); 561 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 562 RenderPass::Id(1, 0), 563 viewport_rect, 564 gfx::Transform()); 565 root_pass->has_transparent_background = false; 566 567 // On DEBUG builds, render passes with opaque background clear to blue to 568 // easily see regions that were not drawn on the screen. 569 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _)) 570 .With(Args<2, 1>(ElementsAre(GL_COLOR_EXT))) 571 .Times(1); 572 #ifdef NDEBUG 573 EXPECT_CALL(*context, clear(_)).Times(0); 574 #else 575 EXPECT_CALL(*context, clear(_)).Times(1); 576 #endif 577 renderer.DrawFrame(&render_passes_in_draw_order_, 578 1.f, 579 viewport_rect, 580 viewport_rect, 581 false); 582 Mock::VerifyAndClearExpectations(context); 583 } 584 585 TEST_F(GLRendererTest, TransparentBackground) { 586 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext); 587 ClearCountingContext* context = context_owned.get(); 588 589 FakeOutputSurfaceClient output_surface_client; 590 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 591 context_owned.PassAs<TestWebGraphicsContext3D>())); 592 CHECK(output_surface->BindToClient(&output_surface_client)); 593 594 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 595 new TestSharedBitmapManager()); 596 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 597 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 598 599 LayerTreeSettings settings; 600 FakeRendererClient renderer_client; 601 FakeRendererGL renderer(&renderer_client, 602 &settings, 603 output_surface.get(), 604 resource_provider.get()); 605 606 gfx::Rect viewport_rect(1, 1); 607 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 608 RenderPass::Id(1, 0), 609 viewport_rect, 610 gfx::Transform()); 611 root_pass->has_transparent_background = true; 612 613 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, 1, _)).Times(1); 614 EXPECT_CALL(*context, clear(_)).Times(1); 615 renderer.DrawFrame(&render_passes_in_draw_order_, 616 1.f, 617 viewport_rect, 618 viewport_rect, 619 false); 620 621 Mock::VerifyAndClearExpectations(context); 622 } 623 624 TEST_F(GLRendererTest, OffscreenOutputSurface) { 625 scoped_ptr<ClearCountingContext> context_owned(new ClearCountingContext); 626 ClearCountingContext* context = context_owned.get(); 627 628 FakeOutputSurfaceClient output_surface_client; 629 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::CreateOffscreen( 630 context_owned.PassAs<TestWebGraphicsContext3D>())); 631 CHECK(output_surface->BindToClient(&output_surface_client)); 632 633 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 634 new TestSharedBitmapManager()); 635 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 636 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 637 638 LayerTreeSettings settings; 639 FakeRendererClient renderer_client; 640 FakeRendererGL renderer(&renderer_client, 641 &settings, 642 output_surface.get(), 643 resource_provider.get()); 644 645 gfx::Rect viewport_rect(1, 1); 646 AddRenderPass(&render_passes_in_draw_order_, 647 RenderPass::Id(1, 0), 648 viewport_rect, 649 gfx::Transform()); 650 651 EXPECT_CALL(*context, discardFramebufferEXT(GL_FRAMEBUFFER, _, _)) 652 .With(Args<2, 1>(ElementsAre(GL_COLOR_ATTACHMENT0))) 653 .Times(1); 654 EXPECT_CALL(*context, clear(_)).Times(AnyNumber()); 655 renderer.DrawFrame(&render_passes_in_draw_order_, 656 1.f, 657 viewport_rect, 658 viewport_rect, 659 false); 660 Mock::VerifyAndClearExpectations(context); 661 } 662 663 class VisibilityChangeIsLastCallTrackingContext 664 : public TestWebGraphicsContext3D { 665 public: 666 VisibilityChangeIsLastCallTrackingContext() 667 : last_call_was_set_visibility_(false) {} 668 669 // TestWebGraphicsContext3D methods. 670 virtual void flush() OVERRIDE { last_call_was_set_visibility_ = false; } 671 virtual void deleteTexture(GLuint) OVERRIDE { 672 last_call_was_set_visibility_ = false; 673 } 674 virtual void deleteFramebuffer(GLuint) OVERRIDE { 675 last_call_was_set_visibility_ = false; 676 } 677 virtual void deleteQueryEXT(GLuint) OVERRIDE { 678 last_call_was_set_visibility_ = false; 679 } 680 virtual void deleteRenderbuffer(GLuint) OVERRIDE { 681 last_call_was_set_visibility_ = false; 682 } 683 684 // Methods added for test. 685 void set_last_call_was_visibility(bool visible) { 686 DCHECK(last_call_was_set_visibility_ == false); 687 last_call_was_set_visibility_ = true; 688 } 689 bool last_call_was_set_visibility() const { 690 return last_call_was_set_visibility_; 691 } 692 693 private: 694 bool last_call_was_set_visibility_; 695 }; 696 697 TEST_F(GLRendererTest, VisibilityChangeIsLastCall) { 698 scoped_ptr<VisibilityChangeIsLastCallTrackingContext> context_owned( 699 new VisibilityChangeIsLastCallTrackingContext); 700 VisibilityChangeIsLastCallTrackingContext* context = context_owned.get(); 701 702 scoped_refptr<TestContextProvider> provider = TestContextProvider::Create( 703 context_owned.PassAs<TestWebGraphicsContext3D>()); 704 705 provider->support()->SetSurfaceVisibleCallback(base::Bind( 706 &VisibilityChangeIsLastCallTrackingContext::set_last_call_was_visibility, 707 base::Unretained(context))); 708 709 FakeOutputSurfaceClient output_surface_client; 710 scoped_ptr<OutputSurface> output_surface( 711 FakeOutputSurface::Create3d(provider)); 712 CHECK(output_surface->BindToClient(&output_surface_client)); 713 714 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 715 new TestSharedBitmapManager()); 716 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 717 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 718 719 LayerTreeSettings settings; 720 FakeRendererClient renderer_client; 721 FakeRendererGL renderer(&renderer_client, 722 &settings, 723 output_surface.get(), 724 resource_provider.get()); 725 726 gfx::Rect viewport_rect(1, 1); 727 AddRenderPass(&render_passes_in_draw_order_, 728 RenderPass::Id(1, 0), 729 viewport_rect, 730 gfx::Transform()); 731 732 // Ensure that the call to SetSurfaceVisible is the last call issue to the 733 // GPU process, after glFlush is called, and after the RendererClient's 734 // SetManagedMemoryPolicy is called. Plumb this tracking between both the 735 // RenderClient and the Context by giving them both a pointer to a variable on 736 // the stack. 737 renderer.SetVisible(true); 738 renderer.DrawFrame(&render_passes_in_draw_order_, 739 1.f, 740 viewport_rect, 741 viewport_rect, 742 false); 743 renderer.SetVisible(false); 744 EXPECT_TRUE(context->last_call_was_set_visibility()); 745 } 746 747 class TextureStateTrackingContext : public TestWebGraphicsContext3D { 748 public: 749 TextureStateTrackingContext() : active_texture_(GL_INVALID_ENUM) { 750 test_capabilities_.gpu.egl_image_external = true; 751 } 752 753 MOCK_METHOD3(texParameteri, void(GLenum target, GLenum pname, GLint param)); 754 MOCK_METHOD4(drawElements, 755 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset)); 756 757 virtual void activeTexture(GLenum texture) { 758 EXPECT_NE(texture, active_texture_); 759 active_texture_ = texture; 760 } 761 762 GLenum active_texture() const { return active_texture_; } 763 764 private: 765 GLenum active_texture_; 766 }; 767 768 TEST_F(GLRendererTest, ActiveTextureState) { 769 scoped_ptr<TextureStateTrackingContext> context_owned( 770 new TextureStateTrackingContext); 771 TextureStateTrackingContext* context = context_owned.get(); 772 773 FakeOutputSurfaceClient output_surface_client; 774 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 775 context_owned.PassAs<TestWebGraphicsContext3D>())); 776 CHECK(output_surface->BindToClient(&output_surface_client)); 777 778 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 779 new TestSharedBitmapManager()); 780 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 781 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 782 783 LayerTreeSettings settings; 784 FakeRendererClient renderer_client; 785 FakeRendererGL renderer(&renderer_client, 786 &settings, 787 output_surface.get(), 788 resource_provider.get()); 789 790 // During initialization we are allowed to set any texture parameters. 791 EXPECT_CALL(*context, texParameteri(_, _, _)).Times(AnyNumber()); 792 793 RenderPass::Id id(1, 1); 794 TestRenderPass* root_pass = AddRenderPass( 795 &render_passes_in_draw_order_, id, gfx::Rect(100, 100), gfx::Transform()); 796 root_pass->AppendOneOfEveryQuadType(resource_provider.get(), 797 RenderPass::Id(2, 1)); 798 799 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 800 801 // Set up expected texture filter state transitions that match the quads 802 // created in AppendOneOfEveryQuadType(). 803 Mock::VerifyAndClearExpectations(context); 804 { 805 InSequence sequence; 806 807 // yuv_quad is drawn with the default linear filter. 808 EXPECT_CALL(*context, drawElements(_, _, _, _)); 809 810 // tile_quad is drawn with GL_NEAREST because it is not transformed or 811 // scaled. 812 EXPECT_CALL( 813 *context, 814 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); 815 EXPECT_CALL( 816 *context, 817 texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); 818 EXPECT_CALL(*context, drawElements(_, _, _, _)); 819 820 // transformed_tile_quad uses GL_LINEAR. 821 EXPECT_CALL(*context, drawElements(_, _, _, _)); 822 823 // scaled_tile_quad also uses GL_LINEAR. 824 EXPECT_CALL(*context, drawElements(_, _, _, _)); 825 826 // The remaining quads also use GL_LINEAR because nearest neighbor 827 // filtering is currently only used with tile quads. 828 EXPECT_CALL(*context, drawElements(_, _, _, _)).Times(6); 829 } 830 831 gfx::Rect viewport_rect(100, 100); 832 renderer.DrawFrame(&render_passes_in_draw_order_, 833 1.f, 834 viewport_rect, 835 viewport_rect, 836 false); 837 Mock::VerifyAndClearExpectations(context); 838 } 839 840 class NoClearRootRenderPassMockContext : public TestWebGraphicsContext3D { 841 public: 842 MOCK_METHOD1(clear, void(GLbitfield mask)); 843 MOCK_METHOD4(drawElements, 844 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset)); 845 }; 846 847 TEST_F(GLRendererTest, ShouldClearRootRenderPass) { 848 scoped_ptr<NoClearRootRenderPassMockContext> mock_context_owned( 849 new NoClearRootRenderPassMockContext); 850 NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get(); 851 852 FakeOutputSurfaceClient output_surface_client; 853 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 854 mock_context_owned.PassAs<TestWebGraphicsContext3D>())); 855 CHECK(output_surface->BindToClient(&output_surface_client)); 856 857 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 858 new TestSharedBitmapManager()); 859 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 860 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 861 862 LayerTreeSettings settings; 863 settings.should_clear_root_render_pass = false; 864 865 FakeRendererClient renderer_client; 866 FakeRendererGL renderer(&renderer_client, 867 &settings, 868 output_surface.get(), 869 resource_provider.get()); 870 871 gfx::Rect viewport_rect(10, 10); 872 873 RenderPass::Id root_pass_id(1, 0); 874 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 875 root_pass_id, 876 viewport_rect, 877 gfx::Transform()); 878 AddQuad(root_pass, viewport_rect, SK_ColorGREEN); 879 880 RenderPass::Id child_pass_id(2, 0); 881 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_, 882 child_pass_id, 883 viewport_rect, 884 gfx::Transform()); 885 AddQuad(child_pass, viewport_rect, SK_ColorBLUE); 886 887 AddRenderPassQuad(root_pass, child_pass); 888 889 #ifdef NDEBUG 890 GLint clear_bits = GL_COLOR_BUFFER_BIT; 891 #else 892 GLint clear_bits = GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; 893 #endif 894 895 // First render pass is not the root one, clearing should happen. 896 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(AtLeast(1)); 897 898 Expectation first_render_pass = 899 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(1); 900 901 // The second render pass is the root one, clearing should be prevented. 902 EXPECT_CALL(*mock_context, clear(clear_bits)).Times(0).After( 903 first_render_pass); 904 905 EXPECT_CALL(*mock_context, drawElements(_, _, _, _)).Times(AnyNumber()).After( 906 first_render_pass); 907 908 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 909 renderer.DrawFrame(&render_passes_in_draw_order_, 910 1.f, 911 viewport_rect, 912 viewport_rect, 913 false); 914 915 // In multiple render passes all but the root pass should clear the 916 // framebuffer. 917 Mock::VerifyAndClearExpectations(&mock_context); 918 } 919 920 class ScissorTestOnClearCheckingContext : public TestWebGraphicsContext3D { 921 public: 922 ScissorTestOnClearCheckingContext() : scissor_enabled_(false) {} 923 924 virtual void clear(GLbitfield) OVERRIDE { EXPECT_FALSE(scissor_enabled_); } 925 926 virtual void enable(GLenum cap) OVERRIDE { 927 if (cap == GL_SCISSOR_TEST) 928 scissor_enabled_ = true; 929 } 930 931 virtual void disable(GLenum cap) OVERRIDE { 932 if (cap == GL_SCISSOR_TEST) 933 scissor_enabled_ = false; 934 } 935 936 private: 937 bool scissor_enabled_; 938 }; 939 940 TEST_F(GLRendererTest, ScissorTestWhenClearing) { 941 scoped_ptr<ScissorTestOnClearCheckingContext> context_owned( 942 new ScissorTestOnClearCheckingContext); 943 944 FakeOutputSurfaceClient output_surface_client; 945 scoped_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( 946 context_owned.PassAs<TestWebGraphicsContext3D>())); 947 CHECK(output_surface->BindToClient(&output_surface_client)); 948 949 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 950 new TestSharedBitmapManager()); 951 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 952 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 953 954 LayerTreeSettings settings; 955 FakeRendererClient renderer_client; 956 FakeRendererGL renderer(&renderer_client, 957 &settings, 958 output_surface.get(), 959 resource_provider.get()); 960 EXPECT_FALSE(renderer.Capabilities().using_partial_swap); 961 962 gfx::Rect viewport_rect(1, 1); 963 964 gfx::Rect grand_child_rect(25, 25); 965 RenderPass::Id grand_child_pass_id(3, 0); 966 TestRenderPass* grand_child_pass = 967 AddRenderPass(&render_passes_in_draw_order_, 968 grand_child_pass_id, 969 grand_child_rect, 970 gfx::Transform()); 971 AddClippedQuad(grand_child_pass, grand_child_rect, SK_ColorYELLOW); 972 973 gfx::Rect child_rect(50, 50); 974 RenderPass::Id child_pass_id(2, 0); 975 TestRenderPass* child_pass = AddRenderPass(&render_passes_in_draw_order_, 976 child_pass_id, 977 child_rect, 978 gfx::Transform()); 979 AddQuad(child_pass, child_rect, SK_ColorBLUE); 980 981 RenderPass::Id root_pass_id(1, 0); 982 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 983 root_pass_id, 984 viewport_rect, 985 gfx::Transform()); 986 AddQuad(root_pass, viewport_rect, SK_ColorGREEN); 987 988 AddRenderPassQuad(root_pass, child_pass); 989 AddRenderPassQuad(child_pass, grand_child_pass); 990 991 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 992 renderer.DrawFrame(&render_passes_in_draw_order_, 993 1.f, 994 viewport_rect, 995 viewport_rect, 996 false); 997 } 998 999 class DiscardCheckingContext : public TestWebGraphicsContext3D { 1000 public: 1001 DiscardCheckingContext() : discarded_(0) { 1002 set_have_post_sub_buffer(true); 1003 set_have_discard_framebuffer(true); 1004 } 1005 1006 virtual void discardFramebufferEXT(GLenum target, 1007 GLsizei numAttachments, 1008 const GLenum* attachments) OVERRIDE { 1009 ++discarded_; 1010 } 1011 1012 int discarded() const { return discarded_; } 1013 void reset() { discarded_ = 0; } 1014 1015 private: 1016 int discarded_; 1017 }; 1018 1019 class NonReshapableOutputSurface : public FakeOutputSurface { 1020 public: 1021 explicit NonReshapableOutputSurface( 1022 scoped_ptr<TestWebGraphicsContext3D> context3d) 1023 : FakeOutputSurface(TestContextProvider::Create(context3d.Pass()), 1024 false) { 1025 surface_size_ = gfx::Size(500, 500); 1026 } 1027 virtual void Reshape(const gfx::Size& size, float scale_factor) OVERRIDE {} 1028 void set_fixed_size(const gfx::Size& size) { surface_size_ = size; } 1029 }; 1030 1031 TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) { 1032 scoped_ptr<DiscardCheckingContext> context_owned(new DiscardCheckingContext); 1033 DiscardCheckingContext* context = context_owned.get(); 1034 1035 FakeOutputSurfaceClient output_surface_client; 1036 scoped_ptr<NonReshapableOutputSurface> output_surface( 1037 new NonReshapableOutputSurface( 1038 context_owned.PassAs<TestWebGraphicsContext3D>())); 1039 CHECK(output_surface->BindToClient(&output_surface_client)); 1040 output_surface->set_fixed_size(gfx::Size(100, 100)); 1041 1042 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 1043 new TestSharedBitmapManager()); 1044 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 1045 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 1046 1047 LayerTreeSettings settings; 1048 settings.partial_swap_enabled = true; 1049 FakeRendererClient renderer_client; 1050 FakeRendererGL renderer(&renderer_client, 1051 &settings, 1052 output_surface.get(), 1053 resource_provider.get()); 1054 EXPECT_TRUE(renderer.Capabilities().using_partial_swap); 1055 1056 gfx::Rect viewport_rect(100, 100); 1057 gfx::Rect clip_rect(100, 100); 1058 1059 { 1060 // Partial frame, should not discard. 1061 RenderPass::Id root_pass_id(1, 0); 1062 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 1063 root_pass_id, 1064 viewport_rect, 1065 gfx::Transform()); 1066 AddQuad(root_pass, viewport_rect, SK_ColorGREEN); 1067 root_pass->damage_rect = gfx::Rect(2, 2, 3, 3); 1068 1069 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1070 renderer.DrawFrame(&render_passes_in_draw_order_, 1071 1.f, 1072 viewport_rect, 1073 clip_rect, 1074 false); 1075 EXPECT_EQ(0, context->discarded()); 1076 context->reset(); 1077 } 1078 { 1079 // Full frame, should discard. 1080 RenderPass::Id root_pass_id(1, 0); 1081 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 1082 root_pass_id, 1083 viewport_rect, 1084 gfx::Transform()); 1085 AddQuad(root_pass, viewport_rect, SK_ColorGREEN); 1086 root_pass->damage_rect = root_pass->output_rect; 1087 1088 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1089 renderer.DrawFrame(&render_passes_in_draw_order_, 1090 1.f, 1091 viewport_rect, 1092 clip_rect, 1093 false); 1094 EXPECT_EQ(1, context->discarded()); 1095 context->reset(); 1096 } 1097 { 1098 // Full frame, external scissor is set, should not discard. 1099 output_surface->set_has_external_stencil_test(true); 1100 RenderPass::Id root_pass_id(1, 0); 1101 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 1102 root_pass_id, 1103 viewport_rect, 1104 gfx::Transform()); 1105 AddQuad(root_pass, viewport_rect, SK_ColorGREEN); 1106 root_pass->damage_rect = root_pass->output_rect; 1107 root_pass->has_transparent_background = false; 1108 1109 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1110 renderer.DrawFrame(&render_passes_in_draw_order_, 1111 1.f, 1112 viewport_rect, 1113 clip_rect, 1114 false); 1115 EXPECT_EQ(0, context->discarded()); 1116 context->reset(); 1117 output_surface->set_has_external_stencil_test(false); 1118 } 1119 { 1120 // Full frame, clipped, should not discard. 1121 clip_rect = gfx::Rect(10, 10, 10, 10); 1122 RenderPass::Id root_pass_id(1, 0); 1123 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 1124 root_pass_id, 1125 viewport_rect, 1126 gfx::Transform()); 1127 AddQuad(root_pass, viewport_rect, SK_ColorGREEN); 1128 root_pass->damage_rect = root_pass->output_rect; 1129 1130 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1131 renderer.DrawFrame(&render_passes_in_draw_order_, 1132 1.f, 1133 viewport_rect, 1134 clip_rect, 1135 false); 1136 EXPECT_EQ(0, context->discarded()); 1137 context->reset(); 1138 } 1139 { 1140 // Full frame, doesn't cover the surface, should not discard. 1141 viewport_rect = gfx::Rect(10, 10, 10, 10); 1142 RenderPass::Id root_pass_id(1, 0); 1143 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 1144 root_pass_id, 1145 viewport_rect, 1146 gfx::Transform()); 1147 AddQuad(root_pass, viewport_rect, SK_ColorGREEN); 1148 root_pass->damage_rect = root_pass->output_rect; 1149 1150 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1151 renderer.DrawFrame(&render_passes_in_draw_order_, 1152 1.f, 1153 viewport_rect, 1154 clip_rect, 1155 false); 1156 EXPECT_EQ(0, context->discarded()); 1157 context->reset(); 1158 } 1159 { 1160 // Full frame, doesn't cover the surface (no offset), should not discard. 1161 clip_rect = gfx::Rect(100, 100); 1162 viewport_rect = gfx::Rect(50, 50); 1163 RenderPass::Id root_pass_id(1, 0); 1164 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 1165 root_pass_id, 1166 viewport_rect, 1167 gfx::Transform()); 1168 AddQuad(root_pass, viewport_rect, SK_ColorGREEN); 1169 root_pass->damage_rect = root_pass->output_rect; 1170 1171 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1172 renderer.DrawFrame(&render_passes_in_draw_order_, 1173 1.f, 1174 viewport_rect, 1175 clip_rect, 1176 false); 1177 EXPECT_EQ(0, context->discarded()); 1178 context->reset(); 1179 } 1180 } 1181 1182 class FlippedScissorAndViewportContext : public TestWebGraphicsContext3D { 1183 public: 1184 FlippedScissorAndViewportContext() 1185 : did_call_viewport_(false), did_call_scissor_(false) {} 1186 virtual ~FlippedScissorAndViewportContext() { 1187 EXPECT_TRUE(did_call_viewport_); 1188 EXPECT_TRUE(did_call_scissor_); 1189 } 1190 1191 virtual void viewport(GLint x, GLint y, GLsizei width, GLsizei height) 1192 OVERRIDE { 1193 EXPECT_EQ(10, x); 1194 EXPECT_EQ(390, y); 1195 EXPECT_EQ(100, width); 1196 EXPECT_EQ(100, height); 1197 did_call_viewport_ = true; 1198 } 1199 1200 virtual void scissor(GLint x, GLint y, GLsizei width, GLsizei height) 1201 OVERRIDE { 1202 EXPECT_EQ(30, x); 1203 EXPECT_EQ(450, y); 1204 EXPECT_EQ(20, width); 1205 EXPECT_EQ(20, height); 1206 did_call_scissor_ = true; 1207 } 1208 1209 private: 1210 bool did_call_viewport_; 1211 bool did_call_scissor_; 1212 }; 1213 1214 TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) { 1215 // In Android WebView, the OutputSurface is unable to respect reshape() calls 1216 // and maintains a fixed size. This test verifies that glViewport and 1217 // glScissor's Y coordinate is flipped correctly in this environment, and that 1218 // the glViewport can be at a nonzero origin within the surface. 1219 scoped_ptr<FlippedScissorAndViewportContext> context_owned( 1220 new FlippedScissorAndViewportContext); 1221 1222 FakeOutputSurfaceClient output_surface_client; 1223 scoped_ptr<OutputSurface> output_surface(new NonReshapableOutputSurface( 1224 context_owned.PassAs<TestWebGraphicsContext3D>())); 1225 CHECK(output_surface->BindToClient(&output_surface_client)); 1226 1227 scoped_ptr<SharedBitmapManager> shared_bitmap_manager( 1228 new TestSharedBitmapManager()); 1229 scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( 1230 output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); 1231 1232 LayerTreeSettings settings; 1233 FakeRendererClient renderer_client; 1234 FakeRendererGL renderer(&renderer_client, 1235 &settings, 1236 output_surface.get(), 1237 resource_provider.get()); 1238 EXPECT_FALSE(renderer.Capabilities().using_partial_swap); 1239 1240 gfx::Rect device_viewport_rect(10, 10, 100, 100); 1241 gfx::Rect viewport_rect(device_viewport_rect.size()); 1242 gfx::Rect quad_rect = gfx::Rect(20, 20, 20, 20); 1243 1244 RenderPass::Id root_pass_id(1, 0); 1245 TestRenderPass* root_pass = AddRenderPass(&render_passes_in_draw_order_, 1246 root_pass_id, 1247 viewport_rect, 1248 gfx::Transform()); 1249 AddClippedQuad(root_pass, quad_rect, SK_ColorGREEN); 1250 1251 renderer.DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1252 renderer.DrawFrame(&render_passes_in_draw_order_, 1253 1.f, 1254 device_viewport_rect, 1255 device_viewport_rect, 1256 false); 1257 } 1258 1259 TEST_F(GLRendererShaderTest, DrawRenderPassQuadShaderPermutations) { 1260 gfx::Rect viewport_rect(1, 1); 1261 1262 gfx::Rect child_rect(50, 50); 1263 RenderPass::Id child_pass_id(2, 0); 1264 TestRenderPass* child_pass; 1265 1266 RenderPass::Id root_pass_id(1, 0); 1267 TestRenderPass* root_pass; 1268 1269 ResourceProvider::ResourceId mask = resource_provider_->CreateResource( 1270 gfx::Size(20, 12), 1271 GL_CLAMP_TO_EDGE, 1272 ResourceProvider::TextureUsageAny, 1273 resource_provider_->best_texture_format()); 1274 resource_provider_->AllocateForTesting(mask); 1275 1276 SkScalar matrix[20]; 1277 float amount = 0.5f; 1278 matrix[0] = 0.213f + 0.787f * amount; 1279 matrix[1] = 0.715f - 0.715f * amount; 1280 matrix[2] = 1.f - (matrix[0] + matrix[1]); 1281 matrix[3] = matrix[4] = 0; 1282 matrix[5] = 0.213f - 0.213f * amount; 1283 matrix[6] = 0.715f + 0.285f * amount; 1284 matrix[7] = 1.f - (matrix[5] + matrix[6]); 1285 matrix[8] = matrix[9] = 0; 1286 matrix[10] = 0.213f - 0.213f * amount; 1287 matrix[11] = 0.715f - 0.715f * amount; 1288 matrix[12] = 1.f - (matrix[10] + matrix[11]); 1289 matrix[13] = matrix[14] = 0; 1290 matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0; 1291 matrix[18] = 1; 1292 skia::RefPtr<SkColorFilter> color_filter( 1293 skia::AdoptRef(SkColorMatrixFilter::Create(matrix))); 1294 skia::RefPtr<SkImageFilter> filter = skia::AdoptRef( 1295 SkColorFilterImageFilter::Create(color_filter.get(), NULL)); 1296 FilterOperations filters; 1297 filters.Append(FilterOperation::CreateReferenceFilter(filter)); 1298 1299 gfx::Transform transform_causing_aa; 1300 transform_causing_aa.Rotate(20.0); 1301 1302 // RenderPassProgram 1303 child_pass = AddRenderPass(&render_passes_in_draw_order_, 1304 child_pass_id, 1305 child_rect, 1306 gfx::Transform()); 1307 1308 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1309 root_pass_id, 1310 viewport_rect, 1311 gfx::Transform()); 1312 1313 AddRenderPassQuad( 1314 root_pass, child_pass, 0, FilterOperations(), gfx::Transform()); 1315 1316 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1317 renderer_->DrawFrame(&render_passes_in_draw_order_, 1318 1.f, 1319 viewport_rect, 1320 viewport_rect, 1321 false); 1322 TestRenderPassProgram(TexCoordPrecisionMedium); 1323 1324 // RenderPassColorMatrixProgram 1325 render_passes_in_draw_order_.clear(); 1326 1327 child_pass = AddRenderPass(&render_passes_in_draw_order_, 1328 child_pass_id, 1329 child_rect, 1330 transform_causing_aa); 1331 1332 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1333 root_pass_id, 1334 viewport_rect, 1335 gfx::Transform()); 1336 1337 AddRenderPassQuad(root_pass, child_pass, 0, filters, gfx::Transform()); 1338 1339 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1340 renderer_->DrawFrame(&render_passes_in_draw_order_, 1341 1.f, 1342 viewport_rect, 1343 viewport_rect, 1344 false); 1345 TestRenderPassColorMatrixProgram(TexCoordPrecisionMedium); 1346 1347 // RenderPassMaskProgram 1348 render_passes_in_draw_order_.clear(); 1349 1350 child_pass = AddRenderPass(&render_passes_in_draw_order_, 1351 child_pass_id, 1352 child_rect, 1353 gfx::Transform()); 1354 1355 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1356 root_pass_id, 1357 viewport_rect, 1358 gfx::Transform()); 1359 1360 AddRenderPassQuad( 1361 root_pass, child_pass, mask, FilterOperations(), gfx::Transform()); 1362 1363 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1364 renderer_->DrawFrame(&render_passes_in_draw_order_, 1365 1.f, 1366 viewport_rect, 1367 viewport_rect, 1368 false); 1369 TestRenderPassMaskProgram(TexCoordPrecisionMedium); 1370 1371 // RenderPassMaskColorMatrixProgram 1372 render_passes_in_draw_order_.clear(); 1373 1374 child_pass = AddRenderPass(&render_passes_in_draw_order_, 1375 child_pass_id, 1376 child_rect, 1377 gfx::Transform()); 1378 1379 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1380 root_pass_id, 1381 viewport_rect, 1382 gfx::Transform()); 1383 1384 AddRenderPassQuad(root_pass, child_pass, mask, filters, gfx::Transform()); 1385 1386 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1387 renderer_->DrawFrame(&render_passes_in_draw_order_, 1388 1.f, 1389 viewport_rect, 1390 viewport_rect, 1391 false); 1392 TestRenderPassMaskColorMatrixProgram(TexCoordPrecisionMedium); 1393 1394 // RenderPassProgramAA 1395 render_passes_in_draw_order_.clear(); 1396 1397 child_pass = AddRenderPass(&render_passes_in_draw_order_, 1398 child_pass_id, 1399 child_rect, 1400 transform_causing_aa); 1401 1402 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1403 root_pass_id, 1404 viewport_rect, 1405 gfx::Transform()); 1406 1407 AddRenderPassQuad( 1408 root_pass, child_pass, 0, FilterOperations(), transform_causing_aa); 1409 1410 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1411 renderer_->DrawFrame(&render_passes_in_draw_order_, 1412 1.f, 1413 viewport_rect, 1414 viewport_rect, 1415 false); 1416 TestRenderPassProgramAA(TexCoordPrecisionMedium); 1417 1418 // RenderPassColorMatrixProgramAA 1419 render_passes_in_draw_order_.clear(); 1420 1421 child_pass = AddRenderPass(&render_passes_in_draw_order_, 1422 child_pass_id, 1423 child_rect, 1424 transform_causing_aa); 1425 1426 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1427 root_pass_id, 1428 viewport_rect, 1429 gfx::Transform()); 1430 1431 AddRenderPassQuad(root_pass, child_pass, 0, filters, transform_causing_aa); 1432 1433 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1434 renderer_->DrawFrame(&render_passes_in_draw_order_, 1435 1.f, 1436 viewport_rect, 1437 viewport_rect, 1438 false); 1439 TestRenderPassColorMatrixProgramAA(TexCoordPrecisionMedium); 1440 1441 // RenderPassMaskProgramAA 1442 render_passes_in_draw_order_.clear(); 1443 1444 child_pass = AddRenderPass(&render_passes_in_draw_order_, 1445 child_pass_id, 1446 child_rect, 1447 transform_causing_aa); 1448 1449 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1450 root_pass_id, 1451 viewport_rect, 1452 gfx::Transform()); 1453 1454 AddRenderPassQuad( 1455 root_pass, child_pass, mask, FilterOperations(), transform_causing_aa); 1456 1457 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1458 renderer_->DrawFrame(&render_passes_in_draw_order_, 1459 1.f, 1460 viewport_rect, 1461 viewport_rect, 1462 false); 1463 TestRenderPassMaskProgramAA(TexCoordPrecisionMedium); 1464 1465 // RenderPassMaskColorMatrixProgramAA 1466 render_passes_in_draw_order_.clear(); 1467 1468 child_pass = AddRenderPass(&render_passes_in_draw_order_, 1469 child_pass_id, 1470 child_rect, 1471 transform_causing_aa); 1472 1473 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1474 root_pass_id, 1475 viewport_rect, 1476 transform_causing_aa); 1477 1478 AddRenderPassQuad(root_pass, child_pass, mask, filters, transform_causing_aa); 1479 1480 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1481 renderer_->DrawFrame(&render_passes_in_draw_order_, 1482 1.f, 1483 viewport_rect, 1484 viewport_rect, 1485 false); 1486 TestRenderPassMaskColorMatrixProgramAA(TexCoordPrecisionMedium); 1487 } 1488 1489 // At this time, the AA code path cannot be taken if the surface's rect would 1490 // project incorrectly by the given transform, because of w<0 clipping. 1491 TEST_F(GLRendererShaderTest, DrawRenderPassQuadSkipsAAForClippingTransform) { 1492 gfx::Rect child_rect(50, 50); 1493 RenderPass::Id child_pass_id(2, 0); 1494 TestRenderPass* child_pass; 1495 1496 gfx::Rect viewport_rect(1, 1); 1497 RenderPass::Id root_pass_id(1, 0); 1498 TestRenderPass* root_pass; 1499 1500 gfx::Transform transform_preventing_aa; 1501 transform_preventing_aa.ApplyPerspectiveDepth(40.0); 1502 transform_preventing_aa.RotateAboutYAxis(-20.0); 1503 transform_preventing_aa.Scale(30.0, 1.0); 1504 1505 // Verify that the test transform and test rect actually do cause the clipped 1506 // flag to trigger. Otherwise we are not testing the intended scenario. 1507 bool clipped = false; 1508 MathUtil::MapQuad(transform_preventing_aa, gfx::QuadF(child_rect), &clipped); 1509 ASSERT_TRUE(clipped); 1510 1511 child_pass = AddRenderPass(&render_passes_in_draw_order_, 1512 child_pass_id, 1513 child_rect, 1514 transform_preventing_aa); 1515 1516 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1517 root_pass_id, 1518 viewport_rect, 1519 gfx::Transform()); 1520 1521 AddRenderPassQuad( 1522 root_pass, child_pass, 0, FilterOperations(), transform_preventing_aa); 1523 1524 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1525 renderer_->DrawFrame(&render_passes_in_draw_order_, 1526 1.f, 1527 viewport_rect, 1528 viewport_rect, 1529 false); 1530 1531 // If use_aa incorrectly ignores clipping, it will use the 1532 // RenderPassProgramAA shader instead of the RenderPassProgram. 1533 TestRenderPassProgram(TexCoordPrecisionMedium); 1534 } 1535 1536 TEST_F(GLRendererShaderTest, DrawSolidColorShader) { 1537 gfx::Rect viewport_rect(1, 1); 1538 RenderPass::Id root_pass_id(1, 0); 1539 TestRenderPass* root_pass; 1540 1541 gfx::Transform pixel_aligned_transform_causing_aa; 1542 pixel_aligned_transform_causing_aa.Translate(25.5f, 25.5f); 1543 pixel_aligned_transform_causing_aa.Scale(0.5f, 0.5f); 1544 1545 root_pass = AddRenderPass(&render_passes_in_draw_order_, 1546 root_pass_id, 1547 viewport_rect, 1548 gfx::Transform()); 1549 AddTransformedQuad(root_pass, 1550 viewport_rect, 1551 SK_ColorYELLOW, 1552 pixel_aligned_transform_causing_aa); 1553 1554 renderer_->DecideRenderPassAllocationsForFrame(render_passes_in_draw_order_); 1555 renderer_->DrawFrame(&render_passes_in_draw_order_, 1556 1.f, 1557 viewport_rect, 1558 viewport_rect, 1559 false); 1560 1561 TestSolidColorProgramAA(); 1562 } 1563 1564 class OutputSurfaceMockContext : public TestWebGraphicsContext3D { 1565 public: 1566 OutputSurfaceMockContext() { test_capabilities_.gpu.post_sub_buffer = true; } 1567 1568 // Specifically override methods even if they are unused (used in conjunction 1569 // with StrictMock). We need to make sure that GLRenderer does not issue 1570 // framebuffer-related GLuint calls directly. Instead these are supposed to go 1571 // through the OutputSurface abstraction. 1572 MOCK_METHOD2(bindFramebuffer, void(GLenum target, GLuint framebuffer)); 1573 MOCK_METHOD3(reshapeWithScaleFactor, 1574 void(int width, int height, float scale_factor)); 1575 MOCK_METHOD4(drawElements, 1576 void(GLenum mode, GLsizei count, GLenum type, GLintptr offset)); 1577 }; 1578 1579 class MockOutputSurface : public OutputSurface { 1580 public: 1581 MockOutputSurface() 1582 : OutputSurface( 1583 TestContextProvider::Create(scoped_ptr<TestWebGraphicsContext3D>( 1584 new StrictMock<OutputSurfaceMockContext>))) { 1585 surface_size_ = gfx::Size(100, 100); 1586 } 1587 virtual ~MockOutputSurface() {} 1588 1589 MOCK_METHOD0(EnsureBackbuffer, void()); 1590 MOCK_METHOD0(DiscardBackbuffer, void()); 1591 MOCK_METHOD2(Reshape, void(const gfx::Size& size, float scale_factor)); 1592 MOCK_METHOD0(BindFramebuffer, void()); 1593 MOCK_METHOD1(SwapBuffers, void(CompositorFrame* frame)); 1594 }; 1595 1596 class MockOutputSurfaceTest : public GLRendererTest { 1597 protected: 1598 virtual void SetUp() { 1599 FakeOutputSurfaceClient output_surface_client_; 1600 CHECK(output_surface_.BindToClient(&output_surface_client_)); 1601 1602 shared_bitmap_manager_.reset(new TestSharedBitmapManager()); 1603 resource_provider_ = 1604 ResourceProvider::Create( 1605 &output_surface_, shared_bitmap_manager_.get(), 0, false, 1, false) 1606 .Pass(); 1607 1608 renderer_.reset(new FakeRendererGL(&renderer_client_, 1609 &settings_, 1610 &output_surface_, 1611 resource_provider_.get())); 1612 } 1613 1614 void SwapBuffers() { renderer_->SwapBuffers(CompositorFrameMetadata()); } 1615 1616 void DrawFrame(float device_scale_factor, 1617 const gfx::Rect& device_viewport_rect) { 1618 RenderPass::Id render_pass_id(1, 0); 1619 TestRenderPass* render_pass = AddRenderPass(&render_passes_in_draw_order_, 1620 render_pass_id, 1621 device_viewport_rect, 1622 gfx::Transform()); 1623 AddQuad(render_pass, device_viewport_rect, SK_ColorGREEN); 1624 1625 EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return()); 1626 1627 EXPECT_CALL(output_surface_, 1628 Reshape(device_viewport_rect.size(), device_scale_factor)) 1629 .Times(1); 1630 1631 EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1); 1632 1633 EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1); 1634 1635 renderer_->DecideRenderPassAllocationsForFrame( 1636 render_passes_in_draw_order_); 1637 renderer_->DrawFrame(&render_passes_in_draw_order_, 1638 device_scale_factor, 1639 device_viewport_rect, 1640 device_viewport_rect, 1641 false); 1642 } 1643 1644 OutputSurfaceMockContext* Context() { 1645 return static_cast<OutputSurfaceMockContext*>( 1646 static_cast<TestContextProvider*>( 1647 output_surface_.context_provider().get())->TestContext3d()); 1648 } 1649 1650 LayerTreeSettings settings_; 1651 FakeOutputSurfaceClient output_surface_client_; 1652 StrictMock<MockOutputSurface> output_surface_; 1653 scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; 1654 scoped_ptr<ResourceProvider> resource_provider_; 1655 FakeRendererClient renderer_client_; 1656 scoped_ptr<FakeRendererGL> renderer_; 1657 }; 1658 1659 TEST_F(MockOutputSurfaceTest, DrawFrameAndSwap) { 1660 gfx::Rect device_viewport_rect(1, 1); 1661 DrawFrame(1.f, device_viewport_rect); 1662 1663 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1664 renderer_->SwapBuffers(CompositorFrameMetadata()); 1665 } 1666 1667 TEST_F(MockOutputSurfaceTest, DrawFrameAndResizeAndSwap) { 1668 gfx::Rect device_viewport_rect(1, 1); 1669 1670 DrawFrame(1.f, device_viewport_rect); 1671 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1672 renderer_->SwapBuffers(CompositorFrameMetadata()); 1673 1674 device_viewport_rect = gfx::Rect(2, 2); 1675 1676 DrawFrame(2.f, device_viewport_rect); 1677 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1678 renderer_->SwapBuffers(CompositorFrameMetadata()); 1679 1680 DrawFrame(2.f, device_viewport_rect); 1681 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1682 renderer_->SwapBuffers(CompositorFrameMetadata()); 1683 1684 device_viewport_rect = gfx::Rect(1, 1); 1685 1686 DrawFrame(1.f, device_viewport_rect); 1687 EXPECT_CALL(output_surface_, SwapBuffers(_)).Times(1); 1688 renderer_->SwapBuffers(CompositorFrameMetadata()); 1689 } 1690 1691 class GLRendererTestSyncPoint : public GLRendererPixelTest { 1692 protected: 1693 static void SyncPointCallback(int* callback_count) { 1694 ++(*callback_count); 1695 base::MessageLoop::current()->QuitWhenIdle(); 1696 } 1697 1698 static void OtherCallback(int* callback_count) { 1699 ++(*callback_count); 1700 base::MessageLoop::current()->QuitWhenIdle(); 1701 } 1702 }; 1703 1704 #if !defined(OS_ANDROID) 1705 TEST_F(GLRendererTestSyncPoint, SignalSyncPointOnLostContext) { 1706 int sync_point_callback_count = 0; 1707 int other_callback_count = 0; 1708 gpu::gles2::GLES2Interface* gl = 1709 output_surface_->context_provider()->ContextGL(); 1710 gpu::ContextSupport* context_support = 1711 output_surface_->context_provider()->ContextSupport(); 1712 1713 uint32 sync_point = gl->InsertSyncPointCHROMIUM(); 1714 1715 gl->LoseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, 1716 GL_INNOCENT_CONTEXT_RESET_ARB); 1717 1718 context_support->SignalSyncPoint( 1719 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count)); 1720 EXPECT_EQ(0, sync_point_callback_count); 1721 EXPECT_EQ(0, other_callback_count); 1722 1723 // Make the sync point happen. 1724 gl->Finish(); 1725 // Post a task after the sync point. 1726 base::MessageLoop::current()->PostTask( 1727 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count)); 1728 1729 base::MessageLoop::current()->Run(); 1730 1731 // The sync point shouldn't have happened since the context was lost. 1732 EXPECT_EQ(0, sync_point_callback_count); 1733 EXPECT_EQ(1, other_callback_count); 1734 } 1735 1736 TEST_F(GLRendererTestSyncPoint, SignalSyncPoint) { 1737 int sync_point_callback_count = 0; 1738 int other_callback_count = 0; 1739 1740 gpu::gles2::GLES2Interface* gl = 1741 output_surface_->context_provider()->ContextGL(); 1742 gpu::ContextSupport* context_support = 1743 output_surface_->context_provider()->ContextSupport(); 1744 1745 uint32 sync_point = gl->InsertSyncPointCHROMIUM(); 1746 1747 context_support->SignalSyncPoint( 1748 sync_point, base::Bind(&SyncPointCallback, &sync_point_callback_count)); 1749 EXPECT_EQ(0, sync_point_callback_count); 1750 EXPECT_EQ(0, other_callback_count); 1751 1752 // Make the sync point happen. 1753 gl->Finish(); 1754 // Post a task after the sync point. 1755 base::MessageLoop::current()->PostTask( 1756 FROM_HERE, base::Bind(&OtherCallback, &other_callback_count)); 1757 1758 base::MessageLoop::current()->Run(); 1759 1760 // The sync point should have happened. 1761 EXPECT_EQ(1, sync_point_callback_count); 1762 EXPECT_EQ(1, other_callback_count); 1763 } 1764 #endif // OS_ANDROID 1765 1766 } // namespace 1767 } // namespace cc 1768