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 12 DelegatedFrameResourceCollection::DelegatedFrameResourceCollection() 13 : client_(NULL), 14 lost_all_resources_(false), 15 weak_ptr_factory_(this) { 16 DCHECK(main_thread_checker_.CalledOnValidThread()); 17 } 18 19 DelegatedFrameResourceCollection::~DelegatedFrameResourceCollection() { 20 DCHECK(main_thread_checker_.CalledOnValidThread()); 21 } 22 23 void DelegatedFrameResourceCollection::SetClient( 24 DelegatedFrameResourceCollectionClient* client) { 25 client_ = client; 26 } 27 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 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 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 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 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 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 126 DelegatedFrameResourceCollection::GetReturnResourcesCallbackForImplThread() { 127 return base::Bind(&UnrefResourcesOnImplThread, 128 weak_ptr_factory_.GetWeakPtr()); 129 } 130 131 } // namespace cc 132