Move XShm helper class to xcbutils

That way it can be used also in other parts of KWin.
icc-effect-5.14.5
Martin Gräßlin 2013-06-17 13:38:24 +02:00
parent b7a1f2b3cf
commit f4ee319c6a
5 changed files with 120 additions and 114 deletions

View File

@ -280,11 +280,11 @@ set(kwin_XCB_LIBS
${XCB_RENDER_LIBRARY}
${XCB_RANDR_LIBRARY}
${XCB_KEYSYMS_LIBRARY}
${XCB_SHM_LIBRARY}
)
set(kwin_WAYLAND_LIBS
${WAYLAND_CLIENT_LIBRARIES}
${XCB_SHM_LIBRARY}
${XCB_XTEST_LIBRARY}
)

View File

@ -22,15 +22,13 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// kwin
#include "options.h"
#include "wayland_backend.h"
#include "xcbutils.h"
// kwin libs
#include <kwinglplatform.h>
// KDE
#include <KDE/KDebug>
// Qt
#include <QOpenGLContext>
// system
#include <sys/shm.h>
#include <sys/types.h>
namespace KWin
{
@ -327,10 +325,10 @@ void EglWaylandBackend::doneCurrent()
eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
}
Shm *EglWaylandBackend::shm()
Xcb::Shm *EglWaylandBackend::shm()
{
if (m_shm.isNull()) {
m_shm.reset(new Shm);
m_shm.reset(new Xcb::Shm);
}
return m_shm.data();
}
@ -380,7 +378,7 @@ bool EglWaylandTexture::loadTexture(const Pixmap &pix, const QSize &size, int de
return false;
m_referencedPixmap = pix;
Shm *shm = m_backend->shm();
Xcb::Shm *shm = m_backend->shm();
if (!shm->isValid()) {
return false;
}
@ -418,7 +416,7 @@ bool EglWaylandTexture::update(const QRegion &damage)
return false;
}
Shm *shm = m_backend->shm();
Xcb::Shm *shm = m_backend->shm();
if (!shm->isValid()) {
return false;
}
@ -446,60 +444,4 @@ bool EglWaylandTexture::update(const QRegion &damage)
return true;
}
Shm::Shm()
: m_shmId(-1)
, m_buffer(NULL)
, m_segment(XCB_NONE)
, m_valid(false)
{
m_valid = init();
}
Shm::~Shm()
{
if (m_valid) {
xcb_shm_detach(connection(), m_segment);
shmdt(m_buffer);
}
}
bool Shm::init()
{
const xcb_query_extension_reply_t *ext = xcb_get_extension_data(connection(), &xcb_shm_id);
if (!ext || !ext->present) {
qDebug() << "SHM extension not available";
return false;
}
ScopedCPointer<xcb_shm_query_version_reply_t> version(xcb_shm_query_version_reply(connection(),
xcb_shm_query_version_unchecked(connection()), NULL));
if (version.isNull()) {
qDebug() << "Failed to get SHM extension version information";
return false;
}
const int MAXSIZE = 4096 * 2048 * 4; // TODO check there are not larger windows
m_shmId = shmget(IPC_PRIVATE, MAXSIZE, IPC_CREAT | 0600);
if (m_shmId < 0) {
qDebug() << "Failed to allocate SHM segment";
return false;
}
m_buffer = shmat(m_shmId, NULL, 0 /*read/write*/);
if (-1 == reinterpret_cast<long>(m_buffer)) {
qDebug() << "Failed to attach SHM segment";
shmctl(m_shmId, IPC_RMID, NULL);
return false;
}
shmctl(m_shmId, IPC_RMID, NULL);
m_segment = xcb_generate_id(connection());
const xcb_void_cookie_t cookie = xcb_shm_attach_checked(connection(), m_segment, m_shmId, false);
ScopedCPointer<xcb_generic_error_t> error(xcb_request_check(connection(), cookie));
if (!error.isNull()) {
qDebug() << "xcb_shm_attach error: " << error->error_code;
shmdt(m_buffer);
return false;
}
return true;
}
} // namespace

View File

@ -22,8 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "scene_opengl.h"
// wayland
#include <wayland-egl.h>
// xcb
#include <xcb/shm.h>
class QTemporaryFile;
struct wl_buffer;
@ -36,7 +34,9 @@ namespace Wayland {
class WaylandBackend;
}
class Shm;
namespace Xcb {
class Shm;
}
/**
* @brief OpenGL Backend using Egl on a Wayland surface.
@ -66,7 +66,7 @@ public:
virtual void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion);
virtual bool makeCurrent() override;
virtual void doneCurrent() override;
Shm *shm();
Xcb::Shm *shm();
protected:
virtual void present();
@ -87,7 +87,7 @@ private:
int m_bufferAge;
Wayland::WaylandBackend *m_wayland;
wl_egl_window *m_overlay;
QScopedPointer<Shm> m_shm;
QScopedPointer<Xcb::Shm> m_shm;
friend class EglWaylandTexture;
};
@ -114,51 +114,6 @@ private:
xcb_pixmap_t m_referencedPixmap;
};
/**
* @brief Small helper class to encapsulate SHM related functionality.
*
*/
class Shm
{
public:
Shm();
~Shm();
int shmId() const;
void *buffer() const;
xcb_shm_seg_t segment() const;
bool isValid() const;
private:
bool init();
int m_shmId;
void *m_buffer;
xcb_shm_seg_t m_segment;
bool m_valid;
};
inline
void *Shm::buffer() const
{
return m_buffer;
}
inline
bool Shm::isValid() const
{
return m_valid;
}
inline
xcb_shm_seg_t Shm::segment() const
{
return m_segment;
}
inline
int Shm::shmId() const
{
return m_shmId;
}
} // namespace
#endif // KWIN_EGL_ON_X_BACKEND_H

View File

@ -30,6 +30,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <xcb/shape.h>
#include <xcb/sync.h>
#include <xcb/xfixes.h>
// system
#include <sys/shm.h>
#include <sys/types.h>
namespace KWin {
@ -254,5 +257,64 @@ QVector<ExtensionData> Extensions::extensions() const
return extensions;
}
//****************************************
// Shm
//****************************************
Shm::Shm()
: m_shmId(-1)
, m_buffer(NULL)
, m_segment(XCB_NONE)
, m_valid(false)
{
m_valid = init();
}
Shm::~Shm()
{
if (m_valid) {
xcb_shm_detach(connection(), m_segment);
shmdt(m_buffer);
}
}
bool Shm::init()
{
const xcb_query_extension_reply_t *ext = xcb_get_extension_data(connection(), &xcb_shm_id);
if (!ext || !ext->present) {
qDebug() << "SHM extension not available";
return false;
}
ScopedCPointer<xcb_shm_query_version_reply_t> version(xcb_shm_query_version_reply(connection(),
xcb_shm_query_version_unchecked(connection()), NULL));
if (version.isNull()) {
qDebug() << "Failed to get SHM extension version information";
return false;
}
const int MAXSIZE = 4096 * 2048 * 4; // TODO check there are not larger windows
m_shmId = shmget(IPC_PRIVATE, MAXSIZE, IPC_CREAT | 0600);
if (m_shmId < 0) {
qDebug() << "Failed to allocate SHM segment";
return false;
}
m_buffer = shmat(m_shmId, NULL, 0 /*read/write*/);
if (-1 == reinterpret_cast<long>(m_buffer)) {
qDebug() << "Failed to attach SHM segment";
shmctl(m_shmId, IPC_RMID, NULL);
return false;
}
shmctl(m_shmId, IPC_RMID, NULL);
m_segment = xcb_generate_id(connection());
const xcb_void_cookie_t cookie = xcb_shm_attach_checked(connection(), m_segment, m_shmId, false);
ScopedCPointer<xcb_generic_error_t> error(xcb_request_check(connection(), cookie));
if (!error.isNull()) {
qDebug() << "xcb_shm_attach error: " << error->error_code;
shmdt(m_buffer);
return false;
}
return true;
}
} // namespace Xcb
} // namespace KWin

View File

@ -31,6 +31,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <xcb/composite.h>
#include <xcb/randr.h>
#include <xcb/shm.h>
namespace KWin {
namespace Xcb {
@ -908,6 +910,51 @@ void selectInput(xcb_window_t window, uint32_t events)
xcb_change_window_attributes(connection(), window, XCB_CW_EVENT_MASK, &events);
}
/**
* @brief Small helper class to encapsulate SHM related functionality.
*
*/
class Shm
{
public:
Shm();
~Shm();
int shmId() const;
void *buffer() const;
xcb_shm_seg_t segment() const;
bool isValid() const;
private:
bool init();
int m_shmId;
void *m_buffer;
xcb_shm_seg_t m_segment;
bool m_valid;
};
inline
void *Shm::buffer() const
{
return m_buffer;
}
inline
bool Shm::isValid() const
{
return m_valid;
}
inline
xcb_shm_seg_t Shm::segment() const
{
return m_segment;
}
inline
int Shm::shmId() const
{
return m_shmId;
}
} // namespace X11
} // namespace KWin