Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(46)

Side by Side Diff: cc/output/gl_renderer.cc

Issue 2674763003: cc: Separate YUV from LUT color conversion (Closed)
Patch Set: More rebaselines Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | cc/output/gl_renderer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 The Chromium Authors. All rights reserved. 1 // Copyright 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/output/gl_renderer.h" 5 #include "cc/output/gl_renderer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <stdint.h> 8 #include <stdint.h>
9 9
10 #include <algorithm> 10 #include <algorithm>
(...skipping 2095 matching lines...) Expand 10 before | Expand all | Expand 10 after
2106 } 2106 }
2107 2107
2108 } // namespace 2108 } // namespace
2109 2109
2110 // TODO(ccameron): This has been replicated in ui/gfx/color_transform.cc. Delete 2110 // TODO(ccameron): This has been replicated in ui/gfx/color_transform.cc. Delete
2111 // one of the instances. 2111 // one of the instances.
2112 void ComputeYUVToRGBMatrices(YUVVideoDrawQuad::ColorSpace color_space, 2112 void ComputeYUVToRGBMatrices(YUVVideoDrawQuad::ColorSpace color_space,
2113 uint32_t bits_per_channel, 2113 uint32_t bits_per_channel,
2114 float resource_multiplier, 2114 float resource_multiplier,
2115 float resource_offset, 2115 float resource_offset,
2116 float* yuv_to_rgb_multiplied, 2116 ColorConversionMode color_conversion_mode,
2117 float* yuv_adjust_with_offset) { 2117 float* yuv_to_rgb_matrix) {
2118 float yuv_to_rgb_multiplied[9];
2119 float yuv_adjust_with_offset[3];
2120
2118 // These values are magic numbers that are used in the transformation from YUV 2121 // These values are magic numbers that are used in the transformation from YUV
2119 // to RGB color values. They are taken from the following webpage: 2122 // to RGB color values. They are taken from the following webpage:
2120 // http://www.fourcc.org/fccyvrgb.php 2123 // http://www.fourcc.org/fccyvrgb.php
2121 float yuv_to_rgb_rec601[9] = { 2124 float yuv_to_rgb_rec601[9] = {
2122 1.164f, 1.164f, 1.164f, 0.0f, -.391f, 2.018f, 1.596f, -.813f, 0.0f, 2125 1.164f, 1.164f, 1.164f, 0.0f, -.391f, 2.018f, 1.596f, -.813f, 0.0f,
2123 }; 2126 };
2124 float yuv_to_rgb_jpeg[9] = { 2127 float yuv_to_rgb_jpeg[9] = {
2125 1.f, 1.f, 1.f, 0.0f, -.34414f, 1.772f, 1.402f, -.71414f, 0.0f, 2128 1.f, 1.f, 1.f, 0.0f, -.34414f, 1.772f, 1.402f, -.71414f, 0.0f,
2126 }; 2129 };
2127 float yuv_to_rgb_rec709[9] = { 2130 float yuv_to_rgb_rec709[9] = {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 2168
2166 // Formula according to BT.601-7 section 2.5.3. 2169 // Formula according to BT.601-7 section 2.5.3.
2167 DCHECK_LE(YUVVideoDrawQuad::kMinBitsPerChannel, bits_per_channel); 2170 DCHECK_LE(YUVVideoDrawQuad::kMinBitsPerChannel, bits_per_channel);
2168 DCHECK_LE(bits_per_channel, YUVVideoDrawQuad::kMaxBitsPerChannel); 2171 DCHECK_LE(bits_per_channel, YUVVideoDrawQuad::kMaxBitsPerChannel);
2169 float adjustment_multiplier = 2172 float adjustment_multiplier =
2170 (1 << (bits_per_channel - 8)) * 1.0f / ((1 << bits_per_channel) - 1); 2173 (1 << (bits_per_channel - 8)) * 1.0f / ((1 << bits_per_channel) - 1);
2171 2174
2172 for (int i = 0; i < 9; ++i) 2175 for (int i = 0; i < 9; ++i)
2173 yuv_to_rgb_multiplied[i] = yuv_to_rgb[i] * resource_multiplier; 2176 yuv_to_rgb_multiplied[i] = yuv_to_rgb[i] * resource_multiplier;
2174 2177
2178 float yuv_adjust_with_offset_untransformed[3];
2175 for (int i = 0; i < 3; ++i) { 2179 for (int i = 0; i < 3; ++i) {
2176 yuv_adjust_with_offset[i] = 2180 yuv_adjust_with_offset_untransformed[i] =
2177 yuv_adjust[i] * adjustment_multiplier / resource_multiplier - 2181 yuv_adjust[i] * adjustment_multiplier / resource_multiplier -
2178 resource_offset; 2182 resource_offset;
2179 } 2183 }
2180 2184
2185 for (int i = 0; i < 3; ++i) {
2186 yuv_adjust_with_offset[i] = 0;
2187 for (int j = 0; j < 3; ++j) {
2188 yuv_adjust_with_offset[i] += yuv_to_rgb_multiplied[3 * j + i] *
2189 yuv_adjust_with_offset_untransformed[j];
2190 }
2191 }
2192
2181 // TODO(ccameron): Delete the above code, and just the below code instead. 2193 // TODO(ccameron): Delete the above code, and just the below code instead.
2182 // Compute the matrix |full_transform| which converts input YUV values to RGB 2194 // Compute the matrix |full_transform| which converts input YUV values to RGB
2183 // values. 2195 // values.
2184 SkMatrix44 full_transform; 2196 SkMatrix44 full_transform;
2185 2197
2186 // Start with the resource adjust. 2198 // Start with the resource adjust.
2187 full_transform.setScale(resource_multiplier, resource_multiplier, 2199 full_transform.setScale(resource_multiplier, resource_multiplier,
2188 resource_multiplier); 2200 resource_multiplier);
2189 full_transform.preTranslate(-resource_offset, -resource_offset, 2201 full_transform.preTranslate(-resource_offset, -resource_offset,
2190 -resource_offset); 2202 -resource_offset);
2191 2203
2204 // If we're using a LUT for conversion, we only need the resource adjust,
2205 // so just return this matrix.
2206 if (color_conversion_mode == COLOR_CONVERSION_MODE_LUT) {
2207 full_transform.asColMajorf(yuv_to_rgb_matrix);
2208 return;
2209 }
2210
2192 // Then apply the range adjust. 2211 // Then apply the range adjust.
2193 { 2212 {
2194 SkMatrix44 range_adjust; 2213 SkMatrix44 range_adjust;
2195 gfx_color_space.GetRangeAdjustMatrix(&range_adjust); 2214 gfx_color_space.GetRangeAdjustMatrix(&range_adjust);
2196 full_transform.postConcat(range_adjust); 2215 full_transform.postConcat(range_adjust);
2197 } 2216 }
2198 2217
2199 // Then apply the YUV to RGB full_transform. 2218 // Then apply the YUV to RGB full_transform.
2200 { 2219 {
2201 SkMatrix44 rgb_to_yuv; 2220 SkMatrix44 rgb_to_yuv;
2202 gfx_color_space.GetTransferMatrix(&rgb_to_yuv); 2221 gfx_color_space.GetTransferMatrix(&rgb_to_yuv);
2203 SkMatrix44 yuv_to_rgb; 2222 SkMatrix44 yuv_to_rgb;
2204 rgb_to_yuv.invert(&yuv_to_rgb); 2223 rgb_to_yuv.invert(&yuv_to_rgb);
2205 full_transform.postConcat(yuv_to_rgb); 2224 full_transform.postConcat(yuv_to_rgb);
2206 } 2225 }
2207 2226
2208 // For the upcoming DCHECKs, convert from the form 2227 SkMatrix44 full_transform_old;
2209 // rgb = A*yuv+b 2228 full_transform_old.set3x3RowMajorf(yuv_to_rgb_multiplied);
2210 // to the form 2229 full_transform_old.transpose();
2211 // rgb = A*(yuv+b) 2230 full_transform_old.postTranslate(yuv_adjust_with_offset[0],
2212 float adjust[4] = {0, 0, 0, 0}; 2231 yuv_adjust_with_offset[1],
2213 { 2232 yuv_adjust_with_offset[2]);
2214 SkMatrix44 full_transform_inverse;
2215 full_transform.invert(&full_transform_inverse);
2216 float adjust_preimage[4] = {full_transform.get(0, 3),
2217 full_transform.get(1, 3),
2218 full_transform.get(2, 3), 0};
2219 full_transform_inverse.mapScalars(adjust_preimage, adjust);
2220 }
2221 2233
2222 // TODO(ccameron): The gfx::ColorSpace-based approach produces some pixel 2234 // TODO(ccameron): The gfx::ColorSpace-based approach produces some pixel
2223 // differences. For the initial checkin, DCHECK that the parameters are 2235 // differences. For the initial checkin, DCHECK that the parameters are
2224 // very close. The subsequent checkins will delete the old path. 2236 // very close. The subsequent checkins will delete the old path.
2225 const float kEpsilon = 1.f / 255.f; 2237 const float kEpsilon = 1.f / 255.f;
2226 for (int i = 0; i < 3; ++i) { 2238 for (int i = 0; i < 4; ++i) {
2227 for (int j = 0; j < 3; ++j) { 2239 for (int j = 0; j < 4; ++j) {
2228 DCHECK_LT(RelativeError(yuv_to_rgb_multiplied[3 * j + i], 2240 DCHECK_LT(
2229 full_transform.get(i, j)), 2241 RelativeError(full_transform_old.get(i, j), full_transform.get(i, j)),
2230 kEpsilon); 2242 kEpsilon);
2231 } 2243 }
2232 DCHECK_LT(RelativeError(yuv_adjust_with_offset[i], adjust[i]), kEpsilon);
2233 } 2244 }
2245 full_transform_old.asColMajorf(yuv_to_rgb_matrix);
2234 } 2246 }
2235 2247
2236 void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, 2248 void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame,
2237 const YUVVideoDrawQuad* quad, 2249 const YUVVideoDrawQuad* quad,
2238 const gfx::QuadF* clip_region) { 2250 const gfx::QuadF* clip_region) {
2239 SetBlendEnabled(quad->ShouldDrawWithBlending()); 2251 SetBlendEnabled(quad->ShouldDrawWithBlending());
2240 2252
2241 TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( 2253 TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired(
2242 gl_, &highp_threshold_cache_, highp_threshold_min_, 2254 gl_, &highp_threshold_cache_, highp_threshold_min_,
2243 quad->shared_quad_state->visible_quad_layer_rect.bottom_right()); 2255 quad->shared_quad_state->visible_quad_layer_rect.bottom_right());
2244 YUVAlphaTextureMode alpha_texture_mode = quad->a_plane_resource_id() 2256 YUVAlphaTextureMode alpha_texture_mode = quad->a_plane_resource_id()
2245 ? YUV_HAS_ALPHA_TEXTURE 2257 ? YUV_HAS_ALPHA_TEXTURE
2246 : YUV_NO_ALPHA_TEXTURE; 2258 : YUV_NO_ALPHA_TEXTURE;
2247 UVTextureMode uv_texture_mode = 2259 UVTextureMode uv_texture_mode =
2248 quad->v_plane_resource_id() == quad->u_plane_resource_id() 2260 quad->v_plane_resource_id() == quad->u_plane_resource_id()
2249 ? UV_TEXTURE_MODE_UV 2261 ? UV_TEXTURE_MODE_UV
2250 : UV_TEXTURE_MODE_U_V; 2262 : UV_TEXTURE_MODE_U_V;
2251 ColorConversionMode color_conversion_mode = 2263 ColorConversionMode color_conversion_mode =
2252 base::FeatureList::IsEnabled(media::kVideoColorManagement) 2264 base::FeatureList::IsEnabled(media::kVideoColorManagement)
2253 ? COLOR_CONVERSION_MODE_LUT_FROM_YUV 2265 ? COLOR_CONVERSION_MODE_LUT
2254 : COLOR_CONVERSION_MODE_NONE; 2266 : COLOR_CONVERSION_MODE_NONE;
2255 ResourceProvider::ScopedSamplerGL y_plane_lock( 2267 ResourceProvider::ScopedSamplerGL y_plane_lock(
2256 resource_provider_, quad->y_plane_resource_id(), GL_TEXTURE1, GL_LINEAR); 2268 resource_provider_, quad->y_plane_resource_id(), GL_TEXTURE1, GL_LINEAR);
2257 ResourceProvider::ScopedSamplerGL u_plane_lock( 2269 ResourceProvider::ScopedSamplerGL u_plane_lock(
2258 resource_provider_, quad->u_plane_resource_id(), GL_TEXTURE2, GL_LINEAR); 2270 resource_provider_, quad->u_plane_resource_id(), GL_TEXTURE2, GL_LINEAR);
2259 DCHECK_EQ(y_plane_lock.target(), u_plane_lock.target()); 2271 DCHECK_EQ(y_plane_lock.target(), u_plane_lock.target());
2260 // TODO(jbauman): Use base::Optional when available. 2272 // TODO(jbauman): Use base::Optional when available.
2261 std::unique_ptr<ResourceProvider::ScopedSamplerGL> v_plane_lock; 2273 std::unique_ptr<ResourceProvider::ScopedSamplerGL> v_plane_lock;
2262 2274
2263 if (uv_texture_mode == UV_TEXTURE_MODE_U_V) { 2275 if (uv_texture_mode == UV_TEXTURE_MODE_U_V) {
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2339 gl_->Uniform1i(program->y_texture_location(), 1); 2351 gl_->Uniform1i(program->y_texture_location(), 1);
2340 if (uv_texture_mode == UV_TEXTURE_MODE_UV) { 2352 if (uv_texture_mode == UV_TEXTURE_MODE_UV) {
2341 gl_->Uniform1i(program->uv_texture_location(), 2); 2353 gl_->Uniform1i(program->uv_texture_location(), 2);
2342 } else { 2354 } else {
2343 gl_->Uniform1i(program->u_texture_location(), 2); 2355 gl_->Uniform1i(program->u_texture_location(), 2);
2344 gl_->Uniform1i(program->v_texture_location(), 3); 2356 gl_->Uniform1i(program->v_texture_location(), 3);
2345 } 2357 }
2346 if (alpha_texture_mode == YUV_HAS_ALPHA_TEXTURE) 2358 if (alpha_texture_mode == YUV_HAS_ALPHA_TEXTURE)
2347 gl_->Uniform1i(program->a_texture_location(), 4); 2359 gl_->Uniform1i(program->a_texture_location(), 4);
2348 2360
2349 if (color_conversion_mode == COLOR_CONVERSION_MODE_LUT_FROM_YUV) { 2361 if (color_conversion_mode == COLOR_CONVERSION_MODE_LUT) {
2350 ColorLUTCache::LUT lut = color_lut_cache_.GetLUT(quad->video_color_space, 2362 ColorLUTCache::LUT lut = color_lut_cache_.GetLUT(quad->video_color_space,
2351 frame->device_color_space); 2363 frame->device_color_space);
2352 gl_->ActiveTexture(GL_TEXTURE5); 2364 gl_->ActiveTexture(GL_TEXTURE5);
2353 gl_->BindTexture(GL_TEXTURE_2D, lut.texture); 2365 gl_->BindTexture(GL_TEXTURE_2D, lut.texture);
2354 gl_->Uniform1i(program->lut_texture_location(), 5); 2366 gl_->Uniform1i(program->lut_texture_location(), 5);
2355 gl_->Uniform1f(program->lut_size_location(), lut.size); 2367 gl_->Uniform1f(program->lut_size_location(), lut.size);
2356 gl_->ActiveTexture(GL_TEXTURE0); 2368 gl_->ActiveTexture(GL_TEXTURE0);
2357 gl_->Uniform1f(program->resource_multiplier_location(),
2358 quad->resource_multiplier);
2359 gl_->Uniform1f(program->resource_offset_location(), quad->resource_offset);
2360 } else {
2361 float yuv_to_rgb_multiplied[9] = {0};
2362 float yuv_adjust_with_offset[3] = {0};
2363 ComputeYUVToRGBMatrices(quad->color_space, quad->bits_per_channel,
2364 quad->resource_multiplier, quad->resource_offset,
2365 yuv_to_rgb_multiplied, yuv_adjust_with_offset);
2366 gl_->UniformMatrix3fv(program->yuv_matrix_location(), 1, 0,
2367 yuv_to_rgb_multiplied);
2368 gl_->Uniform3fv(program->yuv_adj_location(), 1, yuv_adjust_with_offset);
2369 } 2369 }
2370 DCHECK_NE(program->yuv_and_resource_matrix_location(), -1);
2371 float yuv_to_rgb_matrix[16] = {0};
2372 ComputeYUVToRGBMatrices(quad->color_space, quad->bits_per_channel,
2373 quad->resource_multiplier, quad->resource_offset,
2374 color_conversion_mode, yuv_to_rgb_matrix);
2375 gl_->UniformMatrix4fv(program->yuv_and_resource_matrix_location(), 1, 0,
2376 yuv_to_rgb_matrix);
2370 2377
2371 // The transform and vertex data are used to figure out the extents that the 2378 // The transform and vertex data are used to figure out the extents that the
2372 // un-antialiased quad should have and which vertex this is and the float 2379 // un-antialiased quad should have and which vertex this is and the float
2373 // quad passed in via uniform is the actual geometry that gets used to draw 2380 // quad passed in via uniform is the actual geometry that gets used to draw
2374 // it. This is why this centered rect is used and not the original quad_rect. 2381 // it. This is why this centered rect is used and not the original quad_rect.
2375 auto tile_rect = gfx::RectF(quad->rect); 2382 auto tile_rect = gfx::RectF(quad->rect);
2376 2383
2377 SetShaderOpacity(quad->shared_quad_state->opacity, program->alpha_location()); 2384 SetShaderOpacity(quad->shared_quad_state->opacity, program->alpha_location());
2378 if (!clip_region) { 2385 if (!clip_region) {
2379 DrawQuadGeometry(frame->projection_matrix, 2386 DrawQuadGeometry(frame->projection_matrix,
(...skipping 1284 matching lines...) Expand 10 before | Expand all | Expand 10 after
3664 return; 3671 return;
3665 3672
3666 // Report GPU overdraw as a percentage of |max_result|. 3673 // Report GPU overdraw as a percentage of |max_result|.
3667 TRACE_COUNTER1( 3674 TRACE_COUNTER1(
3668 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw", 3675 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw",
3669 (std::accumulate(overdraw->begin(), overdraw->end(), 0) * 100) / 3676 (std::accumulate(overdraw->begin(), overdraw->end(), 0) * 100) /
3670 max_result); 3677 max_result);
3671 } 3678 }
3672 3679
3673 } // namespace cc 3680 } // namespace cc
OLDNEW
« no previous file with comments | « no previous file | cc/output/gl_renderer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698