Add a hwcomposer backend based on libhybris

This backend interacts with libhybris to create a hwcomposer which is
used for creating the egl context and surface. The initial version of
this backend is based on test_hwcomposer.cpp provided by libhybris.

Please note that using the hwcomposer backend requires a newer libepoxy,
the latest stable release is not able to bring up OpenGLES, so one needs
a master build of libepoxy.

Notes on licensing:
libhybris is Apache 2.0 licensed, which is not compatile with GPLv2.
But it is compatible with GPLv3. Thus the source files in the hwcomposer
backend are licensed GPLv3+ and not GPLv2+ as the rest of KWin. If one
uses KWin without the hwcomposer backend (which is obviously the default)
the licence doesn't change. But if the hwcomposer backend is used the
overall license of KWin changes to GPLv3+.
This commit is contained in:
Martin Graesslin 2015-05-06 17:47:07 +02:00 committed by Martin Gräßlin
parent 713c6b25dc
commit e12400a675
15 changed files with 947 additions and 0 deletions

View file

@ -171,6 +171,10 @@ if(HAVE_DRM AND gbm_FOUND)
set(HAVE_GBM TRUE)
endif()
find_package(libhybris)
set_package_properties(libhybris PROPERTIES TYPE OPTIONAL PURPOSE "Required for libhybris backend")
set(HAVE_LIBHYBRIS libhybris_FOUND)
find_package(X11)
set_package_properties(X11 PROPERTIES DESCRIPTION "X11 libraries"
URL "http://www.x.org"

View file

@ -2,5 +2,8 @@ if(HAVE_DRM)
add_subdirectory(drm)
endif()
add_subdirectory(fbdev)
if(HAVE_LIBHYBRIS)
add_subdirectory(hwcomposer)
endif()
add_subdirectory(wayland)
add_subdirectory(x11)

View file

@ -0,0 +1,22 @@
set(HWCOMPOSER_SOURCES
egl_hwcomposer_backend.cpp
hwcomposer_backend.cpp
logging.cpp
screens_hwcomposer.cpp
)
add_library(KWinWaylandHwcomposerBackend MODULE ${HWCOMPOSER_SOURCES})
target_link_libraries(KWinWaylandHwcomposerBackend
kwin
libhybris::libhardware
libhybris::hwcomposer
libhybris::hybriseglplatform
libhybris::sync
)
install(
TARGETS
KWinWaylandHwcomposerBackend
DESTINATION
${PLUGIN_INSTALL_DIR}/org.kde.kwin.waylandbackends/
)

View file

@ -0,0 +1,184 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2015 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 3 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 "egl_hwcomposer_backend.h"
#include "hwcomposer_backend.h"
#include "logging.h"
namespace KWin
{
EglHwcomposerBackend::EglHwcomposerBackend(HwcomposerBackend *backend)
: AbstractEglBackend()
, m_backend(backend)
{
if (!initializeEgl()) {
setFailed("Failed to initialize egl");
return;
}
init();
// EGL is always direct rendering
setIsDirectRendering(true);
}
EglHwcomposerBackend::~EglHwcomposerBackend()
{
cleanup();
delete m_nativeSurface;
}
bool EglHwcomposerBackend::initializeEgl()
{
// cannot use initClientExtensions as that crashes in libhybris
qputenv("EGL_PLATFORM", QByteArrayLiteral("hwcomposer"));
EGLDisplay display = EGL_NO_DISPLAY;
display = eglGetDisplay(nullptr);
if (display == EGL_NO_DISPLAY) {
return false;
}
setEglDisplay(display);
return initEglAPI();
}
void EglHwcomposerBackend::init()
{
if (!initRenderingContext()) {
setFailed("Could not initialize rendering context");
return;
}
initKWinGL();
initBufferAge();
initWayland();
}
bool EglHwcomposerBackend::initBufferConfigs()
{
const EGLint config_attribs[] = {
EGL_BUFFER_SIZE, 32,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE,
};
EGLint count;
EGLConfig configs[1024];
if (eglChooseConfig(eglDisplay(), config_attribs, configs, 1, &count) == EGL_FALSE) {
qCCritical(KWIN_HWCOMPOSER) << "choose config failed";
return false;
}
if (count != 1) {
qCCritical(KWIN_HWCOMPOSER) << "choose config did not return a config" << count;
return false;
}
setConfig(configs[0]);
return true;
}
bool EglHwcomposerBackend::initRenderingContext()
{
if (!initBufferConfigs()) {
return false;
}
EGLContext context = EGL_NO_CONTEXT;
const EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
context = eglCreateContext(eglDisplay(), config(), EGL_NO_CONTEXT, context_attribs);
if (context == EGL_NO_CONTEXT) {
qCCritical(KWIN_HWCOMPOSER) << "Create Context failed";
return false;
}
setContext(context);
m_nativeSurface = m_backend->createSurface();
EGLSurface surface = eglCreateWindowSurface(eglDisplay(), config(), (EGLNativeWindowType)static_cast<ANativeWindow*>(m_nativeSurface), nullptr);
if (surface == EGL_NO_SURFACE) {
qCCritical(KWIN_HWCOMPOSER) << "Create surface failed";
return false;
}
setSurface(surface);
return makeContextCurrent();
}
bool EglHwcomposerBackend::makeContextCurrent()
{
if (eglMakeCurrent(eglDisplay(), surface(), surface(), context()) == EGL_FALSE) {
qCCritical(KWIN_HWCOMPOSER) << "Make Context Current failed";
return false;
}
EGLint error = eglGetError();
if (error != EGL_SUCCESS) {
qCWarning(KWIN_HWCOMPOSER) << "Error occurred while creating context " << error;
return false;
}
return true;
}
void EglHwcomposerBackend::present()
{
eglSwapBuffers(eglDisplay(), surface());
m_nativeSurface->present();
}
void EglHwcomposerBackend::screenGeometryChanged(const QSize &size)
{
Q_UNUSED(size)
}
QRegion EglHwcomposerBackend::prepareRenderingFrame()
{
// TODO: buffer age?
startRenderTimer();
// triggers always a full repaint
return QRegion(QRect(QPoint(0, 0), m_backend->size()));
}
void EglHwcomposerBackend::endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion)
{
Q_UNUSED(renderedRegion)
Q_UNUSED(damagedRegion)
present();
}
SceneOpenGL::TexturePrivate *EglHwcomposerBackend::createBackendTexture(SceneOpenGL::Texture *texture)
{
return new EglHwcomposerTexture(texture, this);
}
bool EglHwcomposerBackend::usesOverlayWindow() const
{
return false;
}
EglHwcomposerTexture::EglHwcomposerTexture(SceneOpenGL::Texture *texture, EglHwcomposerBackend *backend)
: AbstractEglTexture(texture, backend)
{
}
EglHwcomposerTexture::~EglHwcomposerTexture() = default;
}

View file

@ -0,0 +1,66 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2015 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 3 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_EGL_HWCOMPOSER_BACKEND_H
#define KWIN_EGL_HWCOMPOSER_BACKEND_H
#include "abstract_egl_backend.h"
namespace KWin
{
class HwcomposerBackend;
class HwcomposerWindow;
class EglHwcomposerBackend : public AbstractEglBackend
{
public:
EglHwcomposerBackend(HwcomposerBackend *backend);
virtual ~EglHwcomposerBackend();
bool usesOverlayWindow() const override;
SceneOpenGL::TexturePrivate *createBackendTexture(SceneOpenGL::Texture *texture) override;
void screenGeometryChanged(const QSize &size) override;
QRegion prepareRenderingFrame() override;
void endRenderingFrame(const QRegion &renderedRegion, const QRegion &damagedRegion) override;
protected:
void present() override;
private:
void init();
bool initializeEgl();
bool initRenderingContext();
bool initBufferConfigs();
bool makeContextCurrent();
HwcomposerBackend *m_backend;
HwcomposerWindow *m_nativeSurface = nullptr;
};
class EglHwcomposerTexture : public AbstractEglTexture
{
public:
virtual ~EglHwcomposerTexture();
private:
friend class EglHwcomposerBackend;
EglHwcomposerTexture(SceneOpenGL::Texture *texture, EglHwcomposerBackend *backend);
};
}
#endif

View file

@ -0,0 +1,3 @@
{
"input": false
}

View file

@ -0,0 +1,193 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2015 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 3 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 "egl_hwcomposer_backend.h"
#include "hwcomposer_backend.h"
#include "logging.h"
#include "screens_hwcomposer.h"
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
// based on test_hwcomposer.c from libhybris project (Apache 2 licensed)
namespace KWin
{
HwcomposerBackend::HwcomposerBackend(QObject *parent)
: AbstractBackend(parent)
{
}
HwcomposerBackend::~HwcomposerBackend()
{
if (m_device) {
hwc_close_1(m_device);
}
}
static QSize getDisplaySize(hwc_composer_device_1_t *device)
{
uint32_t configs[5];
size_t numConfigs = 5;
if (device->getDisplayConfigs(device, 0, configs, &numConfigs) != 0) {
qCWarning(KWIN_HWCOMPOSER) << "Failed to get hwcomposer display configurations";
return QSize();
}
int32_t attr_values[2];
uint32_t attributes[] = {
HWC_DISPLAY_WIDTH,
HWC_DISPLAY_HEIGHT,
HWC_DISPLAY_NO_ATTRIBUTE
};
device->getDisplayAttributes(device, 0, configs[0], attributes, attr_values);
return QSize(attr_values[0], attr_values[1]);
}
void HwcomposerBackend::init()
{
hw_module_t *hwcModule = nullptr;
if (hw_get_module(HWC_HARDWARE_MODULE_ID, (const hw_module_t **)&hwcModule) != 0) {
qCWarning(KWIN_HWCOMPOSER) << "Failed to get hwcomposer module";
emit initFailed();
return;
}
hwc_composer_device_1_t *hwcDevice = nullptr;
if (hwc_open_1(hwcModule, &hwcDevice) != 0) {
qCWarning(KWIN_HWCOMPOSER) << "Failed to open hwcomposer device";
emit initFailed();
return;
}
// unblank, setPowerMode?
hwcDevice->blank(hwcDevice, 0, 0);
// get display configuration
m_displaySize = getDisplaySize(hwcDevice);
if (!m_displaySize.isValid()) {
emit initFailed();
return;
}
qCDebug(KWIN_HWCOMPOSER) << "Display size:" << m_displaySize;
m_device = hwcDevice;
emit screensQueried();
setReady(true);
}
HwcomposerWindow *HwcomposerBackend::createSurface()
{
return new HwcomposerWindow(this);
}
Screens *HwcomposerBackend::createScreens(QObject *parent)
{
return new HwcomposerScreens(this, parent);
}
OpenGLBackend *HwcomposerBackend::createOpenGLBackend()
{
return new EglHwcomposerBackend(this);
}
static void initLayer(hwc_layer_1_t *layer, const hwc_rect_t &rect)
{
memset(layer, 0, sizeof(hwc_layer_1_t));
layer->compositionType = HWC_FRAMEBUFFER;
layer->hints = 0;
layer->flags = 0;
layer->handle = 0;
layer->transform = 0;
layer->blending = HWC_BLENDING_NONE;
layer->sourceCrop = rect;
layer->displayFrame = rect;
layer->visibleRegionScreen.numRects = 1;
layer->visibleRegionScreen.rects = &layer->displayFrame;
layer->acquireFenceFd = -1;
layer->releaseFenceFd = -1;
}
HwcomposerWindow::HwcomposerWindow(HwcomposerBackend *backend)
: HWComposerNativeWindow(backend->size().width(), backend->size().height(), HAL_PIXEL_FORMAT_RGBA_8888)
, m_backend(backend)
{
size_t size = sizeof(hwc_display_contents_1_t) + 2 * sizeof(hwc_layer_1_t);
hwc_display_contents_1_t *list = (hwc_display_contents_1_t*)malloc(size);
m_list = (hwc_display_contents_1_t**)malloc(HWC_NUM_DISPLAY_TYPES * sizeof(hwc_display_contents_1_t *));
for (int i = 0; i < HWC_NUM_DISPLAY_TYPES; ++i) {
m_list[i] = list;
}
const hwc_rect_t rect = {
0,
0,
m_backend->size().width(),
m_backend->size().height()
};
initLayer(&list->hwLayers[0], rect);
initLayer(&list->hwLayers[1], rect);
list->retireFenceFd = -1;
list->flags = HWC_GEOMETRY_CHANGED;
list->numHwLayers = 2;
}
HwcomposerWindow::~HwcomposerWindow()
{
// TODO: cleanup
}
static void syncWait(int fd)
{
if (fd == -1) {
return;
}
sync_wait(fd, -1);
close(fd);
}
void HwcomposerWindow::present()
{
HWComposerNativeWindowBuffer *front;
lockFrontBuffer(&front);
m_list[0]->hwLayers[1].handle = front->handle;
m_list[0]->hwLayers[0].handle = NULL;
m_list[0]->hwLayers[0].flags = HWC_SKIP_LAYER;
int oldretire = m_list[0]->retireFenceFd;
int oldrelease = m_list[0]->hwLayers[1].releaseFenceFd;
int oldrelease2 = m_list[0]->hwLayers[0].releaseFenceFd;
hwc_composer_device_1_t *device = m_backend->device();
if (device->prepare(device, HWC_NUM_DISPLAY_TYPES, m_list) != 0) {
qCWarning(KWIN_HWCOMPOSER) << "Error preparing hwcomposer for frame";
}
if (device->set(device, HWC_NUM_DISPLAY_TYPES, m_list) != 0) {
qCWarning(KWIN_HWCOMPOSER) << "Error setting device for frame";
}
unlockFrontBuffer(front);
syncWait(oldrelease);
syncWait(oldrelease2);
syncWait(oldretire);
}
}

View file

@ -0,0 +1,82 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2015 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 3 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_HWCOMPOSER_BACKEND_H
#define KWIN_HWCOMPOSER_BACKEND_H
#include "abstract_backend.h"
// libhybris
#include <hwcomposer_window.h>
// needed as hwcomposer_window.h includes EGL which on non-arm includes Xlib
#include <fixx11h.h>
typedef struct hwc_display_contents_1 hwc_display_contents_1_t;
typedef struct hwc_layer_1 hwc_layer_1_t;
typedef struct hwc_composer_device_1 hwc_composer_device_1_t;
namespace KWin
{
class HwcomposerWindow;
class HwcomposerBackend : public AbstractBackend
{
Q_OBJECT
Q_INTERFACES(KWin::AbstractBackend)
Q_PLUGIN_METADATA(IID "org.kde.kwin.AbstractBackend" FILE "hwcomposer.json")
public:
explicit HwcomposerBackend(QObject *parent = nullptr);
virtual ~HwcomposerBackend();
void init() override;
Screens *createScreens(QObject *parent = nullptr) override;
OpenGLBackend *createOpenGLBackend() override;
HwcomposerWindow *createSurface();
QSize size() const {
return m_displaySize;
}
hwc_composer_device_1_t *device() const {
return m_device;
}
private:
QSize m_displaySize;
hwc_composer_device_1_t *m_device = nullptr;
};
class HwcomposerWindow : public HWComposerNativeWindow
{
public:
virtual ~HwcomposerWindow();
void present();
private:
friend HwcomposerBackend;
HwcomposerWindow(HwcomposerBackend *backend);
HwcomposerBackend *m_backend;
hwc_display_contents_1_t **m_list;
};
}
#endif

View file

@ -0,0 +1,21 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2015 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 3 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 "logging.h"
Q_LOGGING_CATEGORY(KWIN_HWCOMPOSER, "kwin_wayland_hwcomposer")

View file

@ -0,0 +1,26 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2015 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 3 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_FB_LOGGING_H
#define KWIN_FB_LOGGING_H
#include <QDebug>
#include <QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(KWIN_HWCOMPOSER)
#endif

View file

@ -0,0 +1,68 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2015 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 3 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 "screens_hwcomposer.h"
#include "hwcomposer_backend.h"
namespace KWin
{
HwcomposerScreens::HwcomposerScreens(HwcomposerBackend *backend, QObject *parent)
: Screens(parent)
, m_backend(backend)
{
}
HwcomposerScreens::~HwcomposerScreens() = default;
void HwcomposerScreens::init()
{
Screens::init();
updateCount();
emit changed();
}
QRect HwcomposerScreens::geometry(int screen) const
{
if (screen == 0) {
return QRect(QPoint(0, 0), size(screen));
}
return QRect();
}
QSize HwcomposerScreens::size(int screen) const
{
if (screen == 0) {
return m_backend->size();
}
return QSize();
}
void HwcomposerScreens::updateCount()
{
setCount(1);
}
int HwcomposerScreens::number(const QPoint &pos) const
{
Q_UNUSED(pos)
return 0;
}
}

View file

@ -0,0 +1,46 @@
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2015 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 3 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_SCREENS_FRAMEBUFFER_H
#define KWIN_SCREENS_FRAMEBUFFER_H
#include "screens.h"
namespace KWin
{
class HwcomposerBackend;
class HwcomposerScreens : public Screens
{
Q_OBJECT
public:
HwcomposerScreens(HwcomposerBackend *backend, QObject *parent = nullptr);
virtual ~HwcomposerScreens();
void init() override;
QRect geometry(int screen) const override;
int number(const QPoint &pos) const override;
QSize size(int screen) const override;
void updateCount() override;
private:
HwcomposerBackend *m_backend;
};
}
#endif

View file

@ -0,0 +1,219 @@
#.rst:
# Findlibhybris
# -------
#
# Try to find libhybris on a Unix system.
#=============================================================================
# Copyright 2015 Martin Gräßlin <mgraesslin@kde.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#=============================================================================
if(CMAKE_VERSION VERSION_LESS 2.8.12)
message(FATAL_ERROR "CMake 2.8.12 is required by Findlibhybris.cmake")
endif()
if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.12)
message(AUTHOR_WARNING "Your project should require at least CMake 2.8.12 to use Findlibhybris.cmake")
endif()
if(NOT WIN32)
# Use pkg-config to get the directories and then use these values
# in the FIND_PATH() and FIND_LIBRARY() calls
find_package(PkgConfig)
pkg_check_modules(PKG_libhardware QUIET libhardware)
pkg_check_modules(PKG_androidheaders QUIET android-headers)
pkg_check_modules(PKG_hwcomposerwindow QUIET hwcomposer-egl)
pkg_check_modules(PKG_hybriseglplatform QUIET hybris-egl-platform)
pkg_check_modules(PKG_hybrissync QUIET libsync)
set(libhardware_DEFINITIONS ${PKG_libhardware_CFLAGS_OTHER})
set(libhardware_VERSION ${PKG_libhardware_VERSION})
find_library(libhardware_LIBRARY
NAMES
libhardware.so
HINTS
${PKG_libhardware_LIBRARY_DIRS}
)
find_path(libhardware_INCLUDE_DIR
NAMES
android-version.h
HINTS
${PKG_androidheaders_INCLUDE_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(libhardware
FOUND_VAR
libhardware_FOUND
REQUIRED_VARS
libhardware_LIBRARY
libhardware_INCLUDE_DIR
VERSION_VAR
libhardware_VERSION
)
if(libhardware_FOUND AND NOT TARGET libhybris::libhardware)
add_library(libhybris::libhardware UNKNOWN IMPORTED)
set_target_properties(libhybris::libhardware PROPERTIES
IMPORTED_LOCATION "${libhardware_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${libhardware_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${libhardware_INCLUDE_DIR}"
)
endif()
mark_as_advanced(libhardware_LIBRARY libhardware_INCLUDE_DIR)
##############################################
# hwcomposerWindow
##############################################
set(libhwcomposer_DEFINITIONS ${PKG_hwcomposerwindow_CFLAGS_OTHER})
set(libhwcomposer_VERSION ${PKG_hwcomposerwindow_VERSION})
find_library(libhwcomposer_LIBRARY
NAMES
libhybris-hwcomposerwindow.so
HINTS
${PKG_hwcomposerwindow_LIBRARY_DIRS}
)
find_path(libhwcomposer_INCLUDE_DIR
NAMES
hwcomposer_window.h
HINTS
${PKG_hwcomposerwindow_INCLUDE_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(libhwcomposer
FOUND_VAR
libhwcomposer_FOUND
REQUIRED_VARS
libhwcomposer_LIBRARY
libhwcomposer_INCLUDE_DIR
VERSION_VAR
libhwcomposer_VERSION
)
if(libhwcomposer_FOUND AND NOT TARGET libhybris::hwcomposer)
add_library(libhybris::hwcomposer UNKNOWN IMPORTED)
set_target_properties(libhybris::hwcomposer PROPERTIES
IMPORTED_LOCATION "${libhwcomposer_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${libhardware_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${libhwcomposer_INCLUDE_DIR}"
)
endif()
mark_as_advanced(libhwcomposer_LIBRARY libhwcomposer_INCLUDE_DIR)
##############################################
# hybriseglplatform
##############################################
set(hybriseglplatform_DEFINITIONS ${PKG_hybriseglplatform_CFLAGS_OTHER})
set(hybriseglplatform_VERSION ${PKG_hybriseglplatform_VERSION})
find_library(hybriseglplatform_LIBRARY
NAMES
libhybris-eglplatformcommon.so
HINTS
${PKG_hybriseglplatform_LIBRARY_DIRS}
)
find_path(hybriseglplatform_INCLUDE_DIR
NAMES
eglplatformcommon.h
HINTS
${PKG_hybriseglplatform_INCLUDE_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(hybriseglplatform
FOUND_VAR
hybriseglplatform_FOUND
REQUIRED_VARS
hybriseglplatform_LIBRARY
hybriseglplatform_INCLUDE_DIR
VERSION_VAR
hybriseglplatform_VERSION
)
if(hybriseglplatform_FOUND AND NOT TARGET libhybris::hybriseglplatform)
add_library(libhybris::hybriseglplatform UNKNOWN IMPORTED)
set_target_properties(libhybris::hybriseglplatform PROPERTIES
IMPORTED_LOCATION "${hybriseglplatform_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${hybriseglplatform_DEFINITIONS}"
INTERFACE_INCLUDE_DIRECTORIES "${hybriseglplatform_INCLUDE_DIR}"
)
endif()
mark_as_advanced(hybriseglplatform_LIBRARY hybriseglplatform_INCLUDE_DIR)
##############################################
# hybrissync
##############################################
set(hybrissync_DEFINITIONS ${PKG_hybrissync_CFLAGS_OTHER})
set(hybrissync_VERSION ${PKG_hybrissync_VERSION})
find_library(hybrissync_LIBRARY
NAMES
libsync.so
HINTS
${PKG_hybrissync_LIBRARY_DIRS}
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(hybrissync
FOUND_VAR
hybrissync_FOUND
REQUIRED_VARS
hybrissync_LIBRARY
VERSION_VAR
hybrissync_VERSION
)
if(hybrissync_FOUND AND NOT TARGET libhybris::sync)
add_library(libhybris::sync UNKNOWN IMPORTED)
set_target_properties(libhybris::sync PROPERTIES
IMPORTED_LOCATION "${hybrissync_LIBRARY}"
INTERFACE_COMPILE_OPTIONS "${hybrissync_DEFINITIONS}"
)
endif()
mark_as_advanced(hybrissync_LIBRARY)
if(libhardware_FOUND AND libhwcomposer_FOUND AND hybriseglplatform_FOUND AND hybrissync_FOUND)
set(libhybris_FOUND TRUE)
else()
set(libhybris_FOUND FALSE)
endif()
else()
message(STATUS "Findlibhardware.cmake cannot find libhybris on Windows systems.")
set(libhybris_FOUND FALSE)
endif()
include(FeatureSummary)
set_package_properties(libhybris PROPERTIES
URL "https://github.com/libhybris/libhybris"
DESCRIPTION "libhybris allows to run bionic-based HW adaptations in glibc systems."
)

View file

@ -17,6 +17,7 @@
#cmakedefine01 HAVE_X11_XCB
#cmakedefine01 HAVE_DRM
#cmakedefine01 HAVE_GBM
#cmakedefine01 HAVE_LIBHYBRIS
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1

View file

@ -411,6 +411,10 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
parser.addOption(framebufferDeviceOption);
parser.addOption(widthOption);
parser.addOption(heightOption);
#if HAVE_LIBHYBRIS
QCommandLineOption hwcomposerOption(QStringLiteral("hwcomposer"), i18n("Use libhybris hwcomposer"));
parser.addOption(hwcomposerOption);
#endif
#if HAVE_INPUT
QCommandLineOption libinputOption(QStringLiteral("libinput"),
i18n("Enable libinput support for input events processing. Note: never use in a nested session."));
@ -483,6 +487,11 @@ KWIN_EXPORT int kdemain(int argc, char * argv[])
pluginName = QStringLiteral("KWinWaylandFbdevBackend");
deviceIdentifier = parser.value(framebufferDeviceOption).toUtf8();
}
#if HAVE_LIBHYBRIS
if (parser.isSet(hwcomposerOption)) {
pluginName = QStringLiteral("KWinWaylandHwcomposerBackend");
}
#endif
const auto pluginCandidates = KPluginLoader::findPlugins(QStringLiteral("org.kde.kwin.waylandbackends"),
[&pluginName] (const KPluginMetaData &plugin) {