[kwin_wayland] Split out Buffer and ShmPool into dedicated files
Moved from wayland_backend.[h|cpp] to buffer.[h|cpp] and shm_pool.[h|cpp]. Buffer is slightly adjusted to have the ShmPool passed in as a ctor argument and the ctor is private and friended with ShmPool, so that it can only be constructed from ShmPool.icc-effect-5.14.5
parent
ce8c4240f7
commit
08ab2c424e
|
@ -426,11 +426,13 @@ if(Wayland_Client_FOUND AND XKB_FOUND)
|
|||
set(kwin_KDEINIT_SRCS
|
||||
${kwin_KDEINIT_SRCS}
|
||||
wayland_backend.cpp
|
||||
wayland_client/buffer.cpp
|
||||
wayland_client/connection_thread.cpp
|
||||
wayland_client/registry.cpp
|
||||
wayland_client/fullscreen_shell.cpp
|
||||
wayland_client/output.cpp
|
||||
wayland_client/shell.cpp
|
||||
wayland_client/shm_pool.cpp
|
||||
wayland_client/surface.cpp
|
||||
${CMAKE_BINARY_DIR}/wayland_protocols/wayland-client-fullscreen-shell.c
|
||||
)
|
||||
|
|
|
@ -28,6 +28,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "toplevel.h"
|
||||
#if HAVE_WAYLAND
|
||||
#include "wayland_backend.h"
|
||||
#include "wayland_client/buffer.h"
|
||||
#include "wayland_client/shm_pool.h"
|
||||
#include "wayland_client/surface.h"
|
||||
#endif
|
||||
#include "workspace.h"
|
||||
|
|
|
@ -37,6 +37,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include "kwinxrenderutils.h"
|
||||
#if HAVE_WAYLAND
|
||||
#include "wayland_backend.h"
|
||||
#include "wayland_client/shm_pool.h"
|
||||
#include "wayland_client/surface.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -22,18 +22,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
// KWin
|
||||
#include "cursor.h"
|
||||
#include "input.h"
|
||||
#include "wayland_client/buffer.h"
|
||||
#include "wayland_client/connection_thread.h"
|
||||
#include "wayland_client/fullscreen_shell.h"
|
||||
#include "wayland_client/output.h"
|
||||
#include "wayland_client/registry.h"
|
||||
#include "wayland_client/shell.h"
|
||||
#include "wayland_client/shm_pool.h"
|
||||
#include "wayland_client/surface.h"
|
||||
// Qt
|
||||
#include <QAbstractEventDispatcher>
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QTemporaryFile>
|
||||
#include <QThread>
|
||||
// xcb
|
||||
#include <xcb/xtest.h>
|
||||
|
@ -41,9 +42,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
// Wayland
|
||||
#include <wayland-client-protocol.h>
|
||||
#include <wayland-cursor.h>
|
||||
// system
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
|
@ -150,15 +148,6 @@ static void keyboardHandleModifiers(void *data, wl_keyboard *keyboard, uint32_t
|
|||
input()->processKeyboardModifiers(modsDepressed, modsLatched, modsLocked, group);
|
||||
}
|
||||
|
||||
static void bufferRelease(void *data, wl_buffer *wl_buffer)
|
||||
{
|
||||
Buffer *buffer = reinterpret_cast<Buffer*>(data);
|
||||
if (buffer->buffer() != wl_buffer) {
|
||||
return;
|
||||
}
|
||||
buffer->setReleased(true);
|
||||
}
|
||||
|
||||
// handlers
|
||||
static const struct wl_pointer_listener s_pointerListener = {
|
||||
pointerHandleEnter,
|
||||
|
@ -180,10 +169,6 @@ static const struct wl_seat_listener s_seatListener = {
|
|||
seatHandleCapabilities
|
||||
};
|
||||
|
||||
static const struct wl_buffer_listener s_bufferListener = {
|
||||
bufferRelease
|
||||
};
|
||||
|
||||
CursorData::CursorData()
|
||||
: m_valid(init())
|
||||
{
|
||||
|
@ -276,152 +261,6 @@ void X11CursorTracker::resetCursor()
|
|||
}
|
||||
}
|
||||
|
||||
Buffer::Buffer(wl_buffer* buffer, const QSize& size, int32_t stride, size_t offset)
|
||||
: m_nativeBuffer(buffer)
|
||||
, m_released(false)
|
||||
, m_size(size)
|
||||
, m_stride(stride)
|
||||
, m_offset(offset)
|
||||
, m_used(false)
|
||||
{
|
||||
wl_buffer_add_listener(m_nativeBuffer, &s_bufferListener, this);
|
||||
}
|
||||
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
wl_buffer_destroy(m_nativeBuffer);
|
||||
}
|
||||
|
||||
void Buffer::copy(const void* src)
|
||||
{
|
||||
memcpy(address(), src, m_size.height()*m_stride);
|
||||
}
|
||||
|
||||
uchar *Buffer::address()
|
||||
{
|
||||
return (uchar*)WaylandBackend::self()->shmPool()->poolAddress() + m_offset;
|
||||
}
|
||||
|
||||
ShmPool::ShmPool(wl_shm *shm)
|
||||
: m_shm(shm)
|
||||
, m_pool(NULL)
|
||||
, m_poolData(NULL)
|
||||
, m_size(1024)
|
||||
, m_tmpFile(new QTemporaryFile())
|
||||
, m_valid(createPool())
|
||||
, m_offset(0)
|
||||
{
|
||||
}
|
||||
|
||||
ShmPool::~ShmPool()
|
||||
{
|
||||
qDeleteAll(m_buffers);
|
||||
if (m_poolData) {
|
||||
munmap(m_poolData, m_size);
|
||||
}
|
||||
if (m_pool) {
|
||||
wl_shm_pool_destroy(m_pool);
|
||||
}
|
||||
if (m_shm) {
|
||||
wl_shm_destroy(m_shm);
|
||||
}
|
||||
m_tmpFile->close();
|
||||
}
|
||||
|
||||
bool ShmPool::createPool()
|
||||
{
|
||||
if (!m_tmpFile->open()) {
|
||||
qDebug() << "Could not open temporary file for Shm pool";
|
||||
return false;
|
||||
}
|
||||
if (ftruncate(m_tmpFile->handle(), m_size) < 0) {
|
||||
qDebug() << "Could not set size for Shm pool file";
|
||||
return false;
|
||||
}
|
||||
m_poolData = mmap(NULL, m_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_tmpFile->handle(), 0);
|
||||
m_pool = wl_shm_create_pool(m_shm, m_tmpFile->handle(), m_size);
|
||||
|
||||
if (!m_poolData || !m_pool) {
|
||||
qDebug() << "Creating Shm pool failed";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShmPool::resizePool(int32_t newSize)
|
||||
{
|
||||
if (ftruncate(m_tmpFile->handle(), newSize) < 0) {
|
||||
qDebug() << "Could not set new size for Shm pool file";
|
||||
return false;
|
||||
}
|
||||
wl_shm_pool_resize(m_pool, newSize);
|
||||
munmap(m_poolData, m_size);
|
||||
m_poolData = mmap(NULL, newSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_tmpFile->handle(), 0);
|
||||
m_size = newSize;
|
||||
if (!m_poolData) {
|
||||
qDebug() << "Resizing Shm pool failed";
|
||||
return false;
|
||||
}
|
||||
emit poolResized();
|
||||
return true;
|
||||
}
|
||||
|
||||
wl_buffer *ShmPool::createBuffer(const QImage& image)
|
||||
{
|
||||
if (image.isNull() || !m_valid) {
|
||||
return NULL;
|
||||
}
|
||||
Buffer *buffer = getBuffer(image.size(), image.bytesPerLine());
|
||||
if (!buffer) {
|
||||
return NULL;
|
||||
}
|
||||
buffer->copy(image.bits());
|
||||
return buffer->buffer();
|
||||
}
|
||||
|
||||
wl_buffer *ShmPool::createBuffer(const QSize &size, int32_t stride, const void *src)
|
||||
{
|
||||
if (size.isNull() || !m_valid) {
|
||||
return NULL;
|
||||
}
|
||||
Buffer *buffer = getBuffer(size, stride);
|
||||
if (!buffer) {
|
||||
return NULL;
|
||||
}
|
||||
buffer->copy(src);
|
||||
return buffer->buffer();
|
||||
}
|
||||
|
||||
Buffer *ShmPool::getBuffer(const QSize &size, int32_t stride)
|
||||
{
|
||||
Q_FOREACH (Buffer *buffer, m_buffers) {
|
||||
if (!buffer->isReleased() || buffer->isUsed()) {
|
||||
continue;
|
||||
}
|
||||
if (buffer->size() != size || buffer->stride() != stride) {
|
||||
continue;
|
||||
}
|
||||
buffer->setReleased(false);
|
||||
return buffer;
|
||||
}
|
||||
const int32_t byteCount = size.height() * stride;
|
||||
if (m_offset + byteCount > m_size) {
|
||||
if (!resizePool(m_size + byteCount)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// we don't have a buffer which we could reuse - need to create a new one
|
||||
wl_buffer *native = wl_shm_pool_create_buffer(m_pool, m_offset, size.width(), size.height(),
|
||||
stride, WL_SHM_FORMAT_ARGB8888);
|
||||
if (!native) {
|
||||
return NULL;
|
||||
}
|
||||
Buffer *buffer = new Buffer(native, size, stride, m_offset);
|
||||
m_offset += byteCount;
|
||||
m_buffers.append(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
WaylandSeat::WaylandSeat(wl_seat *seat, WaylandBackend *backend)
|
||||
: QObject(NULL)
|
||||
, m_seat(seat)
|
||||
|
|
|
@ -35,7 +35,6 @@ class QTemporaryFile;
|
|||
class QImage;
|
||||
struct wl_cursor_theme;
|
||||
struct wl_buffer;
|
||||
struct wl_shm;
|
||||
struct wl_event_queue;
|
||||
|
||||
namespace KWin
|
||||
|
@ -87,57 +86,6 @@ private:
|
|||
uint32_t m_lastX11Cursor;
|
||||
};
|
||||
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
Buffer(wl_buffer *buffer, const QSize &size, int32_t stride, size_t offset);
|
||||
~Buffer();
|
||||
void copy(const void *src);
|
||||
void setReleased(bool released);
|
||||
void setUsed(bool used);
|
||||
|
||||
wl_buffer *buffer() const;
|
||||
const QSize &size() const;
|
||||
int32_t stride() const;
|
||||
bool isReleased() const;
|
||||
bool isUsed() const;
|
||||
uchar *address();
|
||||
private:
|
||||
wl_buffer *m_nativeBuffer;
|
||||
bool m_released;
|
||||
QSize m_size;
|
||||
int32_t m_stride;
|
||||
size_t m_offset;
|
||||
bool m_used;
|
||||
};
|
||||
|
||||
class ShmPool : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ShmPool(wl_shm *shm);
|
||||
~ShmPool();
|
||||
bool isValid() const;
|
||||
wl_buffer *createBuffer(const QImage &image);
|
||||
wl_buffer *createBuffer(const QSize &size, int32_t stride, const void *src);
|
||||
void *poolAddress() const;
|
||||
Buffer *getBuffer(const QSize &size, int32_t stride);
|
||||
wl_shm *shm();
|
||||
Q_SIGNALS:
|
||||
void poolResized();
|
||||
private:
|
||||
bool createPool();
|
||||
bool resizePool(int32_t newSize);
|
||||
wl_shm *m_shm;
|
||||
wl_shm_pool *m_pool;
|
||||
void *m_poolData;
|
||||
int32_t m_size;
|
||||
QScopedPointer<QTemporaryFile> m_tmpFile;
|
||||
bool m_valid;
|
||||
int m_offset;
|
||||
QList<Buffer*> m_buffers;
|
||||
};
|
||||
|
||||
class WaylandSeat : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -243,24 +191,6 @@ wl_seat *WaylandSeat::seat()
|
|||
return m_seat;
|
||||
}
|
||||
|
||||
inline
|
||||
bool ShmPool::isValid() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
inline
|
||||
void* ShmPool::poolAddress() const
|
||||
{
|
||||
return m_poolData;
|
||||
}
|
||||
|
||||
inline
|
||||
wl_shm *ShmPool::shm()
|
||||
{
|
||||
return m_shm;
|
||||
}
|
||||
|
||||
inline
|
||||
wl_display *WaylandBackend::display()
|
||||
{
|
||||
|
@ -297,48 +227,6 @@ const QList< Output* >& WaylandBackend::outputs() const
|
|||
return m_outputs;
|
||||
}
|
||||
|
||||
inline
|
||||
wl_buffer* Buffer::buffer() const
|
||||
{
|
||||
return m_nativeBuffer;
|
||||
}
|
||||
|
||||
inline
|
||||
const QSize& Buffer::size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline
|
||||
int32_t Buffer::stride() const
|
||||
{
|
||||
return m_stride;
|
||||
}
|
||||
|
||||
inline
|
||||
bool Buffer::isReleased() const
|
||||
{
|
||||
return m_released;
|
||||
}
|
||||
|
||||
inline
|
||||
void Buffer::setReleased(bool released)
|
||||
{
|
||||
m_released = released;
|
||||
}
|
||||
|
||||
inline
|
||||
bool Buffer::isUsed() const
|
||||
{
|
||||
return m_used;
|
||||
}
|
||||
|
||||
inline
|
||||
void Buffer::setUsed(bool used)
|
||||
{
|
||||
m_used = used;
|
||||
}
|
||||
|
||||
} // namespace Wayland
|
||||
} // namespace KWin
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#include "buffer.h"
|
||||
#include "shm_pool.h"
|
||||
// system
|
||||
#include <string.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
namespace Wayland
|
||||
{
|
||||
|
||||
const struct wl_buffer_listener Buffer::s_listener = {
|
||||
Buffer::releasedCallback
|
||||
};
|
||||
|
||||
Buffer::Buffer(ShmPool *parent, wl_buffer *buffer, const QSize &size, int32_t stride, size_t offset)
|
||||
: m_shm(parent)
|
||||
, m_nativeBuffer(buffer)
|
||||
, m_released(false)
|
||||
, m_size(size)
|
||||
, m_stride(stride)
|
||||
, m_offset(offset)
|
||||
, m_used(false)
|
||||
{
|
||||
wl_buffer_add_listener(m_nativeBuffer, &s_listener, this);
|
||||
}
|
||||
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
wl_buffer_destroy(m_nativeBuffer);
|
||||
}
|
||||
|
||||
void Buffer::releasedCallback(void *data, wl_buffer *buffer)
|
||||
{
|
||||
Buffer *b = reinterpret_cast<Buffer*>(data);
|
||||
Q_ASSERT(b->m_nativeBuffer == buffer);
|
||||
b->setReleased(true);
|
||||
}
|
||||
|
||||
void Buffer::copy(const void *src)
|
||||
{
|
||||
memcpy(address(), src, m_size.height()*m_stride);
|
||||
}
|
||||
|
||||
uchar *Buffer::address()
|
||||
{
|
||||
return reinterpret_cast<uchar*>(m_shm->poolAddress()) + m_offset;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#ifndef KWIN_WAYLAND_BUFFER_H
|
||||
#define KWIN_WAYLAND_BUFFER_H
|
||||
|
||||
#include <QSize>
|
||||
|
||||
#include <wayland-client-protocol.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
namespace Wayland
|
||||
{
|
||||
|
||||
class ShmPool;
|
||||
|
||||
class Buffer
|
||||
{
|
||||
public:
|
||||
~Buffer();
|
||||
void copy(const void *src);
|
||||
void setReleased(bool released);
|
||||
void setUsed(bool used);
|
||||
|
||||
wl_buffer *buffer() const;
|
||||
const QSize &size() const;
|
||||
int32_t stride() const;
|
||||
bool isReleased() const;
|
||||
bool isUsed() const;
|
||||
uchar *address();
|
||||
|
||||
operator wl_buffer*() {
|
||||
return m_nativeBuffer;
|
||||
}
|
||||
operator wl_buffer*() const {
|
||||
return m_nativeBuffer;
|
||||
}
|
||||
|
||||
static void releasedCallback(void *data, wl_buffer *wl_buffer);
|
||||
|
||||
private:
|
||||
friend class ShmPool;
|
||||
explicit Buffer(ShmPool *parent, wl_buffer *buffer, const QSize &size, int32_t stride, size_t offset);
|
||||
static const struct wl_buffer_listener s_listener;
|
||||
ShmPool *m_shm;
|
||||
wl_buffer *m_nativeBuffer;
|
||||
bool m_released;
|
||||
QSize m_size;
|
||||
int32_t m_stride;
|
||||
size_t m_offset;
|
||||
bool m_used;
|
||||
};
|
||||
|
||||
inline
|
||||
wl_buffer *Buffer::buffer() const
|
||||
{
|
||||
return m_nativeBuffer;
|
||||
}
|
||||
|
||||
inline
|
||||
const QSize &Buffer::size() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
inline
|
||||
int32_t Buffer::stride() const
|
||||
{
|
||||
return m_stride;
|
||||
}
|
||||
|
||||
inline
|
||||
bool Buffer::isReleased() const
|
||||
{
|
||||
return m_released;
|
||||
}
|
||||
|
||||
inline
|
||||
void Buffer::setReleased(bool released)
|
||||
{
|
||||
m_released = released;
|
||||
}
|
||||
|
||||
inline
|
||||
bool Buffer::isUsed() const
|
||||
{
|
||||
return m_used;
|
||||
}
|
||||
|
||||
inline
|
||||
void Buffer::setUsed(bool used)
|
||||
{
|
||||
m_used = used;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,156 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#include "shm_pool.h"
|
||||
#include "buffer.h"
|
||||
// Qt
|
||||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QTemporaryFile>
|
||||
// system
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
namespace Wayland
|
||||
{
|
||||
|
||||
ShmPool::ShmPool(wl_shm *shm)
|
||||
: m_shm(shm)
|
||||
, m_pool(nullptr)
|
||||
, m_poolData(nullptr)
|
||||
, m_size(1024)
|
||||
, m_tmpFile(new QTemporaryFile())
|
||||
, m_valid(createPool())
|
||||
, m_offset(0)
|
||||
{
|
||||
}
|
||||
|
||||
ShmPool::~ShmPool()
|
||||
{
|
||||
qDeleteAll(m_buffers);
|
||||
if (m_poolData) {
|
||||
munmap(m_poolData, m_size);
|
||||
}
|
||||
if (m_pool) {
|
||||
wl_shm_pool_destroy(m_pool);
|
||||
}
|
||||
if (m_shm) {
|
||||
wl_shm_destroy(m_shm);
|
||||
}
|
||||
m_tmpFile->close();
|
||||
}
|
||||
|
||||
bool ShmPool::createPool()
|
||||
{
|
||||
if (!m_tmpFile->open()) {
|
||||
qDebug() << "Could not open temporary file for Shm pool";
|
||||
return false;
|
||||
}
|
||||
if (ftruncate(m_tmpFile->handle(), m_size) < 0) {
|
||||
qDebug() << "Could not set size for Shm pool file";
|
||||
return false;
|
||||
}
|
||||
m_poolData = mmap(NULL, m_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_tmpFile->handle(), 0);
|
||||
m_pool = wl_shm_create_pool(m_shm, m_tmpFile->handle(), m_size);
|
||||
|
||||
if (!m_poolData || !m_pool) {
|
||||
qDebug() << "Creating Shm pool failed";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShmPool::resizePool(int32_t newSize)
|
||||
{
|
||||
if (ftruncate(m_tmpFile->handle(), newSize) < 0) {
|
||||
qDebug() << "Could not set new size for Shm pool file";
|
||||
return false;
|
||||
}
|
||||
wl_shm_pool_resize(m_pool, newSize);
|
||||
munmap(m_poolData, m_size);
|
||||
m_poolData = mmap(NULL, newSize, PROT_READ | PROT_WRITE, MAP_SHARED, m_tmpFile->handle(), 0);
|
||||
m_size = newSize;
|
||||
if (!m_poolData) {
|
||||
qDebug() << "Resizing Shm pool failed";
|
||||
return false;
|
||||
}
|
||||
emit poolResized();
|
||||
return true;
|
||||
}
|
||||
|
||||
wl_buffer *ShmPool::createBuffer(const QImage& image)
|
||||
{
|
||||
if (image.isNull() || !m_valid) {
|
||||
return NULL;
|
||||
}
|
||||
Buffer *buffer = getBuffer(image.size(), image.bytesPerLine());
|
||||
if (!buffer) {
|
||||
return NULL;
|
||||
}
|
||||
buffer->copy(image.bits());
|
||||
return buffer->buffer();
|
||||
}
|
||||
|
||||
wl_buffer *ShmPool::createBuffer(const QSize &size, int32_t stride, const void *src)
|
||||
{
|
||||
if (size.isNull() || !m_valid) {
|
||||
return NULL;
|
||||
}
|
||||
Buffer *buffer = getBuffer(size, stride);
|
||||
if (!buffer) {
|
||||
return NULL;
|
||||
}
|
||||
buffer->copy(src);
|
||||
return buffer->buffer();
|
||||
}
|
||||
|
||||
Buffer *ShmPool::getBuffer(const QSize &size, int32_t stride)
|
||||
{
|
||||
Q_FOREACH (Buffer *buffer, m_buffers) {
|
||||
if (!buffer->isReleased() || buffer->isUsed()) {
|
||||
continue;
|
||||
}
|
||||
if (buffer->size() != size || buffer->stride() != stride) {
|
||||
continue;
|
||||
}
|
||||
buffer->setReleased(false);
|
||||
return buffer;
|
||||
}
|
||||
const int32_t byteCount = size.height() * stride;
|
||||
if (m_offset + byteCount > m_size) {
|
||||
if (!resizePool(m_size + byteCount)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// we don't have a buffer which we could reuse - need to create a new one
|
||||
wl_buffer *native = wl_shm_pool_create_buffer(m_pool, m_offset, size.width(), size.height(),
|
||||
stride, WL_SHM_FORMAT_ARGB8888);
|
||||
if (!native) {
|
||||
return NULL;
|
||||
}
|
||||
Buffer *buffer = new Buffer(this, native, size, stride, m_offset);
|
||||
m_offset += byteCount;
|
||||
m_buffers.append(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
/********************************************************************
|
||||
KWin - the KDE window manager
|
||||
This file is part of the KDE project.
|
||||
|
||||
Copyright (C) 2013 Martin Gräßlin <mgraesslin@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*********************************************************************/
|
||||
#ifndef KWIN_WAYLAND_SHM_POOL_H
|
||||
#define KWIN_WAYLAND_SHM_POOL_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QImage;
|
||||
class QSize;
|
||||
class QTemporaryFile;
|
||||
|
||||
struct wl_shm;
|
||||
struct wl_buffer;
|
||||
struct wl_shm_pool;
|
||||
|
||||
namespace KWin
|
||||
{
|
||||
namespace Wayland
|
||||
{
|
||||
class Buffer;
|
||||
|
||||
class ShmPool : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ShmPool(wl_shm *shm);
|
||||
~ShmPool();
|
||||
bool isValid() const;
|
||||
wl_buffer *createBuffer(const QImage &image);
|
||||
wl_buffer *createBuffer(const QSize &size, int32_t stride, const void *src);
|
||||
void *poolAddress() const;
|
||||
Buffer *getBuffer(const QSize &size, int32_t stride);
|
||||
wl_shm *shm();
|
||||
Q_SIGNALS:
|
||||
void poolResized();
|
||||
private:
|
||||
bool createPool();
|
||||
bool resizePool(int32_t newSize);
|
||||
wl_shm *m_shm;
|
||||
wl_shm_pool *m_pool;
|
||||
void *m_poolData;
|
||||
int32_t m_size;
|
||||
QScopedPointer<QTemporaryFile> m_tmpFile;
|
||||
bool m_valid;
|
||||
int m_offset;
|
||||
QList<Buffer*> m_buffers;
|
||||
};
|
||||
|
||||
inline
|
||||
bool ShmPool::isValid() const
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
|
||||
inline
|
||||
void* ShmPool::poolAddress() const
|
||||
{
|
||||
return m_poolData;
|
||||
}
|
||||
|
||||
inline
|
||||
wl_shm *ShmPool::shm()
|
||||
{
|
||||
return m_shm;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue