prioritized_resource.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright 2012 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/resources/prioritized_resource.h"
6
7#include <algorithm>
8
9#include "cc/resources/platform_color.h"
10#include "cc/resources/prioritized_resource_manager.h"
11#include "cc/resources/priority_calculator.h"
12#include "cc/trees/proxy.h"
13
14namespace cc {
15
16PrioritizedResource::PrioritizedResource(PrioritizedResourceManager* manager,
17                                         gfx::Size size,
18                                         GLenum format)
19    : size_(size),
20      format_(format),
21      bytes_(0),
22      contents_swizzled_(false),
23      priority_(PriorityCalculator::LowestPriority()),
24      is_above_priority_cutoff_(false),
25      is_self_managed_(false),
26      backing_(NULL),
27      manager_(NULL) {
28  // manager_ is set in RegisterTexture() so validity can be checked.
29  DCHECK(format || size.IsEmpty());
30  if (format)
31    bytes_ = Resource::MemorySizeBytes(size, format);
32  if (manager)
33    manager->RegisterTexture(this);
34}
35
36PrioritizedResource::~PrioritizedResource() {
37  if (manager_)
38    manager_->UnregisterTexture(this);
39}
40
41void PrioritizedResource::SetTextureManager(
42    PrioritizedResourceManager* manager) {
43  if (manager_ == manager)
44    return;
45  if (manager_)
46    manager_->UnregisterTexture(this);
47  if (manager)
48    manager->RegisterTexture(this);
49}
50
51void PrioritizedResource::SetDimensions(gfx::Size size, GLenum format) {
52  if (format_ != format || size_ != size) {
53    is_above_priority_cutoff_ = false;
54    format_ = format;
55    size_ = size;
56    bytes_ = Resource::MemorySizeBytes(size, format);
57    DCHECK(manager_ || !backing_);
58    if (manager_)
59      manager_->ReturnBackingTexture(this);
60  }
61}
62
63bool PrioritizedResource::RequestLate() {
64  if (!manager_)
65    return false;
66  return manager_->RequestLate(this);
67}
68
69bool PrioritizedResource::BackingResourceWasEvicted() const {
70  return backing_ ? backing_->ResourceHasBeenDeleted() : false;
71}
72
73void PrioritizedResource::AcquireBackingTexture(
74    ResourceProvider* resource_provider) {
75  DCHECK(is_above_priority_cutoff_);
76  if (is_above_priority_cutoff_)
77    manager_->AcquireBackingTextureIfNeeded(this, resource_provider);
78}
79
80void PrioritizedResource::SetPixels(ResourceProvider* resource_provider,
81                                    const uint8_t* image,
82                                    gfx::Rect image_rect,
83                                    gfx::Rect source_rect,
84                                    gfx::Vector2d dest_offset) {
85  DCHECK(is_above_priority_cutoff_);
86  if (is_above_priority_cutoff_)
87    AcquireBackingTexture(resource_provider);
88  DCHECK(backing_);
89  resource_provider->SetPixels(
90      resource_id(), image, image_rect, source_rect, dest_offset);
91
92  // The component order may be bgra if we uploaded bgra pixels to rgba
93  // texture. Mark contents as swizzled if image component order is
94  // different than texture format.
95  contents_swizzled_ = !PlatformColor::SameComponentOrder(format_);
96}
97
98void PrioritizedResource::Link(Backing* backing) {
99  DCHECK(backing);
100  DCHECK(!backing->owner_);
101  DCHECK(!backing_);
102
103  backing_ = backing;
104  backing_->owner_ = this;
105}
106
107void PrioritizedResource::Unlink() {
108  DCHECK(backing_);
109  DCHECK(backing_->owner_ == this);
110
111  backing_->owner_ = NULL;
112  backing_ = NULL;
113}
114
115void PrioritizedResource::SetToSelfManagedMemoryPlaceholder(size_t bytes) {
116  SetDimensions(gfx::Size(), GL_RGBA);
117  set_is_self_managed(true);
118  bytes_ = bytes;
119}
120
121PrioritizedResource::Backing::Backing(unsigned id,
122                                      ResourceProvider* resource_provider,
123                                      gfx::Size size,
124                                      GLenum format)
125    : Resource(id, size, format),
126      owner_(NULL),
127      priority_at_last_priority_update_(PriorityCalculator::LowestPriority()),
128      was_above_priority_cutoff_at_last_priority_update_(false),
129      in_drawing_impl_tree_(false),
130      resource_has_been_deleted_(false)
131#ifndef NDEBUG
132      ,
133      resource_provider_(resource_provider)
134#endif
135      {
136}
137
138PrioritizedResource::Backing::~Backing() {
139  DCHECK(!owner_);
140  DCHECK(resource_has_been_deleted_);
141}
142
143void PrioritizedResource::Backing::DeleteResource(
144    ResourceProvider* resource_provider) {
145  DCHECK(!proxy() || proxy()->IsImplThread());
146  DCHECK(!resource_has_been_deleted_);
147#ifndef NDEBUG
148  DCHECK(resource_provider == resource_provider_);
149#endif
150
151  resource_provider->DeleteResource(id());
152  set_id(0);
153  resource_has_been_deleted_ = true;
154}
155
156bool PrioritizedResource::Backing::ResourceHasBeenDeleted() const {
157  DCHECK(!proxy() || proxy()->IsImplThread());
158  return resource_has_been_deleted_;
159}
160
161bool PrioritizedResource::Backing::CanBeRecycled() const {
162  DCHECK(!proxy() || proxy()->IsImplThread());
163  return !was_above_priority_cutoff_at_last_priority_update_ &&
164         !in_drawing_impl_tree_;
165}
166
167void PrioritizedResource::Backing::UpdatePriority() {
168  DCHECK(!proxy() || proxy()->IsImplThread() && proxy()->IsMainThreadBlocked());
169  if (owner_) {
170    priority_at_last_priority_update_ = owner_->request_priority();
171    was_above_priority_cutoff_at_last_priority_update_ =
172        owner_->is_above_priority_cutoff();
173  } else {
174    priority_at_last_priority_update_ = PriorityCalculator::LowestPriority();
175    was_above_priority_cutoff_at_last_priority_update_ = false;
176  }
177}
178
179void PrioritizedResource::Backing::UpdateInDrawingImplTree() {
180  DCHECK(!proxy() || proxy()->IsImplThread() && proxy()->IsMainThreadBlocked());
181  in_drawing_impl_tree_ = !!owner();
182  if (!in_drawing_impl_tree_) {
183    DCHECK_EQ(priority_at_last_priority_update_,
184              PriorityCalculator::LowestPriority());
185  }
186}
187
188void PrioritizedResource::ReturnBackingTexture() {
189  DCHECK(manager_ || !backing_);
190  if (manager_)
191    manager_->ReturnBackingTexture(this);
192}
193
194const Proxy* PrioritizedResource::Backing::proxy() const {
195  if (!owner_ || !owner_->resource_manager())
196    return NULL;
197  return owner_->resource_manager()->ProxyForDebug();
198}
199
200}  // namespace cc
201