GLuint WaylandSurface::texture() const
{
Q_D(const WaylandSurface);
- return d->surface->texture();
+ return d->surface->textureId();
}
#else //QT_COMPOSITOR_WAYLAND_GL
uint WaylandSurface::texture() const
enum Type {
Invalid,
Shm,
- Texture
+ Texture,
+ Direct
};
WaylandSurface(Wayland::Surface *surface);
XCompositeBuffer::XCompositeBuffer(Wayland::Compositor *compositor, Window window, const QSize &size, struct wl_visual *visual)
: mWindow(window)
{
- base()->attach = 0;
- base()->damage = 0;
base()->compositor = compositor->base();
base()->height = size.height();
base()->width = size.width();
}
struct wl_buffer_interface XCompositeBuffer::buffer_interface = {
+ XCompositeBuffer::buffer_interface_damage,
XCompositeBuffer::buffer_interface_destroy
};
+void XCompositeBuffer::buffer_interface_damage(struct wl_client *client,
+ struct wl_buffer *wl_buffer,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ Q_UNUSED(client);
+ Q_UNUSED(wl_buffer);
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+ Q_UNUSED(width);
+ Q_UNUSED(height);
+}
+
void XCompositeBuffer::buffer_interface_destroy(wl_client *client, wl_buffer *buffer)
{
Q_UNUSED(client);
static struct wl_buffer_interface buffer_interface;
static void delete_resource(struct wl_resource *resource,
struct wl_client *client);
+
private:
Window mWindow;
static void buffer_interface_destroy(struct wl_client *client,
struct wl_buffer *buffer);
+ static void buffer_interface_damage(struct wl_client *client,
+ struct wl_buffer *wl_buffer,
+ int x,
+ int y,
+ int width,
+ int height);
};
#endif // XCOMPOSITORBUFFER_H
XCompositeBuffer::delete_resource);
}
-void XCompositeHandler::send_root_information(struct wl_client *client, struct wl_object *global)
+void XCompositeHandler::send_root_information(struct wl_client *client, struct wl_object *global, uint32_t version)
{
+ Q_UNUSED(version);
XCompositeHandler *handler = Wayland::wayland_cast<XCompositeHandler *>(global);
const char *displayString = XDisplayString(handler->mDisplay);
wl_client_post_event(client, global, WL_XCOMPOSITE_ROOT, displayString, handler->mFakeRootWidget->winId());
XCompositeHandler(Wayland::Compositor *compositor, Display *display, QWidget *topLevelWidget);
void createBuffer(struct wl_client *client, uint32_t id, Window window, const QSize &size, struct wl_visual *visual);
- static void send_root_information(struct wl_client *client, struct wl_object *global);
+ static void send_root_information(struct wl_client *client, struct wl_object *global, uint32_t version);
static struct wl_xcomposite_interface xcomposite_interface;
private:
Compositor::Compositor(WaylandCompositor *qt_compositor)
: m_display(new Display)
- , m_shm(this)
+ , m_shm(m_display)
, m_current_frame(0)
, m_last_queued_buf(-1)
, m_qt_compositor(qt_compositor)
m_display->addGlobalObject(m_output.base(), &wl_output_interface, 0, output_post_geometry);
m_display->addGlobalObject(&m_shell, &wl_shell_interface, &shell_interface, 0);
- m_display->addGlobalObject(m_shm.base(), &wl_shm_interface, &shm_interface, 0);
wl_input_device_init(&m_input, base());
m_display->addGlobalObject(&m_input.object, &wl_input_device_interface, &input_device_interface, 0);
#include <QtCore/QDebug>
+#include <wayland-server-protocol.h>
+
namespace Wayland {
Display::Display()
template <typename Implementation>
void addGlobalObject(struct wl_object *object, const struct wl_interface *interface,
- Implementation implementation, wl_client_connect_func_t func = 0)
+ Implementation implementation, wl_global_bind_func_t func = 0)
{
object->interface = interface;
object->implementation = (void (**)())implementation;
namespace Wayland {
-void output_post_geometry(struct wl_client *client, struct wl_object *global)
+void output_post_geometry(struct wl_client *client, struct wl_object *global, uint32_t version)
{
+ Q_UNUSED(version);
Output *output = wayland_cast<Output *>(global);
wl_client_post_event(client, global, WL_OUTPUT_GEOMETRY, 0, 0,
int m_numQueued;
};
-void output_post_geometry(struct wl_client *client, struct wl_object *global);
+void output_post_geometry(struct wl_client *client, struct wl_object *global, uint32_t version);
}
#include "wlshmbuffer.h"
+#include "wldisplay.h"
+
#include <QtCore/QDebug>
#include <sys/mman.h>
namespace Wayland {
-void shm_buffer_attach(struct wl_buffer *buffer, struct wl_surface *surface)
+ShmBuffer::ShmBuffer(struct wl_buffer *buffer)
+ : m_buffer(buffer)
{
- wayland_cast<ShmBuffer *>(buffer)->attach(reinterpret_cast<Surface *>(surface));
-}
-
-void shm_buffer_damage(struct wl_buffer *buffer, struct wl_surface *surface, int x, int y, int width, int height)
-{
- wayland_cast<ShmBuffer *>(buffer)->damage(reinterpret_cast<Surface *>(surface), QRect(x, y, width, height));
-}
+ m_buffer->user_data = this;
+ m_data = wl_shm_buffer_get_data(m_buffer);
+ m_stride = wl_shm_buffer_get_stride(m_buffer);
-void shm_buffer_destroy(struct wl_resource *resource, struct wl_client *)
-{
- delete wayland_cast<ShmBuffer *>((wl_buffer *)resource);
+ damage();
}
-void buffer_interface_destroy(struct wl_client *client, struct wl_buffer *buffer)
+ShmBuffer::~ShmBuffer()
{
- Q_UNUSED(client);
- Q_UNUSED(buffer);
- qDebug() << "buffer_interface_destroy()";
}
-const struct wl_buffer_interface buffer_interface = {
- buffer_interface_destroy
-};
-
-void shm_create_buffer(struct wl_client *client,
- struct wl_shm *shm,
- uint32_t id,
- int fd,
- int width,
- int height,
- uint32_t stride,
- struct wl_visual *visual)
+QImage ShmBuffer::image() const
{
- ShmHandler *shmHandler = reinterpret_cast<ShmHandler *>(shm);
-
- ShmBuffer *buffer = shmHandler->createBuffer(fd,QSize(width,height),stride,visual);
-
- addClientResource(client, &buffer->base()->resource, id, &wl_buffer_interface,
- &buffer_interface, shm_buffer_destroy);
+ return m_image;
}
-ShmBuffer::ShmBuffer(int fd,
- Compositor *compositor,
- const QSize &size,
- uint stride,
- struct wl_visual *visual)
+QSize ShmBuffer::size() const
{
- base()->compositor = reinterpret_cast<wl_compositor *>(compositor);
- base()->height = size.height();
- base()->width = size.width();
- base()->visual = visual;
- base()->attach = shm_buffer_attach;
- base()->damage = shm_buffer_damage;
- m_stride = stride;
- m_data = mmap(NULL, stride * size.height(), PROT_READ, MAP_SHARED, fd, 0);
- close(fd);
+ return QSize(m_buffer->width, m_buffer->height);
}
-ShmBuffer::~ShmBuffer()
+void ShmBuffer::damage()
{
- munmap(m_data, m_stride * base()->height);
+ QImage::Format imageFormat = QImage::Format_Invalid;
+ //jl: need to do depth check as well.
+ if (m_buffer->visual == &m_buffer->compositor->premultiplied_argb_visual) {
+ imageFormat = QImage::Format_ARGB32_Premultiplied;
+ } else if (m_buffer->visual == &m_buffer->compositor->rgb_visual) {
+ imageFormat = QImage::Format_RGB32;
+ } else if (m_buffer->visual == &m_buffer->compositor->argb_visual) {
+ imageFormat = QImage::Format_ARGB32;
+ } else {
+ imageFormat = QImage::Format_ARGB32_Premultiplied;
+ }
+
+ m_image = QImage(static_cast<uchar *>(m_data),m_buffer->width, m_buffer->height,m_stride,imageFormat);
}
-void ShmBuffer::attach(Surface *surface)
+ShmHandler::ShmHandler(Display *display)
+ : m_display(display)
{
- printf("ShmBuffer::attach(%p)\n", surface);
+ m_shm = wl_shm_init(m_display->handle(),&shm_callbacks);
}
-void ShmBuffer::damage(Surface *surface, const QRect &rect)
+ShmHandler::~ShmHandler()
{
- printf("ShmBuffer::damage(%p, QRect(%d %d - %dx%d))\n", surface, rect.x(), rect.y(),
- rect.width(), rect.height());
+ wl_shm_finish(m_shm);
}
-QImage ShmBuffer::image() const
-{
- if (m_data)
- return QImage(static_cast<const uchar *>(m_data), base()->width, base()->height, m_stride, QImage::Format_ARGB32_Premultiplied);
- return QImage();
-}
+struct wl_shm_callbacks ShmHandler::shm_callbacks = {
+ buffer_created_callback,
+ buffer_damaged_callback,
+ buffer_destroyed_callback
+};
-QSize ShmBuffer::size() const
+void ShmHandler::buffer_created_callback(struct wl_buffer *buffer)
{
- return QSize(base()->width, base()->height);
+ ShmBuffer *newBuffer = new ShmBuffer(buffer);
}
-ShmHandler::ShmHandler(Wayland::Compositor *compositor)
- :m_compositor(compositor)
+void ShmHandler::buffer_damaged_callback(struct wl_buffer *buffer,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height)
{
+ fprintf(stderr,"damage_callback\n");
}
-
-ShmBuffer *ShmHandler::createBuffer(int fd, const QSize &size, uint32_t stride, struct wl_visual *visual)
+void ShmHandler::buffer_destroyed_callback(struct wl_buffer *buffer)
{
- ShmBuffer *buffer = new ShmBuffer(fd,m_compositor,size,stride,visual);
- return buffer;
+ fprintf(stderr, "destory callback\n");
+ delete static_cast<ShmBuffer *>(buffer->user_data);
}
}
namespace Wayland {
class Surface;
-class Compositor;
+class Display;
-class ShmBuffer : public Object<struct wl_buffer>
+class ShmBuffer
{
public:
- ShmBuffer(int fd,
- Compositor *compositor,
- const QSize &size,
- uint stride,
- struct wl_visual *visual);
+ ShmBuffer(struct wl_buffer *buffer);
~ShmBuffer();
- void attach(Surface *surface);
- void damage(Surface *surface, const QRect &rect);
-
QImage image() const;
QSize size() const;
+ void damage();
+
private:
+ struct wl_buffer *m_buffer;
int m_stride;
void *m_data;
+ QImage m_image;
};
-class ShmHandler : public Object<struct wl_object>
+class ShmHandler
{
public:
- ShmHandler(Compositor *compositor);
+ ShmHandler(Display *display);
+ ~ShmHandler();
- ShmBuffer *createBuffer(int fd, const QSize &size, uint32_t stride, struct wl_visual *visual);
private:
- Compositor *m_compositor;
-};
+ Display *m_display;
+ struct wl_shm *m_shm;
-void shm_create_buffer(struct wl_client *client,
- struct wl_shm *shm,
- uint32_t id,
- int fd,
- int width,
- int height,
- uint32_t stride,
- struct wl_visual *visual);
+ static struct wl_shm_callbacks shm_callbacks;
+ static void buffer_created_callback(struct wl_buffer *buffer);
+ static void buffer_damaged_callback(struct wl_buffer *buffer,
+ int32_t x, int32_t y,
+ int32_t width, int32_t height);
+ static void buffer_destroyed_callback(struct wl_buffer *buffer);
-const struct wl_shm_interface shm_interface = {
- shm_create_buffer
};
-
}
#endif //WL_SHMBUFFER_H
: client(client)
, compositor(compositor)
, needsMap(false)
+ , textureCreatedForBuffer(false)
, directRenderBuffer(0)
+ , surfaceBuffer(0)
+ , surfaceType(WaylandSurface::Invalid)
{
- type = WaylandSurface::Invalid;
#ifdef QT_COMPOSITOR_WAYLAND_GL
texture_id = 0;
#endif
}
- WaylandSurface::Type type;
- QRect rect;
+ WaylandSurface::Type type() const {
+ if (surfaceType == WaylandSurface::Invalid) {
+ SurfacePrivate *that = const_cast<SurfacePrivate *>(this);
+ if (qtSurface->handle() == compositor->directRenderSurface()) {
+ that->surfaceType = WaylandSurface::Direct;
+ } else if (surfaceBuffer && wl_buffer_is_shm(surfaceBuffer)) {
+ that->surfaceType = WaylandSurface::Shm;
+ } else if (surfaceBuffer){
+ that->surfaceType = WaylandSurface::Texture;
+ }
+ }
+ return surfaceType;
+ }
+
+ void attach(struct wl_buffer *buffer) {
+ this->surfaceBuffer = buffer;
+ surfaceType = WaylandSurface::Invalid;
+ textureCreatedForBuffer = false;
+ }
+
+ inline struct wl_buffer *buffer() const { return surfaceBuffer; }
+
struct wl_client *client;
Compositor *compositor;
WaylandSurface *qtSurface;
- ShmBuffer *shm_buffer;
#ifdef QT_COMPOSITOR_WAYLAND_GL
GLuint texture_id;
#endif
bool needsMap;
+ bool textureCreatedForBuffer;
wl_buffer *directRenderBuffer;
-};
-
+private:
+ struct wl_buffer *surfaceBuffer;
+ WaylandSurface::Type surfaceType;
+};
void surface_destroy(struct wl_client *client, struct wl_surface *surface)
{
Q_UNUSED(x);
Q_UNUSED(y);
- if (buffer->attach) {
- wayland_cast<Surface *>(surface)->attachShm(wayland_cast<ShmBuffer *>(buffer));
- }
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- else {
- wayland_cast<Surface *>(surface)->attachHWBuffer(buffer);
- }
-#endif //QT_COMPOSITOR_WAYLAND_EGL
+ wayland_cast<Surface *>(surface)->attach(buffer);
}
void surface_map_toplevel(struct wl_client *client,
{
Q_D(Surface);
d->compositor->surfaceDestroyed(this);
+ glDeleteTextures(1,&d->texture_id);
delete d->qtSurface;
}
WaylandSurface::Type Surface::type() const
{
Q_D(const Surface);
- return d->type;
+ return d->type();
}
void Surface::damage(const QRect &rect)
{
Q_D(Surface);
- if (d->directRenderBuffer) {
- //qDebug() << "DIRECT RENDER";
+ if (d->type() == WaylandSurface::Direct) {
+ //should the texture be deleted here, or should we explicitly delete it
+ //when going into direct mode...
+ if (d->textureCreatedForBuffer) {
+ glDeleteTextures(1,&d->texture_id);
+ d->textureCreatedForBuffer = false;
+ }
if (d->compositor->graphicsHWIntegration()->postBuffer(d->directRenderBuffer))
return;
}
+
+ if (d->needsMap) {
+ QRect rect(0,0,d->buffer()->width,d->buffer()->height);
+ emit d->qtSurface->mapped(rect);
+ d->needsMap = false;
+ }
+
d->compositor->markSurfaceAsDirty(this);
+
+ if (d->type() == WaylandSurface::Shm) {
+ static_cast<ShmBuffer *>(d->buffer()->user_data)->damage();
+ }
+
emit d->qtSurface->damaged(rect);
}
QImage Surface::image() const
{
Q_D(const Surface);
- if (d->type == WaylandSurface::Shm) {
- return d->shm_buffer->image();
+ if (d->type() == WaylandSurface::Shm) {
+ ShmBuffer *shmBuffer = static_cast<ShmBuffer *>(d->buffer()->user_data);
+ return shmBuffer->image();
}
return QImage();
}
#ifdef QT_COMPOSITOR_WAYLAND_GL
-
-void Surface::attachHWBuffer(struct wl_buffer *buffer)
+GLuint Surface::textureId() const
{
- Q_D(Surface);
-
- if (d->compositor->qtCompositor()->directRenderSurface() == handle()) {
- d->directRenderBuffer = buffer;
- if (d->texture_id) {
- glDeleteTextures(1,&d->texture_id);
- d->texture_id = 0;
- }
- //qDebug() << " not creating texture";
- return;
- }
- //qDebug() << "creating texture" << handle() << "direct" << d->compositor->qtCompositor()->directRenderSurface();
- d->directRenderBuffer = 0;
- d->type = WaylandSurface::Texture;
-
- //make current for the topLevel. We could have used the eglContext,
- //but then we would need to handle eglSurfaces as well.
- d->compositor->topLevelWidget()->platformWindow()->glContext()->makeCurrent();
-
- if (d->texture_id)
+ Q_D(const Surface);
+ if (!d->texture_id
+ && d->type() == WaylandSurface::Texture
+ && !d->textureCreatedForBuffer) {
glDeleteTextures(1,&d->texture_id);
-
- d->texture_id = d->compositor->graphicsHWIntegration()->createTextureFromBuffer(buffer);
- d->rect = QRect(QPoint(), QSize(buffer->width, buffer->height));
-
- if (d->needsMap) {
- emit d->qtSurface->mapped(d->rect);
- d->needsMap = false;
+ Surface *that = const_cast<Surface *>(this);
+ GraphicsHardwareIntegration *hwIntegration = d->compositor->graphicsHWIntegration();
+ that->d_func()->texture_id = hwIntegration->createTextureFromBuffer(d->buffer());
+ that->d_func()->textureCreatedForBuffer = true;
}
-}
-
-GLuint Surface::texture() const
-{
- Q_D(const Surface);
return d->texture_id;
}
#endif // QT_COMPOSITOR_WAYLAND_GL
-void Surface::attachShm(Wayland::ShmBuffer *shm_buffer)
+void Surface::attach(struct wl_buffer *buffer)
{
Q_D(Surface);
- d->shm_buffer = shm_buffer;
- d->type = WaylandSurface::Shm;
- d->rect = QRect(QPoint(), shm_buffer->size());
-
- if (d->needsMap) {
- emit d->qtSurface->mapped(d->rect);
- d->needsMap = false;
- }
+ d->attach(buffer);
}
void Surface::mapTopLevel()
{
Q_D(Surface);
- if (d->rect.isEmpty())
+ if (!d->buffer())
d->needsMap = true;
else
- emit d->qtSurface->mapped(d->rect);
+ emit d->qtSurface->mapped(QRect(0,0,d->buffer()->width, d->buffer()->height));
}
WaylandSurface * Surface::handle() const
WaylandSurface::Type type() const;
uint id() const { return base()->resource.object.id; }
-#ifdef QT_COMPOSITOR_WAYLAND_GL
- void attachHWBuffer(struct wl_buffer *buffer);
-#endif
- void attachShm(ShmBuffer *shm_buffer);
+ void attach(struct wl_buffer *buffer);
void mapTopLevel();
QImage image() const;
#ifdef QT_COMPOSITOR_WAYLAND_GL
- GLuint texture() const;
+ GLuint textureId() const;
#endif
void sendMousePressEvent(int x, int y, Qt::MouseButton button);