Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Side by Side Diff: cc/video_layer_impl.cc

Issue 11882037: Activate LayerImpl tree with sync+push instead of pointer swap (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "cc/video_layer_impl.h" 5 #include "cc/video_layer_impl.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "cc/io_surface_draw_quad.h" 8 #include "cc/io_surface_draw_quad.h"
9 #include "cc/layer_tree_impl.h" 9 #include "cc/layer_tree_impl.h"
10 #include "cc/math_util.h" 10 #include "cc/math_util.h"
11 #include "cc/quad_sink.h" 11 #include "cc/quad_sink.h"
12 #include "cc/renderer.h" 12 #include "cc/renderer.h"
13 #include "cc/resource_provider.h" 13 #include "cc/resource_provider.h"
14 #include "cc/stream_video_draw_quad.h" 14 #include "cc/stream_video_draw_quad.h"
15 #include "cc/texture_draw_quad.h" 15 #include "cc/texture_draw_quad.h"
16 #include "cc/video_frame_provider_client_impl.h"
16 #include "cc/yuv_video_draw_quad.h" 17 #include "cc/yuv_video_draw_quad.h"
17 #include "gpu/GLES2/gl2extchromium.h" 18 #include "gpu/GLES2/gl2extchromium.h"
18 #include "media/filters/skcanvas_video_renderer.h" 19 #include "media/filters/skcanvas_video_renderer.h"
19 #include "third_party/khronos/GLES2/gl2.h" 20 #include "third_party/khronos/GLES2/gl2.h"
20 #include "third_party/khronos/GLES2/gl2ext.h" 21 #include "third_party/khronos/GLES2/gl2ext.h"
21 22
22 namespace cc { 23 namespace cc {
23 24
24 VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* treeImpl, int id, VideoFrameProvid er* provider) 25 // static
26 scoped_ptr<VideoLayerImpl> VideoLayerImpl::create(LayerTreeImpl* treeImpl, int i d, VideoFrameProvider* provider)
27 {
28 scoped_ptr<VideoLayerImpl> layer(new VideoLayerImpl(treeImpl, id));
29 layer->setProviderClientImpl(VideoFrameProviderClientImpl::Create(provider)) ;
30 return layer.Pass();
31 }
32
33 VideoLayerImpl::VideoLayerImpl(LayerTreeImpl* treeImpl, int id)
25 : LayerImpl(treeImpl, id) 34 : LayerImpl(treeImpl, id)
26 , m_provider(provider)
27 , m_frame(0) 35 , m_frame(0)
28 , m_format(GL_INVALID_VALUE) 36 , m_format(GL_INVALID_VALUE)
29 , m_convertYUV(false) 37 , m_convertYUV(false)
30 , m_externalTextureResource(0) 38 , m_externalTextureResource(0)
31 { 39 {
32 // This matrix is the default transformation for stream textures, and flips on the Y axis.
33 m_streamTextureMatrix = gfx::Transform(
34 1.0, 0.0, 0.0, 0.0,
35 0.0, -1.0, 0.0, 1.0,
36 0.0, 0.0, 1.0, 0.0,
37 0.0, 0.0, 0.0, 1.0);
38
39 // This only happens during a commit on the compositor thread while the main
40 // thread is blocked. That makes this a thread-safe call to set the video
41 // frame provider client that does not require a lock. The same is true of
42 // the call in the destructor.
43 m_provider->SetVideoFrameProviderClient(this);
44 } 40 }
45 41
46 VideoLayerImpl::~VideoLayerImpl() 42 VideoLayerImpl::~VideoLayerImpl()
47 { 43 {
48 // See comment in constructor for why this doesn't need a lock. 44 // In impl side painting, we may have a pending and active layer
49 if (m_provider) { 45 // associated with the video provider at the same time. Both have a ref on
50 m_provider->SetVideoFrameProviderClient(0); 46 // the VideoFrameProviderClientImpl, but we stop when the first LayerImpl
51 m_provider = 0; 47 // (the one on the pending tree) is destroyed since we know the impl
52 } 48 // thread is blocked for this commit.
49 m_providerClientImpl->Stop();
53 freePlaneData(layerTreeImpl()->resource_provider()); 50 freePlaneData(layerTreeImpl()->resource_provider());
54 51
55 #ifndef NDEBUG 52 #ifndef NDEBUG
56 for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; ++i) 53 for (size_t i = 0; i < media::VideoFrame::kMaxPlanes; ++i)
57 DCHECK(!m_framePlanes[i].resourceId); 54 DCHECK(!m_framePlanes[i].resourceId);
58 DCHECK(!m_externalTextureResource); 55 DCHECK(!m_externalTextureResource);
59 #endif 56 #endif
60 } 57 }
61 58
62 void VideoLayerImpl::StopUsingProvider() 59 scoped_ptr<LayerImpl> VideoLayerImpl::createLayerImpl(LayerTreeImpl* treeImpl)
63 { 60 {
64 // Block the provider from shutting down until this client is done 61 return scoped_ptr<LayerImpl>(new VideoLayerImpl(treeImpl, id()));
65 // using the frame. 62 }
66 base::AutoLock locker(m_providerLock); 63
67 DCHECK(!m_frame); 64 void VideoLayerImpl::pushPropertiesTo(LayerImpl* layer)
68 m_provider = 0; 65 {
66 LayerImpl::pushPropertiesTo(layer);
67
68 VideoLayerImpl* other = static_cast<VideoLayerImpl*>(layer);
69 other->setProviderClientImpl(m_providerClientImpl);
70 }
71
72 void VideoLayerImpl::didBecomeActive()
73 {
74 m_providerClientImpl->set_active_video_layer(this);
69 } 75 }
70 76
71 // Convert media::VideoFrame::Format to OpenGL enum values. 77 // Convert media::VideoFrame::Format to OpenGL enum values.
72 static GLenum convertVFCFormatToGLenum(const media::VideoFrame& frame) 78 static GLenum convertVFCFormatToGLenum(const media::VideoFrame& frame)
73 { 79 {
74 switch (frame.format()) { 80 switch (frame.format()) {
75 case media::VideoFrame::YV12: 81 case media::VideoFrame::YV12:
76 case media::VideoFrame::YV16: 82 case media::VideoFrame::YV16:
77 return GL_LUMINANCE; 83 return GL_LUMINANCE;
78 case media::VideoFrame::NATIVE_TEXTURE: 84 case media::VideoFrame::NATIVE_TEXTURE:
(...skipping 30 matching lines...) Expand all
109 return 0; 115 return 0;
110 } 116 }
111 NOTREACHED(); 117 NOTREACHED();
112 return 0; 118 return 0;
113 } 119 }
114 120
115 void VideoLayerImpl::willDraw(ResourceProvider* resourceProvider) 121 void VideoLayerImpl::willDraw(ResourceProvider* resourceProvider)
116 { 122 {
117 LayerImpl::willDraw(resourceProvider); 123 LayerImpl::willDraw(resourceProvider);
118 124
125
119 // Explicitly acquire and release the provider mutex so it can be held from 126 // Explicitly acquire and release the provider mutex so it can be held from
120 // willDraw to didDraw. Since the compositor thread is in the middle of 127 // willDraw to didDraw. Since the compositor thread is in the middle of
121 // drawing, the layer will not be destroyed before didDraw is called. 128 // drawing, the layer will not be destroyed before didDraw is called.
122 // Therefore, the only thing that will prevent this lock from being released 129 // Therefore, the only thing that will prevent this lock from being released
123 // is the GPU process locking it. As the GPU process can't cause the 130 // is the GPU process locking it. As the GPU process can't cause the
124 // destruction of the provider (calling stopUsingProvider), holding this 131 // destruction of the provider (calling stopUsingProvider), holding this
125 // lock should not cause a deadlock. 132 // lock should not cause a deadlock.
126 m_providerLock.Acquire(); 133 m_frame = m_providerClientImpl->AcquireLockAndCurrentFrame();
127 134
128 willDrawInternal(resourceProvider); 135 willDrawInternal(resourceProvider);
129 freeUnusedPlaneData(resourceProvider); 136 freeUnusedPlaneData(resourceProvider);
130 137
131 if (!m_frame) 138 if (!m_frame)
132 m_providerLock.Release(); 139 m_providerClientImpl->ReleaseLock();
133 } 140 }
134 141
135 void VideoLayerImpl::willDrawInternal(ResourceProvider* resourceProvider) 142 void VideoLayerImpl::willDrawInternal(ResourceProvider* resourceProvider)
136 { 143 {
137 DCHECK(!m_externalTextureResource); 144 DCHECK(!m_externalTextureResource);
138 145
139 if (!m_provider) {
140 m_frame = 0;
141 return;
142 }
143
144 m_frame = m_provider->GetCurrentFrame();
145
146 if (!m_frame) 146 if (!m_frame)
147 return; 147 return;
148 148
149 m_format = convertVFCFormatToGLenum(*m_frame); 149 m_format = convertVFCFormatToGLenum(*m_frame);
150 150
151 // If these fail, we'll have to add draw logic that handles offset bitmap/ 151 // If these fail, we'll have to add draw logic that handles offset bitmap/
152 // texture UVs. For now, just expect (0, 0) offset, since all our decoders 152 // texture UVs. For now, just expect (0, 0) offset, since all our decoders
153 // so far don't offset. 153 // so far don't offset.
154 DCHECK_EQ(m_frame->visible_rect().x(), 0); 154 DCHECK_EQ(m_frame->visible_rect().x(), 0);
155 DCHECK_EQ(m_frame->visible_rect().y(), 0); 155 DCHECK_EQ(m_frame->visible_rect().y(), 0);
156 156
157 if (m_format == GL_INVALID_VALUE) { 157 if (m_format == GL_INVALID_VALUE) {
158 m_provider->PutCurrentFrame(m_frame); 158 m_providerClientImpl->PutCurrentFrame(m_frame);
159 m_frame = 0; 159 m_frame = 0;
160 return; 160 return;
161 } 161 }
162 162
163 // FIXME: If we're in software compositing mode, we do the YUV -> RGB 163 // FIXME: If we're in software compositing mode, we do the YUV -> RGB
164 // conversion here. That involves an extra copy of each frame to a bitmap. 164 // conversion here. That involves an extra copy of each frame to a bitmap.
165 // Obviously, this is suboptimal and should be addressed once ubercompositor 165 // Obviously, this is suboptimal and should be addressed once ubercompositor
166 // starts shaping up. 166 // starts shaping up.
167 m_convertYUV = resourceProvider->defaultResourceType() == ResourceProvider:: Bitmap && 167 m_convertYUV = resourceProvider->defaultResourceType() == ResourceProvider:: Bitmap &&
168 (m_frame->format() == media::VideoFrame::YV12 || 168 (m_frame->format() == media::VideoFrame::YV12 ||
169 m_frame->format() == media::VideoFrame::YV16); 169 m_frame->format() == media::VideoFrame::YV16);
170 170
171 if (m_convertYUV) 171 if (m_convertYUV)
172 m_format = GL_RGBA; 172 m_format = GL_RGBA;
173 173
174 if (!allocatePlaneData(resourceProvider)) { 174 if (!allocatePlaneData(resourceProvider)) {
175 m_provider->PutCurrentFrame(m_frame); 175 m_providerClientImpl->PutCurrentFrame(m_frame);
176 m_frame = 0; 176 m_frame = 0;
177 return; 177 return;
178 } 178 }
179 179
180 if (!copyPlaneData(resourceProvider)) { 180 if (!copyPlaneData(resourceProvider)) {
181 m_provider->PutCurrentFrame(m_frame); 181 m_providerClientImpl->PutCurrentFrame(m_frame);
182 m_frame = 0; 182 m_frame = 0;
183 return; 183 return;
184 } 184 }
185 185
186 if (m_format == GL_TEXTURE_2D) 186 if (m_format == GL_TEXTURE_2D)
187 m_externalTextureResource = resourceProvider->createResourceFromExternal Texture(m_frame->texture_id()); 187 m_externalTextureResource = resourceProvider->createResourceFromExternal Texture(m_frame->texture_id());
188 } 188 }
189 189
190 void VideoLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuad sData) 190 void VideoLayerImpl::appendQuads(QuadSink& quadSink, AppendQuadsData& appendQuad sData)
191 { 191 {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 } 246 }
247 case GL_TEXTURE_RECTANGLE_ARB: { 247 case GL_TEXTURE_RECTANGLE_ARB: {
248 gfx::Size visibleSize(visibleRect.width(), visibleRect.height()); 248 gfx::Size visibleSize(visibleRect.width(), visibleRect.height());
249 scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::Create( ); 249 scoped_ptr<IOSurfaceDrawQuad> ioSurfaceQuad = IOSurfaceDrawQuad::Create( );
250 ioSurfaceQuad->SetNew(sharedQuadState, quadRect, opaqueRect, visibleSize , m_frame->texture_id(), IOSurfaceDrawQuad::UNFLIPPED); 250 ioSurfaceQuad->SetNew(sharedQuadState, quadRect, opaqueRect, visibleSize , m_frame->texture_id(), IOSurfaceDrawQuad::UNFLIPPED);
251 quadSink.append(ioSurfaceQuad.PassAs<DrawQuad>(), appendQuadsData); 251 quadSink.append(ioSurfaceQuad.PassAs<DrawQuad>(), appendQuadsData);
252 break; 252 break;
253 } 253 }
254 case GL_TEXTURE_EXTERNAL_OES: { 254 case GL_TEXTURE_EXTERNAL_OES: {
255 // StreamTexture hardware decoder. 255 // StreamTexture hardware decoder.
256 gfx::Transform transform(m_streamTextureMatrix); 256 gfx::Transform transform(m_providerClientImpl->stream_texture_matrix());
257 transform.Scale(texWidthScale, texHeightScale); 257 transform.Scale(texWidthScale, texHeightScale);
258 scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = StreamVideoDrawQuad::C reate(); 258 scoped_ptr<StreamVideoDrawQuad> streamVideoQuad = StreamVideoDrawQuad::C reate();
259 streamVideoQuad->SetNew(sharedQuadState, quadRect, opaqueRect, m_frame-> texture_id(), transform); 259 streamVideoQuad->SetNew(sharedQuadState, quadRect, opaqueRect, m_frame-> texture_id(), transform);
260 quadSink.append(streamVideoQuad.PassAs<DrawQuad>(), appendQuadsData); 260 quadSink.append(streamVideoQuad.PassAs<DrawQuad>(), appendQuadsData);
261 break; 261 break;
262 } 262 }
263 default: 263 default:
264 NOTREACHED(); // Someone updated convertVFCFormatToGLenum above but upd ate this! 264 NOTREACHED(); // Someone updated convertVFCFormatToGLenum above but upd ate this!
265 break; 265 break;
266 } 266 }
267 } 267 }
268 268
269 void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider) 269 void VideoLayerImpl::didDraw(ResourceProvider* resourceProvider)
270 { 270 {
271 LayerImpl::didDraw(resourceProvider); 271 LayerImpl::didDraw(resourceProvider);
272 272
273 if (!m_frame) 273 if (!m_frame)
274 return; 274 return;
275 275
276 if (m_format == GL_TEXTURE_2D) { 276 if (m_format == GL_TEXTURE_2D) {
277 DCHECK(m_externalTextureResource); 277 DCHECK(m_externalTextureResource);
278 // FIXME: the following assert will not be true when sending resources t o a 278 // FIXME: the following assert will not be true when sending resources t o a
279 // parent compositor. We will probably need to hold on to m_frame for 279 // parent compositor. We will probably need to hold on to m_frame for
280 // longer, and have several "current frames" in the pipeline. 280 // longer, and have several "current frames" in the pipeline.
281 DCHECK(!resourceProvider->inUseByConsumer(m_externalTextureResource)); 281 DCHECK(!resourceProvider->inUseByConsumer(m_externalTextureResource));
282 resourceProvider->deleteResource(m_externalTextureResource); 282 resourceProvider->deleteResource(m_externalTextureResource);
283 m_externalTextureResource = 0; 283 m_externalTextureResource = 0;
284 } 284 }
285 285
286 m_provider->PutCurrentFrame(m_frame); 286 m_providerClientImpl->PutCurrentFrame(m_frame);
287 m_frame = 0; 287 m_frame = 0;
288 288
289 m_providerLock.Release(); 289 m_providerClientImpl->ReleaseLock();
290 } 290 }
291 291
292 static gfx::Size videoFrameDimension(media::VideoFrame* frame, int plane) { 292 static gfx::Size videoFrameDimension(media::VideoFrame* frame, int plane) {
293 gfx::Size dimensions = frame->coded_size(); 293 gfx::Size dimensions = frame->coded_size();
294 switch (frame->format()) { 294 switch (frame->format()) {
295 case media::VideoFrame::YV12: 295 case media::VideoFrame::YV12:
296 if (plane != media::VideoFrame::kYPlane) { 296 if (plane != media::VideoFrame::kYPlane) {
297 dimensions.set_width(dimensions.width() / 2); 297 dimensions.set_width(dimensions.width() / 2);
298 dimensions.set_height(dimensions.height() / 2); 298 dimensions.set_height(dimensions.height() / 2);
299 } 299 }
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 m_framePlanes[i].freeData(resourceProvider); 388 m_framePlanes[i].freeData(resourceProvider);
389 } 389 }
390 390
391 void VideoLayerImpl::freeUnusedPlaneData(ResourceProvider* resourceProvider) 391 void VideoLayerImpl::freeUnusedPlaneData(ResourceProvider* resourceProvider)
392 { 392 {
393 size_t firstUnusedPlane = numPlanes(); 393 size_t firstUnusedPlane = numPlanes();
394 for (size_t i = firstUnusedPlane; i < media::VideoFrame::kMaxPlanes; ++i) 394 for (size_t i = firstUnusedPlane; i < media::VideoFrame::kMaxPlanes; ++i)
395 m_framePlanes[i].freeData(resourceProvider); 395 m_framePlanes[i].freeData(resourceProvider);
396 } 396 }
397 397
398 void VideoLayerImpl::DidReceiveFrame()
399 {
400 setNeedsRedraw();
401 }
402
403 void VideoLayerImpl::DidUpdateMatrix(const float matrix[16])
404 {
405 m_streamTextureMatrix = gfx::Transform(
406 matrix[0], matrix[4], matrix[8], matrix[12],
407 matrix[1], matrix[5], matrix[9], matrix[13],
408 matrix[2], matrix[6], matrix[10], matrix[14],
409 matrix[3], matrix[7], matrix[11], matrix[15]);
410 setNeedsRedraw();
411 }
412
413 void VideoLayerImpl::didLoseOutputSurface() 398 void VideoLayerImpl::didLoseOutputSurface()
414 { 399 {
415 freePlaneData(layerTreeImpl()->resource_provider()); 400 freePlaneData(layerTreeImpl()->resource_provider());
416 } 401 }
417 402
418 void VideoLayerImpl::setNeedsRedraw() 403 void VideoLayerImpl::setNeedsRedraw()
419 { 404 {
420 layerTreeImpl()->SetNeedsRedraw(); 405 layerTreeImpl()->SetNeedsRedraw();
421 } 406 }
422 407
408 void VideoLayerImpl::setProviderClientImpl(scoped_refptr<VideoFrameProviderClien tImpl> providerClientImpl)
409 {
410 m_providerClientImpl = providerClientImpl;
411 }
412
423 const char* VideoLayerImpl::layerTypeAsString() const 413 const char* VideoLayerImpl::layerTypeAsString() const
424 { 414 {
425 return "VideoLayer"; 415 return "VideoLayer";
426 } 416 }
427 417
428 } // namespace cc 418 } // namespace cc
OLDNEW
« cc/video_frame_provider_client_impl.cc ('K') | « cc/video_layer_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698