OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 13 matching lines...) Expand all Loading... |
24 */ | 24 */ |
25 | 25 |
26 #include "config.h" | 26 #include "config.h" |
27 | 27 |
28 #if USE(ACCELERATED_COMPOSITING) | 28 #if USE(ACCELERATED_COMPOSITING) |
29 | 29 |
30 #include "cc/CCVideoLayerImpl.h" | 30 #include "cc/CCVideoLayerImpl.h" |
31 | 31 |
32 #include "Extensions3DChromium.h" | 32 #include "Extensions3DChromium.h" |
33 #include "GraphicsContext3D.h" | 33 #include "GraphicsContext3D.h" |
34 #include "LayerRendererChromium.h" | 34 #include "LayerRendererChromium.h" // For GLC macro |
35 #include "LayerTextureSubImage.h" | 35 #include "LayerTextureSubImage.h" |
36 #include "NotImplemented.h" | 36 #include "NotImplemented.h" |
37 #include "ProgramBinding.h" | 37 #include "ProgramBinding.h" |
38 #include "TextureManager.h" // For TextureAllocator | 38 #include "TextureManager.h" // For TextureAllocator |
39 #include "cc/CCLayerTreeHostImpl.h" | 39 #include "cc/CCLayerTreeHostImpl.h" |
40 #include "cc/CCProxy.h" | 40 #include "cc/CCProxy.h" |
41 #include "cc/CCQuadCuller.h" | 41 #include "cc/CCQuadCuller.h" |
42 #include "cc/CCStreamVideoDrawQuad.h" | 42 #include "cc/CCStreamVideoDrawQuad.h" |
43 #include "cc/CCTextureDrawQuad.h" | 43 #include "cc/CCTextureDrawQuad.h" |
44 #include "cc/CCYUVVideoDrawQuad.h" | 44 #include "cc/CCYUVVideoDrawQuad.h" |
(...skipping 23 matching lines...) Expand all Loading... |
68 } | 68 } |
69 | 69 |
70 CCVideoLayerImpl::~CCVideoLayerImpl() | 70 CCVideoLayerImpl::~CCVideoLayerImpl() |
71 { | 71 { |
72 // See comment in constructor for why this doesn't need a lock. | 72 // See comment in constructor for why this doesn't need a lock. |
73 ASSERT(CCProxy::isMainThreadBlocked()); | 73 ASSERT(CCProxy::isMainThreadBlocked()); |
74 if (m_provider) { | 74 if (m_provider) { |
75 m_provider->setVideoFrameProviderClient(0); | 75 m_provider->setVideoFrameProviderClient(0); |
76 m_provider = 0; | 76 m_provider = 0; |
77 } | 77 } |
78 freePlaneData(layerTreeHostImpl()->layerRenderer()); | 78 freePlaneData(layerTreeHostImpl()->context()); |
79 | 79 |
80 #if !ASSERT_DISABLED | 80 #if !ASSERT_DISABLED |
81 for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) | 81 for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) |
82 ASSERT(!m_framePlanes[i].textureId); | 82 ASSERT(!m_framePlanes[i].textureId); |
83 #endif | 83 #endif |
84 } | 84 } |
85 | 85 |
86 void CCVideoLayerImpl::stopUsingProvider() | 86 void CCVideoLayerImpl::stopUsingProvider() |
87 { | 87 { |
88 // Block the provider from shutting down until this client is done | 88 // Block the provider from shutting down until this client is done |
(...skipping 29 matching lines...) Expand all Loading... |
118 // Explicitly lock and unlock the provider mutex so it can be held from | 118 // Explicitly lock and unlock the provider mutex so it can be held from |
119 // willDraw to didDraw. Since the compositor thread is in the middle of | 119 // willDraw to didDraw. Since the compositor thread is in the middle of |
120 // drawing, the layer will not be destroyed before didDraw is called. | 120 // drawing, the layer will not be destroyed before didDraw is called. |
121 // Therefore, the only thing that will prevent this lock from being released | 121 // Therefore, the only thing that will prevent this lock from being released |
122 // is the GPU process locking it. As the GPU process can't cause the | 122 // is the GPU process locking it. As the GPU process can't cause the |
123 // destruction of the provider (calling stopUsingProvider), holding this | 123 // destruction of the provider (calling stopUsingProvider), holding this |
124 // lock should not cause a deadlock. | 124 // lock should not cause a deadlock. |
125 m_providerMutex.lock(); | 125 m_providerMutex.lock(); |
126 | 126 |
127 willDrawInternal(layerRenderer, context); | 127 willDrawInternal(layerRenderer, context); |
128 freeUnusedPlaneData(layerRenderer); | 128 freeUnusedPlaneData(context); |
129 | 129 |
130 if (!m_frame) | 130 if (!m_frame) |
131 m_providerMutex.unlock(); | 131 m_providerMutex.unlock(); |
132 } | 132 } |
133 | 133 |
134 void CCVideoLayerImpl::willDrawInternal(CCRenderer* layerRenderer, CCGraphicsCon
text* context) | 134 void CCVideoLayerImpl::willDrawInternal(CCRenderer* layerRenderer, CCGraphicsCon
text* context) |
135 { | 135 { |
136 ASSERT(CCProxy::isImplThread()); | 136 ASSERT(CCProxy::isImplThread()); |
137 | 137 |
138 if (!m_provider) { | 138 if (!m_provider) { |
(...skipping 13 matching lines...) Expand all Loading... |
152 m_frame = 0; | 152 m_frame = 0; |
153 return; | 153 return; |
154 } | 154 } |
155 | 155 |
156 if (m_frame->planes() > WebKit::WebVideoFrame::maxPlanes) { | 156 if (m_frame->planes() > WebKit::WebVideoFrame::maxPlanes) { |
157 m_provider->putCurrentFrame(m_frame); | 157 m_provider->putCurrentFrame(m_frame); |
158 m_frame = 0; | 158 m_frame = 0; |
159 return; | 159 return; |
160 } | 160 } |
161 | 161 |
162 if (!allocatePlaneData(layerRenderer)) { | 162 if (!allocatePlaneData(layerRenderer, context)) { |
163 m_provider->putCurrentFrame(m_frame); | 163 m_provider->putCurrentFrame(m_frame); |
164 m_frame = 0; | 164 m_frame = 0; |
165 return; | 165 return; |
166 } | 166 } |
167 | 167 |
168 if (!copyPlaneData(layerRenderer, context)) { | 168 if (!copyPlaneData(layerRenderer, context)) { |
169 m_provider->putCurrentFrame(m_frame); | 169 m_provider->putCurrentFrame(m_frame); |
170 m_frame = 0; | 170 m_frame = 0; |
171 return; | 171 return; |
172 } | 172 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 // width of the Y texture by 2 for proper alignment. This must happen | 275 // width of the Y texture by 2 for proper alignment. This must happen |
276 // always, even if Y's texture does not have padding bytes. | 276 // always, even if Y's texture does not have padding bytes. |
277 if (plane == WebKit::WebVideoFrame::yPlane && frame.format() == WebKit::WebV
ideoFrame::FormatYV12) { | 277 if (plane == WebKit::WebVideoFrame::yPlane && frame.format() == WebKit::WebV
ideoFrame::FormatYV12) { |
278 if (hasPaddingBytes(frame, WebKit::WebVideoFrame::uPlane)) | 278 if (hasPaddingBytes(frame, WebKit::WebVideoFrame::uPlane)) |
279 visibleWidth = originalWidth - 2; | 279 visibleWidth = originalWidth - 2; |
280 } | 280 } |
281 | 281 |
282 return IntSize(visibleWidth, visibleHeight); | 282 return IntSize(visibleWidth, visibleHeight); |
283 } | 283 } |
284 | 284 |
285 bool CCVideoLayerImpl::FramePlane::allocateData(CCRenderer* layerRenderer) | 285 bool CCVideoLayerImpl::FramePlane::allocateData(CCGraphicsContext* context) |
286 { | 286 { |
287 if (textureId) | 287 if (textureId) |
288 return true; | 288 return true; |
289 | 289 |
290 textureId = layerRenderer->contentsTextureAllocator()->createTexture(size, f
ormat); | 290 GraphicsContext3D* context3D = context->context3D(); |
| 291 if (!context3D) |
| 292 return false; |
| 293 |
| 294 GLC(context3D, textureId = context3D->createTexture()); |
| 295 GLC(context3D, context3D->bindTexture(GraphicsContext3D::TEXTURE_2D, texture
Id)); |
| 296 // Do basic linear filtering on resize. |
| 297 GLC(context3D, context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, Graph
icsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); |
| 298 GLC(context3D, context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, Graph
icsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); |
| 299 // NPOT textures in GL ES only work when the wrap mode is set to GraphicsCon
text3D::CLAMP_TO_EDGE. |
| 300 GLC(context3D, context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, Graph
icsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE)); |
| 301 GLC(context3D, context3D->texParameteri(GraphicsContext3D::TEXTURE_2D, Graph
icsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE)); |
| 302 |
| 303 GLC(context3D, context3D->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_
2D, 0, format, size.width(), size.height(), 0, format, GraphicsContext3D::UNSIGN
ED_BYTE)); |
| 304 |
291 return textureId; | 305 return textureId; |
292 } | 306 } |
293 | 307 |
294 void CCVideoLayerImpl::FramePlane::freeData(CCRenderer* layerRenderer) | 308 void CCVideoLayerImpl::FramePlane::freeData(CCGraphicsContext* context) |
295 { | 309 { |
296 if (!textureId) | 310 if (!textureId) |
297 return; | 311 return; |
298 | 312 |
299 layerRenderer->contentsTextureAllocator()->deleteTexture(textureId, size, fo
rmat); | 313 GraphicsContext3D* context3D = context->context3D(); |
| 314 if (!context3D) |
| 315 return; |
| 316 |
| 317 GLC(context3D, context3D->deleteTexture(textureId)); |
300 textureId = 0; | 318 textureId = 0; |
301 } | 319 } |
302 | 320 |
303 bool CCVideoLayerImpl::allocatePlaneData(CCRenderer* layerRenderer) | 321 bool CCVideoLayerImpl::allocatePlaneData(CCRenderer* layerRenderer, CCGraphicsCo
ntext* context) |
304 { | 322 { |
305 int maxTextureSize = layerRenderer->capabilities().maxTextureSize; | 323 int maxTextureSize = layerRenderer->capabilities().maxTextureSize; |
306 for (unsigned planeIndex = 0; planeIndex < m_frame->planes(); ++planeIndex)
{ | 324 for (unsigned planeIndex = 0; planeIndex < m_frame->planes(); ++planeIndex)
{ |
307 CCVideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex]; | 325 CCVideoLayerImpl::FramePlane& plane = m_framePlanes[planeIndex]; |
308 | 326 |
309 IntSize requiredTextureSize(m_frame->stride(planeIndex), videoFrameDimen
sion(m_frame->height(), planeIndex, m_frame->format())); | 327 IntSize requiredTextureSize(m_frame->stride(planeIndex), videoFrameDimen
sion(m_frame->height(), planeIndex, m_frame->format())); |
310 // FIXME: Remove the test against maxTextureSize when tiled layers are i
mplemented. | 328 // FIXME: Remove the test against maxTextureSize when tiled layers are i
mplemented. |
311 if (requiredTextureSize.isZero() || requiredTextureSize.width() > maxTex
tureSize || requiredTextureSize.height() > maxTextureSize) | 329 if (requiredTextureSize.isZero() || requiredTextureSize.width() > maxTex
tureSize || requiredTextureSize.height() > maxTextureSize) |
312 return false; | 330 return false; |
313 | 331 |
314 if (plane.size != requiredTextureSize || plane.format != m_format) { | 332 if (plane.size != requiredTextureSize || plane.format != m_format) { |
315 plane.freeData(layerRenderer); | 333 plane.freeData(context); |
316 plane.size = requiredTextureSize; | 334 plane.size = requiredTextureSize; |
317 plane.format = m_format; | 335 plane.format = m_format; |
318 } | 336 } |
319 | 337 |
320 if (!plane.textureId) { | 338 if (!plane.textureId) { |
321 if (!plane.allocateData(layerRenderer)) | 339 if (!plane.allocateData(context)) |
322 return false; | 340 return false; |
323 plane.visibleSize = computeVisibleSize(*m_frame, planeIndex); | 341 plane.visibleSize = computeVisibleSize(*m_frame, planeIndex); |
324 } | 342 } |
325 } | 343 } |
326 return true; | 344 return true; |
327 } | 345 } |
328 | 346 |
329 bool CCVideoLayerImpl::copyPlaneData(CCRenderer* layerRenderer, CCGraphicsContex
t* context) | 347 bool CCVideoLayerImpl::copyPlaneData(CCRenderer* layerRenderer, CCGraphicsContex
t* context) |
330 { | 348 { |
331 size_t softwarePlaneCount = m_frame->planes(); | 349 size_t softwarePlaneCount = m_frame->planes(); |
(...skipping 12 matching lines...) Expand all Loading... |
344 const uint8_t* softwarePlanePixels = static_cast<const uint8_t*>(m_frame
->data(softwarePlaneIndex)); | 362 const uint8_t* softwarePlanePixels = static_cast<const uint8_t*>(m_frame
->data(softwarePlaneIndex)); |
345 IntRect planeRect(IntPoint(), plane.size); | 363 IntRect planeRect(IntPoint(), plane.size); |
346 | 364 |
347 context3d->bindTexture(GraphicsContext3D::TEXTURE_2D, plane.textureId); | 365 context3d->bindTexture(GraphicsContext3D::TEXTURE_2D, plane.textureId); |
348 uploader.setSubImageSize(plane.size); | 366 uploader.setSubImageSize(plane.size); |
349 uploader.upload(softwarePlanePixels, planeRect, planeRect, planeRect, pl
ane.format, context); | 367 uploader.upload(softwarePlanePixels, planeRect, planeRect, planeRect, pl
ane.format, context); |
350 } | 368 } |
351 return true; | 369 return true; |
352 } | 370 } |
353 | 371 |
354 void CCVideoLayerImpl::freePlaneData(CCRenderer* layerRenderer) | 372 void CCVideoLayerImpl::freePlaneData(CCGraphicsContext* context) |
355 { | 373 { |
356 for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) | 374 for (unsigned i = 0; i < WebKit::WebVideoFrame::maxPlanes; ++i) |
357 m_framePlanes[i].freeData(layerRenderer); | 375 m_framePlanes[i].freeData(context); |
358 } | 376 } |
359 | 377 |
360 void CCVideoLayerImpl::freeUnusedPlaneData(CCRenderer* layerRenderer) | 378 void CCVideoLayerImpl::freeUnusedPlaneData(CCGraphicsContext* context) |
361 { | 379 { |
362 unsigned firstUnusedPlane = m_frame ? m_frame->planes() : 0; | 380 unsigned firstUnusedPlane = m_frame ? m_frame->planes() : 0; |
363 for (unsigned i = firstUnusedPlane; i < WebKit::WebVideoFrame::maxPlanes; ++
i) | 381 for (unsigned i = firstUnusedPlane; i < WebKit::WebVideoFrame::maxPlanes; ++
i) |
364 m_framePlanes[i].freeData(layerRenderer); | 382 m_framePlanes[i].freeData(context); |
365 } | 383 } |
366 | 384 |
367 void CCVideoLayerImpl::didReceiveFrame() | 385 void CCVideoLayerImpl::didReceiveFrame() |
368 { | 386 { |
369 setNeedsRedraw(); | 387 setNeedsRedraw(); |
370 } | 388 } |
371 | 389 |
372 void CCVideoLayerImpl::didUpdateMatrix(const float matrix[16]) | 390 void CCVideoLayerImpl::didUpdateMatrix(const float matrix[16]) |
373 { | 391 { |
374 m_streamTextureMatrix = WebKit::WebTransformationMatrix( | 392 m_streamTextureMatrix = WebKit::WebTransformationMatrix( |
375 matrix[0], matrix[1], matrix[2], matrix[3], | 393 matrix[0], matrix[1], matrix[2], matrix[3], |
376 matrix[4], matrix[5], matrix[6], matrix[7], | 394 matrix[4], matrix[5], matrix[6], matrix[7], |
377 matrix[8], matrix[9], matrix[10], matrix[11], | 395 matrix[8], matrix[9], matrix[10], matrix[11], |
378 matrix[12], matrix[13], matrix[14], matrix[15]); | 396 matrix[12], matrix[13], matrix[14], matrix[15]); |
379 setNeedsRedraw(); | 397 setNeedsRedraw(); |
380 } | 398 } |
381 | 399 |
382 void CCVideoLayerImpl::didLoseContext() | 400 void CCVideoLayerImpl::didLoseContext() |
383 { | 401 { |
384 freePlaneData(layerTreeHostImpl()->layerRenderer()); | 402 freePlaneData(layerTreeHostImpl()->context()); |
385 } | 403 } |
386 | 404 |
387 void CCVideoLayerImpl::setNeedsRedraw() | 405 void CCVideoLayerImpl::setNeedsRedraw() |
388 { | 406 { |
389 layerTreeHostImpl()->setNeedsRedraw(); | 407 layerTreeHostImpl()->setNeedsRedraw(); |
390 } | 408 } |
391 | 409 |
392 void CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const | 410 void CCVideoLayerImpl::dumpLayerProperties(TextStream& ts, int indent) const |
393 { | 411 { |
394 writeIndent(ts, indent); | 412 writeIndent(ts, indent); |
395 ts << "video layer\n"; | 413 ts << "video layer\n"; |
396 CCLayerImpl::dumpLayerProperties(ts, indent); | 414 CCLayerImpl::dumpLayerProperties(ts, indent); |
397 } | 415 } |
398 | 416 |
399 } | 417 } |
400 | 418 |
401 #endif // USE(ACCELERATED_COMPOSITING) | 419 #endif // USE(ACCELERATED_COMPOSITING) |
OLD | NEW |