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 |
2102 // 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 |
2103 // one of the instances. | 2111 // one of the instances. |
2104 void ComputeYUVToRGBMatrices(YUVVideoDrawQuad::ColorSpace color_space, | 2112 void ComputeYUVToRGBMatrices(YUVVideoDrawQuad::ColorSpace color_space, |
2105 uint32_t bits_per_channel, | 2113 uint32_t bits_per_channel, |
2106 float resource_multiplier, | 2114 float resource_multiplier, |
2107 float resource_offset, | 2115 float resource_offset, |
2108 float* yuv_to_rgb_multiplied, | 2116 float* yuv_to_rgb_multiplied, |
2109 float* yuv_adjust_with_offset) { | 2117 float* yuv_adjust_with_offset) { |
2110 // These values are magic numbers that are used in the transformation from YUV | 2118 // These values are magic numbers that are used in the transformation from YUV |
2111 // to RGB color values. They are taken from the following webpage: | 2119 // to RGB color values. They are taken from the following webpage: |
(...skipping 17 matching lines...) Expand all Loading... |
2129 }; | 2137 }; |
2130 | 2138 |
2131 // Same as above, but without the head and footroom. | 2139 // Same as above, but without the head and footroom. |
2132 float yuv_adjust_full[3] = { | 2140 float yuv_adjust_full[3] = { |
2133 0.0f, -128.f, -128.f, | 2141 0.0f, -128.f, -128.f, |
2134 }; | 2142 }; |
2135 | 2143 |
2136 float* yuv_to_rgb = NULL; | 2144 float* yuv_to_rgb = NULL; |
2137 float* yuv_adjust = NULL; | 2145 float* yuv_adjust = NULL; |
2138 | 2146 |
| 2147 gfx::ColorSpace gfx_color_space; |
2139 switch (color_space) { | 2148 switch (color_space) { |
2140 case YUVVideoDrawQuad::REC_601: | 2149 case YUVVideoDrawQuad::REC_601: |
2141 yuv_to_rgb = yuv_to_rgb_rec601; | 2150 yuv_to_rgb = yuv_to_rgb_rec601; |
2142 yuv_adjust = yuv_adjust_constrained; | 2151 yuv_adjust = yuv_adjust_constrained; |
| 2152 gfx_color_space = gfx::ColorSpace::CreateREC601(); |
2143 break; | 2153 break; |
2144 case YUVVideoDrawQuad::REC_709: | 2154 case YUVVideoDrawQuad::REC_709: |
2145 yuv_to_rgb = yuv_to_rgb_rec709; | 2155 yuv_to_rgb = yuv_to_rgb_rec709; |
2146 yuv_adjust = yuv_adjust_constrained; | 2156 yuv_adjust = yuv_adjust_constrained; |
| 2157 gfx_color_space = gfx::ColorSpace::CreateREC709(); |
2147 break; | 2158 break; |
2148 case YUVVideoDrawQuad::JPEG: | 2159 case YUVVideoDrawQuad::JPEG: |
2149 yuv_to_rgb = yuv_to_rgb_jpeg; | 2160 yuv_to_rgb = yuv_to_rgb_jpeg; |
2150 yuv_adjust = yuv_adjust_full; | 2161 yuv_adjust = yuv_adjust_full; |
| 2162 gfx_color_space = gfx::ColorSpace::CreateJpeg(); |
2151 break; | 2163 break; |
2152 } | 2164 } |
2153 | 2165 |
2154 // Formula according to BT.601-7 section 2.5.3. | 2166 // Formula according to BT.601-7 section 2.5.3. |
2155 DCHECK_LE(YUVVideoDrawQuad::kMinBitsPerChannel, bits_per_channel); | 2167 DCHECK_LE(YUVVideoDrawQuad::kMinBitsPerChannel, bits_per_channel); |
2156 DCHECK_LE(bits_per_channel, YUVVideoDrawQuad::kMaxBitsPerChannel); | 2168 DCHECK_LE(bits_per_channel, YUVVideoDrawQuad::kMaxBitsPerChannel); |
2157 float adjustment_multiplier = | 2169 float adjustment_multiplier = |
2158 (1 << (bits_per_channel - 8)) * 1.0f / ((1 << bits_per_channel) - 1); | 2170 (1 << (bits_per_channel - 8)) * 1.0f / ((1 << bits_per_channel) - 1); |
2159 | 2171 |
2160 for (int i = 0; i < 9; ++i) | 2172 for (int i = 0; i < 9; ++i) |
2161 yuv_to_rgb_multiplied[i] = yuv_to_rgb[i] * resource_multiplier; | 2173 yuv_to_rgb_multiplied[i] = yuv_to_rgb[i] * resource_multiplier; |
2162 | 2174 |
2163 for (int i = 0; i < 3; ++i) { | 2175 for (int i = 0; i < 3; ++i) { |
2164 yuv_adjust_with_offset[i] = | 2176 yuv_adjust_with_offset[i] = |
2165 yuv_adjust[i] * adjustment_multiplier / resource_multiplier - | 2177 yuv_adjust[i] * adjustment_multiplier / resource_multiplier - |
2166 resource_offset; | 2178 resource_offset; |
2167 } | 2179 } |
| 2180 |
| 2181 // 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 |
| 2183 // values. |
| 2184 SkMatrix44 full_transform; |
| 2185 |
| 2186 // Start with the resource adjust. |
| 2187 full_transform.setScale(resource_multiplier, resource_multiplier, |
| 2188 resource_multiplier); |
| 2189 full_transform.preTranslate(-resource_offset, -resource_offset, |
| 2190 -resource_offset); |
| 2191 |
| 2192 // Then apply the range adjust. |
| 2193 { |
| 2194 SkMatrix44 range_adjust; |
| 2195 gfx_color_space.GetRangeAdjustMatrix(&range_adjust); |
| 2196 full_transform.postConcat(range_adjust); |
| 2197 } |
| 2198 |
| 2199 // Then apply the YUV to RGB full_transform. |
| 2200 { |
| 2201 SkMatrix44 rgb_to_yuv; |
| 2202 gfx_color_space.GetTransferMatrix(&rgb_to_yuv); |
| 2203 SkMatrix44 yuv_to_rgb; |
| 2204 rgb_to_yuv.invert(&yuv_to_rgb); |
| 2205 full_transform.postConcat(yuv_to_rgb); |
| 2206 } |
| 2207 |
| 2208 // For the upcoming DCHECKs, convert from the form |
| 2209 // rgb = A*yuv+b |
| 2210 // to the form |
| 2211 // rgb = A*(yuv+b) |
| 2212 float adjust[4] = {0, 0, 0, 0}; |
| 2213 { |
| 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 |
| 2222 // TODO(ccameron): The gfx::ColorSpace-based approach produces some pixel |
| 2223 // differences. For the initial checkin, DCHECK that the parameters are |
| 2224 // very close. The subsequent checkins will delete the old path. |
| 2225 const float kEpsilon = 1.f / 255.f; |
| 2226 for (int i = 0; i < 3; ++i) { |
| 2227 for (int j = 0; j < 3; ++j) { |
| 2228 DCHECK_LT(RelativeError(yuv_to_rgb_multiplied[3 * j + i], |
| 2229 full_transform.get(i, j)), |
| 2230 kEpsilon); |
| 2231 } |
| 2232 DCHECK_LT(RelativeError(yuv_adjust_with_offset[i], adjust[i]), kEpsilon); |
| 2233 } |
2168 } | 2234 } |
2169 | 2235 |
2170 void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, | 2236 void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, |
2171 const YUVVideoDrawQuad* quad, | 2237 const YUVVideoDrawQuad* quad, |
2172 const gfx::QuadF* clip_region) { | 2238 const gfx::QuadF* clip_region) { |
2173 SetBlendEnabled(quad->ShouldDrawWithBlending()); | 2239 SetBlendEnabled(quad->ShouldDrawWithBlending()); |
2174 | 2240 |
2175 TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( | 2241 TexCoordPrecision tex_coord_precision = TexCoordPrecisionRequired( |
2176 gl_, &highp_threshold_cache_, highp_threshold_min_, | 2242 gl_, &highp_threshold_cache_, highp_threshold_min_, |
2177 quad->shared_quad_state->visible_quad_layer_rect.bottom_right()); | 2243 quad->shared_quad_state->visible_quad_layer_rect.bottom_right()); |
(...skipping 1420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3598 return; | 3664 return; |
3599 | 3665 |
3600 // Report GPU overdraw as a percentage of |max_result|. | 3666 // Report GPU overdraw as a percentage of |max_result|. |
3601 TRACE_COUNTER1( | 3667 TRACE_COUNTER1( |
3602 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw", | 3668 TRACE_DISABLED_BY_DEFAULT("cc.debug.overdraw"), "GPU Overdraw", |
3603 (std::accumulate(overdraw->begin(), overdraw->end(), 0) * 100) / | 3669 (std::accumulate(overdraw->begin(), overdraw->end(), 0) * 100) / |
3604 max_result); | 3670 max_result); |
3605 } | 3671 } |
3606 | 3672 |
3607 } // namespace cc | 3673 } // namespace cc |
OLD | NEW |