| OLD | NEW |
| 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 2081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2092 | 2092 |
| 2093 static float gl_matrix[16]; | 2093 static float gl_matrix[16]; |
| 2094 ToGLMatrix(&gl_matrix[0], | 2094 ToGLMatrix(&gl_matrix[0], |
| 2095 frame->projection_matrix * | 2095 frame->projection_matrix * |
| 2096 quad->shared_quad_state->quad_to_target_transform); | 2096 quad->shared_quad_state->quad_to_target_transform); |
| 2097 gl_->UniformMatrix4fv(program->matrix_location(), 1, false, &gl_matrix[0]); | 2097 gl_->UniformMatrix4fv(program->matrix_location(), 1, false, &gl_matrix[0]); |
| 2098 | 2098 |
| 2099 gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); | 2099 gl_->DrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0); |
| 2100 } | 2100 } |
| 2101 | 2101 |
| 2102 namespace { | |
| 2103 | |
| 2104 float RelativeError(float a, float b) { | |
| 2105 return std::abs(a - b) / std::max(1.f, std::abs(a + b)); | |
| 2106 } | |
| 2107 | |
| 2108 } // namespace | |
| 2109 | |
| 2110 // TODO(ccameron): This has been replicated in ui/gfx/color_transform.cc. Delete | 2102 // TODO(ccameron): This has been replicated in ui/gfx/color_transform.cc. Delete |
| 2111 // one of the instances. | 2103 // one of the instances. |
| 2112 void ComputeYUVToRGBMatrices(YUVVideoDrawQuad::ColorSpace color_space, | 2104 void ComputeYUVToRGBMatrices(YUVVideoDrawQuad::ColorSpace color_space, |
| 2113 uint32_t bits_per_channel, | 2105 uint32_t bits_per_channel, |
| 2114 float resource_multiplier, | 2106 float resource_multiplier, |
| 2115 float resource_offset, | 2107 float resource_offset, |
| 2116 ColorConversionMode color_conversion_mode, | 2108 ColorConversionMode color_conversion_mode, |
| 2117 float* yuv_to_rgb_matrix) { | 2109 float* yuv_to_rgb_matrix) { |
| 2118 float yuv_to_rgb_multiplied[9]; | |
| 2119 float yuv_adjust_with_offset[3]; | |
| 2120 | |
| 2121 // These values are magic numbers that are used in the transformation from YUV | |
| 2122 // to RGB color values. They are taken from the following webpage: | |
| 2123 // http://www.fourcc.org/fccyvrgb.php | |
| 2124 float yuv_to_rgb_rec601[9] = { | |
| 2125 1.164f, 1.164f, 1.164f, 0.0f, -.391f, 2.018f, 1.596f, -.813f, 0.0f, | |
| 2126 }; | |
| 2127 float yuv_to_rgb_jpeg[9] = { | |
| 2128 1.f, 1.f, 1.f, 0.0f, -.34414f, 1.772f, 1.402f, -.71414f, 0.0f, | |
| 2129 }; | |
| 2130 float yuv_to_rgb_rec709[9] = { | |
| 2131 1.164f, 1.164f, 1.164f, 0.0f, -0.213f, 2.112f, 1.793f, -0.533f, 0.0f, | |
| 2132 }; | |
| 2133 | |
| 2134 // They are used in the YUV to RGBA conversion formula: | |
| 2135 // Y - 16 : Gives 16 values of head and footroom for overshooting | |
| 2136 // U - 128 : Turns unsigned U into signed U [-128,127] | |
| 2137 // V - 128 : Turns unsigned V into signed V [-128,127] | |
| 2138 float yuv_adjust_constrained[3] = { | |
| 2139 -16.f, -128.f, -128.f, | |
| 2140 }; | |
| 2141 | |
| 2142 // Same as above, but without the head and footroom. | |
| 2143 float yuv_adjust_full[3] = { | |
| 2144 0.0f, -128.f, -128.f, | |
| 2145 }; | |
| 2146 | |
| 2147 float* yuv_to_rgb = NULL; | |
| 2148 float* yuv_adjust = NULL; | |
| 2149 | |
| 2150 gfx::ColorSpace gfx_color_space; | 2110 gfx::ColorSpace gfx_color_space; |
| 2151 switch (color_space) { | 2111 switch (color_space) { |
| 2152 case YUVVideoDrawQuad::REC_601: | 2112 case YUVVideoDrawQuad::REC_601: |
| 2153 yuv_to_rgb = yuv_to_rgb_rec601; | |
| 2154 yuv_adjust = yuv_adjust_constrained; | |
| 2155 gfx_color_space = gfx::ColorSpace::CreateREC601(); | 2113 gfx_color_space = gfx::ColorSpace::CreateREC601(); |
| 2156 break; | 2114 break; |
| 2157 case YUVVideoDrawQuad::REC_709: | 2115 case YUVVideoDrawQuad::REC_709: |
| 2158 yuv_to_rgb = yuv_to_rgb_rec709; | |
| 2159 yuv_adjust = yuv_adjust_constrained; | |
| 2160 gfx_color_space = gfx::ColorSpace::CreateREC709(); | 2116 gfx_color_space = gfx::ColorSpace::CreateREC709(); |
| 2161 break; | 2117 break; |
| 2162 case YUVVideoDrawQuad::JPEG: | 2118 case YUVVideoDrawQuad::JPEG: |
| 2163 yuv_to_rgb = yuv_to_rgb_jpeg; | |
| 2164 yuv_adjust = yuv_adjust_full; | |
| 2165 gfx_color_space = gfx::ColorSpace::CreateJpeg(); | 2119 gfx_color_space = gfx::ColorSpace::CreateJpeg(); |
| 2166 break; | 2120 break; |
| 2167 } | 2121 } |
| 2168 | 2122 |
| 2169 // Formula according to BT.601-7 section 2.5.3. | |
| 2170 DCHECK_LE(YUVVideoDrawQuad::kMinBitsPerChannel, bits_per_channel); | |
| 2171 DCHECK_LE(bits_per_channel, YUVVideoDrawQuad::kMaxBitsPerChannel); | |
| 2172 float adjustment_multiplier = | |
| 2173 (1 << (bits_per_channel - 8)) * 1.0f / ((1 << bits_per_channel) - 1); | |
| 2174 | |
| 2175 for (int i = 0; i < 9; ++i) | |
| 2176 yuv_to_rgb_multiplied[i] = yuv_to_rgb[i] * resource_multiplier; | |
| 2177 | |
| 2178 float yuv_adjust_with_offset_untransformed[3]; | |
| 2179 for (int i = 0; i < 3; ++i) { | |
| 2180 yuv_adjust_with_offset_untransformed[i] = | |
| 2181 yuv_adjust[i] * adjustment_multiplier / resource_multiplier - | |
| 2182 resource_offset; | |
| 2183 } | |
| 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 | |
| 2193 // TODO(ccameron): Delete the above code, and just the below code instead. | |
| 2194 // Compute the matrix |full_transform| which converts input YUV values to RGB | 2123 // Compute the matrix |full_transform| which converts input YUV values to RGB |
| 2195 // values. | 2124 // values. |
| 2196 SkMatrix44 full_transform; | 2125 SkMatrix44 full_transform; |
| 2197 | 2126 |
| 2198 // Start with the resource adjust. | 2127 // Start with the resource adjust. |
| 2199 full_transform.setScale(resource_multiplier, resource_multiplier, | 2128 full_transform.setScale(resource_multiplier, resource_multiplier, |
| 2200 resource_multiplier); | 2129 resource_multiplier); |
| 2201 full_transform.preTranslate(-resource_offset, -resource_offset, | 2130 full_transform.preTranslate(-resource_offset, -resource_offset, |
| 2202 -resource_offset); | 2131 -resource_offset); |
| 2203 | 2132 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2217 | 2146 |
| 2218 // Then apply the YUV to RGB full_transform. | 2147 // Then apply the YUV to RGB full_transform. |
| 2219 { | 2148 { |
| 2220 SkMatrix44 rgb_to_yuv; | 2149 SkMatrix44 rgb_to_yuv; |
| 2221 gfx_color_space.GetTransferMatrix(&rgb_to_yuv); | 2150 gfx_color_space.GetTransferMatrix(&rgb_to_yuv); |
| 2222 SkMatrix44 yuv_to_rgb; | 2151 SkMatrix44 yuv_to_rgb; |
| 2223 rgb_to_yuv.invert(&yuv_to_rgb); | 2152 rgb_to_yuv.invert(&yuv_to_rgb); |
| 2224 full_transform.postConcat(yuv_to_rgb); | 2153 full_transform.postConcat(yuv_to_rgb); |
| 2225 } | 2154 } |
| 2226 | 2155 |
| 2227 SkMatrix44 full_transform_old; | 2156 full_transform.asColMajorf(yuv_to_rgb_matrix); |
| 2228 full_transform_old.set3x3RowMajorf(yuv_to_rgb_multiplied); | |
| 2229 full_transform_old.transpose(); | |
| 2230 full_transform_old.postTranslate(yuv_adjust_with_offset[0], | |
| 2231 yuv_adjust_with_offset[1], | |
| 2232 yuv_adjust_with_offset[2]); | |
| 2233 | |
| 2234 // TODO(ccameron): The gfx::ColorSpace-based approach produces some pixel | |
| 2235 // differences. For the initial checkin, DCHECK that the parameters are | |
| 2236 // very close. The subsequent checkins will delete the old path. | |
| 2237 const float kEpsilon = 1.f / 255.f; | |
| 2238 for (int i = 0; i < 4; ++i) { | |
| 2239 for (int j = 0; j < 4; ++j) { | |
| 2240 DCHECK_LT( | |
| 2241 RelativeError(full_transform_old.get(i, j), full_transform.get(i, j)), | |
| 2242 kEpsilon); | |
| 2243 } | |
| 2244 } | |
| 2245 full_transform_old.asColMajorf(yuv_to_rgb_matrix); | |
| 2246 } | 2157 } |
| 2247 | 2158 |
| 2248 void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, | 2159 void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, |
| 2249 const YUVVideoDrawQuad* quad, | 2160 const YUVVideoDrawQuad* quad, |
| 2250 const gfx::QuadF* clip_region) { | 2161 const gfx::QuadF* clip_region) { |
| 2251 SetBlendEnabled(quad->ShouldDrawWithBlending()); | 2162 SetBlendEnabled(quad->ShouldDrawWithBlending()); |
| 2252 | 2163 |
| 2253 TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( | 2164 TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( |
| 2254 gl_, &highp_threshold_cache_, highp_threshold_min_, | 2165 gl_, &highp_threshold_cache_, highp_threshold_min_, |
| 2255 quad->shared_quad_state->visible_quad_layer_rect.bottom_right()); | 2166 quad->shared_quad_state->visible_quad_layer_rect.bottom_right()); |
| (...skipping 1415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3671 return; | 3582 return; |
| 3672 | 3583 |
| 3673 // Report GPU overdraw as a percentage of |max_result|. | 3584 // Report GPU overdraw as a percentage of |max_result|. |
| 3674 TRACE_COUNTER1( | 3585 TRACE_COUNTER1( |
| 3675 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw", | 3586 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw", |
| 3676 (std::accumulate(overdraw->begin(), overdraw->end(), 0) * 100) / | 3587 (std::accumulate(overdraw->begin(), overdraw->end(), 0) * 100) / |
| 3677 max_result); | 3588 max_result); |
| 3678 } | 3589 } |
| 3679 | 3590 |
| 3680 } // namespace cc | 3591 } // namespace cc |
| OLD | NEW |