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/layers/texture_layer.h" 6 7#include <string> 8 9#include "base/callback.h" 10#include "cc/layers/texture_layer_client.h" 11#include "cc/layers/texture_layer_impl.h" 12#include "cc/test/fake_impl_proxy.h" 13#include "cc/test/fake_layer_tree_host_client.h" 14#include "cc/test/fake_layer_tree_host_impl.h" 15#include "cc/test/layer_test_common.h" 16#include "cc/test/layer_tree_test.h" 17#include "cc/trees/layer_tree_host.h" 18#include "cc/trees/layer_tree_impl.h" 19#include "cc/trees/single_thread_proxy.h" 20#include "gpu/GLES2/gl2extchromium.h" 21#include "testing/gmock/include/gmock/gmock.h" 22#include "testing/gtest/include/gtest/gtest.h" 23 24using ::testing::Mock; 25using ::testing::_; 26using ::testing::AtLeast; 27using ::testing::AnyNumber; 28 29namespace cc { 30namespace { 31 32class MockLayerTreeHost : public LayerTreeHost { 33 public: 34 explicit MockLayerTreeHost(LayerTreeHostClient* client) 35 : LayerTreeHost(client, LayerTreeSettings()) { 36 Initialize(NULL); 37 } 38 39 MOCK_METHOD0(AcquireLayerTextures, void()); 40 MOCK_METHOD0(SetNeedsCommit, void()); 41 MOCK_METHOD0(SetNeedsUpdateLayers, void()); 42 MOCK_METHOD1(StartRateLimiter, void(WebKit::WebGraphicsContext3D* context)); 43 MOCK_METHOD1(StopRateLimiter, void(WebKit::WebGraphicsContext3D* context)); 44}; 45 46class TextureLayerTest : public testing::Test { 47 public: 48 TextureLayerTest() 49 : fake_client_( 50 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)), 51 host_impl_(&proxy_) {} 52 53 protected: 54 virtual void SetUp() { 55 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_)); 56 } 57 58 virtual void TearDown() { 59 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 60 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber()); 61 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); 62 63 layer_tree_host_->SetRootLayer(NULL); 64 layer_tree_host_.reset(); 65 } 66 67 scoped_ptr<MockLayerTreeHost> layer_tree_host_; 68 FakeImplProxy proxy_; 69 FakeLayerTreeHostClient fake_client_; 70 FakeLayerTreeHostImpl host_impl_; 71}; 72 73TEST_F(TextureLayerTest, SyncImplWhenChangingTextureId) { 74 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL); 75 ASSERT_TRUE(test_layer.get()); 76 77 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber()); 78 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); 79 layer_tree_host_->SetRootLayer(test_layer); 80 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 81 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get()); 82 83 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 84 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 85 test_layer->SetTextureId(1); 86 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 87 88 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1)); 89 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 90 test_layer->SetTextureId(2); 91 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 92 93 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1)); 94 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 95 test_layer->SetTextureId(0); 96 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 97} 98 99TEST_F(TextureLayerTest, SyncImplWhenDrawing) { 100 gfx::RectF dirty_rect(0.f, 0.f, 1.f, 1.f); 101 102 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL); 103 ASSERT_TRUE(test_layer.get()); 104 scoped_ptr<TextureLayerImpl> impl_layer; 105 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, false); 106 ASSERT_TRUE(impl_layer); 107 108 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber()); 109 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); 110 layer_tree_host_->SetRootLayer(test_layer); 111 test_layer->SetTextureId(1); 112 test_layer->SetIsDrawable(true); 113 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 114 EXPECT_EQ(test_layer->layer_tree_host(), layer_tree_host_.get()); 115 116 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1); 117 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); 118 test_layer->WillModifyTexture(); 119 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 120 121 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 122 EXPECT_CALL(*layer_tree_host_, SetNeedsUpdateLayers()).Times(1); 123 test_layer->SetNeedsDisplayRect(dirty_rect); 124 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 125 126 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 127 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); 128 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit 129 test_layer->SetIsDrawable(false); 130 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 131 132 // Verify that non-drawable layers don't signal the compositor, 133 // except for the first draw after last commit, which must acquire 134 // the texture. 135 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(1); 136 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); 137 test_layer->WillModifyTexture(); 138 test_layer->SetNeedsDisplayRect(dirty_rect); 139 test_layer->PushPropertiesTo(impl_layer.get()); // fake commit 140 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 141 142 // Second draw with layer in non-drawable state: no texture 143 // acquisition. 144 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 145 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(0); 146 test_layer->WillModifyTexture(); 147 test_layer->SetNeedsDisplayRect(dirty_rect); 148 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 149} 150 151TEST_F(TextureLayerTest, SyncImplWhenRemovingFromTree) { 152 scoped_refptr<Layer> root_layer = Layer::Create(); 153 ASSERT_TRUE(root_layer.get()); 154 scoped_refptr<Layer> child_layer = Layer::Create(); 155 ASSERT_TRUE(child_layer.get()); 156 root_layer->AddChild(child_layer); 157 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL); 158 ASSERT_TRUE(test_layer.get()); 159 test_layer->SetTextureId(0); 160 child_layer->AddChild(test_layer); 161 162 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber()); 163 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); 164 layer_tree_host_->SetRootLayer(root_layer); 165 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 166 167 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 168 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 169 test_layer->RemoveFromParent(); 170 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 171 172 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 173 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 174 child_layer->AddChild(test_layer); 175 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 176 177 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 178 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 179 test_layer->SetTextureId(1); 180 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 181 182 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AtLeast(1)); 183 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 184 test_layer->RemoveFromParent(); 185 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 186} 187 188TEST_F(TextureLayerTest, CheckPropertyChangeCausesCorrectBehavior) { 189 scoped_refptr<TextureLayer> test_layer = TextureLayer::Create(NULL); 190 layer_tree_host_->SetRootLayer(test_layer); 191 192 // Test properties that should call SetNeedsCommit. All properties need to 193 // be set to new values in order for SetNeedsCommit to be called. 194 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetFlipped(false)); 195 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUV( 196 gfx::PointF(0.25f, 0.25f), gfx::PointF(0.75f, 0.75f))); 197 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetVertexOpacity( 198 0.5f, 0.5f, 0.5f, 0.5f)); 199 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPremultipliedAlpha(false)); 200 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendBackgroundColor(true)); 201 EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTextureId(1)); 202 203 // Calling SetTextureId can call AcquireLayerTextures. 204 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(AnyNumber()); 205} 206 207TEST_F(TextureLayerTest, VisibleContentOpaqueRegion) { 208 const gfx::Size layer_bounds(100, 100); 209 const gfx::Rect layer_rect(layer_bounds); 210 const Region layer_region(layer_rect); 211 212 scoped_refptr<TextureLayer> layer = TextureLayer::Create(NULL); 213 layer->SetBounds(layer_bounds); 214 layer->draw_properties().visible_content_rect = layer_rect; 215 layer->SetBlendBackgroundColor(true); 216 217 // Verify initial conditions. 218 EXPECT_FALSE(layer->contents_opaque()); 219 EXPECT_EQ(0u, layer->background_color()); 220 EXPECT_EQ(Region().ToString(), 221 layer->VisibleContentOpaqueRegion().ToString()); 222 223 // Opaque background. 224 layer->SetBackgroundColor(SK_ColorWHITE); 225 EXPECT_EQ(layer_region.ToString(), 226 layer->VisibleContentOpaqueRegion().ToString()); 227 228 // Transparent background. 229 layer->SetBackgroundColor(SkColorSetARGB(100, 255, 255, 255)); 230 EXPECT_EQ(Region().ToString(), 231 layer->VisibleContentOpaqueRegion().ToString()); 232} 233 234class FakeTextureLayerClient : public TextureLayerClient { 235 public: 236 FakeTextureLayerClient() : context_(TestWebGraphicsContext3D::Create()) {} 237 238 virtual unsigned PrepareTexture() OVERRIDE { 239 return 0; 240 } 241 242 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { 243 return context_.get(); 244 } 245 246 virtual bool PrepareTextureMailbox(TextureMailbox* mailbox, 247 bool use_shared_memory) OVERRIDE { 248 *mailbox = TextureMailbox(); 249 return true; 250 } 251 252 private: 253 scoped_ptr<TestWebGraphicsContext3D> context_; 254 DISALLOW_COPY_AND_ASSIGN(FakeTextureLayerClient); 255}; 256 257TEST_F(TextureLayerTest, RateLimiter) { 258 FakeTextureLayerClient client; 259 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox( 260 &client); 261 test_layer->SetIsDrawable(true); 262 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); 263 layer_tree_host_->SetRootLayer(test_layer); 264 265 // Don't rate limit until we invalidate. 266 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(_)).Times(0); 267 test_layer->SetRateLimitContext(true); 268 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 269 270 // Do rate limit after we invalidate. 271 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(client.Context3d())); 272 test_layer->SetNeedsDisplay(); 273 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 274 275 // Stop rate limiter when we don't want it any more. 276 EXPECT_CALL(*layer_tree_host_, StopRateLimiter(client.Context3d())); 277 test_layer->SetRateLimitContext(false); 278 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 279 280 // Or we clear the client. 281 test_layer->SetRateLimitContext(true); 282 EXPECT_CALL(*layer_tree_host_, StopRateLimiter(client.Context3d())); 283 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); 284 test_layer->ClearClient(); 285 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 286 287 // Reset to a layer with a client, that started the rate limiter. 288 test_layer = TextureLayer::CreateForMailbox( 289 &client); 290 test_layer->SetIsDrawable(true); 291 test_layer->SetRateLimitContext(true); 292 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); 293 layer_tree_host_->SetRootLayer(test_layer); 294 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(_)).Times(0); 295 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 296 EXPECT_CALL(*layer_tree_host_, StartRateLimiter(client.Context3d())); 297 test_layer->SetNeedsDisplay(); 298 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 299 300 // Stop rate limiter when we're removed from the tree. 301 EXPECT_CALL(*layer_tree_host_, StopRateLimiter(client.Context3d())); 302 layer_tree_host_->SetRootLayer(NULL); 303 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 304} 305 306class MockMailboxCallback { 307 public: 308 MOCK_METHOD3(Release, void(const std::string& mailbox, 309 unsigned sync_point, 310 bool lost_resource)); 311 MOCK_METHOD3(Release2, void(base::SharedMemory* shared_memory, 312 unsigned sync_point, 313 bool lost_resource)); 314}; 315 316struct CommonMailboxObjects { 317 CommonMailboxObjects() 318 : mailbox_name1_(64, '1'), 319 mailbox_name2_(64, '2'), 320 sync_point1_(1), 321 sync_point2_(2), 322 shared_memory_(new base::SharedMemory) { 323 release_mailbox1_ = base::Bind(&MockMailboxCallback::Release, 324 base::Unretained(&mock_callback_), 325 mailbox_name1_); 326 release_mailbox2_ = base::Bind(&MockMailboxCallback::Release, 327 base::Unretained(&mock_callback_), 328 mailbox_name2_); 329 gpu::Mailbox m1; 330 m1.SetName(reinterpret_cast<const int8*>(mailbox_name1_.data())); 331 mailbox1_ = TextureMailbox(m1, release_mailbox1_, sync_point1_); 332 gpu::Mailbox m2; 333 m2.SetName(reinterpret_cast<const int8*>(mailbox_name2_.data())); 334 mailbox2_ = TextureMailbox(m2, release_mailbox2_, sync_point2_); 335 336 gfx::Size size(128, 128); 337 EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea())); 338 release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2, 339 base::Unretained(&mock_callback_), 340 shared_memory_.get()); 341 mailbox3_ = TextureMailbox(shared_memory_.get(), size, release_mailbox3_); 342 } 343 344 std::string mailbox_name1_; 345 std::string mailbox_name2_; 346 MockMailboxCallback mock_callback_; 347 TextureMailbox::ReleaseCallback release_mailbox1_; 348 TextureMailbox::ReleaseCallback release_mailbox2_; 349 TextureMailbox::ReleaseCallback release_mailbox3_; 350 TextureMailbox mailbox1_; 351 TextureMailbox mailbox2_; 352 TextureMailbox mailbox3_; 353 unsigned sync_point1_; 354 unsigned sync_point2_; 355 scoped_ptr<base::SharedMemory> shared_memory_; 356}; 357 358class TextureLayerWithMailboxTest : public TextureLayerTest { 359 protected: 360 virtual void TearDown() { 361 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 362 EXPECT_CALL(test_data_.mock_callback_, 363 Release(test_data_.mailbox_name1_, 364 test_data_.sync_point1_, 365 false)).Times(1); 366 TextureLayerTest::TearDown(); 367 } 368 369 CommonMailboxObjects test_data_; 370}; 371 372TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) { 373 scoped_refptr<TextureLayer> test_layer = TextureLayer::CreateForMailbox(NULL); 374 ASSERT_TRUE(test_layer.get()); 375 376 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 377 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); 378 layer_tree_host_->SetRootLayer(test_layer); 379 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 380 381 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 382 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 383 test_layer->SetTextureMailbox(test_data_.mailbox1_); 384 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 385 386 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 387 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 388 EXPECT_CALL(test_data_.mock_callback_, 389 Release(test_data_.mailbox_name1_, 390 test_data_.sync_point1_, 391 false)) 392 .Times(1); 393 test_layer->SetTextureMailbox(test_data_.mailbox2_); 394 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 395 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 396 397 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 398 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 399 EXPECT_CALL(test_data_.mock_callback_, 400 Release(test_data_.mailbox_name2_, 401 test_data_.sync_point2_, 402 false)) 403 .Times(1); 404 test_layer->SetTextureMailbox(TextureMailbox()); 405 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 406 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 407 408 test_layer->SetTextureMailbox(test_data_.mailbox3_); 409 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 410 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 411 412 EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); 413 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 414 EXPECT_CALL(test_data_.mock_callback_, 415 Release2(test_data_.shared_memory_.get(), 416 0, false)) 417 .Times(1); 418 test_layer->SetTextureMailbox(TextureMailbox()); 419 Mock::VerifyAndClearExpectations(layer_tree_host_.get()); 420 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 421 422 // Test destructor. 423 EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); 424 test_layer->SetTextureMailbox(test_data_.mailbox1_); 425} 426 427class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest { 428 public: 429 TextureLayerImplWithMailboxThreadedCallback() 430 : callback_count_(0), 431 commit_count_(0) {} 432 433 // Make sure callback is received on main and doesn't block the impl thread. 434 void ReleaseCallback(unsigned sync_point, bool lost_resource) { 435 EXPECT_EQ(true, proxy()->IsMainThread()); 436 EXPECT_FALSE(lost_resource); 437 ++callback_count_; 438 } 439 440 void SetMailbox(char mailbox_char) { 441 TextureMailbox mailbox( 442 std::string(64, mailbox_char), 443 base::Bind( 444 &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback, 445 base::Unretained(this))); 446 layer_->SetTextureMailbox(mailbox); 447 } 448 449 virtual void BeginTest() OVERRIDE { 450 gfx::Size bounds(100, 100); 451 root_ = Layer::Create(); 452 root_->SetAnchorPoint(gfx::PointF()); 453 root_->SetBounds(bounds); 454 455 layer_ = TextureLayer::CreateForMailbox(NULL); 456 layer_->SetIsDrawable(true); 457 layer_->SetAnchorPoint(gfx::PointF()); 458 layer_->SetBounds(bounds); 459 460 root_->AddChild(layer_); 461 layer_tree_host()->SetRootLayer(root_); 462 layer_tree_host()->SetViewportSize(bounds); 463 SetMailbox('1'); 464 EXPECT_EQ(0, callback_count_); 465 466 // Case #1: change mailbox before the commit. The old mailbox should be 467 // released immediately. 468 SetMailbox('2'); 469 EXPECT_EQ(1, callback_count_); 470 PostSetNeedsCommitToMainThread(); 471 } 472 473 virtual void DidCommit() OVERRIDE { 474 ++commit_count_; 475 switch (commit_count_) { 476 case 1: 477 // Case #2: change mailbox after the commit (and draw), where the 478 // layer draws. The old mailbox should be released during the next 479 // commit. 480 SetMailbox('3'); 481 EXPECT_EQ(1, callback_count_); 482 break; 483 case 2: 484 // Old mailbox was released, task was posted, but won't execute 485 // until this DidCommit returns. 486 // TODO(piman): fix this. 487 EXPECT_EQ(1, callback_count_); 488 layer_tree_host()->SetNeedsCommit(); 489 break; 490 case 3: 491 EXPECT_EQ(2, callback_count_); 492 // Case #3: change mailbox when the layer doesn't draw. The old 493 // mailbox should be released during the next commit. 494 layer_->SetBounds(gfx::Size()); 495 SetMailbox('4'); 496 break; 497 case 4: 498 // Old mailbox was released, task was posted, but won't execute 499 // until this DidCommit returns. 500 // TODO(piman): fix this. 501 EXPECT_EQ(2, callback_count_); 502 layer_tree_host()->SetNeedsCommit(); 503 break; 504 case 5: 505 EXPECT_EQ(3, callback_count_); 506 // Case #4: release mailbox that was committed but never drawn. The 507 // old mailbox should be released during the next commit. 508 layer_->SetTextureMailbox(TextureMailbox()); 509 break; 510 case 6: 511 // Old mailbox was released, task was posted, but won't execute 512 // until this DidCommit returns. 513 // TODO(piman): fix this. 514 EXPECT_EQ(3, callback_count_); 515 layer_tree_host()->SetNeedsCommit(); 516 break; 517 case 7: 518 EXPECT_EQ(4, callback_count_); 519 // Restore a mailbox for the next step. 520 SetMailbox('5'); 521 break; 522 case 8: 523 // Case #5: remove layer from tree. Callback should *not* be called, the 524 // mailbox is returned to the main thread. 525 EXPECT_EQ(4, callback_count_); 526 layer_->RemoveFromParent(); 527 break; 528 case 9: 529 // Mailbox was released to the main thread, task was posted, but won't 530 // execute until this DidCommit returns. 531 // TODO(piman): fix this. 532 EXPECT_EQ(4, callback_count_); 533 layer_tree_host()->SetNeedsCommit(); 534 break; 535 case 10: 536 EXPECT_EQ(4, callback_count_); 537 // Resetting the mailbox will call the callback now. 538 layer_->SetTextureMailbox(TextureMailbox()); 539 EXPECT_EQ(5, callback_count_); 540 EndTest(); 541 break; 542 default: 543 NOTREACHED(); 544 break; 545 } 546 } 547 548 virtual void AfterTest() OVERRIDE {} 549 550 private: 551 int callback_count_; 552 int commit_count_; 553 scoped_refptr<Layer> root_; 554 scoped_refptr<TextureLayer> layer_; 555}; 556 557SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( 558 TextureLayerImplWithMailboxThreadedCallback); 559 560class TextureLayerImplWithMailboxTest : public TextureLayerTest { 561 protected: 562 TextureLayerImplWithMailboxTest() 563 : fake_client_( 564 FakeLayerTreeHostClient(FakeLayerTreeHostClient::DIRECT_3D)) {} 565 566 virtual void SetUp() { 567 TextureLayerTest::SetUp(); 568 layer_tree_host_.reset(new MockLayerTreeHost(&fake_client_)); 569 EXPECT_TRUE(host_impl_.InitializeRenderer(CreateFakeOutputSurface())); 570 } 571 572 bool WillDraw(TextureLayerImpl* layer, DrawMode mode) { 573 bool will_draw = layer->WillDraw( 574 mode, host_impl_.active_tree()->resource_provider()); 575 if (will_draw) 576 layer->DidDraw(host_impl_.active_tree()->resource_provider()); 577 return will_draw; 578 } 579 580 CommonMailboxObjects test_data_; 581 FakeLayerTreeHostClient fake_client_; 582}; 583 584// Test conditions for results of TextureLayerImpl::WillDraw under 585// different configurations of different mailbox, texture_id, and draw_mode. 586TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { 587 EXPECT_CALL(test_data_.mock_callback_, 588 Release(test_data_.mailbox_name1_, 589 test_data_.sync_point1_, 590 false)) 591 .Times(AnyNumber()); 592 EXPECT_CALL(test_data_.mock_callback_, 593 Release2(test_data_.shared_memory_.get(), 0, false)) 594 .Times(AnyNumber()); 595 // Hardware mode. 596 { 597 scoped_ptr<TextureLayerImpl> impl_layer = 598 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); 599 impl_layer->SetTextureMailbox(test_data_.mailbox1_); 600 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); 601 } 602 603 { 604 scoped_ptr<TextureLayerImpl> impl_layer = 605 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); 606 impl_layer->SetTextureMailbox(TextureMailbox()); 607 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); 608 } 609 610 { 611 // Software resource. 612 scoped_ptr<TextureLayerImpl> impl_layer = 613 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); 614 impl_layer->SetTextureMailbox(test_data_.mailbox3_); 615 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); 616 } 617 618 { 619 scoped_ptr<TextureLayerImpl> impl_layer = 620 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false); 621 unsigned texture = 622 host_impl_.output_surface()->context3d()->createTexture(); 623 impl_layer->set_texture_id(texture); 624 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); 625 } 626 627 { 628 scoped_ptr<TextureLayerImpl> impl_layer = 629 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false); 630 impl_layer->set_texture_id(0); 631 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); 632 } 633 634 // Software mode. 635 { 636 scoped_ptr<TextureLayerImpl> impl_layer = 637 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); 638 impl_layer->SetTextureMailbox(test_data_.mailbox1_); 639 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); 640 } 641 642 { 643 scoped_ptr<TextureLayerImpl> impl_layer = 644 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); 645 impl_layer->SetTextureMailbox(TextureMailbox()); 646 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); 647 } 648 649 { 650 // Software resource. 651 scoped_ptr<TextureLayerImpl> impl_layer = 652 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); 653 impl_layer->SetTextureMailbox(test_data_.mailbox3_); 654 EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); 655 } 656 657 { 658 scoped_ptr<TextureLayerImpl> impl_layer = 659 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false); 660 unsigned texture = 661 host_impl_.output_surface()->context3d()->createTexture(); 662 impl_layer->set_texture_id(texture); 663 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); 664 } 665 666 { 667 scoped_ptr<TextureLayerImpl> impl_layer = 668 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false); 669 impl_layer->set_texture_id(0); 670 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); 671 } 672 673 // Resourceless software mode. 674 { 675 scoped_ptr<TextureLayerImpl> impl_layer = 676 TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); 677 impl_layer->SetTextureMailbox(test_data_.mailbox1_); 678 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE)); 679 } 680 681 { 682 scoped_ptr<TextureLayerImpl> impl_layer = 683 TextureLayerImpl::Create(host_impl_.active_tree(), 1, false); 684 unsigned texture = 685 host_impl_.output_surface()->context3d()->createTexture(); 686 impl_layer->set_texture_id(texture); 687 EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE)); 688 } 689} 690 691TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) { 692 host_impl_.CreatePendingTree(); 693 scoped_ptr<TextureLayerImpl> pending_layer; 694 pending_layer = TextureLayerImpl::Create(host_impl_.pending_tree(), 1, true); 695 ASSERT_TRUE(pending_layer); 696 697 scoped_ptr<LayerImpl> active_layer( 698 pending_layer->CreateLayerImpl(host_impl_.active_tree())); 699 ASSERT_TRUE(active_layer); 700 701 pending_layer->SetTextureMailbox(test_data_.mailbox1_); 702 703 // Test multiple commits without an activation. 704 EXPECT_CALL(test_data_.mock_callback_, 705 Release(test_data_.mailbox_name1_, 706 test_data_.sync_point1_, 707 false)) 708 .Times(1); 709 pending_layer->SetTextureMailbox(test_data_.mailbox2_); 710 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 711 712 // Test callback after activation. 713 pending_layer->PushPropertiesTo(active_layer.get()); 714 active_layer->DidBecomeActive(); 715 716 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0); 717 pending_layer->SetTextureMailbox(test_data_.mailbox1_); 718 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 719 720 EXPECT_CALL(test_data_.mock_callback_, 721 Release(test_data_.mailbox_name2_, _, false)) 722 .Times(1); 723 pending_layer->PushPropertiesTo(active_layer.get()); 724 active_layer->DidBecomeActive(); 725 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 726 727 // Test resetting the mailbox. 728 EXPECT_CALL(test_data_.mock_callback_, 729 Release(test_data_.mailbox_name1_, _, false)) 730 .Times(1); 731 pending_layer->SetTextureMailbox(TextureMailbox()); 732 pending_layer->PushPropertiesTo(active_layer.get()); 733 active_layer->DidBecomeActive(); 734 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 735 736 // Test destructor. 737 EXPECT_CALL(test_data_.mock_callback_, 738 Release(test_data_.mailbox_name1_, 739 test_data_.sync_point1_, 740 false)) 741 .Times(1); 742 pending_layer->SetTextureMailbox(test_data_.mailbox1_); 743} 744 745TEST_F(TextureLayerImplWithMailboxTest, 746 TestDestructorCallbackOnCreatedResource) { 747 scoped_ptr<TextureLayerImpl> impl_layer; 748 impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); 749 ASSERT_TRUE(impl_layer); 750 751 EXPECT_CALL(test_data_.mock_callback_, 752 Release(test_data_.mailbox_name1_, _, false)) 753 .Times(1); 754 impl_layer->SetTextureMailbox(test_data_.mailbox1_); 755 impl_layer->DidBecomeActive(); 756 EXPECT_TRUE(impl_layer->WillDraw( 757 DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider())); 758 impl_layer->DidDraw(host_impl_.active_tree()->resource_provider()); 759 impl_layer->SetTextureMailbox(TextureMailbox()); 760} 761 762TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) { 763 ResourceProvider* provider = host_impl_.active_tree()->resource_provider(); 764 ResourceProvider::ResourceId id = 765 provider->CreateResourceFromTextureMailbox(test_data_.mailbox1_); 766 provider->AllocateForTesting(id); 767 768 // Transfer some resources to the parent. 769 ResourceProvider::ResourceIdArray resource_ids_to_transfer; 770 resource_ids_to_transfer.push_back(id); 771 TransferableResourceArray list; 772 provider->PrepareSendToParent(resource_ids_to_transfer, &list); 773 EXPECT_TRUE(provider->InUseByConsumer(id)); 774 EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0); 775 provider->DeleteResource(id); 776 Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); 777 EXPECT_CALL(test_data_.mock_callback_, 778 Release(test_data_.mailbox_name1_, _, false)) 779 .Times(1); 780 provider->ReceiveFromParent(list); 781} 782 783// Check that ClearClient correctly clears the state so that the impl side 784// doesn't try to use a texture that could have been destroyed. 785class TextureLayerClientTest 786 : public LayerTreeTest, 787 public TextureLayerClient { 788 public: 789 TextureLayerClientTest() 790 : context_(NULL), 791 texture_(0), 792 commit_count_(0), 793 expected_used_textures_on_draw_(0), 794 expected_used_textures_on_commit_(0) {} 795 796 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) 797 OVERRIDE { 798 scoped_ptr<TestWebGraphicsContext3D> context( 799 TestWebGraphicsContext3D::Create()); 800 context_ = context.get(); 801 texture_ = context->createTexture(); 802 return FakeOutputSurface::Create3d( 803 context.PassAs<WebKit::WebGraphicsContext3D>()).PassAs<OutputSurface>(); 804 } 805 806 virtual unsigned PrepareTexture() OVERRIDE { 807 return texture_; 808 } 809 810 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { 811 return context_; 812 } 813 814 virtual bool PrepareTextureMailbox( 815 cc::TextureMailbox* mailbox, bool use_shared_memory) OVERRIDE { 816 return false; 817 } 818 819 virtual void SetupTree() OVERRIDE { 820 scoped_refptr<Layer> root = Layer::Create(); 821 root->SetBounds(gfx::Size(10, 10)); 822 root->SetAnchorPoint(gfx::PointF()); 823 root->SetIsDrawable(true); 824 825 texture_layer_ = TextureLayer::Create(this); 826 texture_layer_->SetBounds(gfx::Size(10, 10)); 827 texture_layer_->SetAnchorPoint(gfx::PointF()); 828 texture_layer_->SetIsDrawable(true); 829 root->AddChild(texture_layer_); 830 831 layer_tree_host()->SetRootLayer(root); 832 LayerTreeTest::SetupTree(); 833 { 834 base::AutoLock lock(lock_); 835 expected_used_textures_on_commit_ = 1; 836 } 837 } 838 839 virtual void BeginTest() OVERRIDE { 840 PostSetNeedsCommitToMainThread(); 841 } 842 843 virtual void DidCommitAndDrawFrame() OVERRIDE { 844 ++commit_count_; 845 switch (commit_count_) { 846 case 1: 847 texture_layer_->ClearClient(); 848 texture_layer_->SetNeedsDisplay(); 849 { 850 base::AutoLock lock(lock_); 851 expected_used_textures_on_commit_ = 0; 852 } 853 texture_ = 0; 854 break; 855 case 2: 856 EndTest(); 857 break; 858 default: 859 NOTREACHED(); 860 break; 861 } 862 } 863 864 virtual void BeginCommitOnThread(LayerTreeHostImpl* host_impl) OVERRIDE { 865 base::AutoLock lock(lock_); 866 expected_used_textures_on_draw_ = expected_used_textures_on_commit_; 867 } 868 869 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, 870 LayerTreeHostImpl::FrameData* frame_data, 871 bool result) OVERRIDE { 872 context_->ResetUsedTextures(); 873 return true; 874 } 875 876 virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl, 877 bool result) OVERRIDE { 878 ASSERT_TRUE(result); 879 EXPECT_EQ(expected_used_textures_on_draw_, context_->NumUsedTextures()); 880 } 881 882 virtual void AfterTest() OVERRIDE {} 883 884 private: 885 scoped_refptr<TextureLayer> texture_layer_; 886 TestWebGraphicsContext3D* context_; 887 unsigned texture_; 888 int commit_count_; 889 890 // Used only on thread. 891 unsigned expected_used_textures_on_draw_; 892 893 // Used on either thread, protected by lock_. 894 base::Lock lock_; 895 unsigned expected_used_textures_on_commit_; 896}; 897 898// The TextureLayerClient does not use mailboxes, so can't use a delegating 899// renderer. 900SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerClientTest); 901 902// Test recovering from a lost context. 903class TextureLayerLostContextTest 904 : public LayerTreeTest, 905 public TextureLayerClient { 906 public: 907 TextureLayerLostContextTest() 908 : texture_(0), 909 draw_count_(0) {} 910 911 virtual scoped_ptr<OutputSurface> CreateOutputSurface(bool fallback) 912 OVERRIDE { 913 texture_context_ = TestWebGraphicsContext3D::Create(); 914 texture_ = texture_context_->createTexture(); 915 return CreateFakeOutputSurface(); 916 } 917 918 virtual unsigned PrepareTexture() OVERRIDE { 919 if (draw_count_ == 0) { 920 texture_context_->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_ARB, 921 GL_INNOCENT_CONTEXT_RESET_ARB); 922 } 923 return texture_; 924 } 925 926 virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { 927 return texture_context_.get(); 928 } 929 930 virtual bool PrepareTextureMailbox( 931 cc::TextureMailbox* mailbox, bool use_shared_memory) OVERRIDE { 932 return false; 933 } 934 935 virtual void SetupTree() OVERRIDE { 936 scoped_refptr<Layer> root = Layer::Create(); 937 root->SetBounds(gfx::Size(10, 10)); 938 root->SetIsDrawable(true); 939 940 texture_layer_ = TextureLayer::Create(this); 941 texture_layer_->SetBounds(gfx::Size(10, 10)); 942 texture_layer_->SetIsDrawable(true); 943 root->AddChild(texture_layer_); 944 945 layer_tree_host()->SetRootLayer(root); 946 LayerTreeTest::SetupTree(); 947 } 948 949 virtual void BeginTest() OVERRIDE { 950 PostSetNeedsCommitToMainThread(); 951 } 952 953 virtual bool PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, 954 LayerTreeHostImpl::FrameData* frame_data, 955 bool result) OVERRIDE { 956 LayerImpl* root = host_impl->RootLayer(); 957 TextureLayerImpl* texture_layer = 958 static_cast<TextureLayerImpl*>(root->children()[0]); 959 if (++draw_count_ == 1) 960 EXPECT_EQ(0u, texture_layer->texture_id()); 961 else 962 EXPECT_EQ(texture_, texture_layer->texture_id()); 963 return true; 964 } 965 966 virtual void DidCommitAndDrawFrame() OVERRIDE { 967 EndTest(); 968 } 969 970 virtual void AfterTest() OVERRIDE {} 971 972 private: 973 scoped_refptr<TextureLayer> texture_layer_; 974 scoped_ptr<TestWebGraphicsContext3D> texture_context_; 975 unsigned texture_; 976 int draw_count_; 977}; 978 979SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F(TextureLayerLostContextTest); 980 981class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest { 982 public: 983 void ReleaseCallback(unsigned sync_point, bool lost_resource) { 984 EXPECT_EQ(true, proxy()->IsMainThread()); 985 EXPECT_FALSE(lost_resource); 986 ++callback_count_; 987 EndTest(); 988 } 989 990 void SetMailbox(char mailbox_char) { 991 TextureMailbox mailbox( 992 std::string(64, mailbox_char), 993 base::Bind( 994 &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback, 995 base::Unretained(this))); 996 layer_->SetTextureMailbox(mailbox); 997 } 998 999 virtual void SetupTree() OVERRIDE { 1000 gfx::Size bounds(100, 100); 1001 root_ = Layer::Create(); 1002 root_->SetAnchorPoint(gfx::PointF()); 1003 root_->SetBounds(bounds); 1004 1005 layer_ = TextureLayer::CreateForMailbox(NULL); 1006 layer_->SetIsDrawable(true); 1007 layer_->SetAnchorPoint(gfx::PointF()); 1008 layer_->SetBounds(bounds); 1009 1010 root_->AddChild(layer_); 1011 layer_tree_host()->SetRootLayer(root_); 1012 layer_tree_host()->SetViewportSize(bounds); 1013 } 1014 1015 virtual void BeginTest() OVERRIDE { 1016 callback_count_ = 0; 1017 1018 // Set the mailbox on the main thread. 1019 SetMailbox('1'); 1020 EXPECT_EQ(0, callback_count_); 1021 1022 PostSetNeedsCommitToMainThread(); 1023 } 1024 1025 virtual void DidCommitAndDrawFrame() OVERRIDE { 1026 switch (layer_tree_host()->source_frame_number()) { 1027 case 1: 1028 // Delete the TextureLayer on the main thread while the mailbox is in 1029 // the impl tree. 1030 layer_->RemoveFromParent(); 1031 layer_ = NULL; 1032 break; 1033 } 1034 } 1035 1036 virtual void AfterTest() OVERRIDE { 1037 EXPECT_EQ(1, callback_count_); 1038 } 1039 1040 private: 1041 int callback_count_; 1042 scoped_refptr<Layer> root_; 1043 scoped_refptr<TextureLayer> layer_; 1044}; 1045 1046SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( 1047 TextureLayerWithMailboxMainThreadDeleted); 1048 1049class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest { 1050 public: 1051 void ReleaseCallback(unsigned sync_point, bool lost_resource) { 1052 EXPECT_EQ(true, proxy()->IsMainThread()); 1053 EXPECT_FALSE(lost_resource); 1054 ++callback_count_; 1055 EndTest(); 1056 } 1057 1058 void SetMailbox(char mailbox_char) { 1059 TextureMailbox mailbox( 1060 std::string(64, mailbox_char), 1061 base::Bind( 1062 &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback, 1063 base::Unretained(this))); 1064 layer_->SetTextureMailbox(mailbox); 1065 } 1066 1067 virtual void SetupTree() OVERRIDE { 1068 gfx::Size bounds(100, 100); 1069 root_ = Layer::Create(); 1070 root_->SetAnchorPoint(gfx::PointF()); 1071 root_->SetBounds(bounds); 1072 1073 layer_ = TextureLayer::CreateForMailbox(NULL); 1074 layer_->SetIsDrawable(true); 1075 layer_->SetAnchorPoint(gfx::PointF()); 1076 layer_->SetBounds(bounds); 1077 1078 root_->AddChild(layer_); 1079 layer_tree_host()->SetRootLayer(root_); 1080 layer_tree_host()->SetViewportSize(bounds); 1081 } 1082 1083 virtual void BeginTest() OVERRIDE { 1084 callback_count_ = 0; 1085 1086 // Set the mailbox on the main thread. 1087 SetMailbox('1'); 1088 EXPECT_EQ(0, callback_count_); 1089 1090 PostSetNeedsCommitToMainThread(); 1091 } 1092 1093 virtual void DidCommitAndDrawFrame() OVERRIDE { 1094 switch (layer_tree_host()->source_frame_number()) { 1095 case 1: 1096 // Remove the TextureLayer on the main thread while the mailbox is in 1097 // the impl tree, but don't delete the TextureLayer until after the impl 1098 // tree side is deleted. 1099 layer_->RemoveFromParent(); 1100 break; 1101 case 2: 1102 layer_ = NULL; 1103 break; 1104 } 1105 } 1106 1107 virtual void AfterTest() OVERRIDE { 1108 EXPECT_EQ(1, callback_count_); 1109 } 1110 1111 private: 1112 int callback_count_; 1113 scoped_refptr<Layer> root_; 1114 scoped_refptr<TextureLayer> layer_; 1115}; 1116 1117SINGLE_AND_MULTI_THREAD_DIRECT_RENDERER_TEST_F( 1118 TextureLayerWithMailboxImplThreadDeleted); 1119 1120} // namespace 1121} // namespace cc 1122