Warning, /graphics/krita/3rdparty/ext_qt/0007-Implement-a-manual-test-for-checking-is-HDR-features.patch is written in an unsupported language. File is not indexed.
0001 From 8c5e4fec56124e22f05881ffa6e6127428d5ee1b Mon Sep 17 00:00:00 2001 0002 From: Dmitry Kazakov <dimula73@gmail.com> 0003 Date: Sun, 10 Feb 2019 22:55:59 +0300 0004 Subject: [PATCH 17/47] Implement a manual test for checking is HDR features 0005 work 0006 0007 Test plan: 0008 0009 1) Run without arguments: `hdr-openglwidget.exe` 0010 It should show you three rectangles: the left one should be HDR'ly 0011 bright, the other ones should be SDR'ly dim and look exactly the same. 0012 0013 3) Run in Bt. 2020 PQ mode: `hdr-openglwidget.exe --bt2020pq` 0014 The result should look exactly the same. 0015 0016 4) Run in SDR sRGB mode: `hdr-openglwidget.exe --srgb`. 0017 All three images should look SDR'ly dim. 0018 0019 NOTE: 0020 Please note that the current implementation of SDR compositing 0021 in QOpenGLTextureBlitter doesn't support user configuration for 0022 SDR brightness from the system. This API is available for UWP 0023 applications only. It means that when changing "SDR brightness" 0024 slider in Windows' settings, the brightness of our SDR widget 0025 will not change. More that that, it might even be different from 0026 the brightness of other SDR applications. 0027 0028 Change-Id: Idccc790937c9061ec618ab21f6b71bd0620cd2cc 0029 --- 0030 .../hdr-qopenglwidget/KisGLImageF16.cpp | 131 +++++++++ 0031 .../manual/hdr-qopenglwidget/KisGLImageF16.h | 68 +++++ 0032 .../hdr-qopenglwidget/KisGLImageWidget.cpp | 252 ++++++++++++++++++ 0033 .../hdr-qopenglwidget/KisGLImageWidget.h | 77 ++++++ 0034 .../hdr-qopenglwidget/hdr-openglwidget.pro | 20 ++ 0035 .../kis_gl_image_widget.frag | 23 ++ 0036 .../hdr-qopenglwidget/kis_gl_image_widget.qrc | 6 + 0037 .../kis_gl_image_widget.vert | 17 ++ 0038 tests/manual/hdr-qopenglwidget/main.cpp | 153 +++++++++++ 0039 .../hdr-qopenglwidget/openglprobeutils.cpp | 139 ++++++++++ 0040 .../hdr-qopenglwidget/openglprobeutils.h | 42 +++ 0041 tests/manual/hdr-qopenglwidget/window.cpp | 219 +++++++++++++++ 0042 tests/manual/hdr-qopenglwidget/window.h | 69 +++++ 0043 tests/manual/manual.pro | 2 +- 0044 14 files changed, 1217 insertions(+), 1 deletion(-) 0045 create mode 100644 tests/manual/hdr-qopenglwidget/KisGLImageF16.cpp 0046 create mode 100644 tests/manual/hdr-qopenglwidget/KisGLImageF16.h 0047 create mode 100644 tests/manual/hdr-qopenglwidget/KisGLImageWidget.cpp 0048 create mode 100644 tests/manual/hdr-qopenglwidget/KisGLImageWidget.h 0049 create mode 100644 tests/manual/hdr-qopenglwidget/hdr-openglwidget.pro 0050 create mode 100644 tests/manual/hdr-qopenglwidget/kis_gl_image_widget.frag 0051 create mode 100644 tests/manual/hdr-qopenglwidget/kis_gl_image_widget.qrc 0052 create mode 100644 tests/manual/hdr-qopenglwidget/kis_gl_image_widget.vert 0053 create mode 100644 tests/manual/hdr-qopenglwidget/main.cpp 0054 create mode 100644 tests/manual/hdr-qopenglwidget/openglprobeutils.cpp 0055 create mode 100644 tests/manual/hdr-qopenglwidget/openglprobeutils.h 0056 create mode 100644 tests/manual/hdr-qopenglwidget/window.cpp 0057 create mode 100644 tests/manual/hdr-qopenglwidget/window.h 0058 0059 diff --git a/tests/manual/hdr-qopenglwidget/KisGLImageF16.cpp b/tests/manual/hdr-qopenglwidget/KisGLImageF16.cpp 0060 new file mode 100644 0061 index 0000000000..a84b676f5b 0062 --- /dev/null 0063 +++ b/tests/manual/hdr-qopenglwidget/KisGLImageF16.cpp 0064 @@ -0,0 +1,131 @@ 0065 +/**************************************************************************** 0066 +** 0067 +** Copyright (C) 2019 The Qt Company Ltd. 0068 +** Contact: https://www.qt.io/licensing/ 0069 +** 0070 +** This file is part of the test suite of the Qt Toolkit. 0071 +** 0072 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 0073 +** Commercial License Usage 0074 +** Licensees holding valid commercial Qt licenses may use this file in 0075 +** accordance with the commercial license agreement provided with the 0076 +** Software or, alternatively, in accordance with the terms contained in 0077 +** a written agreement between you and The Qt Company. For licensing terms 0078 +** and conditions see https://www.qt.io/terms-conditions. For further 0079 +** information use the contact form at https://www.qt.io/contact-us. 0080 +** 0081 +** GNU General Public License Usage 0082 +** Alternatively, this file may be used under the terms of the GNU 0083 +** General Public License version 3 as published by the Free Software 0084 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 0085 +** included in the packaging of this file. Please review the following 0086 +** information to ensure the GNU General Public License requirements will 0087 +** be met: https://www.gnu.org/licenses/gpl-3.0.html. 0088 +** 0089 +** $QT_END_LICENSE$ 0090 +** 0091 +****************************************************************************/ 0092 + 0093 +#include "KisGLImageF16.h" 0094 + 0095 +#include <QByteArray> 0096 +#include <QSize> 0097 + 0098 +struct KisGLImageF16::Private : public QSharedData 0099 +{ 0100 + QSize size; 0101 + QByteArray data; 0102 +}; 0103 + 0104 +KisGLImageF16::KisGLImageF16() 0105 + : m_d(new Private) 0106 +{ 0107 +} 0108 + 0109 +KisGLImageF16::KisGLImageF16(const QSize &size, bool clearPixels) 0110 + : m_d(new Private) 0111 +{ 0112 + resize(size, clearPixels); 0113 +} 0114 + 0115 +KisGLImageF16::KisGLImageF16(int width, int height, bool clearPixels) 0116 + : KisGLImageF16(QSize(width, height), clearPixels) 0117 +{ 0118 +} 0119 + 0120 +KisGLImageF16::KisGLImageF16(const KisGLImageF16 &rhs) 0121 + : m_d(rhs.m_d) 0122 +{ 0123 +} 0124 + 0125 +KisGLImageF16 &KisGLImageF16::operator=(const KisGLImageF16 &rhs) 0126 +{ 0127 + m_d = rhs.m_d; 0128 +} 0129 + 0130 +bool operator==(const KisGLImageF16 &lhs, const KisGLImageF16 &rhs) 0131 +{ 0132 + return lhs.m_d == rhs.m_d; 0133 +} 0134 + 0135 +bool operator!=(const KisGLImageF16 &lhs, const KisGLImageF16 &rhs) 0136 +{ 0137 + return !(lhs == rhs); 0138 +} 0139 + 0140 +KisGLImageF16::~KisGLImageF16() 0141 +{ 0142 +} 0143 + 0144 +void KisGLImageF16::clearPixels() 0145 +{ 0146 + if (!m_d->data.isEmpty()) { 0147 + m_d->data.fill(0); 0148 + } 0149 +} 0150 + 0151 +void KisGLImageF16::resize(const QSize &size, bool clearPixels) 0152 +{ 0153 + const int pixelSize = 2 * 4; 0154 + 0155 + m_d->size = size; 0156 + m_d->data.resize(size.width() * size.height() * pixelSize); 0157 + 0158 + if (clearPixels) { 0159 + m_d->data.fill(0); 0160 + } 0161 +} 0162 + 0163 +const qfloat16 *KisGLImageF16::constData() const 0164 +{ 0165 + Q_ASSERT(!m_d->data.isNull()); 0166 + return reinterpret_cast<const qfloat16*>(m_d->data.data()); 0167 +} 0168 + 0169 +qfloat16 *KisGLImageF16::data() 0170 +{ 0171 + m_d->data.detach(); 0172 + Q_ASSERT(!m_d->data.isNull()); 0173 + 0174 + return reinterpret_cast<qfloat16*>(m_d->data.data()); 0175 +} 0176 + 0177 +QSize KisGLImageF16::size() const 0178 +{ 0179 + return m_d->size; 0180 +} 0181 + 0182 +int KisGLImageF16::width() const 0183 +{ 0184 + return m_d->size.width(); 0185 +} 0186 + 0187 +int KisGLImageF16::height() const 0188 +{ 0189 + return m_d->size.height(); 0190 +} 0191 + 0192 +bool KisGLImageF16::isNull() const 0193 +{ 0194 + return m_d->data.isNull(); 0195 +} 0196 diff --git a/tests/manual/hdr-qopenglwidget/KisGLImageF16.h b/tests/manual/hdr-qopenglwidget/KisGLImageF16.h 0197 new file mode 100644 0198 index 0000000000..335e42ee68 0199 --- /dev/null 0200 +++ b/tests/manual/hdr-qopenglwidget/KisGLImageF16.h 0201 @@ -0,0 +1,68 @@ 0202 +/**************************************************************************** 0203 +** 0204 +** Copyright (C) 2019 The Qt Company Ltd. 0205 +** Contact: https://www.qt.io/licensing/ 0206 +** 0207 +** This file is part of the test suite of the Qt Toolkit. 0208 +** 0209 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 0210 +** Commercial License Usage 0211 +** Licensees holding valid commercial Qt licenses may use this file in 0212 +** accordance with the commercial license agreement provided with the 0213 +** Software or, alternatively, in accordance with the terms contained in 0214 +** a written agreement between you and The Qt Company. For licensing terms 0215 +** and conditions see https://www.qt.io/terms-conditions. For further 0216 +** information use the contact form at https://www.qt.io/contact-us. 0217 +** 0218 +** GNU General Public License Usage 0219 +** Alternatively, this file may be used under the terms of the GNU 0220 +** General Public License version 3 as published by the Free Software 0221 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 0222 +** included in the packaging of this file. Please review the following 0223 +** information to ensure the GNU General Public License requirements will 0224 +** be met: https://www.gnu.org/licenses/gpl-3.0.html. 0225 +** 0226 +** $QT_END_LICENSE$ 0227 +** 0228 +****************************************************************************/ 0229 + 0230 +#ifndef KISGLIMAGEF16_H 0231 +#define KISGLIMAGEF16_H 0232 + 0233 +#include <QSharedDataPointer> 0234 +#include <QFloat16> 0235 + 0236 +class QSize; 0237 + 0238 +class KisGLImageF16 0239 +{ 0240 +public: 0241 + KisGLImageF16(); 0242 + KisGLImageF16(const QSize &size, bool clearPixels = false); 0243 + KisGLImageF16(int width, int height, bool clearPixels = false); 0244 + KisGLImageF16(const KisGLImageF16 &rhs); 0245 + KisGLImageF16& operator=(const KisGLImageF16 &rhs); 0246 + 0247 + friend bool operator==(const KisGLImageF16 &lhs, const KisGLImageF16 &rhs); 0248 + friend bool operator!=(const KisGLImageF16 &lhs, const KisGLImageF16 &rhs); 0249 + 0250 + ~KisGLImageF16(); 0251 + 0252 + void clearPixels(); 0253 + void resize(const QSize &size, bool clearPixels = false); 0254 + 0255 + const qfloat16* constData() const; 0256 + qfloat16* data(); 0257 + 0258 + QSize size() const; 0259 + int width() const; 0260 + int height() const; 0261 + 0262 + bool isNull() const; 0263 + 0264 +private: 0265 + struct Private; 0266 + QSharedDataPointer<Private> m_d; 0267 +}; 0268 + 0269 +#endif // KISGLIMAGEF16_H 0270 diff --git a/tests/manual/hdr-qopenglwidget/KisGLImageWidget.cpp b/tests/manual/hdr-qopenglwidget/KisGLImageWidget.cpp 0271 new file mode 100644 0272 index 0000000000..da36ac1619 0273 --- /dev/null 0274 +++ b/tests/manual/hdr-qopenglwidget/KisGLImageWidget.cpp 0275 @@ -0,0 +1,252 @@ 0276 +/**************************************************************************** 0277 +** 0278 +** Copyright (C) 2019 The Qt Company Ltd. 0279 +** Contact: https://www.qt.io/licensing/ 0280 +** 0281 +** This file is part of the test suite of the Qt Toolkit. 0282 +** 0283 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 0284 +** Commercial License Usage 0285 +** Licensees holding valid commercial Qt licenses may use this file in 0286 +** accordance with the commercial license agreement provided with the 0287 +** Software or, alternatively, in accordance with the terms contained in 0288 +** a written agreement between you and The Qt Company. For licensing terms 0289 +** and conditions see https://www.qt.io/terms-conditions. For further 0290 +** information use the contact form at https://www.qt.io/contact-us. 0291 +** 0292 +** GNU General Public License Usage 0293 +** Alternatively, this file may be used under the terms of the GNU 0294 +** General Public License version 3 as published by the Free Software 0295 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 0296 +** included in the packaging of this file. Please review the following 0297 +** information to ensure the GNU General Public License requirements will 0298 +** be met: https://www.gnu.org/licenses/gpl-3.0.html. 0299 +** 0300 +** $QT_END_LICENSE$ 0301 +** 0302 +****************************************************************************/ 0303 + 0304 +#include "KisGLImageWidget.h" 0305 + 0306 +#include <QPainter> 0307 +#include <QFile> 0308 +#include <QResizeEvent> 0309 + 0310 +#include "KisGLImageF16.h" 0311 + 0312 +namespace { 0313 +inline void rectToVertices(QVector3D* vertices, const QRectF &rc) 0314 +{ 0315 + vertices[0] = QVector3D(rc.left(), rc.bottom(), 0.f); 0316 + vertices[1] = QVector3D(rc.left(), rc.top(), 0.f); 0317 + vertices[2] = QVector3D(rc.right(), rc.bottom(), 0.f); 0318 + vertices[3] = QVector3D(rc.left(), rc.top(), 0.f); 0319 + vertices[4] = QVector3D(rc.right(), rc.top(), 0.f); 0320 + vertices[5] = QVector3D(rc.right(), rc.bottom(), 0.f); 0321 +} 0322 + 0323 +inline void rectToTexCoords(QVector2D* texCoords, const QRectF &rc) 0324 +{ 0325 + texCoords[0] = QVector2D(rc.left(), rc.bottom()); 0326 + texCoords[1] = QVector2D(rc.left(), rc.top()); 0327 + texCoords[2] = QVector2D(rc.right(), rc.bottom()); 0328 + texCoords[3] = QVector2D(rc.left(), rc.top()); 0329 + texCoords[4] = QVector2D(rc.right(), rc.top()); 0330 + texCoords[5] = QVector2D(rc.right(), rc.bottom()); 0331 +} 0332 +} 0333 + 0334 +KisGLImageWidget::KisGLImageWidget(QWidget *parent) 0335 + : KisGLImageWidget(QSurfaceFormat::sRGBColorSpace, parent) 0336 +{ 0337 +} 0338 + 0339 +KisGLImageWidget::KisGLImageWidget(QSurfaceFormat::ColorSpace colorSpace, 0340 + QWidget *parent) 0341 + : QOpenGLWidget(parent), 0342 + m_texture(QOpenGLTexture::Target2D) 0343 +{ 0344 + 0345 + qDebug() << "Crating gl widget"; 0346 + 0347 + setTextureFormat(GL_RGBA16F); 0348 + setTextureColorSpace(colorSpace); 0349 + 0350 + setUpdateBehavior(QOpenGLWidget::NoPartialUpdate); 0351 +} 0352 + 0353 +void KisGLImageWidget::initializeGL() 0354 +{ 0355 + initializeOpenGLFunctions(); 0356 + 0357 + qDebug() << "Initialized with format:" << context()->format(); 0358 + 0359 + QFile vertexShaderFile(QString(":/") + "kis_gl_image_widget.vert"); 0360 + vertexShaderFile.open(QIODevice::ReadOnly); 0361 + QString vertSource = vertexShaderFile.readAll(); 0362 + 0363 + QFile fragShaderFile(QString(":/") + "kis_gl_image_widget.frag"); 0364 + fragShaderFile.open(QIODevice::ReadOnly); 0365 + QString fragSource = fragShaderFile.readAll(); 0366 + 0367 + if (context()->isOpenGLES()) { 0368 + const char *versionHelper = "#define USE_OPENGLES\n"; 0369 + vertSource.prepend(versionHelper); 0370 + fragSource.prepend(versionHelper); 0371 + 0372 + const char *versionDefinition = "#version 100\n"; 0373 + vertSource.prepend(versionDefinition); 0374 + fragSource.prepend(versionDefinition); 0375 + } else { 0376 + const char *versionDefinition = "#version 330 core\n"; 0377 + vertSource.prepend(versionDefinition); 0378 + fragSource.prepend(versionDefinition); 0379 + } 0380 + 0381 + if (!m_shader.addShaderFromSourceCode(QOpenGLShader::Vertex, vertSource)) { 0382 + qDebug() << "Could not add vertex code"; 0383 + return; 0384 + } 0385 + 0386 + if (!m_shader.addShaderFromSourceCode(QOpenGLShader::Fragment, fragSource)) { 0387 + qDebug() << "Could not add fragment code"; 0388 + return; 0389 + } 0390 + 0391 + if (!m_shader.link()) { 0392 + qDebug() << "Could not link"; 0393 + return; 0394 + } 0395 + 0396 + if (!m_shader.bind()) { 0397 + qDebug() << "Could not bind"; 0398 + return; 0399 + } 0400 + 0401 + m_shader.release(); 0402 + 0403 + 0404 + m_vao.create(); 0405 + m_vao.bind(); 0406 + 0407 + m_verticesBuffer.create(); 0408 + updateVerticesBuffer(this->rect()); 0409 + 0410 + QVector<QVector2D> textureVertices(6); 0411 + rectToTexCoords(textureVertices.data(), QRect(0.0, 0.0, 1.0, 1.0)); 0412 + 0413 + m_textureVerticesBuffer.create(); 0414 + m_textureVerticesBuffer.bind(); 0415 + m_textureVerticesBuffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); 0416 + m_textureVerticesBuffer.allocate(2 * 3 * sizeof(QVector2D)); 0417 + m_verticesBuffer.write(0, textureVertices.data(), m_textureVerticesBuffer.size()); 0418 + m_textureVerticesBuffer.release(); 0419 + 0420 + m_vao.release(); 0421 + 0422 + 0423 + if (!m_sourceImage.isNull()) { 0424 + loadImage(m_sourceImage); 0425 + } 0426 +} 0427 + 0428 +void KisGLImageWidget::updateVerticesBuffer(const QRect &rect) 0429 +{ 0430 + if (!m_vao.isCreated() || !m_verticesBuffer.isCreated()) return; 0431 + 0432 + QVector<QVector3D> vertices(6); 0433 + rectToVertices(vertices.data(), rect); 0434 + 0435 + m_verticesBuffer.bind(); 0436 + m_verticesBuffer.setUsagePattern(QOpenGLBuffer::DynamicDraw); 0437 + m_verticesBuffer.allocate(2 * 3 * sizeof(QVector3D)); 0438 + m_verticesBuffer.write(0, vertices.data(), m_verticesBuffer.size()); 0439 + m_verticesBuffer.release(); 0440 +} 0441 + 0442 + 0443 +void KisGLImageWidget::paintGL() 0444 +{ 0445 + const QColor bgColor = palette().background().color(); 0446 + glClearColor(bgColor.redF(), bgColor.greenF(), bgColor.blueF(), 1.0f); 0447 + glClear(GL_COLOR_BUFFER_BIT); 0448 + 0449 + if (!m_texture.isCreated()) return; 0450 + 0451 + glViewport(0, 0, width(), height()); 0452 + 0453 + m_vao.bind(); 0454 + m_shader.bind(); 0455 + 0456 + { 0457 + QMatrix4x4 projectionMatrix; 0458 + projectionMatrix.setToIdentity(); 0459 + projectionMatrix.ortho(0, width(), height(), 0, -1, 1); 0460 + QMatrix4x4 viewProjectionMatrix; 0461 + 0462 + // use a QTransform to scale, translate, rotate your view 0463 + QTransform transform; // TODO: noop! 0464 + viewProjectionMatrix = projectionMatrix * QMatrix4x4(transform); 0465 + 0466 + m_shader.setUniformValue("viewProjectionMatrix", viewProjectionMatrix); 0467 + } 0468 + 0469 + m_shader.enableAttributeArray("vertexPosition"); 0470 + m_verticesBuffer.bind(); 0471 + m_shader.setAttributeBuffer("vertexPosition", GL_FLOAT, 0, 3); 0472 + 0473 + m_shader.enableAttributeArray("texturePosition"); 0474 + m_textureVerticesBuffer.bind(); 0475 + m_shader.setAttributeBuffer("texturePosition", GL_FLOAT, 0, 2); 0476 + 0477 + glActiveTexture(GL_TEXTURE0); 0478 + m_texture.bind(); 0479 + 0480 + // draw 2 triangles = 6 vertices starting at offset 0 in the buffer 0481 + glDrawArrays(GL_TRIANGLES, 0, 6); 0482 + 0483 + m_verticesBuffer.release(); 0484 + m_textureVerticesBuffer.release(); 0485 + m_texture.release(); 0486 + m_shader.release(); 0487 + m_vao.release(); 0488 +} 0489 + 0490 +void KisGLImageWidget::loadImage(const KisGLImageF16 &image) 0491 +{ 0492 + if (m_sourceImage != image) { 0493 + m_sourceImage = image; 0494 + } 0495 + 0496 + if (m_vao.isCreated()) { 0497 + m_texture.setFormat(QOpenGLTexture::RGBA16F); 0498 + m_texture.setSize(image.width(), image.height()); 0499 + m_texture.allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::Float16); 0500 + m_texture.setMinificationFilter(QOpenGLTexture::LinearMipMapLinear); 0501 + m_texture.setMagnificationFilter(QOpenGLTexture::Linear); 0502 + m_texture.setData(QOpenGLTexture::RGBA, QOpenGLTexture::Float16, image.constData()); 0503 + updateGeometry(); 0504 + } 0505 +} 0506 + 0507 +void KisGLImageWidget::paintEvent(QPaintEvent *event) 0508 +{ 0509 + QOpenGLWidget::paintEvent(event); 0510 +} 0511 + 0512 +void KisGLImageWidget::resizeEvent(QResizeEvent *event) 0513 +{ 0514 + updateVerticesBuffer(QRect(QPoint(),event->size())); 0515 + QOpenGLWidget::resizeEvent(event); 0516 +} 0517 + 0518 +QSize KisGLImageWidget::sizeHint() const 0519 +{ 0520 + return m_sourceImage.size(); 0521 +} 0522 + 0523 +KisGLImageF16 KisGLImageWidget::image() const 0524 +{ 0525 + return m_sourceImage; 0526 +} 0527 + 0528 diff --git a/tests/manual/hdr-qopenglwidget/KisGLImageWidget.h b/tests/manual/hdr-qopenglwidget/KisGLImageWidget.h 0529 new file mode 100644 0530 index 0000000000..e807064cb4 0531 --- /dev/null 0532 +++ b/tests/manual/hdr-qopenglwidget/KisGLImageWidget.h 0533 @@ -0,0 +1,77 @@ 0534 +/**************************************************************************** 0535 +** 0536 +** Copyright (C) 2019 The Qt Company Ltd. 0537 +** Contact: https://www.qt.io/licensing/ 0538 +** 0539 +** This file is part of the test suite of the Qt Toolkit. 0540 +** 0541 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 0542 +** Commercial License Usage 0543 +** Licensees holding valid commercial Qt licenses may use this file in 0544 +** accordance with the commercial license agreement provided with the 0545 +** Software or, alternatively, in accordance with the terms contained in 0546 +** a written agreement between you and The Qt Company. For licensing terms 0547 +** and conditions see https://www.qt.io/terms-conditions. For further 0548 +** information use the contact form at https://www.qt.io/contact-us. 0549 +** 0550 +** GNU General Public License Usage 0551 +** Alternatively, this file may be used under the terms of the GNU 0552 +** General Public License version 3 as published by the Free Software 0553 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 0554 +** included in the packaging of this file. Please review the following 0555 +** information to ensure the GNU General Public License requirements will 0556 +** be met: https://www.gnu.org/licenses/gpl-3.0.html. 0557 +** 0558 +** $QT_END_LICENSE$ 0559 +** 0560 +****************************************************************************/ 0561 + 0562 +#ifndef KISGLIMAGEWIDGET_H 0563 +#define KISGLIMAGEWIDGET_H 0564 + 0565 +#include <QOpenGLWidget> 0566 +#include <QOpenGLFunctions> 0567 +#include <QOpenGLTexture> 0568 +#include <QOpenGLShaderProgram> 0569 +#include <QOpenGLVertexArrayObject> 0570 +#include <QOpenGLBuffer> 0571 +#include <QTransform> 0572 +#include <KisGLImageF16.h> 0573 + 0574 + 0575 +class KisGLImageWidget : public QOpenGLWidget, protected QOpenGLFunctions 0576 +{ 0577 + Q_OBJECT 0578 +public: 0579 + KisGLImageWidget(QWidget *parent = nullptr); 0580 + KisGLImageWidget(QSurfaceFormat::ColorSpace colorSpace, 0581 + QWidget *parent = nullptr); 0582 + 0583 + void initializeGL() override; 0584 + void paintGL() override; 0585 + 0586 + void loadImage(const KisGLImageF16 &image); 0587 + 0588 + void paintEvent(QPaintEvent *event) override; 0589 + void resizeEvent(QResizeEvent *event) override; 0590 + 0591 + QSize sizeHint() const override; 0592 + 0593 + KisGLImageF16 image() const; 0594 + 0595 +public Q_SLOTS: 0596 + 0597 +private: 0598 + void updateVerticesBuffer(const QRect &rect); 0599 + 0600 +private: 0601 + KisGLImageF16 m_sourceImage; 0602 + 0603 + QOpenGLShaderProgram m_shader; 0604 + QOpenGLVertexArrayObject m_vao; 0605 + QOpenGLBuffer m_verticesBuffer; 0606 + QOpenGLBuffer m_textureVerticesBuffer; 0607 + QOpenGLTexture m_texture; 0608 +}; 0609 + 0610 +#endif // KISGLIMAGEWIDGET_H 0611 diff --git a/tests/manual/hdr-qopenglwidget/hdr-openglwidget.pro b/tests/manual/hdr-qopenglwidget/hdr-openglwidget.pro 0612 new file mode 100644 0613 index 0000000000..b418e54b43 0614 --- /dev/null 0615 +++ b/tests/manual/hdr-qopenglwidget/hdr-openglwidget.pro 0616 @@ -0,0 +1,20 @@ 0617 +QT += widgets widgets-private gui-private core-private 0618 + 0619 +TARGET = hdr-openglwidget 0620 +TEMPLATE = app 0621 + 0622 +SOURCES += main.cpp \ 0623 + #hdr-openglwidget.cpp \ 0624 + openglprobeutils.cpp \ 0625 + KisGLImageWidget.cpp \ 0626 + KisGLImageF16.cpp \ 0627 + window.cpp 0628 + 0629 +HEADERS += \ 0630 +#hdr-openglwidget.h \ 0631 + openglprobeutils.h \ 0632 + KisGLImageWidget.h \ 0633 + KisGLImageF16.h \ 0634 + window.h 0635 + 0636 +RESOURCES += kis_gl_image_widget.qrc 0637 diff --git a/tests/manual/hdr-qopenglwidget/kis_gl_image_widget.frag b/tests/manual/hdr-qopenglwidget/kis_gl_image_widget.frag 0638 new file mode 100644 0639 index 0000000000..b57c657046 0640 --- /dev/null 0641 +++ b/tests/manual/hdr-qopenglwidget/kis_gl_image_widget.frag 0642 @@ -0,0 +1,23 @@ 0643 +#ifndef USE_OPENGLES 0644 +#define INATTR in 0645 +#define OUTATTR out 0646 +#define DECLARE_OUT_VAR out vec4 f_fragColor; 0647 +#define OUT_VAR f_fragColor 0648 +#define highp 0649 +#define texture2D texture 0650 +#else 0651 +#define INATTR varying 0652 +#define DECLARE_OUT_VAR 0653 +#define OUT_VAR gl_FragColor 0654 +#endif 0655 +// vertices data 0656 +INATTR highp vec4 textureCoordinates; 0657 +uniform sampler2D f_tileTexture; 0658 +DECLARE_OUT_VAR 0659 + 0660 +void main() 0661 +{ 0662 + // get the fragment color from the tile texture 0663 + highp vec4 color = texture2D(f_tileTexture, textureCoordinates.st); 0664 + OUT_VAR = vec4(color); 0665 +} 0666 diff --git a/tests/manual/hdr-qopenglwidget/kis_gl_image_widget.qrc b/tests/manual/hdr-qopenglwidget/kis_gl_image_widget.qrc 0667 new file mode 100644 0668 index 0000000000..ab5b5719a9 0669 --- /dev/null 0670 +++ b/tests/manual/hdr-qopenglwidget/kis_gl_image_widget.qrc 0671 @@ -0,0 +1,6 @@ 0672 +<RCC> 0673 + <qresource prefix="/"> 0674 + <file>kis_gl_image_widget.frag</file> 0675 + <file>kis_gl_image_widget.vert</file> 0676 + </qresource> 0677 +</RCC> 0678 diff --git a/tests/manual/hdr-qopenglwidget/kis_gl_image_widget.vert b/tests/manual/hdr-qopenglwidget/kis_gl_image_widget.vert 0679 new file mode 100644 0680 index 0000000000..9578f47945 0681 --- /dev/null 0682 +++ b/tests/manual/hdr-qopenglwidget/kis_gl_image_widget.vert 0683 @@ -0,0 +1,17 @@ 0684 +#ifndef USE_OPENGLES 0685 +#define INATTR in 0686 +#define OUTATTR out 0687 +#define highp 0688 +#else 0689 +#define INATTR attribute 0690 +#define OUTATTR varying 0691 +#endif 0692 +uniform mat4 viewProjectionMatrix; 0693 +INATTR highp vec3 vertexPosition; 0694 +INATTR highp vec2 texturePosition; 0695 +OUTATTR highp vec4 textureCoordinates; 0696 +void main() 0697 +{ 0698 + textureCoordinates = vec4(texturePosition.x, texturePosition.y, 0.0, 1.0); 0699 + gl_Position = viewProjectionMatrix * vec4(vertexPosition.x, vertexPosition.y, 0.0, 1.0); 0700 +} 0701 diff --git a/tests/manual/hdr-qopenglwidget/main.cpp b/tests/manual/hdr-qopenglwidget/main.cpp 0702 new file mode 100644 0703 index 0000000000..e517ef8579 0704 --- /dev/null 0705 +++ b/tests/manual/hdr-qopenglwidget/main.cpp 0706 @@ -0,0 +1,153 @@ 0707 +/**************************************************************************** 0708 +** 0709 +** Copyright (C) 2016 The Qt Company Ltd. 0710 +** Contact: https://www.qt.io/licensing/ 0711 +** 0712 +** This file is part of the test suite of the Qt Toolkit. 0713 +** 0714 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 0715 +** Commercial License Usage 0716 +** Licensees holding valid commercial Qt licenses may use this file in 0717 +** accordance with the commercial license agreement provided with the 0718 +** Software or, alternatively, in accordance with the terms contained in 0719 +** a written agreement between you and The Qt Company. For licensing terms 0720 +** and conditions see https://www.qt.io/terms-conditions. For further 0721 +** information use the contact form at https://www.qt.io/contact-us. 0722 +** 0723 +** GNU General Public License Usage 0724 +** Alternatively, this file may be used under the terms of the GNU 0725 +** General Public License version 3 as published by the Free Software 0726 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 0727 +** included in the packaging of this file. Please review the following 0728 +** information to ensure the GNU General Public License requirements will 0729 +** be met: https://www.gnu.org/licenses/gpl-3.0.html. 0730 +** 0731 +** $QT_END_LICENSE$ 0732 +** 0733 +****************************************************************************/ 0734 + 0735 +#include <QApplication> 0736 +#include "window.h" 0737 + 0738 +#include "openglprobeutils.h" 0739 +#include <QDebug> 0740 + 0741 +QSurfaceFormat generateSurfaceFormat(QSurfaceFormat::RenderableType renderer, 0742 + QSurfaceFormat::ColorSpace colorSpace, 0743 + int bitDepth) 0744 +{ 0745 + QSurfaceFormat format; 0746 +#ifdef Q_OS_MACOS 0747 + format.setVersion(3, 2); 0748 + format.setProfile(QSurfaceFormat::CoreProfile); 0749 +#else 0750 + format.setVersion(3, 0); 0751 + format.setProfile(QSurfaceFormat::CoreProfile); 0752 +#endif 0753 + format.setDepthBufferSize(24); 0754 + format.setStencilBufferSize(8); 0755 + 0756 + switch (bitDepth) { 0757 + case 8: 0758 + format.setRedBufferSize(8); 0759 + format.setGreenBufferSize(8); 0760 + format.setBlueBufferSize(8); 0761 + format.setAlphaBufferSize(8); 0762 + break; 0763 + case 10: 0764 + format.setRedBufferSize(10); 0765 + format.setGreenBufferSize(10); 0766 + format.setBlueBufferSize(10); 0767 + format.setAlphaBufferSize(2); 0768 + break; 0769 + case 16: 0770 + format.setRedBufferSize(16); 0771 + format.setGreenBufferSize(16); 0772 + format.setBlueBufferSize(16); 0773 + format.setAlphaBufferSize(16); 0774 + break; 0775 + default: 0776 + qFatal("Unsupported surface bit depth %d", bitDepth); 0777 + } 0778 + 0779 + format.setRenderableType(renderer); 0780 + format.setColorSpace(colorSpace); 0781 + 0782 + format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); 0783 + format.setSwapInterval(0); // Disable vertical refresh syncing 0784 + 0785 + return format; 0786 +} 0787 + 0788 +int main(int argc, char *argv[]) 0789 +{ 0790 + QVector<QSurfaceFormat> allFormats; 0791 + 0792 + QVector<QSurfaceFormat::RenderableType> availableRenderers; 0793 + availableRenderers << QSurfaceFormat::OpenGL; 0794 + availableRenderers << QSurfaceFormat::OpenGLES; 0795 + 0796 + for (QSurfaceFormat::RenderableType renderer : availableRenderers) { 0797 + allFormats << generateSurfaceFormat(renderer, QSurfaceFormat::sRGBColorSpace, 8); 0798 + allFormats << generateSurfaceFormat(renderer, QSurfaceFormat::bt2020PQColorSpace, 8); 0799 + allFormats << generateSurfaceFormat(renderer, QSurfaceFormat::sRGBColorSpace, 10); 0800 + allFormats << generateSurfaceFormat(renderer, QSurfaceFormat::bt2020PQColorSpace, 10); 0801 + allFormats << generateSurfaceFormat(renderer, QSurfaceFormat::scRGBColorSpace, 16); 0802 + } 0803 + 0804 + for (QSurfaceFormat format : allFormats) { 0805 + qDebug() << "Probing: " << format; 0806 + bool result = OpenGLProbeUtils::probeFormat(format, true); 0807 + qDebug() << " result:" << result; 0808 + } 0809 + 0810 + 0811 + if (argc > 1 && !strcmp(argv[1], "--sharecontext")) { 0812 + qDebug("Requesting all contexts to share"); 0813 + QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); 0814 + } 0815 + 0816 + QApplication a(argc, argv); 0817 + 0818 + QSurfaceFormat::RenderableType renderer = QSurfaceFormat::OpenGLES; 0819 + QSurfaceFormat::ColorSpace colorSpace = QSurfaceFormat::scRGBColorSpace; 0820 + int bitDepth = 16; 0821 + 0822 + 0823 + if (QCoreApplication::arguments().contains(QLatin1String("--scrgb"))) { 0824 + colorSpace = QSurfaceFormat::scRGBColorSpace; 0825 + bitDepth = 16; 0826 + } else if (QCoreApplication::arguments().contains(QLatin1String("--bt2020pq"))) { 0827 + colorSpace = QSurfaceFormat::bt2020PQColorSpace; 0828 + bitDepth = 10; 0829 + } else if (QCoreApplication::arguments().contains(QLatin1String("--srgb"))) { 0830 + colorSpace = QSurfaceFormat::sRGBColorSpace; 0831 + bitDepth = 8; 0832 + } 0833 + 0834 + if (QCoreApplication::arguments().contains(QLatin1String("--opengl"))) { 0835 + renderer = QSurfaceFormat::OpenGL; 0836 + } else if (QCoreApplication::arguments().contains(QLatin1String("--opengles"))) { 0837 + renderer = QSurfaceFormat::OpenGLES; 0838 + } 0839 + 0840 + QSurfaceFormat format = generateSurfaceFormat(renderer, colorSpace, bitDepth); 0841 + 0842 + if (QCoreApplication::arguments().contains(QLatin1String("--multisample"))) { 0843 + format.setSamples(4); 0844 + } 0845 + 0846 + if (format.renderableType() == QSurfaceFormat::OpenGL) { 0847 + QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true); 0848 + } else if (format.renderableType() == QSurfaceFormat::OpenGLES) { 0849 + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); 0850 + } 0851 + 0852 + qDebug() << "Requesting" << format.renderableType() << format; 0853 + QSurfaceFormat::setDefaultFormat(format); 0854 + 0855 + Window window; 0856 + window.show(); 0857 + 0858 + return a.exec(); 0859 +} 0860 diff --git a/tests/manual/hdr-qopenglwidget/openglprobeutils.cpp b/tests/manual/hdr-qopenglwidget/openglprobeutils.cpp 0861 new file mode 100644 0862 index 0000000000..687cc08904 0863 --- /dev/null 0864 +++ b/tests/manual/hdr-qopenglwidget/openglprobeutils.cpp 0865 @@ -0,0 +1,139 @@ 0866 +/**************************************************************************** 0867 +** 0868 +** Copyright (C) 2019 The Qt Company Ltd. 0869 +** Contact: https://www.qt.io/licensing/ 0870 +** 0871 +** This file is part of the test suite of the Qt Toolkit. 0872 +** 0873 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 0874 +** Commercial License Usage 0875 +** Licensees holding valid commercial Qt licenses may use this file in 0876 +** accordance with the commercial license agreement provided with the 0877 +** Software or, alternatively, in accordance with the terms contained in 0878 +** a written agreement between you and The Qt Company. For licensing terms 0879 +** and conditions see https://www.qt.io/terms-conditions. For further 0880 +** information use the contact form at https://www.qt.io/contact-us. 0881 +** 0882 +** GNU General Public License Usage 0883 +** Alternatively, this file may be used under the terms of the GNU 0884 +** General Public License version 3 as published by the Free Software 0885 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 0886 +** included in the packaging of this file. Please review the following 0887 +** information to ensure the GNU General Public License requirements will 0888 +** be met: https://www.gnu.org/licenses/gpl-3.0.html. 0889 +** 0890 +** $QT_END_LICENSE$ 0891 +** 0892 +****************************************************************************/ 0893 + 0894 +#include "openglprobeutils.h" 0895 + 0896 +#include <QApplication> 0897 +#include <QSurfaceFormat> 0898 +#include <QOpenGLContext> 0899 +#include <QDebug> 0900 +#include <QWindow> 0901 + 0902 +namespace OpenGLProbeUtils { 0903 + 0904 +namespace { 0905 + 0906 +struct AppAttributeSetter 0907 +{ 0908 + AppAttributeSetter(Qt::ApplicationAttribute attribute, bool useOpenGLES) 0909 + : m_attribute(attribute), 0910 + m_oldValue(QCoreApplication::testAttribute(attribute)) 0911 + { 0912 + QCoreApplication::setAttribute(attribute, useOpenGLES); 0913 + } 0914 + 0915 + ~AppAttributeSetter() { 0916 + QCoreApplication::setAttribute(m_attribute, m_oldValue); 0917 + } 0918 + 0919 +private: 0920 + Qt::ApplicationAttribute m_attribute; 0921 + bool m_oldValue = false; 0922 +}; 0923 + 0924 +struct SurfaceFormatSetter 0925 +{ 0926 + SurfaceFormatSetter(const QSurfaceFormat &format) 0927 + : m_oldFormat(QSurfaceFormat::defaultFormat()) 0928 + { 0929 + QSurfaceFormat::setDefaultFormat(format); 0930 + } 0931 + 0932 + ~SurfaceFormatSetter() { 0933 + QSurfaceFormat::setDefaultFormat(m_oldFormat); 0934 + } 0935 + 0936 +private: 0937 + QSurfaceFormat m_oldFormat; 0938 +}; 0939 + 0940 +} 0941 + 0942 +bool fuzzyCompareColorSpaces(const QSurfaceFormat::ColorSpace &lhs, const QSurfaceFormat::ColorSpace &rhs) 0943 +{ 0944 + return lhs == rhs || 0945 + ((lhs == QSurfaceFormat::DefaultColorSpace || 0946 + lhs == QSurfaceFormat::sRGBColorSpace) && 0947 + (rhs == QSurfaceFormat::DefaultColorSpace || 0948 + rhs == QSurfaceFormat::sRGBColorSpace)); 0949 +} 0950 + 0951 +bool probeFormat(const QSurfaceFormat &format, bool adjustGlobalState) 0952 +{ 0953 + QScopedPointer<AppAttributeSetter> sharedContextSetter; 0954 + QScopedPointer<AppAttributeSetter> glSetter; 0955 + QScopedPointer<AppAttributeSetter> glesSetter; 0956 + QScopedPointer<SurfaceFormatSetter> formatSetter; 0957 + QScopedPointer<QApplication> application; 0958 + 0959 + if (adjustGlobalState) { 0960 + sharedContextSetter.reset(new AppAttributeSetter(Qt::AA_ShareOpenGLContexts, false)); 0961 + 0962 + if (format.renderableType() != QSurfaceFormat::DefaultRenderableType) { 0963 + glSetter.reset(new AppAttributeSetter(Qt::AA_UseDesktopOpenGL, format.renderableType() != QSurfaceFormat::OpenGLES)); 0964 + glesSetter.reset(new AppAttributeSetter(Qt::AA_UseOpenGLES, format.renderableType() == QSurfaceFormat::OpenGLES)); 0965 + } 0966 + 0967 + formatSetter.reset(new SurfaceFormatSetter(format)); 0968 + 0969 + int argc = 1; 0970 + QByteArray data("krita"); 0971 + char *argv = data.data(); 0972 + application.reset(new QApplication(argc, &argv)); 0973 + } 0974 + 0975 + QWindow surface; 0976 + surface.setFormat(format); 0977 + surface.setSurfaceType(QSurface::OpenGLSurface); 0978 + surface.create(); 0979 + QOpenGLContext context; 0980 + context.setFormat(format); 0981 + 0982 + 0983 + if (!context.create()) { 0984 + qCritical() << "OpenGL context cannot be created"; 0985 + return false; 0986 + } 0987 + if (!context.isValid()) { 0988 + qCritical() << "OpenGL context is not valid while checking Qt's OpenGL status"; 0989 + return false; 0990 + } 0991 + if (!context.makeCurrent(&surface)) { 0992 + qCritical() << "OpenGL context cannot be made current"; 0993 + return false; 0994 + } 0995 + 0996 + if (!fuzzyCompareColorSpaces(context.format().colorSpace(), format.colorSpace())) { 0997 + qCritical() << "Failed to create an OpenGL context with requested color space. Requested:" << format.colorSpace() << "Actual:" << context.format().colorSpace(); 0998 + return false; 0999 + } 1000 + 1001 + return true; 1002 +} 1003 + 1004 +} 1005 diff --git a/tests/manual/hdr-qopenglwidget/openglprobeutils.h b/tests/manual/hdr-qopenglwidget/openglprobeutils.h 1006 new file mode 100644 1007 index 0000000000..3b2f1ec3d0 1008 --- /dev/null 1009 +++ b/tests/manual/hdr-qopenglwidget/openglprobeutils.h 1010 @@ -0,0 +1,42 @@ 1011 +/**************************************************************************** 1012 +** 1013 +** Copyright (C) 2019 The Qt Company Ltd. 1014 +** Contact: https://www.qt.io/licensing/ 1015 +** 1016 +** This file is part of the test suite of the Qt Toolkit. 1017 +** 1018 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 1019 +** Commercial License Usage 1020 +** Licensees holding valid commercial Qt licenses may use this file in 1021 +** accordance with the commercial license agreement provided with the 1022 +** Software or, alternatively, in accordance with the terms contained in 1023 +** a written agreement between you and The Qt Company. For licensing terms 1024 +** and conditions see https://www.qt.io/terms-conditions. For further 1025 +** information use the contact form at https://www.qt.io/contact-us. 1026 +** 1027 +** GNU General Public License Usage 1028 +** Alternatively, this file may be used under the terms of the GNU 1029 +** General Public License version 3 as published by the Free Software 1030 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 1031 +** included in the packaging of this file. Please review the following 1032 +** information to ensure the GNU General Public License requirements will 1033 +** be met: https://www.gnu.org/licenses/gpl-3.0.html. 1034 +** 1035 +** $QT_END_LICENSE$ 1036 +** 1037 +****************************************************************************/ 1038 + 1039 +#ifndef OPENGLPROBEUTILS_H 1040 +#define OPENGLPROBEUTILS_H 1041 + 1042 +#include <QSurfaceFormat> 1043 + 1044 +namespace OpenGLProbeUtils 1045 +{ 1046 + 1047 +bool fuzzyCompareColorSpaces(const QSurfaceFormat::ColorSpace &lhs, const QSurfaceFormat::ColorSpace &rhs); 1048 +bool probeFormat(const QSurfaceFormat &format, bool adjustGlobalState); 1049 + 1050 +}; 1051 + 1052 +#endif // OPENGLPROBEUTILS_H 1053 diff --git a/tests/manual/hdr-qopenglwidget/window.cpp b/tests/manual/hdr-qopenglwidget/window.cpp 1054 new file mode 100644 1055 index 0000000000..5729660a4f 1056 --- /dev/null 1057 +++ b/tests/manual/hdr-qopenglwidget/window.cpp 1058 @@ -0,0 +1,219 @@ 1059 +/**************************************************************************** 1060 +** 1061 +** Copyright (C) 2019 The Qt Company Ltd. 1062 +** Contact: https://www.qt.io/licensing/ 1063 +** 1064 +** This file is part of the test suite of the Qt Toolkit. 1065 +** 1066 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 1067 +** Commercial License Usage 1068 +** Licensees holding valid commercial Qt licenses may use this file in 1069 +** accordance with the commercial license agreement provided with the 1070 +** Software or, alternatively, in accordance with the terms contained in 1071 +** a written agreement between you and The Qt Company. For licensing terms 1072 +** and conditions see https://www.qt.io/terms-conditions. For further 1073 +** information use the contact form at https://www.qt.io/contact-us. 1074 +** 1075 +** GNU General Public License Usage 1076 +** Alternatively, this file may be used under the terms of the GNU 1077 +** General Public License version 3 as published by the Free Software 1078 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 1079 +** included in the packaging of this file. Please review the following 1080 +** information to ensure the GNU General Public License requirements will 1081 +** be met: https://www.gnu.org/licenses/gpl-3.0.html. 1082 +** 1083 +** $QT_END_LICENSE$ 1084 +** 1085 +****************************************************************************/ 1086 + 1087 +#include "window.h" 1088 + 1089 +#include "KisGLImageWidget.h" 1090 +#include "KisGLImageF16.h" 1091 + 1092 +#include <cmath> 1093 + 1094 +#include <QMenu> 1095 +#include <QMenuBar> 1096 +#include <QToolBar> 1097 +#include <QAction> 1098 +#include <QDebug> 1099 + 1100 +#include <QVBoxLayout> 1101 +#include <QHBoxLayout> 1102 +#include <QLabel> 1103 + 1104 +#include <cmath> 1105 + 1106 + 1107 +Window::Window() 1108 +{ 1109 + setWindowTitle("16 bit float QOpenGLWidget test"); 1110 + QMenu *menu = menuBar()->addMenu("File"); 1111 + QToolBar *tb = addToolBar("File"); 1112 + 1113 + m_quitAction = new QAction("Quit", this); 1114 + connect(m_quitAction, SIGNAL(triggered(bool)), this, SLOT(close())); 1115 + menu->addAction(m_quitAction); 1116 + tb->addAction(m_quitAction); 1117 + 1118 + QWidget *centralWidget = new QWidget(this); 1119 + QVBoxLayout *layout = new QVBoxLayout(centralWidget); 1120 + 1121 + QHBoxLayout *hLayout = new QHBoxLayout(centralWidget); 1122 + 1123 + m_imageWidget = new KisGLImageWidget(QSurfaceFormat::scRGBColorSpace, this); 1124 + m_imageWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); 1125 + hLayout->addWidget(m_imageWidget, 0, Qt::AlignLeft); 1126 + 1127 + m_imageWidgetSdr = new KisGLImageWidget(QSurfaceFormat::scRGBColorSpace, this); 1128 + m_imageWidgetSdr->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); 1129 + hLayout->addWidget(m_imageWidgetSdr, 0, Qt::AlignLeft); 1130 + 1131 + QImage image(QSize(255,255), QImage::Format_ARGB32); 1132 + image.fill(Qt::red); 1133 + 1134 + QLabel *label = new QLabel(this); 1135 + label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); 1136 + hLayout->addWidget(label, 0, Qt::AlignLeft); 1137 + 1138 + m_imageWidget->loadImage(initializeImage(false)); 1139 + m_imageWidgetSdr->loadImage(initializeImage(true)); 1140 + label->setPixmap(QPixmap::fromImage(convertToQImage(m_imageWidget->image()))); 1141 + 1142 + layout->addLayout(hLayout); 1143 + 1144 + m_lblContextInfo = new QLabel(this); 1145 + layout->addWidget(m_lblContextInfo); 1146 + 1147 + QLabel *lblNotes = new QLabel(this); 1148 + lblNotes->setWordWrap(true); 1149 + lblNotes->setText("* In SDR display mode all three images should look exactly the same\n" 1150 + "* In HDR display mode: image 1 should look brighter than the others " 1151 + "(it is HDR), images 2 and 3 should have exactly the same brightness and look"); 1152 + 1153 + layout->addWidget(lblNotes); 1154 + 1155 + centralWidget->setLayout(layout); 1156 + setCentralWidget(centralWidget); 1157 +} 1158 + 1159 +inline qfloat16 floatToFloat16(float x) { 1160 + qfloat16 result; 1161 + qFloatToFloat16(&result, &x, 1); 1162 + return result; 1163 +} 1164 + 1165 +inline float float16ToFloat(qfloat16 x) { 1166 + float result; 1167 + qFloatFromFloat16(&result, &x, 1); 1168 + return result; 1169 +} 1170 + 1171 + 1172 +KisGLImageF16 Window::initializeImage(bool cropRange) const 1173 +{ 1174 + const int size = 256; 1175 + KisGLImageF16 image(size, size); 1176 + image.clearPixels(); 1177 + qfloat16 *pixelPtr = image.data(); 1178 + 1179 + for (int y = 0; y < size; y++) { 1180 + for (int x = 0; x < size; x++) { 1181 + qfloat16 *pxl = reinterpret_cast<qfloat16*>(pixelPtr); 1182 + 1183 + float hdrRedValue = 25.0f * std::pow(float(x) / size, 5.0f); 1184 + 1185 + if (cropRange) { 1186 + hdrRedValue = qMin(hdrRedValue, 1.0f); 1187 + } 1188 + 1189 + pxl[0] = floatToFloat16(hdrRedValue); 1190 + 1191 + if (y > size / 2) { 1192 + const float portion = (float(y) / size - 0.5f) * 2.0f; 1193 + const float value = qMin(1.0f, 0.2f + 1.8f * portion); 1194 + 1195 + pxl[1] = floatToFloat16(value); 1196 + pxl[2] = floatToFloat16(value); 1197 + } else { 1198 + pxl[1] = floatToFloat16(0.2); 1199 + pxl[2] = floatToFloat16(0.2); 1200 + } 1201 + 1202 + pxl[3] = floatToFloat16(1.0); 1203 + 1204 + pixelPtr += 4; 1205 + } 1206 + } 1207 + 1208 + return image; 1209 +} 1210 + 1211 +inline float linearToSRGB(float value) 1212 +{ 1213 + if (value <= 0.0f) { 1214 + value = 0.0f; 1215 + } else if (value < 0.0031308f) { 1216 + value = value * 12.92f; 1217 + } else if (value < 1.0f) { 1218 + value = std::pow(value, 0.41666f) * 1.055f - 0.055f; 1219 + } else { 1220 + value = 1.0f; 1221 + } 1222 + return value; 1223 +} 1224 + 1225 +QImage Window::convertToQImage(const KisGLImageF16 &image) const 1226 +{ 1227 + const QSize size = image.size(); 1228 + const qfloat16 *pixelPtr = image.constData(); 1229 + 1230 + QImage qimage(size, QImage::Format_ARGB32); 1231 + quint8 *qimagePixelPtr = qimage.bits(); 1232 + 1233 + 1234 + for (int y = 0; y < size.height(); y++) { 1235 + for (int x = 0; x < size.width(); x++) { 1236 + const qfloat16 *srcPxl = pixelPtr; 1237 + quint8 *dstPxl = qimagePixelPtr; 1238 + 1239 + auto convertChannel = [] (qfloat16 x) { 1240 + float value = float16ToFloat(x); 1241 + return quint8(linearToSRGB(value) * 255.0f); 1242 + }; 1243 + 1244 + dstPxl[0] = convertChannel(srcPxl[2]); 1245 + dstPxl[1] = convertChannel(srcPxl[1]); 1246 + dstPxl[2] = convertChannel(srcPxl[0]); 1247 + dstPxl[3] = convertChannel(srcPxl[3]); 1248 + 1249 + pixelPtr += 4; 1250 + qimagePixelPtr += 4; 1251 + } 1252 + } 1253 + 1254 + return qimage; 1255 +} 1256 + 1257 +void Window::updateSurfaceInfo() 1258 +{ 1259 + const QSurfaceFormat format = m_imageWidget->context()->format(); 1260 + 1261 + m_lblContextInfo->setText( 1262 + QString("renderer: %1\ncolorSpace: %2\n\n") 1263 + .arg(format.renderableType() == QSurfaceFormat::OpenGL ? "openGL" : "openGL ES") 1264 + .arg(format.colorSpace() == QSurfaceFormat::sRGBColorSpace ? "sRGB" : 1265 + format.colorSpace() == QSurfaceFormat::scRGBColorSpace ? "scRGB" : 1266 + format.colorSpace() == QSurfaceFormat::bt2020PQColorSpace ? "Bt. 2020 PQ" : 1267 + "unknown")); 1268 +} 1269 + 1270 +void Window::showEvent(QShowEvent *ev) 1271 +{ 1272 + QMainWindow::showEvent(ev); 1273 + 1274 + if (m_lblContextInfo->text().isEmpty()) { 1275 + updateSurfaceInfo(); 1276 + } 1277 +} 1278 diff --git a/tests/manual/hdr-qopenglwidget/window.h b/tests/manual/hdr-qopenglwidget/window.h 1279 new file mode 100644 1280 index 0000000000..fd8e5c0393 1281 --- /dev/null 1282 +++ b/tests/manual/hdr-qopenglwidget/window.h 1283 @@ -0,0 +1,69 @@ 1284 +/**************************************************************************** 1285 +** 1286 +** Copyright (C) 2019 The Qt Company Ltd. 1287 +** Contact: https://www.qt.io/licensing/ 1288 +** 1289 +** This file is part of the test suite of the Qt Toolkit. 1290 +** 1291 +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ 1292 +** Commercial License Usage 1293 +** Licensees holding valid commercial Qt licenses may use this file in 1294 +** accordance with the commercial license agreement provided with the 1295 +** Software or, alternatively, in accordance with the terms contained in 1296 +** a written agreement between you and The Qt Company. For licensing terms 1297 +** and conditions see https://www.qt.io/terms-conditions. For further 1298 +** information use the contact form at https://www.qt.io/contact-us. 1299 +** 1300 +** GNU General Public License Usage 1301 +** Alternatively, this file may be used under the terms of the GNU 1302 +** General Public License version 3 as published by the Free Software 1303 +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT 1304 +** included in the packaging of this file. Please review the following 1305 +** information to ensure the GNU General Public License requirements will 1306 +** be met: https://www.gnu.org/licenses/gpl-3.0.html. 1307 +** 1308 +** $QT_END_LICENSE$ 1309 +** 1310 +****************************************************************************/ 1311 + 1312 +#ifndef WINDOW_H 1313 +#define WINDOW_H 1314 + 1315 +#include <QMainWindow> 1316 + 1317 +class QAction; 1318 + 1319 +class GLWidget; 1320 +class KisGLImageWidget; 1321 +class KisGLImageF16; 1322 +class QLabel; 1323 + 1324 +class Window : public QMainWindow 1325 +{ 1326 + Q_OBJECT 1327 + 1328 +public: 1329 + Window(); 1330 + 1331 + void showEvent(QShowEvent *ev) override; 1332 + 1333 +public Q_SLOTS: 1334 + 1335 + 1336 +private: 1337 + KisGLImageF16 initializeImage(bool cropRange) const; 1338 + QImage convertToQImage(const KisGLImageF16 &image) const; 1339 + 1340 + void updateSurfaceInfo(); 1341 + 1342 +private: 1343 + GLWidget *m_glWidget {0}; 1344 + QAction *m_openAction {0}; 1345 + QAction *m_quitAction {0}; 1346 + KisGLImageWidget *m_imageWidget; 1347 + KisGLImageWidget *m_imageWidgetSdr; 1348 + QLabel *m_lblContextInfo; 1349 + 1350 +}; 1351 + 1352 +#endif 1353 diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro 1354 index ab00a5ef60..b202ed0431 100644 1355 --- a/tests/manual/manual.pro 1356 +++ b/tests/manual/manual.pro 1357 @@ -59,7 +59,7 @@ qtabbar 1358 1359 qtConfig(opengl) { 1360 SUBDIRS += qopengltextureblitter 1361 - qtConfig(egl): SUBDIRS += qopenglcontext 1362 + qtConfig(egl): SUBDIRS += qopenglcontext hdr-qopenglwidget 1363 } 1364 1365 win32: SUBDIRS -= network_remote_stresstest network_stresstest 1366 -- 1367 2.20.1.windows.1 1368