summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-08 17:30:06 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-03-15 16:52:21 +0000
commit91e13af7e1056a7bad83eb34ebf63fdd45e24bea (patch)
treece3c3c89d021bc934bf0c64477e0f74357e84a58
parentd5bffb5125da23718e8098441b4a4269a5cf2f33 (diff)
YUV colorspace adaptations
Switch to using Chromium's Colorspace class and its generated shader code instead of our own enums. Change-Id: I89ee96adf68e2421efa2350cb0b78ce0fea7221f Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
-rw-r--r--src/core/delegated_frame_node.cpp24
-rw-r--r--src/core/yuv_video_node.cpp205
-rw-r--r--src/core/yuv_video_node.h15
3 files changed, 90 insertions, 154 deletions
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index 149bd3b5e..51d69fd08 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -196,7 +196,7 @@ public:
virtual void setupDebugBorderNode(QSGGeometry *, QSGFlatColorMaterial *, QSGNode *) = 0;
virtual void setupYUVVideoNode(QSGTexture *, QSGTexture *, QSGTexture *, QSGTexture *,
const QRectF &, const QRectF &, const QSizeF &, const QSizeF &,
- YUVVideoMaterial::ColorSpace, float, float, const QRectF &,
+ gfx::ColorSpace, float, float, const QRectF &,
QSGNode *) = 0;
#ifdef GL_OES_EGL_image_external
virtual void setupStreamVideoNode(MailboxTexture *, const QRectF &,
@@ -283,7 +283,7 @@ public:
void setupYUVVideoNode(QSGTexture *, QSGTexture *, QSGTexture *, QSGTexture *,
const QRectF &, const QRectF &, const QSizeF &, const QSizeF &,
- YUVVideoMaterial::ColorSpace, float, float, const QRectF &,
+ gfx::ColorSpace, float, float, const QRectF &,
QSGNode *) override
{
Q_UNREACHABLE();
@@ -384,7 +384,7 @@ public:
void setupYUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture,
QSGTexture *aTexture, const QRectF &yaTexCoordRect,
const QRectF &uvTexCoordRect, const QSizeF &yaTexSize,
- const QSizeF &uvTexSize, YUVVideoMaterial::ColorSpace colorspace,
+ const QSizeF &uvTexSize, gfx::ColorSpace colorspace,
float rMul, float rOff, const QRectF &rect,
QSGNode *layerChain) override
{
@@ -751,20 +751,6 @@ void DelegatedFrameNode::preprocess()
}
}
-static YUVVideoMaterial::ColorSpace toQt(viz::YUVVideoDrawQuad::ColorSpace color_space)
-{
- switch (color_space) {
- case viz::YUVVideoDrawQuad::REC_601:
- return YUVVideoMaterial::REC_601;
- case viz::YUVVideoDrawQuad::REC_709:
- return YUVVideoMaterial::REC_709;
- case viz::YUVVideoDrawQuad::JPEG:
- return YUVVideoMaterial::JPEG;
- }
- Q_UNREACHABLE();
- return YUVVideoMaterial::REC_601;
-}
-
static bool areSharedQuadStatesEqual(const viz::SharedQuadState *layerState,
const viz::SharedQuadState *prevLayerState)
{
@@ -1186,7 +1172,7 @@ void DelegatedFrameNode::handleQuad(
initAndHoldTexture(vResource, quad->ShouldDrawWithBlending()),
aResource ? initAndHoldTexture(aResource, quad->ShouldDrawWithBlending()) : 0,
toQt(vquad->ya_tex_coord_rect), toQt(vquad->uv_tex_coord_rect),
- toQt(vquad->ya_tex_size), toQt(vquad->uv_tex_size), toQt(vquad->color_space),
+ toQt(vquad->ya_tex_size), toQt(vquad->uv_tex_size), vquad->video_color_space,
vquad->resource_multiplier, vquad->resource_offset, toQt(quad->rect),
currentLayerChain);
break;
@@ -1261,7 +1247,7 @@ void DelegatedFrameNode::fetchAndSyncMailboxes(QList<MailboxTexture *> &mailboxe
for (MailboxTexture *mailboxTexture : qAsConst(mailboxesToFetch)) {
gpu::SyncToken &syncToken = mailboxTexture->mailboxHolder().sync_token;
const auto task = base::Bind(&DelegatedFrameNode::pullTexture, this, mailboxTexture);
- if (!syncPointManager->WaitOutOfOrderNonThreadSafe(syncToken, gpuMessageLoop->task_runner(), std::move(task)))
+ if (!syncPointManager->WaitOutOfOrder(syncToken, std::move(task)))
mailboxesToPull.append(mailboxTexture);
}
if (!mailboxesToPull.isEmpty()) {
diff --git a/src/core/yuv_video_node.cpp b/src/core/yuv_video_node.cpp
index 81afa5674..ebde2e005 100644
--- a/src/core/yuv_video_node.cpp
+++ b/src/core/yuv_video_node.cpp
@@ -48,11 +48,49 @@
#include <QtGui/qopenglfunctions.h>
#include <QtQuick/qsgtexture.h>
+#include "ui/gfx/color_space.h"
+#include "ui/gfx/color_transform.h"
+
namespace QtWebEngineCore {
class YUVVideoMaterialShader : public QSGMaterialShader
{
public:
+ YUVVideoMaterialShader(const gfx::ColorSpace &colorSpace) : m_colorSpace(colorSpace)
+ {
+ static const char *shaderHead =
+ "varying mediump vec2 v_yaTexCoord;\n"
+ "varying mediump vec2 v_uvTexCoord;\n"
+ "uniform sampler2D y_texture;\n"
+ "uniform sampler2D u_texture;\n"
+ "uniform sampler2D v_texture;\n"
+ "uniform mediump float alpha;\n"
+ "uniform mediump vec4 ya_clamp_rect;\n"
+ "uniform mediump vec4 uv_clamp_rect;\n";
+ static const char *shader =
+ "void main() {\n"
+ " mediump vec2 ya_clamped =\n"
+ " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
+ " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
+ " mediump vec2 uv_clamped =\n"
+ " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
+ " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
+ " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
+ " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);\n"
+ " mediump vec3 rgb = DoColorConversion(yuv);\n"
+ " gl_FragColor = vec4(rgb, 1.0) * alpha;\n"
+ "}";
+ gfx::ColorSpace dst = gfx::ColorSpace::CreateSRGB();
+ std::unique_ptr<gfx::ColorTransform> transform =
+ gfx::ColorTransform::NewColorTransform(m_colorSpace, dst, gfx::ColorTransform::Intent::INTENT_PERCEPTUAL);
+
+ QByteArray header(shaderHead);
+ if (QOpenGLContext::currentContext()->isOpenGLES())
+ header = QByteArray("precision mediump float;\n") + header;
+
+ m_csShader = QByteArray::fromStdString(transform->GetShaderSource());
+ m_fragmentShader = header + m_csShader + QByteArray(shader);
+ }
void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
char const *const *attributeNames() const override {
@@ -86,31 +124,7 @@ protected:
}
const char *fragmentShader() const override {
- // Keep in sync with logic in FragmentShader in components/viz/service/display/shader.cc
- static const char *shader =
- "varying mediump vec2 v_yaTexCoord;\n"
- "varying mediump vec2 v_uvTexCoord;\n"
- "uniform sampler2D y_texture;\n"
- "uniform sampler2D u_texture;\n"
- "uniform sampler2D v_texture;\n"
- "uniform mediump float alpha;\n"
- "uniform mediump vec3 yuv_adj;\n"
- "uniform mediump mat3 yuv_matrix;\n"
- "uniform mediump vec4 ya_clamp_rect;\n"
- "uniform mediump vec4 uv_clamp_rect;\n"
- "void main() {\n"
- " mediump vec2 ya_clamped =\n"
- " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
- " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
- " mediump vec2 uv_clamped =\n"
- " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
- " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
- " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
- " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n"
- " mediump vec3 rgb = yuv_matrix * yuv;\n"
- " gl_FragColor = vec4(rgb, 1.0) * alpha;\n"
- "}";
- return shader;
+ return m_fragmentShader.constData();
}
void initialize() override {
@@ -129,6 +143,7 @@ protected:
m_id_opacity = program()->uniformLocation("alpha");
}
+ gfx::ColorSpace m_colorSpace;
int m_id_matrix;
int m_id_yaTexScale;
int m_id_uvTexScale;
@@ -142,43 +157,47 @@ protected:
int m_id_yuvMatrix;
int m_id_yuvAdjust;
int m_id_opacity;
+ QByteArray m_csShader;
+ QByteArray m_fragmentShader;
};
class YUVAVideoMaterialShader : public YUVVideoMaterialShader
{
- void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
-
-protected:
- const char *fragmentShader() const override {
- // Keep in sync with cc::FragmentShaderYUVAVideo
+public:
+ YUVAVideoMaterialShader(const gfx::ColorSpace &colorSpace) : YUVVideoMaterialShader(colorSpace)
+ {
+ static const char *shaderHead =
+ "varying mediump vec2 v_yaTexCoord;\n"
+ "varying mediump vec2 v_uvTexCoord;\n"
+ "uniform sampler2D y_texture;\n"
+ "uniform sampler2D u_texture;\n"
+ "uniform sampler2D v_texture;\n"
+ "uniform sampler2D a_texture;\n"
+ "uniform mediump float alpha;\n"
+ "uniform mediump vec4 ya_clamp_rect;\n"
+ "uniform mediump vec4 uv_clamp_rect;\n";
static const char *shader =
- "varying mediump vec2 v_yaTexCoord;\n"
- "varying mediump vec2 v_uvTexCoord;\n"
- "uniform sampler2D y_texture;\n"
- "uniform sampler2D u_texture;\n"
- "uniform sampler2D v_texture;\n"
- "uniform sampler2D a_texture;\n"
- "uniform mediump float alpha;\n"
- "uniform mediump vec3 yuv_adj;\n"
- "uniform mediump mat3 yuv_matrix;\n"
- "uniform mediump vec4 ya_clamp_rect;\n"
- "uniform mediump vec4 uv_clamp_rect;\n"
- "void main() {\n"
- " mediump vec2 ya_clamped =\n"
- " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
- " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
- " mediump vec2 uv_clamped =\n"
- " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
- " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
- " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
- " mediump float a_raw = texture2D(a_texture, ya_clamped).x;\n"
- " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned) + yuv_adj;\n"
- " mediump vec3 rgb = yuv_matrix * yuv;\n"
- " gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);\n"
- "}";
- return shader;
+ "void main() {\n"
+ " mediump vec2 ya_clamped =\n"
+ " max(ya_clamp_rect.xy, min(ya_clamp_rect.zw, v_yaTexCoord));\n"
+ " mediump float y_raw = texture2D(y_texture, ya_clamped).x;\n"
+ " mediump vec2 uv_clamped =\n"
+ " max(uv_clamp_rect.xy, min(uv_clamp_rect.zw, v_uvTexCoord));\n"
+ " mediump float u_unsigned = texture2D(u_texture, uv_clamped).x;\n"
+ " mediump float v_unsigned = texture2D(v_texture, uv_clamped).x;\n"
+ " mediump float a_raw = texture2D(a_texture, ya_clamped).x;\n"
+ " mediump vec3 yuv = vec3(y_raw, u_unsigned, v_unsigned);\n"
+ " mediump vec3 rgb = DoColorConversion(yuv);\n"
+ " gl_FragColor = vec4(rgb, 1.0) * (alpha * a_raw);\n"
+ "}";
+ QByteArray header(shaderHead);
+ if (QOpenGLContext::currentContext()->isOpenGLES())
+ header = QByteArray("precision mediump float;\n") + header;
+ m_fragmentShader = header + m_csShader + QByteArray(shader);
}
+ void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override;
+protected:
void initialize() override {
// YUVVideoMaterialShader has a subset of the uniforms.
YUVVideoMaterialShader::initialize();
@@ -231,72 +250,6 @@ void YUVVideoMaterialShader::updateState(const RenderState &state, QSGMaterial *
program()->setUniformValue(m_id_yaClampRect, yaClampV);
program()->setUniformValue(m_id_uvClampRect, uvClampV);
- // These values are magic numbers that are used in the transformation from YUV
- // to RGB color values. They are taken from the following webpage:
- // http://www.fourcc.org/fccyvrgb.php
- const float yuv_to_rgb_rec601[9] = {
- 1.164f, 0.0f, 1.596f,
- 1.164f, -.391f, -.813f,
- 1.164f, 2.018f, 0.0f,
- };
- const float yuv_to_rgb_rec709[9] = {
- 1.164f, 0.0f, 1.793f,
- 1.164f, -0.213f, -0.533f,
- 1.164f, 2.112f, 0.0f,
- };
- const float yuv_to_rgb_jpeg[9] = {
- 1.f, 0.0f, 1.402f,
- 1.f, -.34414f, -.71414f,
- 1.f, 1.772f, 0.0f,
- };
-
- // These values map to 16, 128, and 128 respectively, and are computed
- // as a fraction over 256 (e.g. 16 / 256 = 0.0625).
- // They are used in the YUV to RGBA conversion formula:
- // Y - 16 : Gives 16 values of head and footroom for overshooting
- // U - 128 : Turns unsigned U into signed U [-128,127]
- // V - 128 : Turns unsigned V into signed V [-128,127]
- const float yuv_adjust_constrained[3] = {
- -0.0625f, -0.5f, -0.5f,
- };
-
- // Same as above, but without the head and footroom.
- const float yuv_adjust_full[3] = {
- 0.0f, -0.5f, -0.5f,
- };
-
- const float *yuv_to_rgb = 0;
- const float *yuv_adjust = 0;
-
- switch (mat->m_colorSpace) {
- case YUVVideoMaterial::REC_601:
- yuv_to_rgb = yuv_to_rgb_rec601;
- yuv_adjust = yuv_adjust_constrained;
- break;
- case YUVVideoMaterial::REC_709:
- yuv_to_rgb = yuv_to_rgb_rec709;
- yuv_adjust = yuv_adjust_constrained;
- break;
- case YUVVideoMaterial::JPEG:
- yuv_to_rgb = yuv_to_rgb_jpeg;
- yuv_adjust = yuv_adjust_full;
- break;
- }
-
- float yuv_to_rgb_multiplied[9];
- float yuv_adjust_with_offset[3];
-
- for (int i = 0; i < 9; ++i)
- yuv_to_rgb_multiplied[i] = yuv_to_rgb[i] * mat->m_resourceMultiplier;
-
- for (int i = 0; i < 3; ++i)
- yuv_adjust_with_offset[i] =
- yuv_adjust[i] / mat->m_resourceMultiplier - mat->m_resourceOffset;
-
-
- program()->setUniformValue(m_id_yuvMatrix, QMatrix3x3(yuv_to_rgb_multiplied));
- program()->setUniformValue(m_id_yuvAdjust, QVector3D(yuv_adjust_with_offset[0], yuv_adjust_with_offset[1], yuv_adjust_with_offset[2]));
-
if (state.isOpacityDirty())
program()->setUniformValue(m_id_opacity, state.opacity());
@@ -323,7 +276,7 @@ void YUVAVideoMaterialShader::updateState(const RenderState &state, QSGMaterial
YUVVideoMaterial::YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture,
const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- YUVVideoMaterial::ColorSpace colorspace,
+ const gfx::ColorSpace &colorspace,
float rMul, float rOff)
: m_yTexture(yTexture)
, m_uTexture(uTexture)
@@ -340,7 +293,7 @@ YUVVideoMaterial::YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, Q
QSGMaterialShader *YUVVideoMaterial::createShader() const
{
- return new YUVVideoMaterialShader;
+ return new YUVVideoMaterialShader(m_colorSpace);
}
int YUVVideoMaterial::compare(const QSGMaterial *other) const
@@ -355,7 +308,7 @@ int YUVVideoMaterial::compare(const QSGMaterial *other) const
YUVAVideoMaterial::YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- YUVVideoMaterial::ColorSpace colorspace,
+ const gfx::ColorSpace &colorspace,
float rMul, float rOff)
: YUVVideoMaterial(yTexture, uTexture, vTexture, yaTexCoordRect, uvTexCoordRect, yaTexSize, uvTexSize, colorspace, rMul, rOff)
, m_aTexture(aTexture)
@@ -365,7 +318,7 @@ YUVAVideoMaterial::YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture,
QSGMaterialShader *YUVAVideoMaterial::createShader() const
{
- return new YUVAVideoMaterialShader;
+ return new YUVAVideoMaterialShader(m_colorSpace);
}
int YUVAVideoMaterial::compare(const QSGMaterial *other) const
@@ -378,7 +331,7 @@ int YUVAVideoMaterial::compare(const QSGMaterial *other) const
YUVVideoNode::YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- YUVVideoMaterial::ColorSpace colorspace, float rMul, float rOff)
+ const gfx::ColorSpace &colorspace, float rMul, float rOff)
: m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
{
setGeometry(&m_geometry);
diff --git a/src/core/yuv_video_node.h b/src/core/yuv_video_node.h
index 0baa5f5be..dca8fa5e2 100644
--- a/src/core/yuv_video_node.h
+++ b/src/core/yuv_video_node.h
@@ -43,6 +43,8 @@
#include <QtQuick/qsgmaterial.h>
#include <QtQuick/qsgnode.h>
+#include "ui/gfx/color_space.h"
+
QT_FORWARD_DECLARE_CLASS(QSGTexture)
namespace QtWebEngineCore {
@@ -53,14 +55,9 @@ namespace QtWebEngineCore {
class YUVVideoMaterial : public QSGMaterial
{
public:
- enum ColorSpace {
- REC_601, // SDTV standard with restricted "studio swing" color range.
- REC_709, // HDTV standard with restricted "studio swing" color range.
- JPEG // Full color range [0, 255] JPEG color space.
- };
YUVVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture,
const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- ColorSpace colorspace, float rMul, float rOff);
+ const gfx::ColorSpace &colorspace, float rMul, float rOff);
QSGMaterialType *type() const override
{
@@ -78,7 +75,7 @@ public:
QRectF m_uvTexCoordRect;
QSizeF m_yaTexSize;
QSizeF m_uvTexSize;
- ColorSpace m_colorSpace;
+ gfx::ColorSpace m_colorSpace;
float m_resourceMultiplier;
float m_resourceOffset;
};
@@ -88,7 +85,7 @@ class YUVAVideoMaterial : public YUVVideoMaterial
public:
YUVAVideoMaterial(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- ColorSpace colorspace, float rMul, float rOff);
+ const gfx::ColorSpace &colorspace, float rMul, float rOff);
QSGMaterialType *type() const override
{
@@ -107,7 +104,7 @@ class YUVVideoNode : public QSGGeometryNode
public:
YUVVideoNode(QSGTexture *yTexture, QSGTexture *uTexture, QSGTexture *vTexture, QSGTexture *aTexture,
const QRectF &yaTexCoordRect, const QRectF &uvTexCoordRect, const QSizeF &yaTexSize, const QSizeF &uvTexSize,
- YUVVideoMaterial::ColorSpace colorspace, float rMul, float rOff);
+ const gfx::ColorSpace &colorspace, float rMul, float rOff);
void setRect(const QRectF &rect);
private: