blob: ed26f08ec3f84ee00e0acc9eeb829955328ec020 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt WebGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL$
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) any later version
** approved by the KDE Free Qt Foundation. The licenses are as published by
** the Free Software Foundation and appearing in the file LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qwebglwindow.h"
#include "qwebglwindow_p.h"
#include "qwebglintegration_p.h"
#include "qwebglwebsocketserver.h"
#include <QtCore/qtextstream.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/private/qwindow_p.h>
#include <QtGui/qpa/qwindowsysteminterface.h>
#include <QtGui/qpa/qplatformintegration.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/qoffscreensurface.h>
#include "qwebglwindow.h"
QT_BEGIN_NAMESPACE
static Q_LOGGING_CATEGORY(lc, "qt.qpa.webgl.window")
QAtomicInt QWebGLWindowPrivate::nextId(1);
QWebGLWindowPrivate::QWebGLWindowPrivate(QWebGLWindow *p) :
q_ptr(p)
{}
QWebGLWindow::QWebGLWindow(QWindow *w) :
QPlatformWindow(w),
d_ptr(new QWebGLWindowPrivate(this))
{
}
QWebGLWindow::~QWebGLWindow()
{
destroy();
}
void QWebGLWindow::create()
{
Q_D(QWebGLWindow);
if (d->flags.testFlag(QWebGLWindowPrivate::Created))
return;
d->id = QWebGLWindowPrivate::nextId.fetchAndAddAcquire(1);
qCDebug(lc, "Window %d created", d->id);
// Save the original surface type before changing to OpenGLSurface.
d->raster = (window()->surfaceType() == QSurface::RasterSurface);
if (d->raster) // change to OpenGL, but not for RasterGLSurface
window()->setSurfaceType(QSurface::OpenGLSurface);
if (window()->windowState() == Qt::WindowFullScreen) {
QRect fullscreenRect(QPoint(), screen()->availableGeometry().size());
QPlatformWindow::setGeometry(fullscreenRect);
QWindowSystemInterface::handleGeometryChange(window(), fullscreenRect);
return;
}
d->flags = QWebGLWindowPrivate::Created;
if (window()->type() == Qt::Desktop)
return;
d->flags |= QWebGLWindowPrivate::HasNativeWindow;
setGeometry(window()->geometry()); // will become fullscreen
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(0, 0), geometry().size()));
if (d->raster) {
QOpenGLContext *context = new QOpenGLContext(QGuiApplication::instance());
context->setShareContext(qt_gl_global_share_context());
context->setFormat(d->format);
context->setScreen(window()->screen());
if (Q_UNLIKELY(!context->create()))
qFatal("QWebGL: Failed to create compositing context");
}
}
void QWebGLWindow::destroy()
{
Q_D(QWebGLWindow);
qCDebug(lc, "Destroying %d", d->id);
if (d->flags.testFlag(QWebGLWindowPrivate::HasNativeWindow)) {
invalidateSurface();
}
qt_window_private(window())->updateRequestPending = false;
d->flags = QWebGLWindowPrivate::Flags{};
auto integrationPrivate = QWebGLIntegrationPrivate::instance();
auto clientData = integrationPrivate->findClientData(surface()->surfaceHandle());
if (clientData) {
const QVariantMap values {
{ "winId", winId() }
};
if (clientData->socket)
integrationPrivate->sendMessage(clientData->socket,
QWebGLWebSocketServer::MessageType::DestroyCanvas,
values);
clientData->platformWindows.removeAll(this);
}
}
void QWebGLWindow::raise()
{
QWindow *wnd = window();
if (wnd->type() != Qt::Desktop) {
QWindowSystemInterface::handleExposeEvent(wnd, QRect(QPoint(0, 0), wnd->geometry().size()));
}
}
QSurfaceFormat QWebGLWindow::format() const
{
Q_D(const QWebGLWindow);
return d->format;
}
QWebGLScreen *QWebGLWindow::screen() const
{
return static_cast<QWebGLScreen *>(QPlatformWindow::screen());
}
void QWebGLWindow::setGeometry(const QRect &rect)
{
QWindowSystemInterface::handleGeometryChange(window(), rect);
QPlatformWindow::setGeometry(rect);
}
void QWebGLWindow::setDefaults(const QMap<GLenum, QVariant> &values)
{
Q_D(QWebGLWindow);
d->defaults.set_value(values);
}
WId QWebGLWindow::winId() const
{
Q_D(const QWebGLWindow);
return d->id;
}
QWebGLOffscreenSurface::QWebGLOffscreenSurface(QOffscreenSurface *offscreenSurface)
: QPlatformOffscreenSurface(offscreenSurface)
{
}
QSurfaceFormat QWebGLOffscreenSurface::format() const
{
return offscreenSurface()->format();
}
bool QWebGLOffscreenSurface::isValid() const
{
return true;
}
QT_END_NAMESPACE