Android: Enable Adoption of ANativeWindow handle as a QOffscreenSurface
This is done by adding an API to QOffscreenSurface to enable setting a native handle which can represent a native offscreen surface. When using the TexureView it is necessary to render to SurfaceTexture objects which are exposed as offscreen window surfaces. After wraping a SurfaceTexture in a android.view.Surface object and passing it to C++ via the JNI, it is possible to get the needed ANativeWindow* handle required to pass to eglCreateWindowSurface. So by setting this native handle Qt can then render to this "native" offscreen surface. Change-Id: If7fc5ac7ac588fe6c3a6fb883ea7e439d095470f Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> Reviewed-by: J-P Nurmi <jpnurmi@qt.io> Reviewed-by: BogDan Vatra <bogdan@kdab.com>
This commit is contained in:
parent
b750a3786f
commit
9d8db91ada
@ -102,6 +102,7 @@ public:
|
||||
, requestedFormat(QSurfaceFormat::defaultFormat())
|
||||
, screen(0)
|
||||
, size(1, 1)
|
||||
, nativeHandle(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -115,6 +116,7 @@ public:
|
||||
QSurfaceFormat requestedFormat;
|
||||
QScreen *screen;
|
||||
QSize size;
|
||||
void *nativeHandle;
|
||||
};
|
||||
|
||||
|
||||
@ -217,6 +219,8 @@ void QOffscreenSurface::destroy()
|
||||
delete d->offscreenWindow;
|
||||
d->offscreenWindow = 0;
|
||||
}
|
||||
|
||||
d->nativeHandle = nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -330,6 +334,26 @@ void QOffscreenSurface::setScreen(QScreen *newScreen)
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the native handle to which the offscreen surface is connected.
|
||||
|
||||
The native handle will be resolved in the create() function. Calling
|
||||
this function after create() will not re-create a native surface.
|
||||
|
||||
\note The interpretation of the native handle is platform specific. Only
|
||||
some platforms will support adopting native handles of offscreen surfaces
|
||||
and platforms that do not implement this support will ignore the handle.
|
||||
|
||||
\since 5.9
|
||||
\sa nativeHandle()
|
||||
*/
|
||||
|
||||
void QOffscreenSurface::setNativeHandle(void *handle)
|
||||
{
|
||||
Q_D(QOffscreenSurface);
|
||||
d->nativeHandle = handle;
|
||||
}
|
||||
|
||||
/*!
|
||||
Called when the offscreen surface's screen is destroyed.
|
||||
|
||||
@ -361,6 +385,19 @@ QPlatformOffscreenSurface *QOffscreenSurface::handle() const
|
||||
return d->platformOffscreenSurface;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns an optional native handle to which the offscreen surface is connected.
|
||||
|
||||
\since 5.9
|
||||
\sa setNativeHandle()
|
||||
*/
|
||||
|
||||
void *QOffscreenSurface::nativeHandle() const
|
||||
{
|
||||
Q_D(const QOffscreenSurface);
|
||||
return d->nativeHandle;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the platform surface corresponding to the offscreen surface.
|
||||
|
||||
|
@ -79,6 +79,9 @@ public:
|
||||
|
||||
QPlatformOffscreenSurface *handle() const;
|
||||
|
||||
void *nativeHandle() const;
|
||||
void setNativeHandle(void *handle);
|
||||
|
||||
Q_SIGNALS:
|
||||
void screenChanged(QScreen *screen);
|
||||
|
||||
|
@ -43,7 +43,8 @@ SOURCES += $$PWD/androidplatformplugin.cpp \
|
||||
$$PWD/qandroidplatformbackingstore.cpp \
|
||||
$$PWD/qandroidplatformopenglcontext.cpp \
|
||||
$$PWD/qandroidplatformforeignwindow.cpp \
|
||||
$$PWD/qandroideventdispatcher.cpp
|
||||
$$PWD/qandroideventdispatcher.cpp \
|
||||
$$PWD/qandroidplatformoffscreensurface.cpp
|
||||
|
||||
HEADERS += $$PWD/qandroidplatformintegration.h \
|
||||
$$PWD/androiddeadlockprotector.h \
|
||||
@ -71,7 +72,8 @@ HEADERS += $$PWD/qandroidplatformintegration.h \
|
||||
$$PWD/qandroidplatformbackingstore.h \
|
||||
$$PWD/qandroidplatformopenglcontext.h \
|
||||
$$PWD/qandroidplatformforeignwindow.h \
|
||||
$$PWD/qandroideventdispatcher.h
|
||||
$$PWD/qandroideventdispatcher.h \
|
||||
$$PWD/qandroidplatformoffscreensurface.h
|
||||
|
||||
qtConfig(android-style-assets): SOURCES += $$PWD/extract.cpp
|
||||
else: SOURCES += $$PWD/extract-dummy.cpp
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include "qandroidplatformservices.h"
|
||||
#include "qandroidplatformtheme.h"
|
||||
#include "qandroidsystemlocale.h"
|
||||
#include "qandroidplatformoffscreensurface.h"
|
||||
|
||||
#include <QtPlatformHeaders/QEGLNativeContext>
|
||||
|
||||
@ -262,12 +263,20 @@ QPlatformOffscreenSurface *QAndroidPlatformIntegration::createPlatformOffscreenS
|
||||
{
|
||||
if (!QtAndroid::activity())
|
||||
return nullptr;
|
||||
|
||||
QSurfaceFormat format(surface->requestedFormat());
|
||||
format.setAlphaBufferSize(8);
|
||||
format.setRedBufferSize(8);
|
||||
format.setGreenBufferSize(8);
|
||||
format.setBlueBufferSize(8);
|
||||
|
||||
if (surface->nativeHandle()) {
|
||||
// Adopt existing offscreen Surface
|
||||
// The expectation is that nativeHandle is an ANativeWindow* representing
|
||||
// an android.view.Surface
|
||||
return new QAndroidPlatformOffscreenSurface(m_eglDisplay, format, surface);
|
||||
}
|
||||
|
||||
return new QEGLPbuffer(m_eglDisplay, format, surface);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or 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.GPL2 and 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-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "qandroidplatformoffscreensurface.h"
|
||||
|
||||
#include <QtGui/QOffscreenSurface>
|
||||
#include <QtEglSupport/private/qeglconvenience_p.h>
|
||||
|
||||
#include <android/native_window.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QAndroidPlatformOffscreenSurface::QAndroidPlatformOffscreenSurface(EGLDisplay display, const QSurfaceFormat &format, QOffscreenSurface *offscreenSurface)
|
||||
: QPlatformOffscreenSurface(offscreenSurface)
|
||||
, m_format(format)
|
||||
, m_display(display)
|
||||
, m_surface(EGL_NO_SURFACE)
|
||||
{
|
||||
// Get native handle
|
||||
ANativeWindow *surfaceTexture = (ANativeWindow*)offscreenSurface->nativeHandle();
|
||||
|
||||
EGLConfig config = q_configFromGLFormat(m_display, m_format, false);
|
||||
if (config) {
|
||||
const EGLint attributes[] = {
|
||||
EGL_NONE
|
||||
};
|
||||
m_surface = eglCreateWindowSurface(m_display, config, surfaceTexture, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
QAndroidPlatformOffscreenSurface::~QAndroidPlatformOffscreenSurface()
|
||||
{
|
||||
eglDestroySurface(m_display, m_surface);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -0,0 +1,67 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the plugins of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:LGPL$
|
||||
** 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 Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL3 included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 3 requirements
|
||||
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 2.0 or (at your option) the GNU General
|
||||
** Public license version 3 or 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.GPL2 and 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-2.0.html and
|
||||
** https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QANDROIDPLATFORMOFFSCREENSURFACETEXTURE_H
|
||||
#define QANDROIDPLATFORMOFFSCREENSURFACETEXTURE_H
|
||||
|
||||
#include <qpa/qplatformoffscreensurface.h>
|
||||
#include <QtEglSupport/private/qeglplatformcontext_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QOffscreenSurface;
|
||||
class QAndroidPlatformOffscreenSurface : public QPlatformOffscreenSurface
|
||||
{
|
||||
public:
|
||||
QAndroidPlatformOffscreenSurface(EGLDisplay display, const QSurfaceFormat &format,
|
||||
QOffscreenSurface *offscreenSurface);
|
||||
~QAndroidPlatformOffscreenSurface();
|
||||
|
||||
QSurfaceFormat format() const override { return m_format; }
|
||||
bool isValid() const override { return m_surface != EGL_NO_SURFACE; }
|
||||
|
||||
EGLSurface surface() const { return m_surface; }
|
||||
private:
|
||||
QSurfaceFormat m_format;
|
||||
EGLDisplay m_display;
|
||||
EGLSurface m_surface;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QANDROIDPLATFORMOFFSCREENSURFACETEXTURE_H
|
@ -41,11 +41,13 @@
|
||||
#include "qandroidplatformopenglcontext.h"
|
||||
#include "qandroidplatformopenglwindow.h"
|
||||
#include "qandroidplatformintegration.h"
|
||||
#include "qandroidplatformoffscreensurface.h"
|
||||
|
||||
#include <QtEglSupport/private/qeglpbuffer_p.h>
|
||||
|
||||
#include <QSurface>
|
||||
#include <QtGui/private/qopenglcontext_p.h>
|
||||
#include <QtGui/QOffscreenSurface>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
@ -110,10 +112,15 @@ bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface)
|
||||
|
||||
EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)
|
||||
{
|
||||
if (surface->surface()->surfaceClass() == QSurface::Window)
|
||||
if (surface->surface()->surfaceClass() == QSurface::Window) {
|
||||
return static_cast<QAndroidPlatformOpenGLWindow *>(surface)->eglSurface(eglConfig());
|
||||
else
|
||||
return static_cast<QEGLPbuffer *>(surface)->pbuffer();
|
||||
} else {
|
||||
auto platformOffscreenSurface = static_cast<QPlatformOffscreenSurface*>(surface);
|
||||
if (platformOffscreenSurface->offscreenSurface()->nativeHandle())
|
||||
return static_cast<QAndroidPlatformOffscreenSurface *>(surface)->surface();
|
||||
else
|
||||
return static_cast<QEGLPbuffer *>(surface)->pbuffer();
|
||||
}
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
Reference in New Issue
Block a user