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.
4
5 #include "cc/layers/delegated_frame_resource_collection.h"
6
7 #include "base/bind.h"
8 #include "cc/trees/blocking_task_runner.h"
9
10 namespace cc {
11
DelegatedFrameResourceCollection()12 DelegatedFrameResourceCollection::DelegatedFrameResourceCollection()
13 : client_(NULL),
14 lost_all_resources_(false),
15 weak_ptr_factory_(this) {
16 DCHECK(main_thread_checker_.CalledOnValidThread());
17 }
18
~DelegatedFrameResourceCollection()19 DelegatedFrameResourceCollection::~DelegatedFrameResourceCollection() {
20 DCHECK(main_thread_checker_.CalledOnValidThread());
21 }
22
SetClient(DelegatedFrameResourceCollectionClient * client)23 void DelegatedFrameResourceCollection::SetClient(
24 DelegatedFrameResourceCollectionClient* client) {
25 client_ = client;
26 }
27
TakeUnusedResourcesForChildCompositor(ReturnedResourceArray * array)28 void DelegatedFrameResourceCollection::TakeUnusedResourcesForChildCompositor(
29 ReturnedResourceArray* array) {
30 DCHECK(main_thread_checker_.CalledOnValidThread());
31 DCHECK(array->empty());
32 array->swap(returned_resources_for_child_compositor_);
33 }
34
LoseAllResources()35 bool DelegatedFrameResourceCollection::LoseAllResources() {
36 DCHECK(main_thread_checker_.CalledOnValidThread());
37 DCHECK(!lost_all_resources_);
38 lost_all_resources_ = true;
39
40 if (resource_id_ref_count_map_.empty())
41 return false;
42
43 ReturnedResourceArray to_return;
44
45 for (ResourceIdRefCountMap::iterator it = resource_id_ref_count_map_.begin();
46 it != resource_id_ref_count_map_.end();
47 ++it) {
48 DCHECK_GE(it->second.refs_to_wait_for, 1);
49
50 ReturnedResource returned;
51 returned.id = it->first;
52 returned.count = it->second.refs_to_return;
53 returned.lost = true;
54 to_return.push_back(returned);
55 }
56
57 returned_resources_for_child_compositor_.insert(
58 returned_resources_for_child_compositor_.end(),
59 to_return.begin(),
60 to_return.end());
61 if (client_)
62 client_->UnusedResourcesAreAvailable();
63 return true;
64 }
65
ReceivedResources(const TransferableResourceArray & resources)66 void DelegatedFrameResourceCollection::ReceivedResources(
67 const TransferableResourceArray& resources) {
68 DCHECK(main_thread_checker_.CalledOnValidThread());
69 DCHECK(!lost_all_resources_);
70
71 for (size_t i = 0; i < resources.size(); ++i)
72 resource_id_ref_count_map_[resources[i].id].refs_to_return++;
73 }
74
UnrefResources(const ReturnedResourceArray & returned)75 void DelegatedFrameResourceCollection::UnrefResources(
76 const ReturnedResourceArray& returned) {
77 DCHECK(main_thread_checker_.CalledOnValidThread());
78
79 if (lost_all_resources_)
80 return;
81
82 ReturnedResourceArray to_return;
83
84 for (size_t i = 0; i < returned.size(); ++i) {
85 ResourceIdRefCountMap::iterator it =
86 resource_id_ref_count_map_.find(returned[i].id);
87 DCHECK(it != resource_id_ref_count_map_.end());
88 DCHECK_GE(it->second.refs_to_wait_for, returned[i].count);
89 it->second.refs_to_wait_for -= returned[i].count;
90 if (it->second.refs_to_wait_for == 0) {
91 to_return.push_back(returned[i]);
92 to_return.back().count = it->second.refs_to_return;
93 resource_id_ref_count_map_.erase(it);
94 }
95 }
96
97 if (to_return.empty())
98 return;
99
100 returned_resources_for_child_compositor_.insert(
101 returned_resources_for_child_compositor_.end(),
102 to_return.begin(),
103 to_return.end());
104 if (client_)
105 client_->UnusedResourcesAreAvailable();
106 }
107
RefResources(const TransferableResourceArray & resources)108 void DelegatedFrameResourceCollection::RefResources(
109 const TransferableResourceArray& resources) {
110 DCHECK(main_thread_checker_.CalledOnValidThread());
111 for (size_t i = 0; i < resources.size(); ++i)
112 resource_id_ref_count_map_[resources[i].id].refs_to_wait_for++;
113 }
114
UnrefResourcesOnImplThread(base::WeakPtr<DelegatedFrameResourceCollection> self,const ReturnedResourceArray & returned,BlockingTaskRunner * main_thread_task_runner)115 static void UnrefResourcesOnImplThread(
116 base::WeakPtr<DelegatedFrameResourceCollection> self,
117 const ReturnedResourceArray& returned,
118 BlockingTaskRunner* main_thread_task_runner) {
119 main_thread_task_runner->PostTask(
120 FROM_HERE,
121 base::Bind(
122 &DelegatedFrameResourceCollection::UnrefResources, self, returned));
123 }
124
125 ReturnCallback
GetReturnResourcesCallbackForImplThread()126 DelegatedFrameResourceCollection::GetReturnResourcesCallbackForImplThread() {
127 return base::Bind(&UnrefResourcesOnImplThread,
128 weak_ptr_factory_.GetWeakPtr());
129 }
130
131 } // namespace cc
132