Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the QtOpenVG module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
38 | ** $QT_END_LICENSE$ |
39 | ** |
40 | ****************************************************************************/ |
41 | |
42 | #include "qgltexturepool_p.h" |
43 | #include "qpixmapdata_gl_p.h" |
44 | #include "qgl_p.h" |
45 | |
46 | QT_BEGIN_NAMESPACE |
47 | |
48 | Q_OPENGL_EXPORT extern QGLWidget* qt_gl_share_widget(); |
49 | |
50 | static QGLTexturePool *qt_gl_texture_pool = 0; |
51 | |
52 | class QGLTexturePoolPrivate |
53 | { |
54 | public: |
55 | QGLTexturePoolPrivate() : lruFirst(0), lruLast(0) {} |
56 | |
57 | QGLTexture *lruFirst; |
58 | QGLTexture *lruLast; |
59 | }; |
60 | |
61 | QGLTexturePool::QGLTexturePool() |
62 | : d_ptr(new QGLTexturePoolPrivate()) |
63 | { |
64 | } |
65 | |
66 | QGLTexturePool::~QGLTexturePool() |
67 | { |
68 | } |
69 | |
70 | QGLTexturePool *QGLTexturePool::instance() |
71 | { |
72 | if (!qt_gl_texture_pool) |
73 | qt_gl_texture_pool = new QGLTexturePool(); |
74 | return qt_gl_texture_pool; |
75 | } |
76 | |
77 | GLuint QGLTexturePool::createTexture(GLenum target, |
78 | GLint level, |
79 | GLint internalformat, |
80 | GLsizei width, |
81 | GLsizei height, |
82 | GLenum format, |
83 | GLenum type, |
84 | QGLTexture *texture) |
85 | { |
86 | GLuint tex; |
87 | glGenTextures(1, &tex); |
88 | glBindTexture(target, tex); |
89 | do { |
90 | glTexImage2D(target, level, internalformat, width, height, 0, format, type, 0); |
91 | GLenum error = glGetError(); |
92 | if (error == GL_NO_ERROR) { |
93 | if (texture) |
94 | moveToHeadOfLRU(texture); |
95 | return tex; |
96 | } else if (error != GL_OUT_OF_MEMORY) { |
97 | qWarning("QGLTexturePool: cannot create temporary texture because of invalid params"); |
98 | return 0; |
99 | } |
100 | } while (reclaimSpace(internalformat, width, height, format, type, texture)); |
101 | qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d texture", |
102 | width, height); |
103 | return 0; |
104 | } |
105 | |
106 | bool QGLTexturePool::createPermanentTexture(GLuint tex, |
107 | GLenum target, |
108 | GLint level, |
109 | GLint internalformat, |
110 | GLsizei width, |
111 | GLsizei height, |
112 | GLenum format, |
113 | GLenum type, |
114 | const GLvoid *data) |
115 | { |
116 | glBindTexture(target, tex); |
117 | do { |
118 | glTexImage2D(target, level, internalformat, width, height, 0, format, type, data); |
119 | |
120 | GLenum error = glGetError(); |
121 | if (error == GL_NO_ERROR) { |
122 | return true; |
123 | } else if (error != GL_OUT_OF_MEMORY) { |
124 | qWarning("QGLTexturePool: cannot create permanent texture because of invalid params"); |
125 | return false; |
126 | } |
127 | } while (reclaimSpace(internalformat, width, height, format, type, 0)); |
128 | qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d texture", |
129 | width, height); |
130 | return 0; |
131 | } |
132 | |
133 | void QGLTexturePool::useTexture(QGLTexture *texture) |
134 | { |
135 | moveToHeadOfLRU(texture); |
136 | texture->inTexturePool = true; |
137 | } |
138 | |
139 | void QGLTexturePool::detachTexture(QGLTexture *texture) |
140 | { |
141 | removeFromLRU(texture); |
142 | texture->inTexturePool = false; |
143 | } |
144 | |
145 | bool QGLTexturePool::reclaimSpace(GLint internalformat, |
146 | GLsizei width, |
147 | GLsizei height, |
148 | GLenum format, |
149 | GLenum type, |
150 | QGLTexture *texture) |
151 | { |
152 | Q_UNUSED(internalformat); // For future use in picking the best texture to eject. |
153 | Q_UNUSED(width); |
154 | Q_UNUSED(height); |
155 | Q_UNUSED(format); |
156 | Q_UNUSED(type); |
157 | |
158 | bool succeeded = false; |
159 | bool wasInLRU = false; |
160 | if (texture) { |
161 | wasInLRU = texture->inLRU; |
162 | moveToHeadOfLRU(texture); |
163 | } |
164 | |
165 | QGLTexture *lrutexture = textureLRU(); |
166 | if (lrutexture && lrutexture != texture) { |
167 | if (lrutexture->boundPixmap) |
168 | lrutexture->boundPixmap->reclaimTexture(); |
169 | else |
170 | QGLTextureCache::instance()->remove(lrutexture->boundKey); |
171 | succeeded = true; |
172 | } |
173 | |
174 | if (texture && !wasInLRU) |
175 | removeFromLRU(texture); |
176 | |
177 | return succeeded; |
178 | } |
179 | |
180 | void QGLTexturePool::hibernate() |
181 | { |
182 | Q_D(QGLTexturePool); |
183 | QGLTexture *texture = d->lruLast; |
184 | while (texture) { |
185 | QGLTexture *prevLRU = texture->prevLRU; |
186 | texture->inTexturePool = false; |
187 | texture->inLRU = false; |
188 | texture->nextLRU = 0; |
189 | texture->prevLRU = 0; |
190 | if (texture->boundPixmap) |
191 | texture->boundPixmap->hibernate(); |
192 | else |
193 | QGLTextureCache::instance()->remove(texture->boundKey); |
194 | texture = prevLRU; |
195 | } |
196 | d->lruFirst = 0; |
197 | d->lruLast = 0; |
198 | } |
199 | |
200 | void QGLTexturePool::moveToHeadOfLRU(QGLTexture *texture) |
201 | { |
202 | Q_D(QGLTexturePool); |
203 | if (texture->inLRU) { |
204 | if (!texture->prevLRU) |
205 | return; // Already at the head of the list. |
206 | removeFromLRU(texture); |
207 | } |
208 | texture->inLRU = true; |
209 | texture->nextLRU = d->lruFirst; |
210 | texture->prevLRU = 0; |
211 | if (d->lruFirst) |
212 | d->lruFirst->prevLRU = texture; |
213 | else |
214 | d->lruLast = texture; |
215 | d->lruFirst = texture; |
216 | } |
217 | |
218 | void QGLTexturePool::removeFromLRU(QGLTexture *texture) |
219 | { |
220 | Q_D(QGLTexturePool); |
221 | if (!texture->inLRU) |
222 | return; |
223 | if (texture->nextLRU) |
224 | texture->nextLRU->prevLRU = texture->prevLRU; |
225 | else |
226 | d->lruLast = texture->prevLRU; |
227 | if (texture->prevLRU) |
228 | texture->prevLRU->nextLRU = texture->nextLRU; |
229 | else |
230 | d->lruFirst = texture->nextLRU; |
231 | texture->inLRU = false; |
232 | } |
233 | |
234 | QGLTexture *QGLTexturePool::textureLRU() |
235 | { |
236 | Q_D(QGLTexturePool); |
237 | return d->lruLast; |
238 | } |
239 | |
240 | QT_END_NAMESPACE |
241 |
Warning: That file was not part of the compilation database. It may have many parsing errors.