Move XShm helper class to xcbutils
That way it can be used also in other parts of KWin.
This commit is contained in:
parent
b7a1f2b3cf
commit
f4ee319c6a
5 changed files with 120 additions and 114 deletions
|
@ -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}
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
62
xcbutils.cpp
62
xcbutils.cpp
|
@ -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
|
||||
|
|
47
xcbutils.h
47
xcbutils.h
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue