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       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