[server] BufferInterface can resolve size through egl extension

Uses eglQueryWaylandBufferWL (if available) to determine the size of the
buffer. In order to do so, the server library links against egl (1) and
one needs to register the EGLDisplay in Server::Display by the user of
the library. For this a new method Display::setEglDisplay is added.

1: not using epoxy as it doesn't wrap the Wayland interfaces yet.
This commit is contained in:
Martin Gräßlin 2015-03-03 09:43:30 +01:00
parent b95858e961
commit 846a4e1d79
5 changed files with 67 additions and 2 deletions

View file

@ -35,7 +35,9 @@ target_include_directories(KF5WaylandServer INTERFACE "$<INSTALL_INTERFACE:${KF5
target_link_libraries(KF5WaylandServer
PUBLIC Qt5::Gui
PRIVATE Wayland::Server
PRIVATE
Wayland::Server
EGL::EGL
)
if(IS_ABSOLUTE "${KF5_INCLUDE_INSTALL_DIR}")

View file

@ -34,6 +34,8 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
#include <wayland-server.h>
#include <EGL/egl.h>
namespace KWayland
{
namespace Server
@ -53,6 +55,7 @@ public:
bool running = false;
QList<OutputInterface*> outputs;
QVector<ClientConnection*> clients;
EGLDisplay eglDisplay = EGL_NO_DISPLAY;
private:
Display *q;
@ -294,5 +297,19 @@ ClientConnection *Display::createClient(int fd)
return getConnection(c);
}
void Display::setEglDisplay(void *display)
{
if (d->eglDisplay != EGL_NO_DISPLAY) {
qCWarning(KWAYLAND_SERVER) << "EGLDisplay cannot be changed";
return;
}
d->eglDisplay = (EGLDisplay)display;
}
void *Display::eglDisplay() const
{
return d->eglDisplay;
}
}
}

View file

@ -123,6 +123,23 @@ public:
ClientConnection *getConnection(wl_client *client);
QVector<ClientConnection*> connections() const;
/**
* Set the EGL @p display for this Wayland display.
* The EGLDisplay can only be set once and must be alive as long as the Wayland display
* is alive. The user should have set up the binding between the EGLDisplay and the
* Wayland display prior to calling this method.
*
* @see eglDisplay
* @since 5.3
**/
void setEglDisplay(void *display);
/**
* @returns the EGLDisplay used for this Wayland display or EGL_NO_DISPLAY if not set.
* @see setEglDisplay
* @since 5.3
**/
void *eglDisplay() const;
Q_SIGNALS:
void socketNameChanged(const QString&);
void runningChanged(bool);

View file

@ -18,15 +18,25 @@ You should have received a copy of the GNU Lesser General Public
License along with this library. If not, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "buffer_interface.h"
#include "display.h"
#include "surface_interface.h"
// Wayland
#include <wayland-server.h>
// EGL
#include <EGL/egl.h>
#include <QtGui/qopengl.h>
namespace KWayland
{
namespace Server
{
namespace EGL
{
typedef GLboolean(*eglQueryWaylandBufferWL_func)(EGLDisplay dpy, struct wl_resource *buffer, EGLint attribute, EGLint *value);
eglQueryWaylandBufferWL_func eglQueryWaylandBufferWL = nullptr;
}
class BufferInterface::Private
{
public:
@ -89,6 +99,23 @@ BufferInterface::Private::Private(BufferInterface *q, wl_resource *resource, Sur
wl_resource_add_destroy_listener(resource, &listener);
if (shmBuffer) {
size = QSize(wl_shm_buffer_get_width(shmBuffer), wl_shm_buffer_get_height(shmBuffer));
} else if (parent) {
EGLDisplay eglDisplay = parent->global()->display()->eglDisplay();
static bool resolved = false;
using namespace EGL;
if (!resolved && eglDisplay != EGL_NO_DISPLAY) {
eglQueryWaylandBufferWL = (eglQueryWaylandBufferWL_func)eglGetProcAddress("eglQueryWaylandBufferWL");
resolved = true;
}
if (eglQueryWaylandBufferWL) {
EGLint width, height;
bool valid = false;
valid = eglQueryWaylandBufferWL(eglDisplay, buffer, EGL_WIDTH, &width);
valid = valid && eglQueryWaylandBufferWL(eglDisplay, buffer, EGL_HEIGHT, &height);
if (valid) {
size = QSize(width, height);
}
}
}
}

View file

@ -73,9 +73,11 @@ public:
/**
* Returns the size of this BufferInterface.
* Note: only for shared memory buffers (shmBuffer) the size can be derived,
* for other buffers the user of the BufferInterface has to use setSize to
* for other buffers it might be possible to derive the size if an EGL display
* is set on Display otherwise the user of the BufferInterface has to use setSize to
* provide the proper size.
* @see setSize
* @see Display::setEglDisplay
* @since 5.3
**/
QSize size() const;