Revision control

Copy as Markdown

// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:significant reason:default
#include "qeglfsopenwfdintegration.h"
#include "wfd.h"
#include "wfdext2.h"
QT_BEGIN_NAMESPACE
#define MAX_NUM_OF_WFD_BUFFERS 3
#define MAX_NUM_OF_WFD_DEVICES 4
#define MAX_NUM_OF_WFD_PIPELINES 16
#define MAX_NUM_OF_WFD_PORT_MODES 64
#define MAX_NUM_OF_WFD_PORTS 4
typedef struct wfd_buffer {
WFD_EGLImageType* image;
WFDSource source;
} wfd_buffer_t;
typedef struct wfd_window {
WFDDevice dev;
WFDPort port;
WFDPipeline pipeline;
int numBuffers;
wfd_buffer_t buffers[MAX_NUM_OF_WFD_BUFFERS];
} wfd_window_t;
void QEglFSOpenWFDIntegration::platformInit()
{
QEglFSDeviceIntegration::platformInit();
mNativeDisplay = EGL_DEFAULT_DISPLAY;
// Get device list
WFDint numDevs = wfdEnumerateDevices(nullptr, 0, nullptr);
WFDint devIds[MAX_NUM_OF_WFD_DEVICES];
if (numDevs > 0)
wfdEnumerateDevices(devIds, numDevs, nullptr);
// Create device
WFDint dev_attribs[3] = {WFD_DEVICE_CLIENT_TYPE,
WFD_CLIENT_ID_CLUSTER,
WFD_NONE};
bool ok;
WFDint clientType = qgetenv("QT_OPENWFD_CLIENT_ID").toInt(&ok, 16);
if (ok)
dev_attribs[1] = clientType;
mDevice = wfdCreateDevice(WFD_DEFAULT_DEVICE_ID, dev_attribs);
if (WFD_INVALID_HANDLE == mDevice)
qFatal( "Failed to create wfd device");
// Get port list
WFDint portIds[MAX_NUM_OF_WFD_PORTS];
WFDint numPorts = wfdEnumeratePorts(mDevice, nullptr, 0, nullptr);
wfdEnumeratePorts(mDevice, portIds, numPorts, nullptr);
// Create port
mPort = wfdCreatePort(mDevice, portIds[0], nullptr);
if (WFD_INVALID_HANDLE == mPort)
qFatal("Failed to create wfd port");
// Get port modes
WFDint numPortModes = wfdGetPortModes(mDevice, mPort, nullptr, 0);
WFDPortMode portModes[MAX_NUM_OF_WFD_PORT_MODES];
wfdGetPortModes(mDevice, mPort, portModes, numPortModes);
// Get width and height
mScreenSize.setWidth(wfdGetPortModeAttribi(mDevice, mPort, portModes[0], WFD_PORT_MODE_WIDTH));
mScreenSize.setHeight(wfdGetPortModeAttribi(mDevice, mPort, portModes[0], WFD_PORT_MODE_HEIGHT));
// Set port mode
wfdSetPortMode(mDevice, mPort, portModes[0]);
WFDErrorCode eError = wfdGetError(mDevice);
if (WFD_ERROR_NONE != eError)
qFatal("Failed to set wfd port mode");
// Power on
wfdSetPortAttribi(mDevice, mPort, WFD_PORT_POWER_MODE, WFD_POWER_MODE_ON);
eError = wfdGetError(mDevice);
if (WFD_ERROR_NONE != eError)
qFatal("Failed to power on wfd port");
}
QSize QEglFSOpenWFDIntegration::screenSize() const
{
return mScreenSize;
}
EGLNativeDisplayType QEglFSOpenWFDIntegration::platformDisplay() const
{
return mNativeDisplay;
}
EGLNativeWindowType QEglFSOpenWFDIntegration::createNativeWindow(QPlatformWindow *window,
const QSize &size,
const QSurfaceFormat &format)
{
Q_UNUSED(window);
Q_UNUSED(format);
// Get list of pipelines
WFDint numPipelines = wfdEnumeratePipelines(mDevice, nullptr, 0, nullptr);
WFDint pipelineIds[MAX_NUM_OF_WFD_PIPELINES];
wfdEnumeratePipelines(mDevice, pipelineIds, numPipelines, nullptr);
bool ok;
WFDint pipelineId = qgetenv("QT_OPENWFD_PIPELINE_ID").toInt(&ok);
if (!ok)
pipelineId = pipelineIds[0];
mPipeline = wfdCreatePipeline(mDevice, pipelineId, nullptr);
if (WFD_INVALID_HANDLE == mPipeline)
qFatal("Failed to create wfd pipeline");
wfdSetPipelineAttribi(mDevice, mPipeline, WFD_PIPELINE_TRANSPARENCY_ENABLE,
(WFD_TRANSPARENCY_SOURCE_ALPHA|WFD_TRANSPARENCY_GLOBAL_ALPHA));
WFDErrorCode eError = wfdGetError(mDevice);
if (WFD_ERROR_NONE != eError)
qFatal("Failed to set WFD_PIPELINE_TRANSPARENCY_ENABLE");
wfdSetPipelineAttribi(mDevice, mPipeline, WFD_PIPELINE_GLOBAL_ALPHA, 255);
eError = wfdGetError(mDevice);
if (WFD_ERROR_NONE != eError)
qFatal("Failed to set WFD_PIPELINE_GLOBAL_ALPHA");
wfdBindPipelineToPort(mDevice, mPort, mPipeline);
eError = wfdGetError(mDevice);
if (WFD_ERROR_NONE != eError)
qFatal("Failed to bind port to pipeline");
// Create buffers
WFDSource source[MAX_NUM_OF_WFD_BUFFERS] = {WFD_INVALID_HANDLE, WFD_INVALID_HANDLE,
WFD_INVALID_HANDLE};
WFDEGLImage eglImageHandles[MAX_NUM_OF_WFD_BUFFERS];
WFD_EGLImageType* wfdEglImages[MAX_NUM_OF_WFD_BUFFERS];
for (int i = 0; i < MAX_NUM_OF_WFD_BUFFERS; i++) {
wfdCreateWFDEGLImages(mDevice, mScreenSize.width(), mScreenSize.height(),
WFD_FORMAT_RGBA8888, WFD_USAGE_OPENGL_ES2 | WFD_USAGE_DISPLAY,
1, &(eglImageHandles[i]), 0);
wfdEglImages[i] = (WFD_EGLImageType *)(eglImageHandles[i]);
if (WFD_INVALID_HANDLE == wfdEglImages[i])
qFatal("Failed to create WDFEGLImages");
source[i] = wfdCreateSourceFromImage(mDevice, mPipeline, eglImageHandles[i], nullptr);
if (WFD_INVALID_HANDLE == source[i])
qFatal("Failed to create source from EGLImage");
}
// Commit port
wfdDeviceCommit(mDevice, WFD_COMMIT_ENTIRE_PORT, mPort);
eError = wfdGetError(mDevice);
if (WFD_ERROR_NONE != eError)
qFatal("Failed to commit port");
// Create native window
wfd_window_t* nativeWindow = (wfd_window_t*)malloc(sizeof(wfd_window_t));
if (nullptr == nativeWindow)
qFatal("Failed to allocate memory for native window");
nativeWindow->dev = mDevice;
nativeWindow->port = mPort;
nativeWindow->pipeline = mPipeline;
nativeWindow->numBuffers = MAX_NUM_OF_WFD_BUFFERS;
for (int i = 0; i < MAX_NUM_OF_WFD_BUFFERS; i++) {
nativeWindow->buffers[i].image = wfdEglImages[i];
nativeWindow->buffers[i].source = source[i];
}
return (EGLNativeWindowType)nativeWindow;
}
QSurfaceFormat QEglFSOpenWFDIntegration::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
{
QSurfaceFormat format = inputFormat;
format.setRedBufferSize(8);
format.setGreenBufferSize(8);
format.setBlueBufferSize(8);
format.setAlphaBufferSize(8);
return format;
}
void QEglFSOpenWFDIntegration::destroyNativeWindow(EGLNativeWindowType window)
{
wfdDestroyPipeline(mDevice, mPipeline);
free((void*)window);
}
void QEglFSOpenWFDIntegration::platformDestroy()
{
wfdDestroyPort(mDevice, mPort);
WFDErrorCode error = wfdDestroyDevice(mDevice);
if (error != WFD_ERROR_NONE)
qWarning() << "Failed to release wfd device! Error = " << error;
}
QT_END_NAMESPACE