1// Copyright 2014 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/surfaces/surface_resource_holder.h"
6
7#include "cc/surfaces/surface_factory_client.h"
8
9namespace cc {
10
11SurfaceResourceHolder::SurfaceResourceHolder(SurfaceFactoryClient* client)
12    : client_(client) {
13}
14
15SurfaceResourceHolder::~SurfaceResourceHolder() {
16}
17
18SurfaceResourceHolder::ResourceRefs::ResourceRefs()
19    : refs_received_from_child(0), refs_holding_resource_alive(0) {
20}
21
22void SurfaceResourceHolder::ReceiveFromChild(
23    const TransferableResourceArray& resources) {
24  for (TransferableResourceArray::const_iterator it = resources.begin();
25       it != resources.end();
26       ++it) {
27    ResourceRefs& ref = resource_id_use_count_map_[it->id];
28    ref.refs_holding_resource_alive++;
29    ref.refs_received_from_child++;
30  }
31}
32
33void SurfaceResourceHolder::RefResources(
34    const TransferableResourceArray& resources) {
35  for (TransferableResourceArray::const_iterator it = resources.begin();
36       it != resources.end();
37       ++it) {
38    ResourceIdCountMap::iterator count_it =
39        resource_id_use_count_map_.find(it->id);
40    DCHECK(count_it != resource_id_use_count_map_.end());
41    count_it->second.refs_holding_resource_alive++;
42  }
43}
44
45void SurfaceResourceHolder::UnrefResources(
46    const ReturnedResourceArray& resources) {
47  ReturnedResourceArray resources_available_to_return;
48
49  for (ReturnedResourceArray::const_iterator it = resources.begin();
50       it != resources.end();
51       ++it) {
52    ResourceProvider::ResourceId id = it->id;
53    ResourceIdCountMap::iterator count_it = resource_id_use_count_map_.find(id);
54    if (count_it == resource_id_use_count_map_.end())
55      continue;
56    ResourceRefs& ref = count_it->second;
57    ref.refs_holding_resource_alive -= it->count;
58    if (ref.refs_holding_resource_alive == 0) {
59      ReturnedResource returned = *it;
60      returned.count = ref.refs_received_from_child;
61      resources_available_to_return.push_back(returned);
62      resource_id_use_count_map_.erase(count_it);
63    }
64  }
65
66  client_->ReturnResources(resources_available_to_return);
67}
68
69}  // namespace cc
70