| Index: cc/video_layer_impl.cc
|
| diff --git a/cc/video_layer_impl.cc b/cc/video_layer_impl.cc
|
| index b536bbe9f0dd7224b2957b10a0186c2b8d2eee3a..8a624bfa678eb242bc4553b27aad42be5596ef39 100644
|
| --- a/cc/video_layer_impl.cc
|
| +++ b/cc/video_layer_impl.cc
|
| @@ -13,6 +13,7 @@
|
| #include "cc/resource_provider.h"
|
| #include "cc/stream_video_draw_quad.h"
|
| #include "cc/texture_draw_quad.h"
|
| +#include "cc/video_frame_provider_client_impl.h"
|
| #include "cc/yuv_video_draw_quad.h"
|
| #include "gpu/GLES2/gl2extchromium.h"
|
| #include "media/filters/skcanvas_video_renderer.h"
|
| @@ -21,34 +22,36 @@
|
|
|
| namespace cc {
|
|
|
| -VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* treeImpl, int id, VideoFrameProvider* provider)
|
| +// static
|
| +scoped_ptr<VideoLayerImpl> VideoLayerImpl::create(LayerTreeImpl* treeImpl, int id, VideoFrameProvider* provider)
|
| +{
|
| + scoped_ptr<VideoLayerImpl> layer(new VideoLayerImpl(treeImpl, id));
|
| + layer->setProviderClientImpl(VideoFrameProviderClientImpl::Create(provider));
|
| + DCHECK(treeImpl->proxy()->isImplThread());
|
| + DCHECK(treeImpl->proxy()->isMainThreadBlocked());
|
| + return layer.Pass();
|
| +}
|
| +
|
| +VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* treeImpl, int id)
|
| : LayerImpl(treeImpl, id)
|
| - , m_provider(provider)
|
| , m_frame(0)
|
| , m_format(GL_INVALID_VALUE)
|
| , m_convertYUV(false)
|
| , m_externalTextureResource(0)
|
| {
|
| - // This matrix is the default transformation for stream textures, and flips on the Y axis.
|
| - m_streamTextureMatrix = gfx::Transform(
|
| - 1.0, 0.0, 0.0, 0.0,
|
| - 0.0, -1.0, 0.0, 1.0,
|
| - 0.0, 0.0, 1.0, 0.0,
|
| - 0.0, 0.0, 0.0, 1.0);
|
| -
|
| - // This only happens during a commit on the compositor thread while the main
|
| - // thread is blocked. That makes this a thread-safe call to set the video
|
| - // frame provider client that does not require a lock. The same is true of
|
| - // the call in the destructor.
|
| - m_provider->SetVideoFrameProviderClient(this);
|
| }
|
|
|
| VideoLayerImpl::~VideoLayerImpl()
|
| {
|
| - // See comment in constructor for why this doesn't need a lock.
|
| - if (m_provider) {
|
| - m_provider->SetVideoFrameProviderClient(0);
|
| - m_provider = 0;
|
| + if (!m_providerClientImpl->Stopped()) {
|
| + // In impl side painting, we may have a pending and active layer
|
| + // associated with the video provider at the same time. Both have a ref
|
| + // on the VideoFrameProviderClientImpl, but we stop when the first
|
| + // LayerImpl (the one on the pending tree) is destroyed since we know
|
| + // the main thread is blocked for this commit.
|
| + DCHECK(layerTreeImpl()->proxy()->isImplThread());
|
| + DCHECK(layerTreeImpl()->proxy()->isMainThreadBlocked());
|
| + m_providerClientImpl->Stop();
|
| }
|
| freePlaneData(layerTreeImpl()->resource_provider());
|
|
|
| @@ -59,13 +62,22 @@ VideoLayerImpl::~VideoLayerImpl()
|
| #endif
|
| }
|
|
|
| -void VideoLayerImpl::StopUsingProvider()
|
| +scoped_ptr<LayerImpl> VideoLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
|
| {
|
| - // Block the provider from shutting down until this client is done
|
| - // using the frame.
|
| - base::AutoLock locker(m_providerLock);
|
| - DCHECK(!m_frame);
|
| - m_provider = 0;
|
| + return scoped_ptr<LayerImpl>(new VideoLayerImpl(treeImpl, id()));
|
| +}
|
| +
|
| +void VideoLayerImpl::pushPropertiesTo(LayerImpl* layer)
|
| +{
|
| + LayerImpl::pushPropertiesTo(layer);
|
| +
|
| + VideoLayerImpl* other = static_cast<VideoLayerImpl*>(layer);
|
| + other->setProviderClientImpl(m_providerClientImpl);
|
| +}
|
| +
|
| +void VideoLayerImpl::didBecomeActive()
|
| +{
|
| + m_providerClientImpl->set_active_video_layer(this);
|
| }
|
|
|
| // Convert media::VideoFrame::Format to OpenGL enum values.
|
| @@ -116,6 +128,7 @@ void VideoLayerImpl::willDraw(ResourceProvider* resourceProvider)
|
| {
|
| LayerImpl::willDraw(resourceProvider);
|
|
|
| +
|
| // Explicitly acquire and release the provider mutex so it can be held from
|
| // willDraw to didDraw. Since the compositor thread is in the middle of
|
| // drawing, the layer will not be destroyed before didDraw is called.
|
| @@ -123,26 +136,19 @@ void VideoLayerImpl::willDraw(ResourceProvider* resourceProvider)
|
| // is the GPU process locking it. As the GPU process can't cause the
|
| // destruction of the provider (calling stopUsingProvider), holding this
|
| // lock should not cause a deadlock.
|
| - m_providerLock.Acquire();
|
| + m_frame = m_providerClientImpl->AcquireLockAndCurrentFrame();
|
|
|
| willDrawInternal(resourceProvider);
|
| freeUnusedPlaneData(resourceProvider);
|
|
|
| if (!m_frame)
|
| - m_providerLock.Release();
|
| + m_providerClientImpl->ReleaseLock();
|
| }
|
|
|
| void VideoLayerImpl::willDrawInternal(ResourceProvider* resourceProvider)
|
| {
|
| DCHECK(!m_externalTextureResource);
|
|
|
| - if (!m_provider) {
|
| - m_frame = 0;
|
| - return;
|
| - }
|
| -
|
| - m_frame = m_provider->GetCurrentFrame();
|
| -
|
| if (!m_frame)
|
| return;
|
|
|
| @@ -155,7 +161,7 @@ void VideoLayerImpl::willDrawInternal(ResourceProvider* resourceProvider)
|
| DCHECK_EQ(m_frame->visible_rect().y(), 0);
|
|
|
| if (m_format == GL_INVALID_VALUE) {
|
| - m_provider->PutCurrentFrame(m_frame);
|
| + m_providerClientImpl->PutCurrentFrame(m_frame);
|
| m_frame = 0;
|
| return;
|
| }
|
| @@ -172,13 +178,13 @@ void VideoLayerImpl::willDrawInternal(ResourceProvider* resourceProvider)
|
| m_format = GL_RGBA;
|
|
|
| if (!allocatePlaneData(resourceProvider)) {
|
| - m_provider->PutCurrentFrame(m_frame);
|
| + m_providerClientImpl->PutCurrentFrame(m_frame);
|
| m_frame = 0;
|
| return;
|
| }
|
|
|
| if (!copyPlaneData(resourceProvider)) {
|
| - m_provider->PutCurrentFrame(m_frame);
|
| + m_providerClientImpl->PutCurrentFrame(m_frame);
|
| m_frame = 0;
|
| return;
|
| }
|
| @@ -255,7 +261,7 @@ void VideoLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuad
|
| }
|
| case GL_TEXTURE_EXTERNAL_OES: {
|
| // StreamTexture hardware decoder.
|
| - gfx::Transform transform(m_streamTextureMatrix);
|
| + gfx::Transform transform(m_providerClientImpl->stream_texture_matrix());
|
| transform.Scale(texWidthScale, texHeightScale);
|
| scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = StreamVideoDrawQuad::Create();
|
| streamVideoQuad->SetNew(sharedQuadState, quadRect, opaqueRect, m_frame->texture_id(), transform);
|
| @@ -285,10 +291,10 @@ void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider)
|
| m_externalTextureResource = 0;
|
| }
|
|
|
| - m_provider->PutCurrentFrame(m_frame);
|
| + m_providerClientImpl->PutCurrentFrame(m_frame);
|
| m_frame = 0;
|
|
|
| - m_providerLock.Release();
|
| + m_providerClientImpl->ReleaseLock();
|
| }
|
|
|
| static gfx::Size videoFrameDimension(media::VideoFrame* frame, int plane) {
|
| @@ -397,21 +403,6 @@ void VideoLayerImpl::freeUnusedPlaneData(ResourceProvider* resourceProvider)
|
| m_framePlanes[i].freeData(resourceProvider);
|
| }
|
|
|
| -void VideoLayerImpl::DidReceiveFrame()
|
| -{
|
| - setNeedsRedraw();
|
| -}
|
| -
|
| -void VideoLayerImpl::DidUpdateMatrix(const float matrix[16])
|
| -{
|
| - m_streamTextureMatrix = gfx::Transform(
|
| - matrix[0], matrix[4], matrix[8], matrix[12],
|
| - matrix[1], matrix[5], matrix[9], matrix[13],
|
| - matrix[2], matrix[6], matrix[10], matrix[14],
|
| - matrix[3], matrix[7], matrix[11], matrix[15]);
|
| - setNeedsRedraw();
|
| -}
|
| -
|
| void VideoLayerImpl::didLoseOutputSurface()
|
| {
|
| freePlaneData(layerTreeImpl()->resource_provider());
|
| @@ -422,6 +413,11 @@ void VideoLayerImpl::setNeedsRedraw()
|
| layerTreeImpl()->SetNeedsRedraw();
|
| }
|
|
|
| +void VideoLayerImpl::setProviderClientImpl(scoped_refptr<VideoFrameProviderClientImpl> providerClientImpl)
|
| +{
|
| + m_providerClientImpl = providerClientImpl;
|
| +}
|
| +
|
| const char* VideoLayerImpl::layerTypeAsString() const
|
| {
|
| return "VideoLayer";
|
|
|