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