Home | History | Annotate | Download | only in layers
      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       main_thread_runner_(BlockingTaskRunner::current()),
     15       lost_all_resources_(false),
     16       weak_ptr_factory_(this) {
     17   DCHECK(main_thread_checker_.CalledOnValidThread());
     18 }
     19 
     20 DelegatedFrameResourceCollection::~DelegatedFrameResourceCollection() {
     21   DCHECK(main_thread_checker_.CalledOnValidThread());
     22 }
     23 
     24 void DelegatedFrameResourceCollection::SetClient(
     25     DelegatedFrameResourceCollectionClient* client) {
     26   client_ = client;
     27 }
     28 
     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 
     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 
     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 
     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 
    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 
    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
    127 DelegatedFrameResourceCollection::GetReturnResourcesCallbackForImplThread() {
    128   return base::Bind(&UnrefResourcesOnImplThread,
    129                     weak_ptr_factory_.GetWeakPtr(),
    130                     main_thread_runner_);
    131 }
    132 
    133 }  // namespace cc
    134