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
|
#include "xcompositeglxintegration.h"
#include "waylandobject.h"
#include "wayland_wrapper/wlcompositor.h"
#include "wayland-xcomposite-server-protocol.h"
#include <QtGui/QPlatformNativeInterface>
#include <QtGui/QOpenGLContext>
#include "xcompositebuffer.h"
#include "xcompositehandler.h"
#include <X11/extensions/Xcomposite.h>
#include <QtCore/QDebug>
QVector<int> qglx_buildSpec()
{
QVector<int> spec(48);
int i = 0;
spec[i++] = GLX_LEVEL;
spec[i++] = 0;
spec[i++] = GLX_DRAWABLE_TYPE; spec[i++] = GLX_PIXMAP_BIT | GLX_WINDOW_BIT;
spec[i++] = GLX_BIND_TO_TEXTURE_TARGETS_EXT; spec[i++] = GLX_TEXTURE_2D_BIT_EXT;
spec[i++] = GLX_BIND_TO_TEXTURE_RGB_EXT; spec[i++] = TRUE;
spec[i++] = 0;
return spec;
}
struct wl_xcomposite_interface XCompositeHandler::xcomposite_interface = {
XCompositeHandler::create_buffer
};
GraphicsHardwareIntegration *GraphicsHardwareIntegration::createGraphicsHardwareIntegration(WaylandCompositor *compositor)
{
return new XCompositeGLXIntegration(compositor);
}
XCompositeGLXIntegration::XCompositeGLXIntegration(WaylandCompositor *compositor)
: GraphicsHardwareIntegration(compositor)
, mDisplay(0)
{
QPlatformNativeInterface *nativeInterface = QGuiApplicationPrivate::platformIntegration()->nativeInterface();
if (nativeInterface) {
mDisplay = static_cast<Display *>(nativeInterface->nativeResourceForWindow("Display",m_compositor->window()));
if (!mDisplay)
qFatal("could not retireve Display from platform integration");
} else {
qFatal("Platform integration doesn't have native interface");
}
mScreen = XDefaultScreen(mDisplay);
}
void XCompositeGLXIntegration::initializeHardware(Wayland::Display *waylandDisplay)
{
XCompositeHandler *handler = new XCompositeHandler(m_compositor->handle(),mDisplay,m_compositor->window());
wl_display_add_global(waylandDisplay->handle(),&wl_xcomposite_interface,handler,XCompositeHandler::xcomposite_bind_func);
QOpenGLContext *glContext = new QOpenGLContext();
glContext->create();
m_glxBindTexImageEXT = reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(glContext->getProcAddress("glXBindTexImageEXT"));
if (!m_glxBindTexImageEXT) {
qDebug() << "Did not find glxBindTexImageExt, everything will FAIL!";
}
m_glxReleaseTexImageEXT = reinterpret_cast<PFNGLXRELEASETEXIMAGEEXTPROC>(glContext->getProcAddress("glXReleaseTexImageEXT"));
if (!m_glxReleaseTexImageEXT) {
qDebug() << "Did not find glxReleaseTexImageExt";
}
delete glContext;
}
GLuint XCompositeGLXIntegration::createTextureFromBuffer(wl_buffer *buffer, QOpenGLContext *)
{
XCompositeBuffer *compositorBuffer = Wayland::wayland_cast<XCompositeBuffer *>(buffer);
Pixmap pixmap = XCompositeNameWindowPixmap(mDisplay, compositorBuffer->window());
QVector<int> glxConfigSpec = qglx_buildSpec();
int numberOfConfigs;
GLXFBConfig *configs = glXChooseFBConfig(mDisplay,mScreen,glxConfigSpec.constData(),&numberOfConfigs);
QVector<int> attribList;
attribList.append(GLX_TEXTURE_FORMAT_EXT);
attribList.append(GLX_TEXTURE_FORMAT_RGB_EXT);
attribList.append(GLX_TEXTURE_TARGET_EXT);
attribList.append(GLX_TEXTURE_2D_EXT);
attribList.append(0);
GLXPixmap glxPixmap = glXCreatePixmap(mDisplay,*configs,pixmap,attribList.constData());
uint inverted = 0;
glXQueryDrawable(mDisplay, glxPixmap, GLX_Y_INVERTED_EXT,&inverted);
compositorBuffer->setInvertedY(!inverted);
XFree(configs);
GLuint textureId;
glGenTextures(1,&textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
m_glxBindTexImageEXT(mDisplay,glxPixmap,GLX_FRONT_EXT, 0);
//Do we need to change the api so that we do bind and release in the painevent?
//The specification states that when deleting the texture the color buffer is deleted
// m_glxReleaseTexImageEXT(mDisplay,glxPixmap,GLX_FRONT_EXT);
return textureId;
}
bool XCompositeGLXIntegration::isYInverted(wl_buffer *buffer) const
{
XCompositeBuffer *compositorBuffer = Wayland::wayland_cast<XCompositeBuffer *>(buffer);
return compositorBuffer->isYInverted();
}
|