• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
14 namespace cc {
15 
PrioritizedResource(PrioritizedResourceManager * manager,gfx::Size size,ResourceFormat format)16 PrioritizedResource::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 
~PrioritizedResource()33 PrioritizedResource::~PrioritizedResource() {
34   if (manager_)
35     manager_->UnregisterTexture(this);
36 }
37 
SetTextureManager(PrioritizedResourceManager * manager)38 void 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 
SetDimensions(gfx::Size size,ResourceFormat format)48 void 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 
RequestLate()60 bool PrioritizedResource::RequestLate() {
61   if (!manager_)
62     return false;
63   return manager_->RequestLate(this);
64 }
65 
BackingResourceWasEvicted() const66 bool PrioritizedResource::BackingResourceWasEvicted() const {
67   return backing_ ? backing_->ResourceHasBeenDeleted() : false;
68 }
69 
AcquireBackingTexture(ResourceProvider * resource_provider)70 void 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 
SetPixels(ResourceProvider * resource_provider,const uint8_t * image,gfx::Rect image_rect,gfx::Rect source_rect,gfx::Vector2d dest_offset)77 void 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 
Link(Backing * backing)95 void PrioritizedResource::Link(Backing* backing) {
96   DCHECK(backing);
97   DCHECK(!backing->owner_);
98   DCHECK(!backing_);
99 
100   backing_ = backing;
101   backing_->owner_ = this;
102 }
103 
Unlink()104 void PrioritizedResource::Unlink() {
105   DCHECK(backing_);
106   DCHECK(backing_->owner_ == this);
107 
108   backing_->owner_ = NULL;
109   backing_ = NULL;
110 }
111 
SetToSelfManagedMemoryPlaceholder(size_t bytes)112 void PrioritizedResource::SetToSelfManagedMemoryPlaceholder(size_t bytes) {
113   SetDimensions(gfx::Size(), RGBA_8888);
114   set_is_self_managed(true);
115   bytes_ = bytes;
116 }
117 
Backing(unsigned id,ResourceProvider * resource_provider,gfx::Size size,ResourceFormat format)118 PrioritizedResource::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       in_parent_compositor_(false),
128 #ifdef NDEBUG
129       resource_has_been_deleted_(false) {}
130 #else
131       resource_has_been_deleted_(false),
132       resource_provider_(resource_provider) {}
133 #endif
134 
~Backing()135 PrioritizedResource::Backing::~Backing() {
136   DCHECK(!owner_);
137   DCHECK(resource_has_been_deleted_);
138 }
139 
DeleteResource(ResourceProvider * resource_provider)140 void PrioritizedResource::Backing::DeleteResource(
141     ResourceProvider* resource_provider) {
142   DCHECK(!proxy() || proxy()->IsImplThread());
143   DCHECK(!resource_has_been_deleted_);
144 #ifndef NDEBUG
145   DCHECK(resource_provider == resource_provider_);
146 #endif
147 
148   resource_provider->DeleteResource(id());
149   set_id(0);
150   resource_has_been_deleted_ = true;
151 }
152 
ResourceHasBeenDeleted() const153 bool PrioritizedResource::Backing::ResourceHasBeenDeleted() const {
154   DCHECK(!proxy() || proxy()->IsImplThread());
155   return resource_has_been_deleted_;
156 }
157 
CanBeRecycledIfNotInExternalUse() const158 bool PrioritizedResource::Backing::CanBeRecycledIfNotInExternalUse() const {
159   DCHECK(!proxy() || proxy()->IsImplThread());
160   return !was_above_priority_cutoff_at_last_priority_update_ &&
161          !in_drawing_impl_tree_;
162 }
163 
UpdatePriority()164 void PrioritizedResource::Backing::UpdatePriority() {
165   DCHECK(!proxy() ||
166          (proxy()->IsImplThread() && proxy()->IsMainThreadBlocked()));
167   if (owner_) {
168     priority_at_last_priority_update_ = owner_->request_priority();
169     was_above_priority_cutoff_at_last_priority_update_ =
170         owner_->is_above_priority_cutoff();
171   } else {
172     priority_at_last_priority_update_ = PriorityCalculator::LowestPriority();
173     was_above_priority_cutoff_at_last_priority_update_ = false;
174   }
175 }
176 
UpdateState(ResourceProvider * resource_provider)177 void PrioritizedResource::Backing::UpdateState(
178     ResourceProvider* resource_provider) {
179   DCHECK(!proxy() ||
180          (proxy()->IsImplThread() && proxy()->IsMainThreadBlocked()));
181   in_drawing_impl_tree_ = !!owner();
182   in_parent_compositor_ = resource_provider->InUseByConsumer(id());
183   if (!in_drawing_impl_tree_) {
184     DCHECK_EQ(priority_at_last_priority_update_,
185               PriorityCalculator::LowestPriority());
186   }
187 }
188 
ReturnBackingTexture()189 void PrioritizedResource::ReturnBackingTexture() {
190   DCHECK(manager_ || !backing_);
191   if (manager_)
192     manager_->ReturnBackingTexture(this);
193 }
194 
proxy() const195 const Proxy* PrioritizedResource::Backing::proxy() const {
196   if (!owner_ || !owner_->resource_manager())
197     return NULL;
198   return owner_->resource_manager()->ProxyForDebug();
199 }
200 
201 }  // namespace cc
202