summaryrefslogtreecommitdiffstats
path: root/chromium/cc/resources/prioritized_resource.h
blob: ee90024fd5c82384b95fef4762278a19130fefd8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_RESOURCES_PRIORITIZED_RESOURCE_H_
#define CC_RESOURCES_PRIORITIZED_RESOURCE_H_

#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/resources/priority_calculator.h"
#include "cc/resources/resource.h"
#include "cc/resources/resource_provider.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
#include "ui/gfx/vector2d.h"

namespace cc {

class PrioritizedResourceManager;
class Proxy;

class CC_EXPORT PrioritizedResource {
 public:
  static scoped_ptr<PrioritizedResource> Create(
      PrioritizedResourceManager* manager,
      gfx::Size size,
      ResourceFormat format) {
    return make_scoped_ptr(new PrioritizedResource(manager, size, format));
  }
  static scoped_ptr<PrioritizedResource> Create(
      PrioritizedResourceManager* manager) {
    return make_scoped_ptr(
        new PrioritizedResource(manager, gfx::Size(), RGBA_8888));
  }
  ~PrioritizedResource();

  // Texture properties. Changing these causes the backing texture to be lost.
  // Setting these to the same value is a no-op.
  void SetTextureManager(PrioritizedResourceManager* manager);
  PrioritizedResourceManager* resource_manager() { return manager_; }
  void SetDimensions(gfx::Size size, ResourceFormat format);
  ResourceFormat format() const { return format_; }
  gfx::Size size() const { return size_; }
  size_t bytes() const { return bytes_; }
  bool contents_swizzled() const { return contents_swizzled_; }

  // Set priority for the requested texture.
  void set_request_priority(int priority) { priority_ = priority; }
  int request_priority() const { return priority_; }

  // After PrioritizedResource::PrioritizeTextures() is called, this returns
  // if the the request succeeded and this texture can be acquired for use.
  bool can_acquire_backing_texture() const { return is_above_priority_cutoff_; }

  // This returns whether we still have a backing texture. This can continue
  // to be true even after CanAcquireBackingTexture() becomes false. In this
  // case the texture can be used but shouldn't be updated since it will get
  // taken away "soon".
  bool have_backing_texture() const { return !!backing(); }

  bool BackingResourceWasEvicted() const;

  // If CanAcquireBackingTexture() is true AcquireBackingTexture() will acquire
  // a backing texture for use. Call this whenever the texture is actually
  // needed.
  void AcquireBackingTexture(ResourceProvider* resource_provider);

  // TODO(epenner): Request late is really a hack for when we are totally out of
  // memory (all textures are visible) but we can still squeeze into the limit
  // by not painting occluded textures. In this case the manager refuses all
  // visible textures and RequestLate() will enable CanAcquireBackingTexture()
  // on a call-order basis. We might want to just remove this in the future
  // (carefully) and just make sure we don't regress OOMs situations.
  bool RequestLate();

  // Update pixels of backing resource from image. This functions will aquire
  // the backing if needed.
  void SetPixels(ResourceProvider* resource_provider,
                 const uint8_t* image,
                 gfx::Rect image_rect,
                 gfx::Rect source_rect,
                 gfx::Vector2d dest_offset);

  ResourceProvider::ResourceId resource_id() const {
    return backing_ ? backing_->id() : 0;
  }

  // Self-managed textures are accounted for when prioritizing other textures,
  // but they are not allocated/recycled/deleted, so this needs to be done
  // externally. CanAcquireBackingTexture() indicates if the texture would have
  // been allowed given its priority.
  void set_is_self_managed(bool is_self_managed) {
    is_self_managed_ = is_self_managed;
  }
  bool is_self_managed() { return is_self_managed_; }
  void SetToSelfManagedMemoryPlaceholder(size_t bytes);

  void ReturnBackingTexture();

 private:
  friend class PrioritizedResourceManager;
  friend class PrioritizedResourceTest;

  class Backing : public Resource {
   public:
    Backing(unsigned id,
            ResourceProvider* resource_provider,
            gfx::Size size,
            ResourceFormat format);
    ~Backing();
    void UpdatePriority();
    void UpdateState(ResourceProvider* resource_provider);

    PrioritizedResource* owner() { return owner_; }
    bool CanBeRecycledIfNotInExternalUse() const;
    int request_priority_at_last_priority_update() const {
      return priority_at_last_priority_update_;
    }
    bool was_above_priority_cutoff_at_last_priority_update() const {
      return was_above_priority_cutoff_at_last_priority_update_;
    }
    bool in_drawing_impl_tree() const { return in_drawing_impl_tree_; }
    bool in_parent_compositor() const { return in_parent_compositor_; }

    void DeleteResource(ResourceProvider* resource_provider);
    bool ResourceHasBeenDeleted() const;

   private:
    const Proxy* proxy() const;

    friend class PrioritizedResource;
    friend class PrioritizedResourceManager;
    PrioritizedResource* owner_;
    int priority_at_last_priority_update_;
    bool was_above_priority_cutoff_at_last_priority_update_;

    // Set if this is currently-drawing impl tree.
    bool in_drawing_impl_tree_;
    // Set if this is in the parent compositor.
    bool in_parent_compositor_;

    bool resource_has_been_deleted_;

#ifndef NDEBUG
    ResourceProvider* resource_provider_;
#endif
    DISALLOW_COPY_AND_ASSIGN(Backing);
  };

  PrioritizedResource(PrioritizedResourceManager* resource_manager,
                      gfx::Size size,
                      ResourceFormat format);

  bool is_above_priority_cutoff() { return is_above_priority_cutoff_; }
  void set_above_priority_cutoff(bool is_above_priority_cutoff) {
    is_above_priority_cutoff_ = is_above_priority_cutoff;
  }
  void set_manager_internal(PrioritizedResourceManager* manager) {
    manager_ = manager;
  }

  Backing* backing() const { return backing_; }
  void Link(Backing* backing);
  void Unlink();

  gfx::Size size_;
  ResourceFormat format_;
  size_t bytes_;
  bool contents_swizzled_;

  int priority_;
  bool is_above_priority_cutoff_;
  bool is_self_managed_;

  Backing* backing_;
  PrioritizedResourceManager* manager_;

  DISALLOW_COPY_AND_ASSIGN(PrioritizedResource);
};

}  // namespace cc

#endif  // CC_RESOURCES_PRIORITIZED_RESOURCE_H_