50 #include <QDebug> |
50 #include <QDebug> |
51 |
51 |
52 |
52 |
53 QT_BEGIN_NAMESPACE |
53 QT_BEGIN_NAMESPACE |
54 |
54 |
|
55 |
|
56 bool qt_egl_setup_x11_visual(XVisualInfo &vi, EGLDisplay display, EGLConfig config, |
|
57 const QX11Info &x11Info, bool useArgbVisual); |
|
58 |
|
59 /* |
|
60 QGLTemporaryContext implementation |
|
61 */ |
|
62 |
|
63 class QGLTemporaryContextPrivate |
|
64 { |
|
65 public: |
|
66 bool initialized; |
|
67 Window window; |
|
68 EGLContext context; |
|
69 EGLSurface surface; |
|
70 EGLDisplay display; |
|
71 }; |
|
72 |
|
73 QGLTemporaryContext::QGLTemporaryContext(bool, QWidget *) |
|
74 : d(new QGLTemporaryContextPrivate) |
|
75 { |
|
76 d->initialized = false; |
|
77 d->window = 0; |
|
78 d->context = 0; |
|
79 d->surface = 0; |
|
80 int screen = 0; |
|
81 |
|
82 d->display = eglGetDisplay(EGLNativeDisplayType(X11->display)); |
|
83 |
|
84 if (!eglInitialize(d->display, NULL, NULL)) { |
|
85 qWarning("QGLTemporaryContext: Unable to initialize EGL display."); |
|
86 return; |
|
87 } |
|
88 |
|
89 EGLConfig config; |
|
90 int numConfigs = 0; |
|
91 EGLint attribs[] = { |
|
92 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
|
93 #ifdef QT_OPENGL_ES_2 |
|
94 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, |
|
95 #endif |
|
96 EGL_NONE |
|
97 }; |
|
98 |
|
99 eglChooseConfig(d->display, attribs, &config, 1, &numConfigs); |
|
100 if (!numConfigs) { |
|
101 qWarning("QGLTemporaryContext: No EGL configurations available."); |
|
102 return; |
|
103 } |
|
104 |
|
105 XVisualInfo visualInfo; |
|
106 XVisualInfo *vi; |
|
107 int numVisuals; |
|
108 EGLint id = 0; |
|
109 |
|
110 eglGetConfigAttrib(d->display, config, EGL_NATIVE_VISUAL_ID, &id); |
|
111 if (id == 0) { |
|
112 // EGL_NATIVE_VISUAL_ID is optional and might not be supported |
|
113 // on some implementations - we'll have to do it the hard way |
|
114 QX11Info xinfo; |
|
115 qt_egl_setup_x11_visual(visualInfo, d->display, config, xinfo, false); |
|
116 } else { |
|
117 visualInfo.visualid = id; |
|
118 } |
|
119 vi = XGetVisualInfo(X11->display, VisualIDMask, &visualInfo, &numVisuals); |
|
120 if (!vi || numVisuals < 1) { |
|
121 qWarning("QGLTemporaryContext: Unable to get X11 visual info id."); |
|
122 return; |
|
123 } |
|
124 |
|
125 d->window = XCreateWindow(X11->display, RootWindow(X11->display, screen), |
|
126 0, 0, 1, 1, 0, |
|
127 vi->depth, InputOutput, vi->visual, |
|
128 0, 0); |
|
129 |
|
130 d->surface = eglCreateWindowSurface(d->display, config, (EGLNativeWindowType) d->window, NULL); |
|
131 |
|
132 if (d->surface == EGL_NO_SURFACE) { |
|
133 qWarning("QGLTemporaryContext: Error creating EGL surface."); |
|
134 XFree(vi); |
|
135 XDestroyWindow(X11->display, d->window); |
|
136 return; |
|
137 } |
|
138 |
|
139 EGLint contextAttribs[] = { |
|
140 #ifdef QT_OPENGL_ES_2 |
|
141 EGL_CONTEXT_CLIENT_VERSION, 2, |
|
142 #endif |
|
143 EGL_NONE |
|
144 }; |
|
145 d->context = eglCreateContext(d->display, config, 0, contextAttribs); |
|
146 if (d->context != EGL_NO_CONTEXT |
|
147 && eglMakeCurrent(d->display, d->surface, d->surface, d->context)) |
|
148 { |
|
149 d->initialized = true; |
|
150 } else { |
|
151 qWarning("QGLTemporaryContext: Error creating EGL context."); |
|
152 eglDestroySurface(d->display, d->surface); |
|
153 XDestroyWindow(X11->display, d->window); |
|
154 } |
|
155 XFree(vi); |
|
156 } |
|
157 |
|
158 QGLTemporaryContext::~QGLTemporaryContext() |
|
159 { |
|
160 if (d->initialized) { |
|
161 eglMakeCurrent(d->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
|
162 eglDestroyContext(d->display, d->context); |
|
163 eglDestroySurface(d->display, d->surface); |
|
164 XDestroyWindow(X11->display, d->window); |
|
165 } |
|
166 } |
|
167 |
55 bool QGLFormat::hasOpenGLOverlays() |
168 bool QGLFormat::hasOpenGLOverlays() |
56 { |
169 { |
57 return false; |
170 return false; |
58 } |
171 } |
59 |
172 |
75 |
188 |
76 // Get the display and initialize it. |
189 // Get the display and initialize it. |
77 if (d->eglContext == 0) { |
190 if (d->eglContext == 0) { |
78 d->eglContext = new QEglContext(); |
191 d->eglContext = new QEglContext(); |
79 d->eglContext->setApi(QEgl::OpenGL); |
192 d->eglContext->setApi(QEgl::OpenGL); |
80 if (!d->eglContext->openDisplay(device())) { |
|
81 delete d->eglContext; |
|
82 d->eglContext = 0; |
|
83 return false; |
|
84 } |
|
85 |
193 |
86 // Construct the configuration we need for this surface. |
194 // Construct the configuration we need for this surface. |
87 QEglProperties configProps; |
195 QEglProperties configProps; |
88 qt_egl_set_format(configProps, devType, d->glFormat); |
196 qt_egl_set_format(configProps, devType, d->glFormat); |
89 qt_egl_add_platform_config(configProps, device()); |
197 qt_egl_add_platform_config(configProps, device()); |
237 } |
345 } |
238 } |
346 } |
239 |
347 |
240 // If EGL does not know the visual ID, so try to select an appropriate one ourselves, first |
348 // If EGL does not know the visual ID, so try to select an appropriate one ourselves, first |
241 // using XRender if we're supposed to have an alpha, then falling back to XGetVisualInfo |
349 // using XRender if we're supposed to have an alpha, then falling back to XGetVisualInfo |
242 |
350 |
243 #if !defined(QT_NO_XRENDER) |
351 #if !defined(QT_NO_XRENDER) |
244 if (vi.visualid == 0 && useArgbVisual) { |
352 if (vi.visualid == 0 && useArgbVisual) { |
245 // Try to use XRender to find an ARGB visual we can use |
353 // Try to use XRender to find an ARGB visual we can use |
246 vi.screen = x11Info.screen(); |
354 vi.screen = x11Info.screen(); |
247 vi.depth = 32; //### We might at some point (soon) get ARGB4444 |
355 vi.depth = 32; //### We might at some point (soon) get ARGB4444 |
516 configAttribs.setValue(EGL_SAMPLE_BUFFERS, 1); |
607 configAttribs.setValue(EGL_SAMPLE_BUFFERS, 1); |
517 } |
608 } |
518 |
609 |
519 EGLint configCount = 0; |
610 EGLint configCount = 0; |
520 do { |
611 do { |
521 eglChooseConfig(QEglContext::defaultDisplay(0), configAttribs.properties(), targetConfig, 1, &configCount); |
612 eglChooseConfig(QEglContext::display(), configAttribs.properties(), targetConfig, 1, &configCount); |
522 if (configCount > 0) { |
613 if (configCount > 0) { |
523 // Got one |
614 // Got one |
524 qDebug() << "Found an" << (hasAlpha ? "ARGB" : "RGB") << (readOnly ? "readonly" : "target" ) |
615 qDebug() << "Found an" << (hasAlpha ? "ARGB" : "RGB") << (readOnly ? "readonly" : "target" ) |
525 << "config (" << int(*targetConfig) << ") to create a pixmap surface:"; |
616 << "config (" << int(*targetConfig) << ") to create a pixmap surface:"; |
526 |
617 |
555 pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA); |
646 pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA); |
556 else |
647 else |
557 pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB); |
648 pixmapAttribs.setValue(EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB); |
558 |
649 |
559 EGLSurface pixmapSurface; |
650 EGLSurface pixmapSurface; |
560 pixmapSurface = eglCreatePixmapSurface(QEglContext::defaultDisplay(0), |
651 pixmapSurface = eglCreatePixmapSurface(QEglContext::display(), |
561 pixmapConfig, |
652 pixmapConfig, |
562 (EGLNativePixmapType) pixmapData->handle(), |
653 (EGLNativePixmapType) pixmapData->handle(), |
563 pixmapAttribs.properties()); |
654 pixmapAttribs.properties()); |
564 // qDebug("qt_createEGLSurfaceForPixmap() created surface 0x%x for pixmap 0x%x", |
655 // qDebug("qt_createEGLSurfaceForPixmap() created surface 0x%x for pixmap 0x%x", |
565 // pixmapSurface, pixmapData->handle()); |
656 // pixmapSurface, pixmapData->handle()); |
664 { |
755 { |
665 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); |
756 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); |
666 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); |
757 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); |
667 if (pixmapData->gl_surface) { |
758 if (pixmapData->gl_surface) { |
668 EGLBoolean success; |
759 EGLBoolean success; |
669 success = eglDestroySurface(QEglContext::defaultDisplay(0), (EGLSurface)pixmapData->gl_surface); |
760 success = eglDestroySurface(QEglContext::display(), (EGLSurface)pixmapData->gl_surface); |
670 if (success == EGL_FALSE) { |
761 if (success == EGL_FALSE) { |
671 qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: " |
762 qWarning() << "destroyGlSurfaceForPixmap() - Error deleting surface: " |
672 << QEglContext::errorString(eglGetError()); |
763 << QEglContext::errorString(eglGetError()); |
673 } |
764 } |
674 pixmapData->gl_surface = 0; |
765 pixmapData->gl_surface = 0; |
679 { |
770 { |
680 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); |
771 Q_ASSERT(pmd->classId() == QPixmapData::X11Class); |
681 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); |
772 QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd); |
682 if (pixmapData->gl_surface) { |
773 if (pixmapData->gl_surface) { |
683 EGLBoolean success; |
774 EGLBoolean success; |
684 success = eglReleaseTexImage(QEglContext::defaultDisplay(0), |
775 success = eglReleaseTexImage(QEglContext::display(), |
685 (EGLSurface)pixmapData->gl_surface, |
776 (EGLSurface)pixmapData->gl_surface, |
686 EGL_BACK_BUFFER); |
777 EGL_BACK_BUFFER); |
687 if (success == EGL_FALSE) { |
778 if (success == EGL_FALSE) { |
688 qWarning() << "unbindPixmapFromTexture() - Unable to release bound texture: " |
779 qWarning() << "unbindPixmapFromTexture() - Unable to release bound texture: " |
689 << QEglContext::errorString(eglGetError()); |
780 << QEglContext::errorString(eglGetError()); |