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 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(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 60 bool PrioritizedResource::RequestLate() { 61 if (!manager_) 62 return false; 63 return manager_->RequestLate(this); 64 } 65 66 bool PrioritizedResource::BackingResourceWasEvicted() const { 67 return backing_ ? backing_->ResourceHasBeenDeleted() : false; 68 } 69 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 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 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 104 void PrioritizedResource::Unlink() { 105 DCHECK(backing_); 106 DCHECK(backing_->owner_ == this); 107 108 backing_->owner_ = NULL; 109 backing_ = NULL; 110 } 111 112 void PrioritizedResource::SetToSelfManagedMemoryPlaceholder(size_t bytes) { 113 SetDimensions(gfx::Size(), RGBA_8888); 114 set_is_self_managed(true); 115 bytes_ = bytes; 116 } 117 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 135 PrioritizedResource::Backing::~Backing() { 136 DCHECK(!owner_); 137 DCHECK(resource_has_been_deleted_); 138 } 139 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 153 bool PrioritizedResource::Backing::ResourceHasBeenDeleted() const { 154 DCHECK(!proxy() || proxy()->IsImplThread()); 155 return resource_has_been_deleted_; 156 } 157 158 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 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 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 189 void PrioritizedResource::ReturnBackingTexture() { 190 DCHECK(manager_ || !backing_); 191 if (manager_) 192 manager_->ReturnBackingTexture(this); 193 } 194 195 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