Home | History | Annotate | Download | only in resources
      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