/**************************************************************************** ** ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the qmake spec of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 or version 3 as published by the Free ** Software Foundation and appearing in the file LICENSE.LGPLv21 and ** LICENSE.LGPLv3 included in the packaging of this file. Please review the ** following information to ensure the GNU Lesser General Public License ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qeglfshooks.h" #include #include #include #include QT_BEGIN_NAMESPACE static DISPMANX_DISPLAY_HANDLE_T dispman_display = 0; static EGLNativeWindowType createDispmanxLayer(const QPoint &pos, const QSize &size, int z, DISPMANX_FLAGS_ALPHA_T flags) { VC_RECT_T dst_rect; dst_rect.x = pos.x(); dst_rect.y = pos.y(); dst_rect.width = size.width(); dst_rect.height = size.height(); VC_RECT_T src_rect; src_rect.x = 0; src_rect.y = 0; src_rect.width = size.width() << 16; src_rect.height = size.height() << 16; DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0); VC_DISPMANX_ALPHA_T alpha; alpha.flags = flags; alpha.opacity = 0xFF; alpha.mask = 0; DISPMANX_ELEMENT_HANDLE_T dispman_element = vc_dispmanx_element_add( dispman_update, dispman_display, z, &dst_rect, 0, &src_rect, DISPMANX_PROTECTION_NONE, &alpha, (DISPMANX_CLAMP_T *)NULL, (DISPMANX_TRANSFORM_T)0); vc_dispmanx_update_submit_sync(dispman_update); EGL_DISPMANX_WINDOW_T *eglWindow = new EGL_DISPMANX_WINDOW_T; eglWindow->element = dispman_element; eglWindow->width = size.width(); eglWindow->height = size.height(); return eglWindow; } // these constants are not in any headers (yet) #define ELEMENT_CHANGE_LAYER (1<<0) #define ELEMENT_CHANGE_OPACITY (1<<1) #define ELEMENT_CHANGE_DEST_RECT (1<<2) #define ELEMENT_CHANGE_SRC_RECT (1<<3) #define ELEMENT_CHANGE_MASK_RESOURCE (1<<4) #define ELEMENT_CHANGE_TRANSFORM (1<<5) static void moveDispmanxLayer(EGLNativeWindowType window, const QPoint &pos) { EGL_DISPMANX_WINDOW_T *eglWindow = static_cast(window); QSize size(eglWindow->width, eglWindow->height); VC_RECT_T dst_rect; dst_rect.x = pos.x(); dst_rect.y = pos.y(); dst_rect.width = size.width(); dst_rect.height = size.height(); DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0); vc_dispmanx_element_change_attributes(dispman_update, eglWindow->element, ELEMENT_CHANGE_DEST_RECT /*change_flags*/, 0, 0, &dst_rect, NULL, 0, (DISPMANX_TRANSFORM_T)0); vc_dispmanx_update_submit_sync(dispman_update); } static void destroyDispmanxLayer(EGLNativeWindowType window) { EGL_DISPMANX_WINDOW_T *eglWindow = static_cast(window); DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0); vc_dispmanx_element_remove(dispman_update, eglWindow->element); vc_dispmanx_update_submit_sync(dispman_update); delete eglWindow; } class QEglFSPiHooks : public QEglFSHooks { public: virtual void platformInit(); virtual void platformDestroy(); virtual EGLNativeDisplayType platformDisplay() const; virtual QSize screenSize() const; virtual EGLNativeWindowType createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format); virtual void destroyNativeWindow(EGLNativeWindowType window); virtual bool hasCapability(QPlatformIntegration::Capability cap) const; }; void QEglFSPiHooks::platformInit() { bcm_host_init(); } EGLNativeDisplayType QEglFSPiHooks::platformDisplay() const { dispman_display = vc_dispmanx_display_open(0/* LCD */); return EGL_DEFAULT_DISPLAY; } void QEglFSPiHooks::platformDestroy() { vc_dispmanx_display_close(dispman_display); } QSize QEglFSPiHooks::screenSize() const { uint32_t width, height; graphics_get_display_size(0 /* LCD */, &width, &height); return QSize(width, height); } EGLNativeWindowType QEglFSPiHooks::createNativeWindow(QPlatformWindow *window, const QSize &size, const QSurfaceFormat &format) { Q_UNUSED(window) return createDispmanxLayer(QPoint(0, 0), size, 1, format.hasAlpha() ? DISPMANX_FLAGS_ALPHA_FROM_SOURCE : DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS); } void QEglFSPiHooks::destroyNativeWindow(EGLNativeWindowType window) { destroyDispmanxLayer(window); } bool QEglFSPiHooks::hasCapability(QPlatformIntegration::Capability cap) const { switch (cap) { case QPlatformIntegration::ThreadedPixmaps: case QPlatformIntegration::OpenGL: case QPlatformIntegration::ThreadedOpenGL: case QPlatformIntegration::BufferQueueingOpenGL: return true; default: return false; } } QEglFSPiHooks eglFSPiHooks; QEglFSHooks *platformHooks = &eglFSPiHooks; QT_END_NAMESPACE