• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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