Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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 "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "cc/video_layer_impl.h" | 7 #include "cc/video_layer_impl.h" |
| 8 | 8 |
| 9 #include "NotImplemented.h" | 9 #include "NotImplemented.h" |
| 10 #include "cc/io_surface_draw_quad.h" | 10 #include "cc/io_surface_draw_quad.h" |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 115 if (!m_provider) { | 115 if (!m_provider) { |
| 116 m_frame = 0; | 116 m_frame = 0; |
| 117 return; | 117 return; |
| 118 } | 118 } |
| 119 | 119 |
| 120 m_frame = m_provider->getCurrentFrame(); | 120 m_frame = m_provider->getCurrentFrame(); |
| 121 | 121 |
| 122 if (!m_frame) | 122 if (!m_frame) |
| 123 return; | 123 return; |
| 124 | 124 |
| 125 // If these fail, we'll have to add draw logic that handles offset bitmap/ | |
| 126 // texture UVs. | |
| 127 DCHECK(m_frame->visibleX() == 0 && m_frame->visibleY() == 0); | |
|
jamesr
2012/10/25 00:26:34
Can you make these separate DCHECK()s and use DCHE
Ami GONE FROM CHROMIUM
2012/10/25 00:43:07
DCHECKs are for programming errors, not creatively
sheu
2012/10/25 01:53:54
Updated the comment a bit. It's not really an err
| |
| 128 | |
| 129 // The visible contents might not cover the entire texture; e.g. padding | |
|
Ami GONE FROM CHROMIUM
2012/10/25 00:43:07
This comment seems oddly placed.
sheu
2012/10/25 01:53:54
Done.
| |
| 130 | |
| 125 m_format = convertVFCFormatToGC3DFormat(*m_frame); | 131 m_format = convertVFCFormatToGC3DFormat(*m_frame); |
| 126 | 132 |
| 127 if (m_format == GL_INVALID_VALUE) { | 133 if (m_format == GL_INVALID_VALUE) { |
| 128 m_provider->putCurrentFrame(m_frame); | 134 m_provider->putCurrentFrame(m_frame); |
| 129 m_frame = 0; | 135 m_frame = 0; |
| 130 return; | 136 return; |
| 131 } | 137 } |
| 132 | 138 |
| 133 if (m_frame->planes() > WebKit::WebVideoFrame::maxPlanes) { | 139 if (m_frame->planes() > WebKit::WebVideoFrame::maxPlanes) { |
| 134 m_provider->putCurrentFrame(m_frame); | 140 m_provider->putCurrentFrame(m_frame); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 160 return; | 166 return; |
| 161 | 167 |
| 162 SharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQ uadState()); | 168 SharedQuadState* sharedQuadState = quadSink.useSharedQuadState(createSharedQ uadState()); |
| 163 appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData); | 169 appendDebugBorderQuad(quadSink, sharedQuadState, appendQuadsData); |
| 164 | 170 |
| 165 // FIXME: When we pass quads out of process, we need to double-buffer, or | 171 // FIXME: When we pass quads out of process, we need to double-buffer, or |
| 166 // otherwise synchonize use of all textures in the quad. | 172 // otherwise synchonize use of all textures in the quad. |
| 167 | 173 |
| 168 IntRect quadRect(IntPoint(), contentBounds()); | 174 IntRect quadRect(IntPoint(), contentBounds()); |
| 169 | 175 |
| 176 // pixels for macroblocked formats. | |
| 177 const float texWidthScale = | |
| 178 static_cast<float>(m_frame->visibleWidth()) / m_frame->textureWidth(); | |
| 179 const float texHeightScale = | |
| 180 static_cast<float>(m_frame->visibleHeight()) / m_frame->textureHeight(); | |
| 181 | |
| 170 switch (m_format) { | 182 switch (m_format) { |
| 171 case GL_LUMINANCE: { | 183 case GL_LUMINANCE: { |
| 172 // YUV software decoder. | 184 // YUV software decoder. |
|
Ami GONE FROM CHROMIUM
2012/10/25 00:43:07
I don't believe it's possible to get here with sca
sheu
2012/10/25 01:53:54
It's not an error condition though, and we can han
| |
| 173 const FramePlane& yPlane = m_framePlanes[WebKit::WebVideoFrame::yPlane]; | 185 const FramePlane& yPlane = m_framePlanes[WebKit::WebVideoFrame::yPlane]; |
| 174 const FramePlane& uPlane = m_framePlanes[WebKit::WebVideoFrame::uPlane]; | 186 const FramePlane& uPlane = m_framePlanes[WebKit::WebVideoFrame::uPlane]; |
| 175 const FramePlane& vPlane = m_framePlanes[WebKit::WebVideoFrame::vPlane]; | 187 const FramePlane& vPlane = m_framePlanes[WebKit::WebVideoFrame::vPlane]; |
| 176 scoped_ptr<YUVVideoDrawQuad> yuvVideoQuad = YUVVideoDrawQuad::create(sha redQuadState, quadRect, yPlane, uPlane, vPlane); | 188 FloatSize texScale(texWidthScale, texHeightScale); |
| 189 scoped_ptr<YUVVideoDrawQuad> yuvVideoQuad = YUVVideoDrawQuad::create( | |
| 190 sharedQuadState, quadRect, texScale, yPlane, uPlane, vPlane); | |
| 177 quadSink.append(yuvVideoQuad.PassAs<DrawQuad>(), appendQuadsData); | 191 quadSink.append(yuvVideoQuad.PassAs<DrawQuad>(), appendQuadsData); |
| 178 break; | 192 break; |
| 179 } | 193 } |
| 180 case GL_RGBA: { | 194 case GL_RGBA: { |
| 181 // RGBA software decoder. | 195 // RGBA software decoder. |
| 182 const FramePlane& plane = m_framePlanes[WebKit::WebVideoFrame::rgbPlane] ; | 196 const FramePlane& plane = m_framePlanes[WebKit::WebVideoFrame::rgbPlane] ; |
| 183 float widthScaleFactor = static_cast<float>(plane.visibleSize.width()) / plane.size.width(); | |
| 184 | |
| 185 bool premultipliedAlpha = true; | 197 bool premultipliedAlpha = true; |
| 186 FloatRect uvRect(0, 0, widthScaleFactor, 1); | 198 FloatRect uvRect(0, 0, texWidthScale, texHeightScale); |
| 187 bool flipped = false; | 199 bool flipped = false; |
| 188 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, plane.resourceId, premultipliedAlpha, uvRect, flipped); | 200 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, plane.resourceId, premultipliedAlpha, uvRect, flipped); |
| 189 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); | 201 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); |
| 190 break; | 202 break; |
| 191 } | 203 } |
| 192 case GL_TEXTURE_2D: { | 204 case GL_TEXTURE_2D: { |
| 193 // NativeTexture hardware decoder. | 205 // NativeTexture hardware decoder. |
| 194 bool premultipliedAlpha = true; | 206 bool premultipliedAlpha = true; |
| 195 FloatRect uvRect(0, 0, 1, 1); | 207 FloatRect uvRect(0, 0, texWidthScale, texHeightScale); |
| 196 bool flipped = false; | 208 bool flipped = false; |
| 197 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, m_externalTextureResource, premultipliedAlpha, uvRect, flip ped); | 209 scoped_ptr<TextureDrawQuad> textureQuad = TextureDrawQuad::create(shared QuadState, quadRect, m_externalTextureResource, premultipliedAlpha, uvRect, flip ped); |
| 198 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); | 210 quadSink.append(textureQuad.PassAs<DrawQuad>(), appendQuadsData); |
| 199 break; | 211 break; |
| 200 } | 212 } |
| 201 case GL_TEXTURE_RECTANGLE_ARB: { | 213 case GL_TEXTURE_RECTANGLE_ARB: { |
| 202 IntSize textureSize(m_frame->width(), m_frame->height()); | 214 IntSize visibleSize(m_frame->visibleWidth(), m_frame->visibleHeight()); |
| 203 scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::create( sharedQuadState, quadRect, textureSize, m_frame->textureId(), IOSurfaceDrawQuad: :Unflipped); | 215 scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::create( sharedQuadState, quadRect, visibleSize, m_frame->textureId(), IOSurfaceDrawQuad: :Unflipped); |
| 204 quadSink.append(ioSurfaceQuad.PassAs<DrawQuad>(), appendQuadsData); | 216 quadSink.append(ioSurfaceQuad.PassAs<DrawQuad>(), appendQuadsData); |
| 205 break; | 217 break; |
| 206 } | 218 } |
| 207 case GL_TEXTURE_EXTERNAL_OES: { | 219 case GL_TEXTURE_EXTERNAL_OES: { |
| 208 // StreamTexture hardware decoder. | 220 // StreamTexture hardware decoder. |
| 209 scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = StreamVideoDrawQuad::c reate(sharedQuadState, quadRect, m_frame->textureId(), m_streamTextureMatrix); | 221 WebKit::WebTransformationMatrix transform(m_streamTextureMatrix); |
| 222 transform.scaleNonUniform(texWidthScale, texHeightScale); | |
| 223 scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = | |
| 224 StreamVideoDrawQuad::create(sharedQuadState, quadRect, | |
| 225 m_frame->textureId(), | |
| 226 m_streamTextureMatrix); | |
| 210 quadSink.append(streamVideoQuad.PassAs<DrawQuad>(), appendQuadsData); | 227 quadSink.append(streamVideoQuad.PassAs<DrawQuad>(), appendQuadsData); |
| 211 break; | 228 break; |
| 212 } | 229 } |
| 213 default: | 230 default: |
| 214 CRASH(); // Someone updated convertVFCFormatToGC3DFormat above but updat e this! | 231 CRASH(); // Someone updated convertVFCFormatToGC3DFormat above but updat e this! |
| 215 } | 232 } |
| 216 } | 233 } |
| 217 | 234 |
| 218 void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider) | 235 void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider) |
| 219 { | 236 { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 232 resourceProvider->deleteResource(m_externalTextureResource); | 249 resourceProvider->deleteResource(m_externalTextureResource); |
| 233 m_externalTextureResource = 0; | 250 m_externalTextureResource = 0; |
| 234 } | 251 } |
| 235 | 252 |
| 236 m_provider->putCurrentFrame(m_frame); | 253 m_provider->putCurrentFrame(m_frame); |
| 237 m_frame = 0; | 254 m_frame = 0; |
| 238 | 255 |
| 239 m_providerLock.Release(); | 256 m_providerLock.Release(); |
| 240 } | 257 } |
| 241 | 258 |
| 242 static int videoFrameDimension(int originalDimension, unsigned plane, int format ) | 259 bool VideoLayerImpl::FramePlane::allocateData( |
| 243 { | 260 ResourceProvider* resourceProvider) |
| 244 if (format == WebKit::WebVideoFrame::FormatYV12 && plane != WebKit::WebVideo Frame::yPlane) | |
| 245 return originalDimension / 2; | |
| 246 return originalDimension; | |
| 247 } | |
| 248 | |
| 249 static bool hasPaddingBytes(const WebKit::WebVideoFrame& frame, unsigned plane) | |
| 250 { | |
| 251 return frame.stride(plane) > videoFrameDimension(frame.width(), plane, frame .format()); | |
| 252 } | |
| 253 | |
| 254 IntSize VideoLayerImpl::computeVisibleSize(const WebKit::WebVideoFrame& frame, u nsigned plane) | |
| 255 { | |
| 256 int visibleWidth = videoFrameDimension(frame.width(), plane, frame.format()) ; | |
| 257 int originalWidth = visibleWidth; | |
| 258 int visibleHeight = videoFrameDimension(frame.height(), plane, frame.format( )); | |
| 259 | |
| 260 // When there are dead pixels at the edge of the texture, decrease | |
| 261 // the frame width by 1 to prevent the rightmost pixels from | |
| 262 // interpolating with the dead pixels. | |
| 263 if (hasPaddingBytes(frame, plane)) | |
| 264 --visibleWidth; | |
| 265 | |
| 266 // In YV12, every 2x2 square of Y values corresponds to one U and | |
| 267 // one V value. If we decrease the width of the UV plane, we must decrease t he | |
| 268 // width of the Y texture by 2 for proper alignment. This must happen | |
| 269 // always, even if Y's texture does not have padding bytes. | |
| 270 if (plane == WebKit::WebVideoFrame::yPlane && frame.format() == WebKit::WebV ideoFrame::FormatYV12) { | |
| 271 if (hasPaddingBytes(frame, WebKit::WebVideoFrame::uPlane)) | |
| 272 visibleWidth = originalWidth - 2; | |
| 273 } | |
| 274 | |
| 275 return IntSize(visibleWidth, visibleHeight); | |
| 276 } | |
| 277 | |
| 278 bool VideoLayerImpl::FramePlane::allocateData(ResourceProvider* resourceProvider ) | |
| 279 { | 261 { |
| 280 if (resourceId) | 262 if (resourceId) |
| 281 return true; | 263 return true; |
| 282 | 264 |
| 283 resourceId = resourceProvider->createResource(Renderer::ImplPool, size, form at, ResourceProvider::TextureUsageAny); | 265 resourceId = resourceProvider->createResource(Renderer::ImplPool, size, form at, ResourceProvider::TextureUsageAny); |
| 284 return resourceId; | 266 return resourceId; |
| 285 } | 267 } |
| 286 | 268 |
| 287 void VideoLayerImpl::FramePlane::freeData(ResourceProvider* resourceProvider) | 269 void VideoLayerImpl::FramePlane::freeData(ResourceProvider* resourceProvider) |
| 288 { | 270 { |
| 289 if (!resourceId) | 271 if (!resourceId) |
| 290 return; | 272 return; |
| 291 | 273 |
| 292 resourceProvider->deleteResource(resourceId); | 274 resourceProvider->deleteResource(resourceId); |
| 293 resourceId = 0; | 275 resourceId = 0; |
| 294 } | 276 } |
| 295 | 277 |
| 296 bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider) | 278 bool VideoLayerImpl::allocatePlaneData(ResourceProvider* resourceProvider) |
| 297 { | 279 { |
| 298 int maxTextureSize = resourceProvider->maxTextureSize(); | 280 int maxTextureSize = resourceProvider->maxTextureSize(); |
| 299 for (unsigned planeIndex = 0; planeIndex < m_frame->planes(); ++planeIndex) { | 281 for (unsigned planeIdx = 0; planeIdx < m_frame->planes(); ++planeIdx) { |
| 300 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex]; | 282 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIdx]; |
| 301 | 283 |
| 302 IntSize requiredTextureSize(m_frame->stride(planeIndex), videoFrameDimen sion(m_frame->height(), planeIndex, m_frame->format())); | 284 IntSize requiredTextureSize(m_frame->textureWidth(), |
| 303 // FIXME: Remove the test against maxTextureSize when tiled layers are i mplemented. | 285 m_frame->textureHeight()); |
| 304 if (requiredTextureSize.isZero() || requiredTextureSize.width() > maxTex tureSize || requiredTextureSize.height() > maxTextureSize) | 286 // FIXME: Remove the test against maxTextureSize when tiled layers are |
| 287 // implemented. | |
| 288 if (requiredTextureSize.isZero() || | |
| 289 requiredTextureSize.width() > maxTextureSize || | |
| 290 requiredTextureSize.height() > maxTextureSize) | |
| 305 return false; | 291 return false; |
| 306 | 292 |
| 307 if (plane.size != requiredTextureSize || plane.format != m_format) { | 293 if (plane.size != requiredTextureSize || plane.format != m_format) { |
| 308 plane.freeData(resourceProvider); | 294 plane.freeData(resourceProvider); |
| 309 plane.size = requiredTextureSize; | 295 plane.size = requiredTextureSize; |
| 310 plane.format = m_format; | 296 plane.format = m_format; |
| 311 } | 297 } |
| 312 | 298 |
| 313 if (!plane.resourceId) { | 299 if (!plane.allocateData(resourceProvider)) |
| 314 if (!plane.allocateData(resourceProvider)) | 300 return false; |
| 315 return false; | |
| 316 plane.visibleSize = computeVisibleSize(*m_frame, planeIndex); | |
| 317 } | |
| 318 } | 301 } |
| 319 return true; | 302 return true; |
| 320 } | 303 } |
| 321 | 304 |
| 322 bool VideoLayerImpl::copyPlaneData(ResourceProvider* resourceProvider) | 305 bool VideoLayerImpl::copyPlaneData(ResourceProvider* resourceProvider) |
| 323 { | 306 { |
| 324 size_t softwarePlaneCount = m_frame->planes(); | 307 for (unsigned planeIdx = 0; planeIdx < m_frame->planes(); ++planeIdx) { |
| 325 if (!softwarePlaneCount) | 308 VideoLayerImpl::FramePlane& plane = m_framePlanes[planeIdx]; |
| 326 return true; | 309 const uint8_t* planePixels = static_cast<const uint8_t*>( |
| 310 m_frame->data(planeIdx)); | |
|
jamesr
2012/10/25 00:26:34
General note for stuff in src/cc/ - we're still us
sheu
2012/10/25 01:53:54
Done.
| |
| 327 | 311 |
| 328 for (size_t softwarePlaneIndex = 0; softwarePlaneIndex < softwarePlaneCount; ++softwarePlaneIndex) { | 312 // Only non-FormatNativeTexture planes should need upload. |
| 329 VideoLayerImpl::FramePlane& plane = m_framePlanes[softwarePlaneIndex]; | 313 DCHECK(plane.format == GL_LUMINANCE); |
|
jamesr
2012/10/25 00:26:34
DCHECK_EQ please, it'll print the format if the ch
sheu
2012/10/25 01:53:54
Done.
| |
| 330 const uint8_t* softwarePlanePixels = static_cast<const uint8_t*>(m_frame ->data(softwarePlaneIndex)); | 314 |
| 331 IntRect planeRect(IntPoint(), plane.size); | 315 IntRect planeRect(0, 0, plane.size.width(), plane.size.height()); |
| 332 resourceProvider->upload(plane.resourceId, softwarePlanePixels, planeRec t, planeRect, IntSize()); | 316 IntRect visibleRect(0, 0, m_frame->textureWidth(), |
| 317 m_frame->textureHeight()); | |
| 318 resourceProvider->upload(plane.resourceId, planePixels, planeRect, | |
| 319 visibleRect, IntSize()); | |
| 333 } | 320 } |
| 334 return true; | 321 return true; |
| 335 } | 322 } |
| 336 | 323 |
| 337 void VideoLayerImpl::freePlaneData(ResourceProvider* resourceProvider) | 324 void VideoLayerImpl::freePlaneData(ResourceProvider* resourceProvider) |
| 338 { | 325 { |
| 339 for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) | 326 for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) |
| 340 m_framePlanes[i].freeData(resourceProvider); | 327 m_framePlanes[i].freeData(resourceProvider); |
| 341 } | 328 } |
| 342 | 329 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 378 str->append("video layer\n"); | 365 str->append("video layer\n"); |
| 379 LayerImpl::dumpLayerProperties(str, indent); | 366 LayerImpl::dumpLayerProperties(str, indent); |
| 380 } | 367 } |
| 381 | 368 |
| 382 const char* VideoLayerImpl::layerTypeAsString() const | 369 const char* VideoLayerImpl::layerTypeAsString() const |
| 383 { | 370 { |
| 384 return "VideoLayer"; | 371 return "VideoLayer"; |
| 385 } | 372 } |
| 386 | 373 |
| 387 } | 374 } |
| OLD | NEW |