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