OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 1.f, 1.f, 1.f, | 49 1.f, 1.f, 1.f, |
50 0.f, -.344f, 1.772f, | 50 0.f, -.344f, 1.772f, |
51 1.403f, -.714f, 0.f, | 51 1.403f, -.714f, 0.f, |
52 }; | 52 }; |
53 | 53 |
54 VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) | 54 VideoLayerChromium::SharedValues::SharedValues(GraphicsContext3D* context) |
55 : m_context(context) | 55 : m_context(context) |
56 , m_yuvShaderProgram(0) | 56 , m_yuvShaderProgram(0) |
57 , m_rgbaShaderProgram(0) | 57 , m_rgbaShaderProgram(0) |
58 , m_yuvShaderMatrixLocation(0) | 58 , m_yuvShaderMatrixLocation(0) |
59 , m_yuvWidthScaleFactorLocation(0) | 59 , m_yWidthScaleFactorLocation(0) |
| 60 , m_uvWidthScaleFactorLocation(0) |
60 , m_rgbaShaderMatrixLocation(0) | 61 , m_rgbaShaderMatrixLocation(0) |
61 , m_rgbaWidthScaleFactorLocation(0) | 62 , m_rgbaWidthScaleFactorLocation(0) |
62 , m_ccMatrixLocation(0) | 63 , m_ccMatrixLocation(0) |
63 , m_signAdjLocation(0) | 64 , m_signAdjLocation(0) |
64 , m_yTextureLocation(0) | 65 , m_yTextureLocation(0) |
65 , m_uTextureLocation(0) | 66 , m_uTextureLocation(0) |
66 , m_vTextureLocation(0) | 67 , m_vTextureLocation(0) |
67 , m_rgbaTextureLocation(0) | 68 , m_rgbaTextureLocation(0) |
68 , m_yuvAlphaLocation(0) | 69 , m_yuvAlphaLocation(0) |
69 , m_rgbaAlphaLocation(0) | 70 , m_rgbaAlphaLocation(0) |
70 , m_initialized(false) | 71 , m_initialized(false) |
71 { | 72 { |
72 // Frame textures are allocated based on stride width, not visible frame | 73 // Frame textures are allocated based on stride width, not visible frame |
73 // width, such that there is a guarantee that the frame rows line up | 74 // width, such that there is a guarantee that the frame rows line up |
74 // properly and are not shifted by (stride - width) pixels. To hide the | 75 // properly and are not shifted by (stride - width) pixels. To hide the |
75 // "padding" pixels between the edge of the visible frame width and the end | 76 // "padding" pixels between the edge of the visible frame width and the end |
76 // of the stride, we give the shader a widthScaleFactor (<=1.0) of how much | 77 // of the stride, we give the shader a widthScaleFactor (<=1.0) of how much |
77 // of the width of the texture should be shown when drawing the texture onto | 78 // of the width of the texture should be shown when drawing the texture onto |
78 // the vertices. | 79 // the vertices. |
79 char vertexShaderString[] = | 80 char vertexShaderString[] = |
80 "precision mediump float; \n" | 81 "precision mediump float; \n" |
81 "attribute vec4 a_position; \n" | 82 "attribute vec4 a_position; \n" |
82 "attribute vec2 a_texCoord; \n" | 83 "attribute vec2 a_texCoord; \n" |
83 "uniform mat4 matrix; \n" | 84 "uniform mat4 matrix; \n" |
84 "varying vec2 v_texCoord; \n" | 85 "varying vec2 y_texCoord; \n" |
85 "uniform float widthScaleFactor; \n" | 86 "varying vec2 uv_texCoord; \n" |
| 87 "uniform float y_widthScaleFactor; \n" |
| 88 "uniform float uv_widthScaleFactor; \n" |
86 "void main() \n" | 89 "void main() \n" |
87 "{ \n" | 90 "{ \n" |
88 " gl_Position = matrix * a_position; \n" | 91 " gl_Position = matrix * a_position; \n" |
89 " v_texCoord = vec2(widthScaleFactor * a_texCoord.x, a_texCoord.y); \n" | 92 " y_texCoord = vec2(y_widthScaleFactor * a_texCoord.x, a_texCoord.y); \
n" |
| 93 " uv_texCoord = vec2(uv_widthScaleFactor * a_texCoord.x, a_texCoord.y);
\n" |
90 "} \n"; | 94 "} \n"; |
91 | 95 |
92 char yuvFragmentShaderString[] = | 96 char yuvFragmentShaderString[] = |
93 "precision mediump float; \n" | 97 "precision mediump float; \n" |
94 "precision mediump int; \n" | 98 "precision mediump int; \n" |
95 "varying vec2 v_texCoord; \n" | 99 "varying vec2 y_texCoord; \n" |
| 100 "varying vec2 uv_texCoord; \n" |
96 "uniform sampler2D y_texture; \n" | 101 "uniform sampler2D y_texture; \n" |
97 "uniform sampler2D u_texture; \n" | 102 "uniform sampler2D u_texture; \n" |
98 "uniform sampler2D v_texture; \n" | 103 "uniform sampler2D v_texture; \n" |
99 "uniform float alpha; \n" | 104 "uniform float alpha; \n" |
100 "uniform float adj; \n" | 105 "uniform float adj; \n" |
101 "uniform mat3 cc_matrix; \n" | 106 "uniform mat3 cc_matrix; \n" |
102 "void main() \n" | 107 "void main() \n" |
103 "{ \n" | 108 "{ \n" |
104 " float y = texture2D(y_texture, v_texCoord).x; \n" | 109 " float y = texture2D(y_texture, y_texCoord).x; \n" |
105 " float u = texture2D(u_texture, v_texCoord).x - adj; \n" | 110 " float u = texture2D(u_texture, uv_texCoord).x - adj; \n" |
106 " float v = texture2D(v_texture, v_texCoord).x - adj; \n" | 111 " float v = texture2D(v_texture, uv_texCoord).x - adj; \n" |
107 " vec3 rgb = cc_matrix * vec3(y, u, v); \n" | 112 " vec3 rgb = cc_matrix * vec3(y, u, v); \n" |
108 " gl_FragColor = vec4(rgb, float(1)) * alpha; \n" | 113 " gl_FragColor = vec4(rgb, float(1)) * alpha; \n" |
109 "} \n"; | 114 "} \n"; |
110 | 115 |
111 char rgbaFragmentShaderString[] = | 116 char rgbaFragmentShaderString[] = |
112 "precision mediump float; \n" | 117 "precision mediump float; \n" |
113 "varying vec2 v_texCoord; \n" | 118 "varying vec2 y_texCoord; \n" |
114 "uniform sampler2D rgba_texture; \n" | 119 "uniform sampler2D rgba_texture; \n" |
115 "uniform float alpha; \n" | 120 "uniform float alpha; \n" |
116 "void main() \n" | 121 "void main() \n" |
117 "{ \n" | 122 "{ \n" |
118 " vec4 texColor = texture2D(rgba_texture, vec2(v_texCoord.x, float(1) -
v_texCoord.y)); \n" | 123 " vec4 texColor = texture2D(rgba_texture, vec2(y_texCoord.x, float(1) -
y_texCoord.y)); \n" |
119 " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) *
alpha; \n" | 124 " gl_FragColor = vec4(texColor.x, texColor.y, texColor.z, texColor.w) *
alpha; \n" |
120 "} \n"; | 125 "} \n"; |
121 | 126 |
122 m_rgbaShaderProgram = createShaderProgram(m_context, vertexShaderString, rgb
aFragmentShaderString); | 127 m_rgbaShaderProgram = createShaderProgram(m_context, vertexShaderString, rgb
aFragmentShaderString); |
123 if (!m_rgbaShaderProgram) { | 128 if (!m_rgbaShaderProgram) { |
124 LOG_ERROR("VideoLayerChromium: Failed to create rgba shader program"); | 129 LOG_ERROR("VideoLayerChromium: Failed to create rgba shader program"); |
125 return; | 130 return; |
126 } | 131 } |
127 | 132 |
128 m_yuvShaderProgram = createShaderProgram(m_context, vertexShaderString, yuvF
ragmentShaderString); | 133 m_yuvShaderProgram = createShaderProgram(m_context, vertexShaderString, yuvF
ragmentShaderString); |
129 if (!m_yuvShaderProgram) { | 134 if (!m_yuvShaderProgram) { |
130 LOG_ERROR("VideoLayerChromium: Failed to create yuv shader program"); | 135 LOG_ERROR("VideoLayerChromium: Failed to create yuv shader program"); |
131 return; | 136 return; |
132 } | 137 } |
133 | 138 |
134 m_yuvShaderMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram
, "matrix"); | 139 m_yuvShaderMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram
, "matrix"); |
135 m_yuvWidthScaleFactorLocation = m_context->getUniformLocation(m_yuvShaderPro
gram, "widthScaleFactor"); | 140 m_yWidthScaleFactorLocation = m_context->getUniformLocation(m_yuvShaderProgr
am, "y_widthScaleFactor"); |
| 141 m_uvWidthScaleFactorLocation = m_context->getUniformLocation(m_yuvShaderProg
ram, "uv_widthScaleFactor"); |
136 m_yTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "y_te
xture"); | 142 m_yTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "y_te
xture"); |
137 m_uTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "u_te
xture"); | 143 m_uTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "u_te
xture"); |
138 m_vTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "v_te
xture"); | 144 m_vTextureLocation = m_context->getUniformLocation(m_yuvShaderProgram, "v_te
xture"); |
139 m_ccMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "cc_m
atrix"); | 145 m_ccMatrixLocation = m_context->getUniformLocation(m_yuvShaderProgram, "cc_m
atrix"); |
140 m_signAdjLocation = m_context->getUniformLocation(m_yuvShaderProgram, "adj")
; | 146 m_signAdjLocation = m_context->getUniformLocation(m_yuvShaderProgram, "adj")
; |
141 m_yuvAlphaLocation = m_context->getUniformLocation(m_yuvShaderProgram, "alph
a"); | 147 m_yuvAlphaLocation = m_context->getUniformLocation(m_yuvShaderProgram, "alph
a"); |
142 | 148 |
143 ASSERT(m_yuvShaderMatrixLocation != -1); | 149 ASSERT(m_yuvShaderMatrixLocation != -1); |
144 ASSERT(m_yuvWidthScaleFactorLocation != -1); | 150 ASSERT(m_yWidthScaleFactorLocation != -1); |
| 151 ASSERT(m_uvWidthScaleFactorLocation != -1); |
145 ASSERT(m_yTextureLocation != -1); | 152 ASSERT(m_yTextureLocation != -1); |
146 ASSERT(m_uTextureLocation != -1); | 153 ASSERT(m_uTextureLocation != -1); |
147 ASSERT(m_vTextureLocation != -1); | 154 ASSERT(m_vTextureLocation != -1); |
148 ASSERT(m_ccMatrixLocation != -1); | 155 ASSERT(m_ccMatrixLocation != -1); |
149 ASSERT(m_signAdjLocation != -1); | 156 ASSERT(m_signAdjLocation != -1); |
150 ASSERT(m_yuvAlphaLocation != -1); | 157 ASSERT(m_yuvAlphaLocation != -1); |
151 | 158 |
152 m_rgbaShaderMatrixLocation = m_context->getUniformLocation(m_rgbaShaderProgr
am, "matrix"); | 159 m_rgbaShaderMatrixLocation = m_context->getUniformLocation(m_rgbaShaderProgr
am, "matrix"); |
153 m_rgbaTextureLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "
rgba_texture"); | 160 m_rgbaTextureLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "
rgba_texture"); |
154 m_rgbaWidthScaleFactorLocation = m_context->getUniformLocation(m_rgbaShaderP
rogram, "widthScaleFactor"); | 161 m_rgbaWidthScaleFactorLocation = m_context->getUniformLocation(m_rgbaShaderP
rogram, "y_widthScaleFactor"); |
155 m_rgbaAlphaLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "al
pha"); | 162 m_rgbaAlphaLocation = m_context->getUniformLocation(m_rgbaShaderProgram, "al
pha"); |
156 | 163 |
157 ASSERT(m_rgbaShaderMatrixLocation != -1); | 164 ASSERT(m_rgbaShaderMatrixLocation != -1); |
158 ASSERT(m_rgbaTextureLocation != -1); | 165 ASSERT(m_rgbaTextureLocation != -1); |
159 ASSERT(m_rgbaWidthScaleFactorLocation != -1); | 166 ASSERT(m_rgbaWidthScaleFactorLocation != -1); |
160 ASSERT(m_rgbaAlphaLocation != -1); | 167 ASSERT(m_rgbaAlphaLocation != -1); |
161 | 168 |
162 m_initialized = true; | 169 m_initialized = true; |
163 } | 170 } |
164 | 171 |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 // FIXME: Remove this test when tiled layers are implemented. | 297 // FIXME: Remove this test when tiled layers are implemented. |
291 if (!layerRenderer()->checkTextureSize(planeTextureSize)) | 298 if (!layerRenderer()->checkTextureSize(planeTextureSize)) |
292 return false; | 299 return false; |
293 | 300 |
294 if (!m_textures[plane]) | 301 if (!m_textures[plane]) |
295 m_textures[plane] = layerRenderer()->createLayerTexture(); | 302 m_textures[plane] = layerRenderer()->createLayerTexture(); |
296 | 303 |
297 if (!planeTextureSize.isZero() && planeTextureSize != m_textureSizes[pla
ne]) { | 304 if (!planeTextureSize.isZero() && planeTextureSize != m_textureSizes[pla
ne]) { |
298 allocateTexture(context, m_textures[plane], planeTextureSize, textur
eFormat); | 305 allocateTexture(context, m_textures[plane], planeTextureSize, textur
eFormat); |
299 m_textureSizes[plane] = planeTextureSize; | 306 m_textureSizes[plane] = planeTextureSize; |
300 m_frameSizes[plane] = IntSize(frame->width(), frame->height()); | 307 int frameWidth = frame->width(plane); |
| 308 int frameHeight = frame->height(plane); |
| 309 // When there are dead pixels at the edge of the texture, decrease |
| 310 // the frame width by 1 to prevent the rightmost pixels from |
| 311 // interpolating with the dead pixels. |
| 312 if (frame->hasPaddingBytes(plane)) |
| 313 --frameWidth; |
| 314 m_frameSizes[plane] = IntSize(frameWidth, frameHeight); |
301 } | 315 } |
302 } | 316 } |
| 317 |
| 318 // In YV12, every 2x2 square of Y values corresponds to one U and |
| 319 // one V value. If we decrease the width of the UV plane, we must decrease t
he |
| 320 // width of the Y texture by 2 for proper alignment. This must happen |
| 321 // always, even if Y's texture does not have padding bytes. |
| 322 if (frame->format() == VideoFrameChromium::YV12) { |
| 323 int yPlaneOriginalWidth = frame->width(VideoFrameChromium::yPlane); |
| 324 if (frame->hasPaddingBytes(VideoFrameChromium::uPlane)) |
| 325 m_frameSizes[VideoFrameChromium::yPlane].setWidth(yPlaneOriginalWidt
h - 2); |
| 326 } |
| 327 |
303 return true; | 328 return true; |
304 } | 329 } |
305 | 330 |
306 void VideoLayerChromium::allocateTexture(GraphicsContext3D* context, unsigned te
xtureId, const IntSize& dimensions, unsigned textureFormat) | 331 void VideoLayerChromium::allocateTexture(GraphicsContext3D* context, unsigned te
xtureId, const IntSize& dimensions, unsigned textureFormat) |
307 { | 332 { |
308 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId))
; | 333 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId))
; |
309 GLC(context, context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D,
0, textureFormat, dimensions.width(), dimensions.height(), 0, textureFormat, Gra
phicsContext3D::UNSIGNED_BYTE)); | 334 GLC(context, context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D,
0, textureFormat, dimensions.width(), dimensions.height(), 0, textureFormat, Gra
phicsContext3D::UNSIGNED_BYTE)); |
310 } | 335 } |
311 | 336 |
312 void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned text
ureId, const IntSize& dimensions, unsigned format, const void* data) | 337 void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned text
ureId, const IntSize& dimensions, unsigned format, const void* data) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 { | 388 { |
364 GraphicsContext3D* context = layerRendererContext(); | 389 GraphicsContext3D* context = layerRendererContext(); |
365 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1)); | 390 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE1)); |
366 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[
VideoFrameChromium::yPlane])); | 391 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[
VideoFrameChromium::yPlane])); |
367 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2)); | 392 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE2)); |
368 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[
VideoFrameChromium::uPlane])); | 393 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[
VideoFrameChromium::uPlane])); |
369 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3)); | 394 GLC(context, context->activeTexture(GraphicsContext3D::TEXTURE3)); |
370 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[
VideoFrameChromium::vPlane])); | 395 GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textures[
VideoFrameChromium::vPlane])); |
371 | 396 |
372 layerRenderer()->useShader(sv->yuvShaderProgram()); | 397 layerRenderer()->useShader(sv->yuvShaderProgram()); |
373 unsigned frameWidth = m_frameSizes[VideoFrameChromium::yPlane].width(); | 398 unsigned yFrameWidth = m_frameSizes[VideoFrameChromium::yPlane].width(); |
374 unsigned textureWidth = m_textureSizes[VideoFrameChromium::yPlane].width(); | 399 unsigned yTextureWidth = m_textureSizes[VideoFrameChromium::yPlane].width(); |
375 float widthScaleFactor = static_cast<float>(frameWidth) / textureWidth; | 400 // Arbitrarily take the u sizes because u and v dimensions are identical. |
376 GLC(context, context->uniform1f(sv->yuvWidthScaleFactorLocation(), widthScal
eFactor)); | 401 unsigned uvFrameWidth = m_frameSizes[VideoFrameChromium::uPlane].width(); |
| 402 unsigned uvTextureWidth = m_textureSizes[VideoFrameChromium::uPlane].width()
; |
| 403 |
| 404 float yWidthScaleFactor = static_cast<float>(yFrameWidth) / yTextureWidth; |
| 405 float uvWidthScaleFactor = static_cast<float>(uvFrameWidth) / uvTextureWidth
; |
| 406 GLC(context, context->uniform1f(sv->yWidthScaleFactorLocation(), yWidthScale
Factor)); |
| 407 GLC(context, context->uniform1f(sv->uvWidthScaleFactorLocation(), uvWidthSca
leFactor)); |
377 | 408 |
378 GLC(context, context->uniform1i(sv->yTextureLocation(), 1)); | 409 GLC(context, context->uniform1i(sv->yTextureLocation(), 1)); |
379 GLC(context, context->uniform1i(sv->uTextureLocation(), 2)); | 410 GLC(context, context->uniform1i(sv->uTextureLocation(), 2)); |
380 GLC(context, context->uniform1i(sv->vTextureLocation(), 3)); | 411 GLC(context, context->uniform1i(sv->vTextureLocation(), 3)); |
381 | 412 |
382 // This value of 0.5 maps to 128. It is used in the YUV to RGB conversion | 413 // This value of 0.5 maps to 128. It is used in the YUV to RGB conversion |
383 // formula to turn unsigned u and v values to signed u and v values. | 414 // formula to turn unsigned u and v values to signed u and v values. |
384 // This is loaded as a uniform because certain drivers have problems | 415 // This is loaded as a uniform because certain drivers have problems |
385 // reading literal float values. | 416 // reading literal float values. |
386 GLC(context, context->uniform1f(sv->signAdjLocation(), 0.5)); | 417 GLC(context, context->uniform1f(sv->signAdjLocation(), 0.5)); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 for (unsigned plane = 0; plane < frame->planes(); plane++) { | 461 for (unsigned plane = 0; plane < frame->planes(); plane++) { |
431 m_textures[plane] = frame->texture(plane); | 462 m_textures[plane] = frame->texture(plane); |
432 m_textureSizes[plane] = frame->requiredTextureSize(plane); | 463 m_textureSizes[plane] = frame->requiredTextureSize(plane); |
433 m_frameSizes[plane] = m_textureSizes[plane]; | 464 m_frameSizes[plane] = m_textureSizes[plane]; |
434 } | 465 } |
435 } | 466 } |
436 | 467 |
437 } // namespace WebCore | 468 } // namespace WebCore |
438 | 469 |
439 #endif // USE(ACCELERATED_COMPOSITING) | 470 #endif // USE(ACCELERATED_COMPOSITING) |
OLD | NEW |