Re-apply change 353dcfd307853da289fdd245410e2e07358624a0 by Friedemann Kleint
[qt-netbsd.git] / src / opengl / qgl_p.h
blob85e9bd7020ad97876dfbbf88813b7bf2033c6184
1 /****************************************************************************
2 **
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: Nokia Corporation (qt-info@nokia.com)
5 **
6 ** This file is part of the QtOpenGL module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** No Commercial Usage
10 ** This file contains pre-release code and may not be distributed.
11 ** You may use this file in accordance with the terms and conditions
12 ** contained in the either Technology Preview License Agreement or the
13 ** Beta Release License Agreement.
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
36 ** If you are unsure which license is appropriate for your use, please
37 ** contact the sales department at http://www.qtsoftware.com/contact.
38 ** $QT_END_LICENSE$
40 ****************************************************************************/
42 #ifndef QGL_P_H
43 #define QGL_P_H
46 // W A R N I N G
47 // -------------
49 // This file is not part of the Qt API. It exists for the convenience
50 // of the QGLWidget class. This header file may change from
51 // version to version without notice, or even be removed.
53 // We mean it.
56 #include "QtOpenGL/qgl.h"
57 #include "QtOpenGL/qglcolormap.h"
58 #include "QtCore/qmap.h"
59 #include "QtCore/qthread.h"
60 #include "QtCore/qthreadstorage.h"
61 #include "QtCore/qhash.h"
62 #include "private/qwidget_p.h"
64 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
65 #include "private/qpixmapdata_gl_p.h"
66 #endif
68 #ifndef QT_OPENGL_ES_1_CL
69 #define q_vertexType float
70 #define q_vertexTypeEnum GL_FLOAT
71 #define f2vt(f) (f)
72 #define vt2f(x) (x)
73 #define i2vt(i) (float(i))
74 #else
75 #define FLOAT2X(f) (int( (f) * (65536)))
76 #define X2FLOAT(x) (float(x) / 65536.0f)
77 #define f2vt(f) FLOAT2X(f)
78 #define i2vt(i) ((i)*65536)
79 #define vt2f(x) X2FLOAT(x)
80 #define q_vertexType GLfixed
81 #define q_vertexTypeEnum GL_FIXED
82 #endif //QT_OPENGL_ES_1_CL
84 #ifdef QT_OPENGL_ES
85 QT_BEGIN_INCLUDE_NAMESPACE
86 #if defined(QT_OPENGL_ES_2)
87 #include <EGL/egl.h>
88 #else
89 #include <GLES/egl.h>
90 #endif
91 QT_END_INCLUDE_NAMESPACE
92 #endif
94 QT_BEGIN_NAMESPACE
96 class QGLContext;
97 class QGLOverlayWidget;
98 class QPixmap;
99 class QPixmapFilter;
100 #ifdef Q_WS_MAC
101 # ifdef qDebug
102 # define old_qDebug qDebug
103 # undef qDebug
104 # endif
105 QT_BEGIN_INCLUDE_NAMESPACE
106 #ifndef QT_MAC_USE_COCOA
107 # include <AGL/agl.h>
108 #endif
109 QT_END_INCLUDE_NAMESPACE
110 # ifdef old_qDebug
111 # undef qDebug
112 # define qDebug QT_QDEBUG_MACRO
113 # undef old_qDebug
114 # endif
115 class QMacWindowChangeEvent;
116 #endif
118 #ifdef Q_WS_QWS
119 class QWSGLWindowSurface;
120 #endif
122 #if defined(QT_OPENGL_ES)
123 class QEglContext;
124 #endif
126 QT_BEGIN_INCLUDE_NAMESPACE
127 #include <QtOpenGL/private/qglextensions_p.h>
128 QT_END_INCLUDE_NAMESPACE
130 class QGLFormatPrivate
132 public:
133 QGLFormatPrivate() {
134 opts = QGL::DoubleBuffer | QGL::DepthBuffer | QGL::Rgba | QGL::DirectRendering | QGL::StencilBuffer;
135 #if defined(QT_OPENGL_ES_2)
136 opts |= QGL::SampleBuffers;
137 #endif
138 pln = 0;
139 depthSize = accumSize = stencilSize = redSize = greenSize = blueSize = alphaSize = -1;
140 numSamples = -1;
141 swapInterval = -1;
143 QGL::FormatOptions opts;
144 int pln;
145 int depthSize;
146 int accumSize;
147 int stencilSize;
148 int redSize;
149 int greenSize;
150 int blueSize;
151 int alphaSize;
152 int numSamples;
153 int swapInterval;
156 class QGLWidgetPrivate : public QWidgetPrivate
158 Q_DECLARE_PUBLIC(QGLWidget)
159 public:
160 QGLWidgetPrivate() : QWidgetPrivate()
161 #ifdef Q_WS_QWS
162 , wsurf(0)
163 #endif
164 #if defined(Q_WS_X11) && defined(QT_OPENGL_ES)
165 , eglSurfaceWindowId(0)
166 #endif
169 ~QGLWidgetPrivate() {}
171 void init(QGLContext *context, const QGLWidget* shareWidget);
172 void initContext(QGLContext *context, const QGLWidget* shareWidget);
173 bool renderCxPm(QPixmap *pixmap);
174 void cleanupColormaps();
176 QGLContext *glcx;
177 bool autoSwap;
179 QGLColormap cmap;
180 QMap<QString, int> displayListCache;
182 #if defined(Q_WS_WIN)
183 void updateColormap();
184 QGLContext *olcx;
185 #elif defined(Q_WS_X11)
186 QGLOverlayWidget *olw;
187 #if defined(QT_OPENGL_ES)
188 void recreateEglSurface(bool force);
189 WId eglSurfaceWindowId;
190 #endif
191 #elif defined(Q_WS_MAC)
192 QGLContext *olcx;
193 void updatePaintDevice();
194 #elif defined(Q_WS_QWS)
195 QWSGLWindowSurface *wsurf;
196 #endif
199 class QGLContextPrivate
201 Q_DECLARE_PUBLIC(QGLContext)
202 public:
203 explicit QGLContextPrivate(QGLContext *context) : internal_context(false), q_ptr(context) {}
204 ~QGLContextPrivate() {}
205 GLuint bindTexture(const QImage &image, GLenum target, GLint format, const qint64 key,
206 bool clean = false);
207 GLuint bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean);
208 GLuint bindTexture(const QImage &image, GLenum target, GLint format, bool clean);
209 bool textureCacheLookup(const qint64 key, GLenum target, GLuint *id);
210 void init(QPaintDevice *dev, const QGLFormat &format);
211 QImage convertToGLFormat(const QImage &image, bool force_premul, GLenum texture_format);
212 int maxTextureSize();
214 void cleanup();
216 #if defined(Q_WS_WIN)
217 HGLRC rc;
218 HDC dc;
219 WId win;
220 int pixelFormatId;
221 QGLCmap* cmap;
222 HBITMAP hbitmap;
223 HDC hbitmap_hdc;
224 #endif
225 #if defined(QT_OPENGL_ES)
226 QEglContext *eglContext;
227 #elif defined(Q_WS_X11) || defined(Q_WS_MAC)
228 void* cx;
229 #endif
230 #if defined(Q_WS_X11) || defined(Q_WS_MAC)
231 void* vi;
232 #endif
233 #if defined(Q_WS_X11)
234 void* pbuf;
235 quint32 gpm;
236 int screen;
237 #endif
238 #if defined(Q_WS_MAC)
239 bool update;
240 void *tryFormat(const QGLFormat &format);
241 void clearDrawable();
242 #endif
243 QGLFormat glFormat;
244 QGLFormat reqFormat;
245 GLuint pbo;
246 GLuint fbo;
248 uint valid : 1;
249 uint sharing : 1;
250 uint initDone : 1;
251 uint crWin : 1;
252 uint clear_on_painter_begin : 1;
253 uint internal_context : 1;
254 uint version_flags_cached : 1;
255 QPaintDevice *paintDevice;
256 QColor transpColor;
257 QGLContext *q_ptr;
258 QGLFormat::OpenGLVersionFlags version_flags;
260 QGLExtensionFuncs extensionFuncs;
261 GLint max_texture_size;
263 GLuint current_fbo;
264 QPaintEngine *active_engine;
266 #ifdef Q_WS_WIN
267 static inline QGLExtensionFuncs& qt_get_extension_funcs(const QGLContext *ctx) { return ctx->d_ptr->extensionFuncs; }
268 #endif
270 #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS)
271 static QGLExtensionFuncs qt_extensionFuncs;
272 static inline QGLExtensionFuncs& qt_get_extension_funcs(const QGLContext *) { return qt_extensionFuncs; }
273 #endif
275 QPixmapFilter *createPixmapFilter(int type) const;
278 // ### make QGLContext a QObject in 5.0 and remove the proxy stuff
279 class Q_OPENGL_EXPORT QGLSignalProxy : public QObject
281 Q_OBJECT
282 public:
283 QGLSignalProxy() : QObject() {}
284 void emitAboutToDestroyContext(const QGLContext *context) {
285 emit aboutToDestroyContext(context);
287 static QGLSignalProxy *instance();
288 Q_SIGNALS:
289 void aboutToDestroyContext(const QGLContext *context);
292 class QGLPixelBuffer;
293 class QGLFramebufferObject;
294 class QWSGLWindowSurface;
295 class QGLWindowSurface;
296 class QGLDrawable {
297 public:
298 QGLDrawable() : widget(0), buffer(0), fbo(0)
299 #if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL))
300 , wsurf(0)
301 #endif
302 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
303 , pixmapData(0)
304 #endif
306 void setDevice(QPaintDevice *pdev);
307 void swapBuffers();
308 void makeCurrent();
309 void doneCurrent();
310 QSize size() const;
311 QGLFormat format() const;
312 GLuint bindTexture(const QImage &image, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA);
313 GLuint bindTexture(const QPixmap &pixmap, GLenum target = GL_TEXTURE_2D, GLint format = GL_RGBA);
314 QColor backgroundColor() const;
315 QGLContext *context() const;
316 bool autoFillBackground() const;
317 bool hasTransparentBackground() const;
319 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
320 QGLPixmapData *copyOnBegin() const;
321 #endif
323 private:
324 bool wasBound;
325 QGLWidget *widget;
326 QGLPixelBuffer *buffer;
327 QGLFramebufferObject *fbo;
328 #ifdef Q_WS_QWS
329 QWSGLWindowSurface *wsurf;
330 #elif !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
331 QGLWindowSurface *wsurf;
332 #endif
334 #if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)
335 QGLPixmapData *pixmapData;
336 #endif
337 int previous_fbo;
340 // GL extension definitions
341 class QGLExtensions {
342 public:
343 enum Extension {
344 TextureRectangle = 0x00000001,
345 SampleBuffers = 0x00000002,
346 GenerateMipmap = 0x00000004,
347 TextureCompression = 0x00000008,
348 FragmentProgram = 0x00000010,
349 MirroredRepeat = 0x00000020,
350 FramebufferObject = 0x00000040,
351 StencilTwoSide = 0x00000080,
352 StencilWrap = 0x00000100,
353 PackedDepthStencil = 0x00000200,
354 NVFloatBuffer = 0x00000400,
355 PixelBufferObject = 0x00000800,
356 FramebufferBlit = 0x00001000
358 Q_DECLARE_FLAGS(Extensions, Extension)
360 static Extensions glExtensions;
361 static bool nvidiaFboNeedsFinish;
362 static void init(); // sys dependent
363 static void init_extensions(); // general: called by init()
366 Q_DECLARE_OPERATORS_FOR_FLAGS(QGLExtensions::Extensions)
369 struct QGLThreadContext {
370 QGLContext *context;
372 extern QThreadStorage<QGLThreadContext *> qgl_context_storage;
374 typedef QMultiHash<const QGLContext *, const QGLContext *> QGLSharingHash;
375 class QGLShareRegister
377 public:
378 QGLShareRegister() {}
379 ~QGLShareRegister() { reg.clear(); }
381 bool checkSharing(const QGLContext *context1, const QGLContext *context2, const QGLContext * skip=0) {
382 if (context1 == context2)
383 return true;
384 QList<const QGLContext *> shares = reg.values(context1);
385 for (int k=0; k<shares.size(); ++k) {
386 const QGLContext *ctx = shares.at(k);
387 if (ctx == skip) // avoid an indirect circular loop (infinite recursion)
388 continue;
389 if (ctx == context2)
390 return true;
391 if (checkSharing(ctx, context2, context1))
392 return true;
394 return false;
397 void addShare(const QGLContext *context, const QGLContext *share) {
398 reg.insert(context, share); // context sharing works both ways
399 reg.insert(share, context);
402 void removeShare(const QGLContext *context) {
403 QGLSharingHash::iterator it = reg.begin();
404 while (it != reg.end()) {
405 if (it.key() == context || it.value() == context)
406 it = reg.erase(it);
407 else
408 ++it;
412 void replaceShare(const QGLContext *oldContext, const QGLContext *newContext) {
413 QGLSharingHash::iterator it = reg.begin();
414 while (it != reg.end()) {
415 if (it.key() == oldContext)
416 reg.insert(newContext, it.value());
417 else if (it.value() == oldContext)
418 reg.insert(it.key(), newContext);
419 ++it;
421 removeShare(oldContext);
424 private:
425 QGLSharingHash reg;
428 extern Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg();
430 #ifdef Q_WS_QWS
431 extern QPaintEngine* qt_qgl_paint_engine();
433 extern EGLDisplay qt_qgl_egl_display();
434 #endif
436 inline bool qt_gl_preferGL2Engine()
438 #if defined(QT_OPENGL_ES_2)
439 return true;
440 #else
441 return (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)
442 && qgetenv("QT_GL_USE_OPENGL1ENGINE").isEmpty();
443 #endif
446 inline GLenum qt_gl_preferredTextureFormat()
448 return QSysInfo::ByteOrder == QSysInfo::BigEndian ? GL_RGBA : GL_BGRA;
451 inline GLenum qt_gl_preferredTextureTarget()
453 #if defined(QT_OPENGL_ES_2)
454 return GL_TEXTURE_2D;
455 #else
456 return (QGLExtensions::glExtensions & QGLExtensions::TextureRectangle)
457 && !qt_gl_preferGL2Engine()
458 ? GL_TEXTURE_RECTANGLE_NV
459 : GL_TEXTURE_2D;
460 #endif
463 QT_END_NAMESPACE
465 #endif // QGL_P_H