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
|
// 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();
void reduceMemoryOnImplThread(size_t limitBytes, CCResourceProvider*);
bool evictedBackingsExist() const { return !m_evictedBackings.isEmpty(); }
void getEvictedBackings(BackingVector& evictedBackings);
void unlinkEvictedBackings(const BackingVector& evictedBackings);
// Deletes all evicted backings, unlinking them from their owning textures if needed.
// Returns true if this function unlinked any backings from their owning texture while
// destroying them.
bool deleteEvictedBackings();
bool requestLate(CCPrioritizedTexture*);
void reduceMemory(CCResourceProvider*);
void clearAllMemory(CCResourceProvider*);
void acquireBackingTextureIfNeeded(CCPrioritizedTexture*, CCResourceProvider*);
void registerTexture(CCPrioritizedTexture*);
void unregisterTexture(CCPrioritizedTexture*);
void returnBackingTexture(CCPrioritizedTexture*);
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)
{
int priorityA = a->requestPriorityAtLastPriorityUpdate();
int priorityB = b->requestPriorityAtLastPriorityUpdate();
if (priorityA != priorityB)
return CCPriorityCalculator::priorityIsLower(priorityA, priorityB);
bool aboveCutoffA = a->wasAbovePriorityCutoffAtLastPriorityUpdate();
bool aboveCutoffB = b->wasAbovePriorityCutoffAtLastPriorityUpdate();
if (!aboveCutoffA && aboveCutoffB)
return true;
if (aboveCutoffA && !aboveCutoffB)
return false;
return a < b;
}
CCPrioritizedTextureManager(size_t maxMemoryLimitBytes, int maxTextureSize, int pool);
void updateBackingsPriorities();
void evictBackingsToReduceMemory(size_t limitBytes, EvictionPriorityPolicy, CCResourceProvider*);
CCPrioritizedTexture::Backing* createBacking(IntSize, GC3Denum format, CCResourceProvider*);
void evictBackingResource(CCPrioritizedTexture::Backing*, CCResourceProvider*);
#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;
// Set by the main thread when it adjust priorities in such a way that
// the m_backings array's view of priorities is now out of date.
bool m_needsUpdateBackingsPrioritites;
DISALLOW_COPY_AND_ASSIGN(CCPrioritizedTextureManager);
};
} // namespace cc
#endif
|