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                                          GLenum 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   // manager_ is set in RegisterTexture() so validity can be checked.
     29   DCHECK(format || size.IsEmpty());
     30   if (format)
     31     bytes_ = Resource::MemorySizeBytes(size, format);
     32   if (manager)
     33     manager->RegisterTexture(this);
     34 }
     35 
     36 PrioritizedResource::~PrioritizedResource() {
     37   if (manager_)
     38     manager_->UnregisterTexture(this);
     39 }
     40 
     41 void PrioritizedResource::SetTextureManager(
     42     PrioritizedResourceManager* manager) {
     43   if (manager_ == manager)
     44     return;
     45   if (manager_)
     46     manager_->UnregisterTexture(this);
     47   if (manager)
     48     manager->RegisterTexture(this);
     49 }
     50 
     51 void PrioritizedResource::SetDimensions(gfx::Size size, GLenum format) {
     52   if (format_ != format || size_ != size) {
     53     is_above_priority_cutoff_ = false;
     54     format_ = format;
     55     size_ = size;
     56     bytes_ = Resource::MemorySizeBytes(size, format);
     57     DCHECK(manager_ || !backing_);
     58     if (manager_)
     59       manager_->ReturnBackingTexture(this);
     60   }
     61 }
     62 
     63 bool PrioritizedResource::RequestLate() {
     64   if (!manager_)
     65     return false;
     66   return manager_->RequestLate(this);
     67 }
     68 
     69 bool PrioritizedResource::BackingResourceWasEvicted() const {
     70   return backing_ ? backing_->ResourceHasBeenDeleted() : false;
     71 }
     72 
     73 void PrioritizedResource::AcquireBackingTexture(
     74     ResourceProvider* resource_provider) {
     75   DCHECK(is_above_priority_cutoff_);
     76   if (is_above_priority_cutoff_)
     77     manager_->AcquireBackingTextureIfNeeded(this, resource_provider);
     78 }
     79 
     80 void PrioritizedResource::SetPixels(ResourceProvider* resource_provider,
     81                                     const uint8_t* image,
     82                                     gfx::Rect image_rect,
     83                                     gfx::Rect source_rect,
     84                                     gfx::Vector2d dest_offset) {
     85   DCHECK(is_above_priority_cutoff_);
     86   if (is_above_priority_cutoff_)
     87     AcquireBackingTexture(resource_provider);
     88   DCHECK(backing_);
     89   resource_provider->SetPixels(
     90       resource_id(), image, image_rect, source_rect, dest_offset);
     91 
     92   // The component order may be bgra if we uploaded bgra pixels to rgba
     93   // texture. Mark contents as swizzled if image component order is
     94   // different than texture format.
     95   contents_swizzled_ = !PlatformColor::SameComponentOrder(format_);
     96 }
     97 
     98 void PrioritizedResource::Link(Backing* backing) {
     99   DCHECK(backing);
    100   DCHECK(!backing->owner_);
    101   DCHECK(!backing_);
    102 
    103   backing_ = backing;
    104   backing_->owner_ = this;
    105 }
    106 
    107 void PrioritizedResource::Unlink() {
    108   DCHECK(backing_);
    109   DCHECK(backing_->owner_ == this);
    110 
    111   backing_->owner_ = NULL;
    112   backing_ = NULL;
    113 }
    114 
    115 void PrioritizedResource::SetToSelfManagedMemoryPlaceholder(size_t bytes) {
    116   SetDimensions(gfx::Size(), GL_RGBA);
    117   set_is_self_managed(true);
    118   bytes_ = bytes;
    119 }
    120 
    121 PrioritizedResource::Backing::Backing(unsigned id,
    122                                       ResourceProvider* resource_provider,
    123                                       gfx::Size size,
    124                                       GLenum format)
    125     : Resource(id, size, format),
    126       owner_(NULL),
    127       priority_at_last_priority_update_(PriorityCalculator::LowestPriority()),
    128       was_above_priority_cutoff_at_last_priority_update_(false),
    129       in_drawing_impl_tree_(false),
    130 #ifdef NDEBUG
    131       resource_has_been_deleted_(false) {}
    132 #else
    133       resource_has_been_deleted_(false),
    134       resource_provider_(resource_provider) {}
    135 #endif
    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 #ifndef NDEBUG
    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::CanBeRecycled() 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::UpdateInDrawingImplTree() {
    180   DCHECK(!proxy() ||
    181          (proxy()->IsImplThread() && proxy()->IsMainThreadBlocked()));
    182   in_drawing_impl_tree_ = !!owner();
    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