summaryrefslogtreecommitdiffstats
path: root/cc/layers/delegated_frame_resource_collection.cc
blob: a1bc759a0330eb531601eb19ddab2a0d09c72fd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cc/layers/delegated_frame_resource_collection.h"

#include "base/bind.h"
#include "cc/trees/blocking_task_runner.h"

namespace cc {

DelegatedFrameResourceCollection::DelegatedFrameResourceCollection()
    : client_(nullptr), lost_all_resources_(false), weak_ptr_factory_(this) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
}

DelegatedFrameResourceCollection::~DelegatedFrameResourceCollection() {
  DCHECK(main_thread_checker_.CalledOnValidThread());
}

void DelegatedFrameResourceCollection::SetClient(
    DelegatedFrameResourceCollectionClient* client) {
  client_ = client;
}

void DelegatedFrameResourceCollection::TakeUnusedResourcesForChildCompositor(
    ReturnedResourceArray* array) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DCHECK(array->empty());
  array->swap(returned_resources_for_child_compositor_);
}

bool DelegatedFrameResourceCollection::LoseAllResources() {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DCHECK(!lost_all_resources_);
  lost_all_resources_ = true;

  if (resource_id_ref_count_map_.empty())
    return false;

  ReturnedResourceArray to_return;

  for (ResourceIdRefCountMap::iterator it = resource_id_ref_count_map_.begin();
       it != resource_id_ref_count_map_.end();
       ++it) {
    DCHECK_GE(it->second.refs_to_wait_for, 1);

    ReturnedResource returned;
    returned.id = it->first;
    returned.count = it->second.refs_to_return;
    returned.lost = true;
    to_return.push_back(returned);
  }

  returned_resources_for_child_compositor_.insert(
      returned_resources_for_child_compositor_.end(),
      to_return.begin(),
      to_return.end());
  if (client_)
    client_->UnusedResourcesAreAvailable();
  return true;
}

void DelegatedFrameResourceCollection::ReceivedResources(
    const TransferableResourceArray& resources) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  DCHECK(!lost_all_resources_);

  for (size_t i = 0; i < resources.size(); ++i)
    resource_id_ref_count_map_[resources[i].id].refs_to_return++;
}

void DelegatedFrameResourceCollection::UnrefResources(
    const ReturnedResourceArray& returned) {
  DCHECK(main_thread_checker_.CalledOnValidThread());

  if (lost_all_resources_)
    return;

  ReturnedResourceArray to_return;

  for (size_t i = 0; i < returned.size(); ++i) {
    ResourceIdRefCountMap::iterator it =
        resource_id_ref_count_map_.find(returned[i].id);
    DCHECK(it != resource_id_ref_count_map_.end());
    DCHECK_GE(it->second.refs_to_wait_for, returned[i].count);
    it->second.refs_to_wait_for -= returned[i].count;
    if (it->second.refs_to_wait_for == 0) {
      to_return.push_back(returned[i]);
      to_return.back().count = it->second.refs_to_return;
      resource_id_ref_count_map_.erase(it);
    }
  }

  if (to_return.empty())
    return;

  returned_resources_for_child_compositor_.insert(
      returned_resources_for_child_compositor_.end(),
      to_return.begin(),
      to_return.end());
  if (client_)
    client_->UnusedResourcesAreAvailable();
}

void DelegatedFrameResourceCollection::RefResources(
    const TransferableResourceArray& resources) {
  DCHECK(main_thread_checker_.CalledOnValidThread());
  for (size_t i = 0; i < resources.size(); ++i)
    resource_id_ref_count_map_[resources[i].id].refs_to_wait_for++;
}

static void UnrefResourcesOnImplThread(
    base::WeakPtr<DelegatedFrameResourceCollection> self,
    const ReturnedResourceArray& returned,
    BlockingTaskRunner* main_thread_task_runner) {
  main_thread_task_runner->PostTask(
      FROM_HERE,
      base::Bind(
          &DelegatedFrameResourceCollection::UnrefResources, self, returned));
}

ReturnCallback
DelegatedFrameResourceCollection::GetReturnResourcesCallbackForImplThread() {
  return base::Bind(&UnrefResourcesOnImplThread,
                    weak_ptr_factory_.GetWeakPtr());
}

}  // namespace cc