| Index: cc/output/gl_renderer.cc
|
| diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc
|
| index 2ef2d36ba4252b5e864e25c652a5af8a11448f79..c3b8dadfca20c6991bdd2c5a5d5822803ffe04ae 100644
|
| --- a/cc/output/gl_renderer.cc
|
| +++ b/cc/output/gl_renderer.cc
|
| @@ -2086,6 +2086,74 @@ void GLRenderer::DrawContentQuadNoAA(const DrawingFrame* frame,
|
| gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
|
| }
|
|
|
| +// TODO(ccameron): This has been replicated in ui/gfx/color_transform.cc. Delete
|
| +// one of the instances.
|
| +void ComputeYUVToRGBMatrices(YUVVideoDrawQuad::ColorSpace color_space,
|
| + uint32_t bits_per_channel,
|
| + float resource_multiplier,
|
| + float resource_offset,
|
| + float* yuv_to_rgb_multiplied,
|
| + float* yuv_adjust_with_offset) {
|
| + // 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
|
| + float yuv_to_rgb_rec601[9] = {
|
| + 1.164f, 1.164f, 1.164f, 0.0f, -.391f, 2.018f, 1.596f, -.813f, 0.0f,
|
| + };
|
| + float yuv_to_rgb_jpeg[9] = {
|
| + 1.f, 1.f, 1.f, 0.0f, -.34414f, 1.772f, 1.402f, -.71414f, 0.0f,
|
| + };
|
| + float yuv_to_rgb_rec709[9] = {
|
| + 1.164f, 1.164f, 1.164f, 0.0f, -0.213f, 2.112f, 1.793f, -0.533f, 0.0f,
|
| + };
|
| +
|
| + // 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]
|
| + float yuv_adjust_constrained[3] = {
|
| + -16.f, -128.f, -128.f,
|
| + };
|
| +
|
| + // Same as above, but without the head and footroom.
|
| + float yuv_adjust_full[3] = {
|
| + 0.0f, -128.f, -128.f,
|
| + };
|
| +
|
| + float* yuv_to_rgb = NULL;
|
| + float* yuv_adjust = NULL;
|
| +
|
| + switch (color_space) {
|
| + case YUVVideoDrawQuad::REC_601:
|
| + yuv_to_rgb = yuv_to_rgb_rec601;
|
| + yuv_adjust = yuv_adjust_constrained;
|
| + break;
|
| + case YUVVideoDrawQuad::REC_709:
|
| + yuv_to_rgb = yuv_to_rgb_rec709;
|
| + yuv_adjust = yuv_adjust_constrained;
|
| + break;
|
| + case YUVVideoDrawQuad::JPEG:
|
| + yuv_to_rgb = yuv_to_rgb_jpeg;
|
| + yuv_adjust = yuv_adjust_full;
|
| + break;
|
| + }
|
| +
|
| + // Formula according to BT.601-7 section 2.5.3.
|
| + DCHECK_LE(YUVVideoDrawQuad::kMinBitsPerChannel, bits_per_channel);
|
| + DCHECK_LE(bits_per_channel, YUVVideoDrawQuad::kMaxBitsPerChannel);
|
| + float adjustment_multiplier =
|
| + (1 << (bits_per_channel - 8)) * 1.0f / ((1 << bits_per_channel) - 1);
|
| +
|
| + for (int i = 0; i < 9; ++i)
|
| + yuv_to_rgb_multiplied[i] = yuv_to_rgb[i] * resource_multiplier;
|
| +
|
| + for (int i = 0; i < 3; ++i) {
|
| + yuv_adjust_with_offset[i] =
|
| + yuv_adjust[i] * adjustment_multiplier / resource_multiplier -
|
| + resource_offset;
|
| + }
|
| +}
|
| +
|
| void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
|
| const YUVVideoDrawQuad* quad,
|
| const gfx::QuadF* clip_region) {
|
| @@ -2094,13 +2162,17 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
|
| TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
|
| gl_, &highp_threshold_cache_, highp_threshold_min_,
|
| quad->shared_quad_state->visible_quad_layer_rect.bottom_right());
|
| -
|
| - bool use_alpha_plane = quad->a_plane_resource_id() != 0;
|
| - bool use_nv12 = quad->v_plane_resource_id() == quad->u_plane_resource_id();
|
| - bool use_color_lut =
|
| - base::FeatureList::IsEnabled(media::kVideoColorManagement);
|
| - DCHECK(!(use_nv12 && use_alpha_plane));
|
| -
|
| + YUVAlphaTextureMode alpha_texture_mode = quad->a_plane_resource_id()
|
| + ? YUV_HAS_ALPHA_TEXTURE
|
| + : YUV_NO_ALPHA_TEXTURE;
|
| + UVTextureMode uv_texture_mode =
|
| + quad->v_plane_resource_id() == quad->u_plane_resource_id()
|
| + ? UV_TEXTURE_MODE_UV
|
| + : UV_TEXTURE_MODE_U_V;
|
| + ColorConversionMode color_conversion_mode =
|
| + base::FeatureList::IsEnabled(media::kVideoColorManagement)
|
| + ? COLOR_CONVERSION_MODE_LUT_FROM_YUV
|
| + : COLOR_CONVERSION_MODE_NONE;
|
| ResourceProvider::ScopedSamplerGL y_plane_lock(
|
| resource_provider_, quad->y_plane_resource_id(), GL_TEXTURE1, GL_LINEAR);
|
| ResourceProvider::ScopedSamplerGL u_plane_lock(
|
| @@ -2108,14 +2180,15 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
|
| DCHECK_EQ(y_plane_lock.target(), u_plane_lock.target());
|
| // TODO(jbauman): Use base::Optional when available.
|
| std::unique_ptr<ResourceProvider::ScopedSamplerGL> v_plane_lock;
|
| - if (!use_nv12) {
|
| +
|
| + if (uv_texture_mode == UV_TEXTURE_MODE_U_V) {
|
| v_plane_lock.reset(new ResourceProvider::ScopedSamplerGL(
|
| resource_provider_, quad->v_plane_resource_id(), GL_TEXTURE3,
|
| GL_LINEAR));
|
| DCHECK_EQ(y_plane_lock.target(), v_plane_lock->target());
|
| }
|
| std::unique_ptr<ResourceProvider::ScopedSamplerGL> a_plane_lock;
|
| - if (use_alpha_plane) {
|
| + if (alpha_texture_mode == YUV_HAS_ALPHA_TEXTURE) {
|
| a_plane_lock.reset(new ResourceProvider::ScopedSamplerGL(
|
| resource_provider_, quad->a_plane_resource_id(), GL_TEXTURE4,
|
| GL_LINEAR));
|
| @@ -2125,51 +2198,11 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
|
| // All planes must have the same sampler type.
|
| SamplerType sampler = SamplerTypeFromTextureTarget(y_plane_lock.target());
|
|
|
| - int matrix_location = -1;
|
| - int ya_tex_scale_location = -1;
|
| - int ya_tex_offset_location = -1;
|
| - int uv_tex_scale_location = -1;
|
| - int uv_tex_offset_location = -1;
|
| - int ya_clamp_rect_location = -1;
|
| - int uv_clamp_rect_location = -1;
|
| - int y_texture_location = -1;
|
| - int u_texture_location = -1;
|
| - int v_texture_location = -1;
|
| - int uv_texture_location = -1;
|
| - int a_texture_location = -1;
|
| - int lut_texture_location = -1;
|
| - int yuv_matrix_location = -1;
|
| - int yuv_adj_location = -1;
|
| - int alpha_location = -1;
|
| - int resource_multiplier_location = -1;
|
| - int resource_offset_location = -1;
|
| - const Program* program = GetProgram(ProgramKey::YUVVideo(
|
| - tex_coord_precision, sampler,
|
| - use_alpha_plane ? YUV_HAS_ALPHA_TEXTURE : YUV_NO_ALPHA_TEXTURE,
|
| - use_nv12 ? UV_TEXTURE_MODE_UV : UV_TEXTURE_MODE_U_V,
|
| - use_color_lut ? COLOR_CONVERSION_MODE_2D_LUT_AS_3D_FROM_YUV
|
| - : COLOR_CONVERSION_MODE_NONE));
|
| - DCHECK(program);
|
| - DCHECK(program->initialized() || IsContextLost());
|
| + const Program* program = GetProgram(
|
| + ProgramKey::YUVVideo(tex_coord_precision, sampler, alpha_texture_mode,
|
| + uv_texture_mode, color_conversion_mode));
|
| + DCHECK(program && (program->initialized() || IsContextLost()));
|
| SetUseProgram(program->program());
|
| - matrix_location = program->matrix_location();
|
| - ya_tex_scale_location = program->ya_tex_scale_location();
|
| - ya_tex_offset_location = program->ya_tex_offset_location();
|
| - uv_tex_scale_location = program->uv_tex_scale_location();
|
| - uv_tex_offset_location = program->uv_tex_offset_location();
|
| - y_texture_location = program->y_texture_location();
|
| - u_texture_location = program->u_texture_location();
|
| - v_texture_location = program->v_texture_location();
|
| - uv_texture_location = program->uv_texture_location();
|
| - a_texture_location = program->a_texture_location();
|
| - lut_texture_location = program->lut_texture_location();
|
| - yuv_matrix_location = program->yuv_matrix_location();
|
| - yuv_adj_location = program->yuv_adj_location();
|
| - ya_clamp_rect_location = program->ya_clamp_rect_location();
|
| - uv_clamp_rect_location = program->uv_clamp_rect_location();
|
| - alpha_location = program->alpha_location();
|
| - resource_multiplier_location = program->resource_multiplier_location();
|
| - resource_offset_location = program->resource_offset_location();
|
|
|
| gfx::SizeF ya_tex_scale(1.0f, 1.0f);
|
| gfx::SizeF uv_tex_scale(1.0f, 1.0f);
|
| @@ -2200,13 +2233,13 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
|
| float uv_vertex_tex_scale_y =
|
| quad->uv_tex_coord_rect.height() * uv_tex_scale.height();
|
|
|
| - gl_->Uniform2f(ya_tex_scale_location, ya_vertex_tex_scale_x,
|
| + gl_->Uniform2f(program->ya_tex_scale_location(), ya_vertex_tex_scale_x,
|
| ya_vertex_tex_scale_y);
|
| - gl_->Uniform2f(ya_tex_offset_location, ya_vertex_tex_translate_x,
|
| + gl_->Uniform2f(program->ya_tex_offset_location(), ya_vertex_tex_translate_x,
|
| ya_vertex_tex_translate_y);
|
| - gl_->Uniform2f(uv_tex_scale_location, uv_vertex_tex_scale_x,
|
| + gl_->Uniform2f(program->uv_tex_scale_location(), uv_vertex_tex_scale_x,
|
| uv_vertex_tex_scale_y);
|
| - gl_->Uniform2f(uv_tex_offset_location, uv_vertex_tex_translate_x,
|
| + gl_->Uniform2f(program->uv_tex_offset_location(), uv_vertex_tex_translate_x,
|
| uv_vertex_tex_translate_y);
|
|
|
| gfx::RectF ya_clamp_rect(ya_vertex_tex_translate_x, ya_vertex_tex_translate_y,
|
| @@ -2217,98 +2250,44 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
|
| uv_vertex_tex_scale_x, uv_vertex_tex_scale_y);
|
| uv_clamp_rect.Inset(0.5f * uv_tex_scale.width(),
|
| 0.5f * uv_tex_scale.height());
|
| - gl_->Uniform4f(ya_clamp_rect_location, ya_clamp_rect.x(), ya_clamp_rect.y(),
|
| - ya_clamp_rect.right(), ya_clamp_rect.bottom());
|
| - gl_->Uniform4f(uv_clamp_rect_location, uv_clamp_rect.x(), uv_clamp_rect.y(),
|
| - uv_clamp_rect.right(), uv_clamp_rect.bottom());
|
| -
|
| - gl_->Uniform1i(y_texture_location, 1);
|
| - if (use_nv12) {
|
| - gl_->Uniform1i(uv_texture_location, 2);
|
| + gl_->Uniform4f(program->ya_clamp_rect_location(), ya_clamp_rect.x(),
|
| + ya_clamp_rect.y(), ya_clamp_rect.right(),
|
| + ya_clamp_rect.bottom());
|
| + gl_->Uniform4f(program->uv_clamp_rect_location(), uv_clamp_rect.x(),
|
| + uv_clamp_rect.y(), uv_clamp_rect.right(),
|
| + uv_clamp_rect.bottom());
|
| +
|
| + gl_->Uniform1i(program->y_texture_location(), 1);
|
| + if (uv_texture_mode == UV_TEXTURE_MODE_UV) {
|
| + gl_->Uniform1i(program->uv_texture_location(), 2);
|
| } else {
|
| - gl_->Uniform1i(u_texture_location, 2);
|
| - gl_->Uniform1i(v_texture_location, 3);
|
| - }
|
| - if (use_alpha_plane)
|
| - gl_->Uniform1i(a_texture_location, 4);
|
| -
|
| - // 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
|
| - float yuv_to_rgb_rec601[9] = {
|
| - 1.164f, 1.164f, 1.164f, 0.0f, -.391f, 2.018f, 1.596f, -.813f, 0.0f,
|
| - };
|
| - float yuv_to_rgb_jpeg[9] = {
|
| - 1.f, 1.f, 1.f, 0.0f, -.34414f, 1.772f, 1.402f, -.71414f, 0.0f,
|
| - };
|
| - float yuv_to_rgb_rec709[9] = {
|
| - 1.164f, 1.164f, 1.164f, 0.0f, -0.213f, 2.112f, 1.793f, -0.533f, 0.0f,
|
| - };
|
| -
|
| - // 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]
|
| - float yuv_adjust_constrained[3] = {
|
| - -16.f, -128.f, -128.f,
|
| - };
|
| -
|
| - // Same as above, but without the head and footroom.
|
| - float yuv_adjust_full[3] = {
|
| - 0.0f, -128.f, -128.f,
|
| - };
|
| -
|
| - float* yuv_to_rgb = NULL;
|
| - float* yuv_adjust = NULL;
|
| -
|
| - switch (quad->color_space) {
|
| - case YUVVideoDrawQuad::REC_601:
|
| - yuv_to_rgb = yuv_to_rgb_rec601;
|
| - yuv_adjust = yuv_adjust_constrained;
|
| - break;
|
| - case YUVVideoDrawQuad::REC_709:
|
| - yuv_to_rgb = yuv_to_rgb_rec709;
|
| - yuv_adjust = yuv_adjust_constrained;
|
| - break;
|
| - case YUVVideoDrawQuad::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];
|
| -
|
| - // Formula according to BT.601-7 section 2.5.3.
|
| - DCHECK_LE(YUVVideoDrawQuad::kMinBitsPerChannel, quad->bits_per_channel);
|
| - DCHECK_LE(quad->bits_per_channel, YUVVideoDrawQuad::kMaxBitsPerChannel);
|
| - float adjustment_multiplier = (1 << (quad->bits_per_channel - 8)) * 1.0f /
|
| - ((1 << quad->bits_per_channel) - 1);
|
| -
|
| - for (int i = 0; i < 9; ++i)
|
| - yuv_to_rgb_multiplied[i] = yuv_to_rgb[i] * quad->resource_multiplier;
|
| -
|
| - for (int i = 0; i < 3; ++i) {
|
| - yuv_adjust_with_offset[i] =
|
| - yuv_adjust[i] * adjustment_multiplier / quad->resource_multiplier -
|
| - quad->resource_offset;
|
| + gl_->Uniform1i(program->u_texture_location(), 2);
|
| + gl_->Uniform1i(program->v_texture_location(), 3);
|
| }
|
| + if (alpha_texture_mode == YUV_HAS_ALPHA_TEXTURE)
|
| + gl_->Uniform1i(program->a_texture_location(), 4);
|
|
|
| - if (lut_texture_location != -1) {
|
| + if (color_conversion_mode == COLOR_CONVERSION_MODE_LUT_FROM_YUV) {
|
| + const int kLUTSize = 17;
|
| unsigned int lut_texture = color_lut_cache_.GetLUT(
|
| - quad->video_color_space, frame->device_color_space, 17);
|
| + quad->video_color_space, frame->device_color_space, kLUTSize);
|
| gl_->ActiveTexture(GL_TEXTURE5);
|
| gl_->BindTexture(GL_TEXTURE_2D, lut_texture);
|
| - gl_->Uniform1i(lut_texture_location, 5);
|
| + gl_->Uniform1i(program->lut_texture_location(), 5);
|
| + gl_->Uniform1f(program->lut_size_location(), kLUTSize);
|
| gl_->ActiveTexture(GL_TEXTURE0);
|
| - }
|
| -
|
| - if (resource_multiplier_location != -1) {
|
| - gl_->Uniform1f(resource_multiplier_location, quad->resource_multiplier);
|
| - }
|
| -
|
| - if (resource_offset_location != -1) {
|
| - gl_->Uniform1f(resource_offset_location, quad->resource_offset);
|
| + gl_->Uniform1f(program->resource_multiplier_location(),
|
| + quad->resource_multiplier);
|
| + gl_->Uniform1f(program->resource_offset_location(), quad->resource_offset);
|
| + } else {
|
| + float yuv_to_rgb_multiplied[9] = {0};
|
| + float yuv_adjust_with_offset[3] = {0};
|
| + ComputeYUVToRGBMatrices(quad->color_space, quad->bits_per_channel,
|
| + quad->resource_multiplier, quad->resource_offset,
|
| + yuv_to_rgb_multiplied, yuv_adjust_with_offset);
|
| + gl_->UniformMatrix3fv(program->yuv_matrix_location(), 1, 0,
|
| + yuv_to_rgb_multiplied);
|
| + gl_->Uniform3fv(program->yuv_adj_location(), 1, yuv_adjust_with_offset);
|
| }
|
|
|
| // The transform and vertex data are used to figure out the extents that the
|
| @@ -2316,19 +2295,12 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
|
| // quad passed in via uniform is the actual geometry that gets used to draw
|
| // it. This is why this centered rect is used and not the original quad_rect.
|
| auto tile_rect = gfx::RectF(quad->rect);
|
| - if (yuv_matrix_location != -1) {
|
| - gl_->UniformMatrix3fv(yuv_matrix_location, 1, 0, yuv_to_rgb_multiplied);
|
| - }
|
|
|
| - if (yuv_adj_location) {
|
| - gl_->Uniform3fv(yuv_adj_location, 1, yuv_adjust_with_offset);
|
| - }
|
| -
|
| - SetShaderOpacity(quad->shared_quad_state->opacity, alpha_location);
|
| + SetShaderOpacity(quad->shared_quad_state->opacity, program->alpha_location());
|
| if (!clip_region) {
|
| DrawQuadGeometry(frame->projection_matrix,
|
| quad->shared_quad_state->quad_to_target_transform,
|
| - tile_rect, matrix_location);
|
| + tile_rect, program->matrix_location());
|
| } else {
|
| float uvs[8] = {0};
|
| GetScaledUVs(quad->visible_rect, clip_region, uvs);
|
| @@ -2337,7 +2309,7 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
|
| region_quad -= gfx::Vector2dF(0.5f, 0.5f);
|
| DrawQuadGeometryClippedByQuadF(
|
| frame, quad->shared_quad_state->quad_to_target_transform, tile_rect,
|
| - region_quad, matrix_location, uvs);
|
| + region_quad, program->matrix_location(), uvs);
|
| }
|
| }
|
|
|
|
|