1 // Copyright 2013 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.
6 #include "base/run_loop.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "base/threading/thread.h"
9 #include "cc/layers/delegated_frame_resource_collection.h"
10 #include "cc/resources/returned_resource.h"
11 #include "cc/resources/transferable_resource.h"
12 #include "testing/gtest/include/gtest/gtest.h"
17 class DelegatedFrameResourceCollectionTest
18 : public testing::Test
,
19 public DelegatedFrameResourceCollectionClient
{
21 DelegatedFrameResourceCollectionTest() : resources_available_(false) {}
23 virtual void SetUp() OVERRIDE
{ CreateResourceCollection(); }
25 virtual void TearDown() OVERRIDE
{ DestroyResourceCollection(); }
27 void CreateResourceCollection() {
28 DCHECK(!resource_collection_
);
29 resource_collection_
= new DelegatedFrameResourceCollection
;
30 resource_collection_
->SetClient(this);
33 void DestroyResourceCollection() {
34 if (resource_collection_
) {
35 resource_collection_
->SetClient(NULL
);
36 resource_collection_
= NULL
;
40 TransferableResourceArray
CreateResourceArray() {
41 TransferableResourceArray resources
;
42 TransferableResource resource
;
44 resources
.push_back(resource
);
48 virtual void UnusedResourcesAreAvailable() OVERRIDE
{
49 resources_available_
= true;
50 resource_collection_
->TakeUnusedResourcesForChildCompositor(
51 &returned_resources_
);
52 if (!resources_available_closure_
.is_null())
53 resources_available_closure_
.Run();
56 bool ReturnAndResetResourcesAvailable() {
57 bool r
= resources_available_
;
58 resources_available_
= false;
62 scoped_refptr
<DelegatedFrameResourceCollection
> resource_collection_
;
63 bool resources_available_
;
64 ReturnedResourceArray returned_resources_
;
65 base::Closure resources_available_closure_
;
68 // This checks that taking the return callback doesn't take extra refcounts,
69 // since it's sent to other threads.
70 TEST_F(DelegatedFrameResourceCollectionTest
, NoRef
) {
71 // Start with one ref.
72 EXPECT_TRUE(resource_collection_
->HasOneRef());
74 ReturnCallback return_callback
=
75 resource_collection_
->GetReturnResourcesCallbackForImplThread();
77 // Callback shouldn't take a ref since it's sent to other threads.
78 EXPECT_TRUE(resource_collection_
->HasOneRef());
81 void ReturnResourcesOnThread(ReturnCallback callback
,
82 const ReturnedResourceArray
& resources
,
83 base::WaitableEvent
* event
) {
84 callback
.Run(resources
);
89 // Tests that the ReturnCallback can run safely on threads even after the
90 // last references to the collection were dropped.
91 // Flaky: crbug.com/313441
92 TEST_F(DelegatedFrameResourceCollectionTest
, Thread
) {
93 base::Thread
thread("test thread");
96 TransferableResourceArray resources
= CreateResourceArray();
97 resource_collection_
->ReceivedResources(resources
);
98 resource_collection_
->RefResources(resources
);
100 ReturnedResourceArray returned_resources
;
101 TransferableResource::ReturnResources(resources
, &returned_resources
);
103 base::WaitableEvent
event(false, false);
106 base::RunLoop run_loop
;
107 resources_available_closure_
= run_loop
.QuitClosure();
109 thread
.message_loop()->PostTask(
112 &ReturnResourcesOnThread
,
113 resource_collection_
->GetReturnResourcesCallbackForImplThread(),
119 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
120 EXPECT_EQ(1u, returned_resources_
.size());
121 EXPECT_EQ(444u, returned_resources_
[0].id
);
122 EXPECT_EQ(1, returned_resources_
[0].count
);
123 returned_resources_
.clear();
125 // The event prevents the return resources callback from being deleted.
126 // Destroy the last reference from this thread to the collection before
127 // signaling the event, to ensure any reference taken by the callback, if any,
128 // would be the last one.
129 DestroyResourceCollection();
132 CreateResourceCollection();
133 resource_collection_
->ReceivedResources(resources
);
134 resource_collection_
->RefResources(resources
);
136 // Destroy the collection before we have a chance to run the return callback.
137 ReturnCallback return_callback
=
138 resource_collection_
->GetReturnResourcesCallbackForImplThread();
139 resource_collection_
->LoseAllResources();
140 DestroyResourceCollection();
142 EXPECT_TRUE(ReturnAndResetResourcesAvailable());
143 EXPECT_EQ(1u, returned_resources_
.size());
144 EXPECT_EQ(444u, returned_resources_
[0].id
);
145 EXPECT_EQ(1, returned_resources_
[0].count
);
146 EXPECT_TRUE(returned_resources_
[0].lost
);
147 returned_resources_
.clear();
149 base::WaitableEvent
* null_event
= NULL
;
150 thread
.message_loop()->PostTask(FROM_HERE
,
151 base::Bind(&ReturnResourcesOnThread
,