| OLD | NEW | 
|    1 // Copyright 2014 The Chromium Authors. All rights reserved. |    1 // Copyright 2014 The Chromium Authors. All rights reserved. | 
|    2 // Use of this source code is governed by a BSD-style license that can be |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4  |    4  | 
|    5 #include "cc/surfaces/surface_factory.h" |    5 #include "cc/surfaces/surface_factory.h" | 
|    6  |    6  | 
|    7 #include <stddef.h> |    7 #include <stddef.h> | 
|    8 #include <stdint.h> |    8 #include <stdint.h> | 
|    9  |    9  | 
|   10 #include <utility> |   10 #include <utility> | 
|   11  |   11  | 
|   12 #include "base/bind.h" |   12 #include "base/bind.h" | 
|   13 #include "base/macros.h" |   13 #include "base/macros.h" | 
|   14 #include "cc/output/compositor_frame.h" |   14 #include "cc/output/compositor_frame.h" | 
|   15 #include "cc/output/copy_output_request.h" |   15 #include "cc/output/copy_output_request.h" | 
|   16 #include "cc/output/copy_output_result.h" |   16 #include "cc/output/copy_output_result.h" | 
|   17 #include "cc/output/delegated_frame_data.h" |   17 #include "cc/output/delegated_frame_data.h" | 
|   18 #include "cc/resources/resource_provider.h" |   18 #include "cc/resources/resource_provider.h" | 
|   19 #include "cc/surfaces/surface.h" |   19 #include "cc/surfaces/surface.h" | 
|   20 #include "cc/surfaces/surface_factory_client.h" |   20 #include "cc/surfaces/surface_factory_client.h" | 
|   21 #include "cc/surfaces/surface_manager.h" |   21 #include "cc/surfaces/surface_manager.h" | 
|   22 #include "cc/test/scheduler_test_common.h" |   22 #include "cc/test/scheduler_test_common.h" | 
|   23 #include "testing/gtest/include/gtest/gtest.h" |   23 #include "testing/gtest/include/gtest/gtest.h" | 
|   24 #include "ui/gfx/geometry/size.h" |   24 #include "ui/gfx/geometry/size.h" | 
|   25  |   25  | 
|   26 namespace cc { |   26 namespace cc { | 
|   27 namespace { |   27 namespace { | 
|   28  |   28  | 
|   29 static constexpr uint32_t kArbitraryClientId = 0; |   29 static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); | 
|   30  |   30  | 
|   31 class TestSurfaceFactoryClient : public SurfaceFactoryClient { |   31 class TestSurfaceFactoryClient : public SurfaceFactoryClient { | 
|   32  public: |   32  public: | 
|   33   TestSurfaceFactoryClient() : begin_frame_source_(nullptr) {} |   33   TestSurfaceFactoryClient() : begin_frame_source_(nullptr) {} | 
|   34   ~TestSurfaceFactoryClient() override {} |   34   ~TestSurfaceFactoryClient() override {} | 
|   35  |   35  | 
|   36   void ReturnResources(const ReturnedResourceArray& resources) override { |   36   void ReturnResources(const ReturnedResourceArray& resources) override { | 
|   37     returned_resources_.insert( |   37     returned_resources_.insert( | 
|   38         returned_resources_.end(), resources.begin(), resources.end()); |   38         returned_resources_.end(), resources.begin(), resources.end()); | 
|   39   } |   39   } | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
|   61   gpu::SyncToken token; |   61   gpu::SyncToken token; | 
|   62   token.Set(gpu::CommandBufferNamespace::GPU_IO, 0, |   62   token.Set(gpu::CommandBufferNamespace::GPU_IO, 0, | 
|   63             gpu::CommandBufferId::FromUnsafeValue(id), 1); |   63             gpu::CommandBufferId::FromUnsafeValue(id), 1); | 
|   64   return token; |   64   return token; | 
|   65 } |   65 } | 
|   66  |   66  | 
|   67 class SurfaceFactoryTest : public testing::Test, public SurfaceDamageObserver { |   67 class SurfaceFactoryTest : public testing::Test, public SurfaceDamageObserver { | 
|   68  public: |   68  public: | 
|   69   SurfaceFactoryTest() |   69   SurfaceFactoryTest() | 
|   70       : factory_(new SurfaceFactory(&manager_, &client_)), |   70       : factory_(new SurfaceFactory(&manager_, &client_)), | 
|   71         surface_id_(kArbitraryClientId, 3, 0), |   71         surface_id_(kArbitraryFrameSinkId, 3, 0), | 
|   72         frame_sync_token_(GenTestSyncToken(4)), |   72         frame_sync_token_(GenTestSyncToken(4)), | 
|   73         consumer_sync_token_(GenTestSyncToken(5)) { |   73         consumer_sync_token_(GenTestSyncToken(5)) { | 
|   74     manager_.AddObserver(this); |   74     manager_.AddObserver(this); | 
|   75     factory_->Create(surface_id_); |   75     factory_->Create(surface_id_); | 
|   76   } |   76   } | 
|   77  |   77  | 
|   78   // SurfaceDamageObserver implementation. |   78   // SurfaceDamageObserver implementation. | 
|   79   void OnSurfaceDamaged(const SurfaceId& id, bool* changed) override { |   79   void OnSurfaceDamaged(const SurfaceId& id, bool* changed) override { | 
|   80     *changed = true; |   80     *changed = true; | 
|   81   } |   81   } | 
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  414     SCOPED_TRACE("fourth frame, second unref"); |  414     SCOPED_TRACE("fourth frame, second unref"); | 
|  415     ResourceId expected_returned_ids[] = {12, 13}; |  415     ResourceId expected_returned_ids[] = {12, 13}; | 
|  416     int expected_returned_counts[] = {2, 2}; |  416     int expected_returned_counts[] = {2, 2}; | 
|  417     CheckReturnedResourcesMatchExpected( |  417     CheckReturnedResourcesMatchExpected( | 
|  418         expected_returned_ids, expected_returned_counts, |  418         expected_returned_ids, expected_returned_counts, | 
|  419         arraysize(expected_returned_counts), consumer_sync_token_); |  419         arraysize(expected_returned_counts), consumer_sync_token_); | 
|  420   } |  420   } | 
|  421 } |  421 } | 
|  422  |  422  | 
|  423 TEST_F(SurfaceFactoryTest, BlankNoIndexIncrement) { |  423 TEST_F(SurfaceFactoryTest, BlankNoIndexIncrement) { | 
|  424   SurfaceId surface_id(kArbitraryClientId, 6, 0); |  424   SurfaceId surface_id(kArbitraryFrameSinkId, 6, 0); | 
|  425   factory_->Create(surface_id); |  425   factory_->Create(surface_id); | 
|  426   Surface* surface = manager_.GetSurfaceForId(surface_id); |  426   Surface* surface = manager_.GetSurfaceForId(surface_id); | 
|  427   ASSERT_NE(nullptr, surface); |  427   ASSERT_NE(nullptr, surface); | 
|  428   EXPECT_EQ(2, surface->frame_index()); |  428   EXPECT_EQ(2, surface->frame_index()); | 
|  429   CompositorFrame frame; |  429   CompositorFrame frame; | 
|  430   frame.delegated_frame_data.reset(new DelegatedFrameData); |  430   frame.delegated_frame_data.reset(new DelegatedFrameData); | 
|  431  |  431  | 
|  432   factory_->SubmitCompositorFrame(surface_id, std::move(frame), |  432   factory_->SubmitCompositorFrame(surface_id, std::move(frame), | 
|  433                                   SurfaceFactory::DrawCallback()); |  433                                   SurfaceFactory::DrawCallback()); | 
|  434   EXPECT_EQ(2, surface->frame_index()); |  434   EXPECT_EQ(2, surface->frame_index()); | 
|  435   factory_->Destroy(surface_id); |  435   factory_->Destroy(surface_id); | 
|  436 } |  436 } | 
|  437  |  437  | 
|  438 void CreateSurfaceDrawCallback(SurfaceFactory* factory, |  438 void CreateSurfaceDrawCallback(SurfaceFactory* factory, | 
|  439                                uint32_t* execute_count) { |  439                                uint32_t* execute_count) { | 
|  440   SurfaceId new_id(kArbitraryClientId, 7, 0); |  440   SurfaceId new_id(kArbitraryFrameSinkId, 7, 0); | 
|  441   factory->Create(new_id); |  441   factory->Create(new_id); | 
|  442   factory->Destroy(new_id); |  442   factory->Destroy(new_id); | 
|  443   *execute_count += 1; |  443   *execute_count += 1; | 
|  444 } |  444 } | 
|  445  |  445  | 
|  446 TEST_F(SurfaceFactoryTest, AddDuringDestroy) { |  446 TEST_F(SurfaceFactoryTest, AddDuringDestroy) { | 
|  447   SurfaceId surface_id(kArbitraryClientId, 6, 0); |  447   SurfaceId surface_id(kArbitraryFrameSinkId, 6, 0); | 
|  448   factory_->Create(surface_id); |  448   factory_->Create(surface_id); | 
|  449   CompositorFrame frame; |  449   CompositorFrame frame; | 
|  450   frame.delegated_frame_data.reset(new DelegatedFrameData); |  450   frame.delegated_frame_data.reset(new DelegatedFrameData); | 
|  451  |  451  | 
|  452   uint32_t execute_count = 0; |  452   uint32_t execute_count = 0; | 
|  453   factory_->SubmitCompositorFrame( |  453   factory_->SubmitCompositorFrame( | 
|  454       surface_id, std::move(frame), |  454       surface_id, std::move(frame), | 
|  455       base::Bind(&CreateSurfaceDrawCallback, base::Unretained(factory_.get()), |  455       base::Bind(&CreateSurfaceDrawCallback, base::Unretained(factory_.get()), | 
|  456                  &execute_count)); |  456                  &execute_count)); | 
|  457   EXPECT_EQ(0u, execute_count); |  457   EXPECT_EQ(0u, execute_count); | 
|  458   factory_->Destroy(surface_id); |  458   factory_->Destroy(surface_id); | 
|  459   EXPECT_EQ(1u, execute_count); |  459   EXPECT_EQ(1u, execute_count); | 
|  460 } |  460 } | 
|  461  |  461  | 
|  462 void DrawCallback(uint32_t* execute_count) { |  462 void DrawCallback(uint32_t* execute_count) { | 
|  463   *execute_count += 1; |  463   *execute_count += 1; | 
|  464 } |  464 } | 
|  465  |  465  | 
|  466 // Tests doing a DestroyAll before shutting down the factory; |  466 // Tests doing a DestroyAll before shutting down the factory; | 
|  467 TEST_F(SurfaceFactoryTest, DestroyAll) { |  467 TEST_F(SurfaceFactoryTest, DestroyAll) { | 
|  468   SurfaceId id(kArbitraryClientId, 7, 0); |  468   SurfaceId id(kArbitraryFrameSinkId, 7, 0); | 
|  469   factory_->Create(id); |  469   factory_->Create(id); | 
|  470  |  470  | 
|  471   std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); |  471   std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); | 
|  472   TransferableResource resource; |  472   TransferableResource resource; | 
|  473   resource.id = 1; |  473   resource.id = 1; | 
|  474   resource.mailbox_holder.texture_target = GL_TEXTURE_2D; |  474   resource.mailbox_holder.texture_target = GL_TEXTURE_2D; | 
|  475   frame_data->resource_list.push_back(resource); |  475   frame_data->resource_list.push_back(resource); | 
|  476   CompositorFrame frame; |  476   CompositorFrame frame; | 
|  477   frame.delegated_frame_data = std::move(frame_data); |  477   frame.delegated_frame_data = std::move(frame_data); | 
|  478   uint32_t execute_count = 0; |  478   uint32_t execute_count = 0; | 
|  479   factory_->SubmitCompositorFrame(id, std::move(frame), |  479   factory_->SubmitCompositorFrame(id, std::move(frame), | 
|  480                                   base::Bind(&DrawCallback, &execute_count)); |  480                                   base::Bind(&DrawCallback, &execute_count)); | 
|  481  |  481  | 
|  482   surface_id_ = SurfaceId(); |  482   surface_id_ = SurfaceId(); | 
|  483   factory_->DestroyAll(); |  483   factory_->DestroyAll(); | 
|  484   EXPECT_EQ(1u, execute_count); |  484   EXPECT_EQ(1u, execute_count); | 
|  485 } |  485 } | 
|  486  |  486  | 
|  487 TEST_F(SurfaceFactoryTest, DestroySequence) { |  487 TEST_F(SurfaceFactoryTest, DestroySequence) { | 
|  488   SurfaceId id2(kArbitraryClientId, 5, 0); |  488   SurfaceId id2(kArbitraryFrameSinkId, 5, 0); | 
|  489   factory_->Create(id2); |  489   factory_->Create(id2); | 
|  490  |  490  | 
|  491   manager_.RegisterSurfaceClientId(0); |  491   manager_.RegisterFrameSinkId(kArbitraryFrameSinkId); | 
|  492  |  492  | 
|  493   // Check that waiting before the sequence is satisfied works. |  493   // Check that waiting before the sequence is satisfied works. | 
|  494   manager_.GetSurfaceForId(id2) |  494   manager_.GetSurfaceForId(id2)->AddDestructionDependency( | 
|  495       ->AddDestructionDependency(SurfaceSequence(0, 4)); |  495       SurfaceSequence(kArbitraryFrameSinkId, 4)); | 
|  496   factory_->Destroy(id2); |  496   factory_->Destroy(id2); | 
|  497  |  497  | 
|  498   std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); |  498   std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); | 
|  499   CompositorFrame frame; |  499   CompositorFrame frame; | 
|  500   frame.metadata.satisfies_sequences.push_back(6); |  500   frame.metadata.satisfies_sequences.push_back(6); | 
|  501   frame.metadata.satisfies_sequences.push_back(4); |  501   frame.metadata.satisfies_sequences.push_back(4); | 
|  502   frame.delegated_frame_data = std::move(frame_data); |  502   frame.delegated_frame_data = std::move(frame_data); | 
|  503   DCHECK(manager_.GetSurfaceForId(id2)); |  503   DCHECK(manager_.GetSurfaceForId(id2)); | 
|  504   factory_->SubmitCompositorFrame(surface_id_, std::move(frame), |  504   factory_->SubmitCompositorFrame(surface_id_, std::move(frame), | 
|  505                                   SurfaceFactory::DrawCallback()); |  505                                   SurfaceFactory::DrawCallback()); | 
|  506   DCHECK(!manager_.GetSurfaceForId(id2)); |  506   DCHECK(!manager_.GetSurfaceForId(id2)); | 
|  507  |  507  | 
|  508   // Check that waiting after the sequence is satisfied works. |  508   // Check that waiting after the sequence is satisfied works. | 
|  509   factory_->Create(id2); |  509   factory_->Create(id2); | 
|  510   DCHECK(manager_.GetSurfaceForId(id2)); |  510   DCHECK(manager_.GetSurfaceForId(id2)); | 
|  511   manager_.GetSurfaceForId(id2) |  511   manager_.GetSurfaceForId(id2)->AddDestructionDependency( | 
|  512       ->AddDestructionDependency(SurfaceSequence(0, 6)); |  512       SurfaceSequence(FrameSinkId(0, 0), 6)); | 
|  513   factory_->Destroy(id2); |  513   factory_->Destroy(id2); | 
|  514   DCHECK(!manager_.GetSurfaceForId(id2)); |  514   DCHECK(!manager_.GetSurfaceForId(id2)); | 
|  515 } |  515 } | 
|  516  |  516  | 
|  517 // Tests that Surface ID namespace invalidation correctly allows |  517 // Tests that Surface ID namespace invalidation correctly allows | 
|  518 // Sequences to be ignored. |  518 // Sequences to be ignored. | 
|  519 TEST_F(SurfaceFactoryTest, InvalidClientId) { |  519 TEST_F(SurfaceFactoryTest, InvalidClientId) { | 
|  520   uint32_t id_namespace = 9u; |  520   FrameSinkId frame_sink_id(9, 9); | 
|  521   SurfaceId id(id_namespace, 5, 0); |  521   SurfaceId id(frame_sink_id, 5, 0); | 
|  522   factory_->Create(id); |  522   factory_->Create(id); | 
|  523  |  523  | 
|  524   manager_.RegisterSurfaceClientId(id_namespace); |  524   manager_.RegisterFrameSinkId(frame_sink_id); | 
|  525   manager_.GetSurfaceForId(id) |  525   manager_.GetSurfaceForId(id)->AddDestructionDependency( | 
|  526       ->AddDestructionDependency(SurfaceSequence(id_namespace, 4)); |  526       SurfaceSequence(frame_sink_id, 4)); | 
|  527   factory_->Destroy(id); |  527   factory_->Destroy(id); | 
|  528  |  528  | 
|  529   // Verify the dependency has prevented the surface from getting destroyed. |  529   // Verify the dependency has prevented the surface from getting destroyed. | 
|  530   EXPECT_TRUE(manager_.GetSurfaceForId(id)); |  530   EXPECT_TRUE(manager_.GetSurfaceForId(id)); | 
|  531  |  531  | 
|  532   manager_.InvalidateSurfaceClientId(id_namespace); |  532   manager_.InvalidateFrameSinkId(frame_sink_id); | 
|  533  |  533  | 
|  534   // Verify that the invalidated namespace caused the unsatisfied sequence |  534   // Verify that the invalidated namespace caused the unsatisfied sequence | 
|  535   // to be ignored. |  535   // to be ignored. | 
|  536   EXPECT_FALSE(manager_.GetSurfaceForId(id)); |  536   EXPECT_FALSE(manager_.GetSurfaceForId(id)); | 
|  537 } |  537 } | 
|  538  |  538  | 
|  539 TEST_F(SurfaceFactoryTest, DestroyCycle) { |  539 TEST_F(SurfaceFactoryTest, DestroyCycle) { | 
|  540   SurfaceId id2(kArbitraryClientId, 5, 0); |  540   SurfaceId id2(kArbitraryFrameSinkId, 5, 0); | 
|  541   factory_->Create(id2); |  541   factory_->Create(id2); | 
|  542  |  542  | 
|  543   manager_.RegisterSurfaceClientId(0); |  543   manager_.RegisterFrameSinkId(FrameSinkId(0, 0)); | 
|  544  |  544  | 
|  545   manager_.GetSurfaceForId(id2) |  545   manager_.GetSurfaceForId(id2)->AddDestructionDependency( | 
|  546       ->AddDestructionDependency(SurfaceSequence(0, 4)); |  546       SurfaceSequence(FrameSinkId(0, 0), 4)); | 
|  547  |  547  | 
|  548   // Give id2 a frame that references surface_id_. |  548   // Give id2 a frame that references surface_id_. | 
|  549   { |  549   { | 
|  550     std::unique_ptr<RenderPass> render_pass(RenderPass::Create()); |  550     std::unique_ptr<RenderPass> render_pass(RenderPass::Create()); | 
|  551     std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); |  551     std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); | 
|  552     frame_data->render_pass_list.push_back(std::move(render_pass)); |  552     frame_data->render_pass_list.push_back(std::move(render_pass)); | 
|  553     CompositorFrame frame; |  553     CompositorFrame frame; | 
|  554     frame.metadata.referenced_surfaces.push_back(surface_id_); |  554     frame.metadata.referenced_surfaces.push_back(surface_id_); | 
|  555     frame.delegated_frame_data = std::move(frame_data); |  555     frame.delegated_frame_data = std::move(frame_data); | 
|  556     factory_->SubmitCompositorFrame(id2, std::move(frame), |  556     factory_->SubmitCompositorFrame(id2, std::move(frame), | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
|  570                                     SurfaceFactory::DrawCallback()); |  570                                     SurfaceFactory::DrawCallback()); | 
|  571   } |  571   } | 
|  572   factory_->Destroy(surface_id_); |  572   factory_->Destroy(surface_id_); | 
|  573   EXPECT_TRUE(manager_.GetSurfaceForId(id2)); |  573   EXPECT_TRUE(manager_.GetSurfaceForId(id2)); | 
|  574   // surface_id_ should be retained by reference from id2. |  574   // surface_id_ should be retained by reference from id2. | 
|  575   EXPECT_TRUE(manager_.GetSurfaceForId(surface_id_)); |  575   EXPECT_TRUE(manager_.GetSurfaceForId(surface_id_)); | 
|  576  |  576  | 
|  577   // Satisfy last destruction dependency for id2. |  577   // Satisfy last destruction dependency for id2. | 
|  578   std::vector<uint32_t> to_satisfy; |  578   std::vector<uint32_t> to_satisfy; | 
|  579   to_satisfy.push_back(4); |  579   to_satisfy.push_back(4); | 
|  580   manager_.DidSatisfySequences(0, &to_satisfy); |  580   manager_.DidSatisfySequences(FrameSinkId(0, 0), &to_satisfy); | 
|  581  |  581  | 
|  582   // id2 and surface_id_ are in a reference cycle that has no surface |  582   // id2 and surface_id_ are in a reference cycle that has no surface | 
|  583   // sequences holding on to it, so they should be destroyed. |  583   // sequences holding on to it, so they should be destroyed. | 
|  584   EXPECT_TRUE(!manager_.GetSurfaceForId(id2)); |  584   EXPECT_TRUE(!manager_.GetSurfaceForId(id2)); | 
|  585   EXPECT_TRUE(!manager_.GetSurfaceForId(surface_id_)); |  585   EXPECT_TRUE(!manager_.GetSurfaceForId(surface_id_)); | 
|  586  |  586  | 
|  587   surface_id_ = SurfaceId(); |  587   surface_id_ = SurfaceId(); | 
|  588 } |  588 } | 
|  589  |  589  | 
|  590 void CopyRequestTestCallback(bool* called, |  590 void CopyRequestTestCallback(bool* called, | 
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  638  |  638  | 
|  639   factory_->Destroy(surface_id_); |  639   factory_->Destroy(surface_id_); | 
|  640   surface_id_ = SurfaceId(); |  640   surface_id_ = SurfaceId(); | 
|  641   EXPECT_TRUE(called1); |  641   EXPECT_TRUE(called1); | 
|  642   EXPECT_TRUE(called2); |  642   EXPECT_TRUE(called2); | 
|  643   EXPECT_TRUE(called3); |  643   EXPECT_TRUE(called3); | 
|  644 } |  644 } | 
|  645  |  645  | 
|  646 }  // namespace |  646 }  // namespace | 
|  647 }  // namespace cc |  647 }  // namespace cc | 
| OLD | NEW |