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
|
// 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 CCPrioritizedTextureManager_h
#define CCPrioritizedTextureManager_h
#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "CCPrioritizedTexture.h"
#include "CCPriorityCalculator.h"
#include "CCTexture.h"
#include "GraphicsContext3D.h"
#include "IntRect.h"
#include "IntSize.h"
#include <wtf/ListHashSet.h>
#include <wtf/Vector.h>
#if defined(COMPILER_GCC)
namespace BASE_HASH_NAMESPACE {
template<>
struct hash<cc::CCPrioritizedTexture*> {
size_t operator()(cc::CCPrioritizedTexture* ptr) const {
return hash<size_t>()(reinterpret_cast<size_t>(ptr));
}
};
} // namespace BASE_HASH_NAMESPACE
#endif // COMPILER
namespace cc {
class CCPriorityCalculator;
class CCPrioritizedTextureManager {
public:
static scoped_ptr<CCPrioritizedTextureManager> create(size_t maxMemoryLimitBytes, int maxTextureSize, int pool)
{
return make_scoped_ptr(new CCPrioritizedTextureManager(maxMemoryLimitBytes, maxTextureSize, pool));
}
scoped_ptr<CCPrioritizedTexture> createTexture(IntSize size, GC3Denum format)
{
return make_scoped_ptr(new CCPrioritizedTexture(this, size, format));
}
~CCPrioritizedTextureManager();
typedef Vector<CCPrioritizedTexture::Backing*> BackingVector;
// FIXME (http://crbug.com/137094): This 64MB default is a straggler from the
// old texture manager and is just to give us a default memory allocation before
// we get a callback from the GPU memory manager. We should probaby either:
// - wait for the callback before rendering anything instead
// - push this into the GPU memory manager somehow.
static size_t defaultMemoryAllocationLimit() { return 64 * 1024 * 1024; }
// memoryUseBytes() describes the number of bytes used by existing allocated textures.
// memoryAboveCutoffBytes() describes the number of bytes that would be used if all
// textures that are above the cutoff were allocated.
// memoryUseBytes() <= memoryAboveCutoffBytes() should always be true.
size_t memoryUseBytes() const { return m_memoryUseBytes; }
size_t memoryAboveCutoffBytes() const { return m_memoryAboveCutoffBytes; }
size_t memoryForSelfManagedTextures() const { return m_maxMemoryLimitBytes - m_memoryAvailableBytes; }
void setMaxMemoryLimitBytes(size_t bytes) { m_maxMemoryLimitBytes = bytes; }
size_t maxMemoryLimitBytes() const { return m_maxMemoryLimitBytes; }
void prioritizeTextures();
void clearPriorities();
// Delete contents textures' backing resources until they use only bytesLimit bytes. This may
// be called on the impl thread while the main thread is running.
void reduceMemoryOnImplThread(size_t limitBytes, CCResourceProvider*);
// Returns true if there exist any textures that are linked to backings that have had their
// resources evicted. Only when we commit a tree that has no textures linked to evicted backings
// may we allow drawing.
bool linkedEvictedBackingsExist() const;
// Retrieve the list of all contents textures' backings that have been evicted, to pass to the
// main thread to unlink them from their owning textures.
void getEvictedBackings(BackingVector& evictedBackings);
// Unlink the list of contents textures' backings from their owning textures on the main thread
// before updating layers.
void unlinkEvictedBackings(const BackingVector& evictedBackings);
bool requestLate(CCPrioritizedTexture*);
void reduceMemory(CCResourceProvider*);
void clearAllMemory(CCResourceProvider*);
void acquireBackingTextureIfNeeded(CCPrioritizedTexture*, CCResourceProvider*);
void registerTexture(CCPrioritizedTexture*);
void unregisterTexture(CCPrioritizedTexture*);
void returnBackingTexture(CCPrioritizedTexture*);
// Update all backings' priorities from their owning texture.
void pushTexturePrioritiesToBackings();
// Mark all textures' backings as being in the drawing impl tree.
void updateBackingsInDrawingImplTree();
private:
friend class CCPrioritizedTextureTest;
enum EvictionPriorityPolicy {
RespectManagerPriorityCutoff,
DoNotRespectManagerPriorityCutoff,
};
// Compare textures. Highest priority first.
static inline bool compareTextures(CCPrioritizedTexture* a, CCPrioritizedTexture* b)
{
if (a->requestPriority() == b->requestPriority())
return a < b;
return CCPriorityCalculator::priorityIsHigher(a->requestPriority(), b->requestPriority());
}
// Compare backings. Lowest priority first.
static inline bool compareBackings(CCPrioritizedTexture::Backing* a, CCPrioritizedTexture::Backing* b)
{
// Make textures that can be recycled appear first
if (a->canBeRecycled() != b->canBeRecycled())
return (a->canBeRecycled() > b->canBeRecycled());
// Then sort by being above or below the priority cutoff.
if (a->wasAbovePriorityCutoffAtLastPriorityUpdate() != b->wasAbovePriorityCutoffAtLastPriorityUpdate())
return (a->wasAbovePriorityCutoffAtLastPriorityUpdate() < b->wasAbovePriorityCutoffAtLastPriorityUpdate());
// Then sort by priority (note that backings that no longer have owners will
// always have the lowest priority)
if (a->requestPriorityAtLastPriorityUpdate() != b->requestPriorityAtLastPriorityUpdate())
return CCPriorityCalculator::priorityIsLower(a->requestPriorityAtLastPriorityUpdate(), b->requestPriorityAtLastPriorityUpdate());
// Finally sort by being in the impl tree versus being completely unreferenced
if (a->inDrawingImplTree() != b->inDrawingImplTree())
return (a->inDrawingImplTree() < b->inDrawingImplTree());
return a < b;
}
CCPrioritizedTextureManager(size_t maxMemoryLimitBytes, int maxTextureSize, int pool);
void evictBackingsToReduceMemory(size_t limitBytes, EvictionPriorityPolicy, CCResourceProvider*);
CCPrioritizedTexture::Backing* createBacking(IntSize, GC3Denum format, CCResourceProvider*);
void evictBackingResource(CCPrioritizedTexture::Backing*, CCResourceProvider*);
void deleteUnlinkedEvictedBackings();
void sortBackings();
#if !ASSERT_DISABLED
void assertInvariants();
#endif
size_t m_maxMemoryLimitBytes;
unsigned m_priorityCutoff;
size_t m_memoryUseBytes;
size_t m_memoryAboveCutoffBytes;
size_t m_memoryAvailableBytes;
int m_pool;
typedef base::hash_set<CCPrioritizedTexture*> TextureSet;
typedef ListHashSet<CCPrioritizedTexture::Backing*> BackingSet;
typedef Vector<CCPrioritizedTexture*> TextureVector;
TextureSet m_textures;
BackingSet m_backings;
BackingVector m_evictedBackings;
TextureVector m_tempTextureVector;
BackingVector m_tempBackingVector;
DISALLOW_COPY_AND_ASSIGN(CCPrioritizedTextureManager);
};
} // namespace cc
#endif
|