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