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