220 }; |
217 }; |
221 |
218 |
222 class QGLContextResource; |
219 class QGLContextResource; |
223 class QGLSharedResourceGuard; |
220 class QGLSharedResourceGuard; |
224 |
221 |
|
222 typedef QHash<QString, GLuint> QGLDDSCache; |
|
223 |
225 // QGLContextPrivate has the responsibility of creating context groups. |
224 // QGLContextPrivate has the responsibility of creating context groups. |
226 // QGLContextPrivate and QGLShareRegister will both maintain the reference counter and destroy |
225 // QGLContextPrivate and QGLShareRegister will both maintain the reference counter and destroy |
227 // context groups when needed. |
226 // context groups when needed. |
228 // QGLShareRegister has the responsibility of keeping the context pointer up to date. |
227 // QGLShareRegister has the responsibility of keeping the context pointer up to date. |
229 class QGLContextGroup |
228 class QGLContextGroup |
231 public: |
230 public: |
232 ~QGLContextGroup(); |
231 ~QGLContextGroup(); |
233 |
232 |
234 QGLExtensionFuncs &extensionFuncs() {return m_extensionFuncs;} |
233 QGLExtensionFuncs &extensionFuncs() {return m_extensionFuncs;} |
235 const QGLContext *context() const {return m_context;} |
234 const QGLContext *context() const {return m_context;} |
|
235 bool isSharing() const { return m_shares.size() >= 2; } |
236 |
236 |
237 void addGuard(QGLSharedResourceGuard *guard); |
237 void addGuard(QGLSharedResourceGuard *guard); |
238 void removeGuard(QGLSharedResourceGuard *guard); |
238 void removeGuard(QGLSharedResourceGuard *guard); |
239 private: |
239 private: |
240 QGLContextGroup(const QGLContext *context) : m_context(context), m_guards(0), m_refs(1) { } |
240 QGLContextGroup(const QGLContext *context) : m_context(context), m_guards(0), m_refs(1) { } |
243 const QGLContext *m_context; // context group's representative |
243 const QGLContext *m_context; // context group's representative |
244 QList<const QGLContext *> m_shares; |
244 QList<const QGLContext *> m_shares; |
245 QHash<QGLContextResource *, void *> m_resources; |
245 QHash<QGLContextResource *, void *> m_resources; |
246 QGLSharedResourceGuard *m_guards; // double-linked list of active guards. |
246 QGLSharedResourceGuard *m_guards; // double-linked list of active guards. |
247 QAtomicInt m_refs; |
247 QAtomicInt m_refs; |
|
248 QGLDDSCache m_dds_cache; |
248 |
249 |
249 void cleanupResources(const QGLContext *ctx); |
250 void cleanupResources(const QGLContext *ctx); |
250 |
251 |
251 friend class QGLShareRegister; |
252 friend class QGLShareRegister; |
252 friend class QGLContext; |
253 friend class QGLContext; |
285 HDC hbitmap_hdc; |
286 HDC hbitmap_hdc; |
286 #endif |
287 #endif |
287 #if defined(QT_OPENGL_ES) |
288 #if defined(QT_OPENGL_ES) |
288 QEglContext *eglContext; |
289 QEglContext *eglContext; |
289 EGLSurface eglSurface; |
290 EGLSurface eglSurface; |
|
291 void destroyEglSurfaceForDevice(); |
290 #elif defined(Q_WS_X11) || defined(Q_WS_MAC) |
292 #elif defined(Q_WS_X11) || defined(Q_WS_MAC) |
291 void* cx; |
293 void* cx; |
292 #endif |
294 #endif |
293 #if defined(Q_WS_X11) || defined(Q_WS_MAC) |
295 #if defined(Q_WS_X11) || defined(Q_WS_MAC) |
294 void* vi; |
296 void* vi; |
372 StencilWrap = 0x00000100, |
375 StencilWrap = 0x00000100, |
373 PackedDepthStencil = 0x00000200, |
376 PackedDepthStencil = 0x00000200, |
374 NVFloatBuffer = 0x00000400, |
377 NVFloatBuffer = 0x00000400, |
375 PixelBufferObject = 0x00000800, |
378 PixelBufferObject = 0x00000800, |
376 FramebufferBlit = 0x00001000, |
379 FramebufferBlit = 0x00001000, |
377 NPOTTextures = 0x00002000 |
380 NPOTTextures = 0x00002000, |
|
381 BGRATextureFormat = 0x00004000, |
|
382 DDSTextureCompression = 0x00008000, |
|
383 ETC1TextureCompression = 0x00010000, |
|
384 PVRTCTextureCompression = 0x00020000, |
|
385 FragmentShader = 0x00040000 |
378 }; |
386 }; |
379 Q_DECLARE_FLAGS(Extensions, Extension) |
387 Q_DECLARE_FLAGS(Extensions, Extension) |
380 |
388 |
381 static Extensions glExtensions; |
389 static Extensions glExtensions; |
382 static bool nvidiaFboNeedsFinish; |
390 static bool nvidiaFboNeedsFinish; |
477 |
485 |
478 #if defined(Q_WS_X11) |
486 #if defined(Q_WS_X11) |
479 QPixmapData* boundPixmap; |
487 QPixmapData* boundPixmap; |
480 #endif |
488 #endif |
481 |
489 |
|
490 bool canBindCompressedTexture |
|
491 (const char *buf, int len, const char *format, bool *hasAlpha); |
|
492 QSize bindCompressedTexture |
|
493 (const QString& fileName, const char *format = 0); |
|
494 QSize bindCompressedTexture |
|
495 (const char *buf, int len, const char *format = 0); |
|
496 QSize bindCompressedTextureDDS(const char *buf, int len); |
|
497 QSize bindCompressedTexturePVR(const char *buf, int len); |
482 }; |
498 }; |
483 |
499 |
484 class QGLTextureCache { |
500 class QGLTextureCache { |
485 public: |
501 public: |
486 QGLTextureCache(); |
502 QGLTextureCache(); |
513 |
529 |
514 bool qt_gl_preferGL2Engine(); |
530 bool qt_gl_preferGL2Engine(); |
515 |
531 |
516 inline GLenum qt_gl_preferredTextureFormat() |
532 inline GLenum qt_gl_preferredTextureFormat() |
517 { |
533 { |
518 return QSysInfo::ByteOrder == QSysInfo::BigEndian ? GL_RGBA : GL_BGRA; |
534 return (QGLExtensions::glExtensions & QGLExtensions::BGRATextureFormat) && QSysInfo::ByteOrder == QSysInfo::LittleEndian |
|
535 ? GL_BGRA : GL_RGBA; |
519 } |
536 } |
520 |
537 |
521 inline GLenum qt_gl_preferredTextureTarget() |
538 inline GLenum qt_gl_preferredTextureTarget() |
522 { |
539 { |
523 #if defined(QT_OPENGL_ES_2) |
540 #if defined(QT_OPENGL_ES_2) |
592 QGLSharedResourceGuard *m_prev; |
609 QGLSharedResourceGuard *m_prev; |
593 |
610 |
594 friend class QGLContextGroup; |
611 friend class QGLContextGroup; |
595 }; |
612 }; |
596 |
613 |
|
614 |
|
615 // This class can be used to match GL extensions with doing any mallocs. The |
|
616 // class assumes that the GL extension string ends with a space character, |
|
617 // which it should do on all conformant platforms. Create the object and pass |
|
618 // in a pointer to the extension string, then call match() on each extension |
|
619 // that should be matched. The match() function takes the extension name |
|
620 // *without* the terminating space character as input. |
|
621 |
|
622 class QGLExtensionMatcher |
|
623 { |
|
624 public: |
|
625 QGLExtensionMatcher(const char *str) |
|
626 : gl_extensions(str), gl_extensions_length(qstrlen(str)) |
|
627 {} |
|
628 |
|
629 bool match(const char *str) { |
|
630 int str_length = qstrlen(str); |
|
631 const char *extensions = gl_extensions; |
|
632 int extensions_length = gl_extensions_length; |
|
633 |
|
634 while (1) { |
|
635 // the total length that needs to be matched is the str_length + |
|
636 // the space character that terminates the extension name |
|
637 if (extensions_length < str_length + 1) |
|
638 return false; |
|
639 if (qstrncmp(extensions, str, str_length) == 0 && extensions[str_length] == ' ') |
|
640 return true; |
|
641 |
|
642 int split_pos = 0; |
|
643 while (split_pos < extensions_length && extensions[split_pos] != ' ') |
|
644 ++split_pos; |
|
645 ++split_pos; // added for the terminating space character |
|
646 extensions += split_pos; |
|
647 extensions_length -= split_pos; |
|
648 } |
|
649 return false; |
|
650 } |
|
651 |
|
652 private: |
|
653 const char *gl_extensions; |
|
654 int gl_extensions_length; |
|
655 }; |
|
656 |
597 QT_END_NAMESPACE |
657 QT_END_NAMESPACE |
598 |
658 |
599 #endif // QGL_P_H |
659 #endif // QGL_P_H |