| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "cc/layers/delegated_frame_resource_collection.h" |
| |
| #include "base/bind.h" |
| #include "cc/trees/blocking_task_runner.h" |
| |
| namespace cc { |
| |
| DelegatedFrameResourceCollection::DelegatedFrameResourceCollection() |
| : client_(NULL), |
| main_thread_runner_(BlockingTaskRunner::current()), |
| lost_all_resources_(false), |
| weak_ptr_factory_(this) { |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| } |
| |
| DelegatedFrameResourceCollection::~DelegatedFrameResourceCollection() { |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| } |
| |
| void DelegatedFrameResourceCollection::SetClient( |
| DelegatedFrameResourceCollectionClient* client) { |
| client_ = client; |
| } |
| |
| void DelegatedFrameResourceCollection::TakeUnusedResourcesForChildCompositor( |
| ReturnedResourceArray* array) { |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| DCHECK(array->empty()); |
| array->swap(returned_resources_for_child_compositor_); |
| } |
| |
| bool DelegatedFrameResourceCollection::LoseAllResources() { |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| DCHECK(!lost_all_resources_); |
| lost_all_resources_ = true; |
| |
| if (resource_id_ref_count_map_.empty()) |
| return false; |
| |
| ReturnedResourceArray to_return; |
| |
| for (ResourceIdRefCountMap::iterator it = resource_id_ref_count_map_.begin(); |
| it != resource_id_ref_count_map_.end(); |
| ++it) { |
| DCHECK_GE(it->second.refs_to_wait_for, 1); |
| |
| ReturnedResource returned; |
| returned.id = it->first; |
| returned.count = it->second.refs_to_return; |
| returned.lost = true; |
| to_return.push_back(returned); |
| } |
| |
| returned_resources_for_child_compositor_.insert( |
| returned_resources_for_child_compositor_.end(), |
| to_return.begin(), |
| to_return.end()); |
| if (client_) |
| client_->UnusedResourcesAreAvailable(); |
| return true; |
| } |
| |
| void DelegatedFrameResourceCollection::ReceivedResources( |
| const TransferableResourceArray& resources) { |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| DCHECK(!lost_all_resources_); |
| |
| for (size_t i = 0; i < resources.size(); ++i) |
| resource_id_ref_count_map_[resources[i].id].refs_to_return++; |
| } |
| |
| void DelegatedFrameResourceCollection::UnrefResources( |
| const ReturnedResourceArray& returned) { |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| |
| if (lost_all_resources_) |
| return; |
| |
| ReturnedResourceArray to_return; |
| |
| for (size_t i = 0; i < returned.size(); ++i) { |
| ResourceIdRefCountMap::iterator it = |
| resource_id_ref_count_map_.find(returned[i].id); |
| DCHECK(it != resource_id_ref_count_map_.end()); |
| DCHECK_GE(it->second.refs_to_wait_for, returned[i].count); |
| it->second.refs_to_wait_for -= returned[i].count; |
| if (it->second.refs_to_wait_for == 0) { |
| to_return.push_back(returned[i]); |
| to_return.back().count = it->second.refs_to_return; |
| resource_id_ref_count_map_.erase(it); |
| } |
| } |
| |
| if (to_return.empty()) |
| return; |
| |
| returned_resources_for_child_compositor_.insert( |
| returned_resources_for_child_compositor_.end(), |
| to_return.begin(), |
| to_return.end()); |
| if (client_) |
| client_->UnusedResourcesAreAvailable(); |
| } |
| |
| void DelegatedFrameResourceCollection::RefResources( |
| const TransferableResourceArray& resources) { |
| DCHECK(main_thread_checker_.CalledOnValidThread()); |
| for (size_t i = 0; i < resources.size(); ++i) |
| resource_id_ref_count_map_[resources[i].id].refs_to_wait_for++; |
| } |
| |
| static void UnrefResourcesOnImplThread( |
| base::WeakPtr<DelegatedFrameResourceCollection> self, |
| scoped_refptr<BlockingTaskRunner> main_thread_runner, |
| const ReturnedResourceArray& returned) { |
| main_thread_runner->PostTask( |
| FROM_HERE, |
| base::Bind( |
| &DelegatedFrameResourceCollection::UnrefResources, self, returned)); |
| } |
| |
| ReturnCallback |
| DelegatedFrameResourceCollection::GetReturnResourcesCallbackForImplThread() { |
| return base::Bind(&UnrefResourcesOnImplThread, |
| weak_ptr_factory_.GetWeakPtr(), |
| main_thread_runner_); |
| } |
| |
| } // namespace cc |