OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "content/common/gpu/media/android_deferred_rendering_backing_strategy.h
" | 5 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h
" |
6 | 6 |
7 #include <EGL/egl.h> | 7 #include <EGL/egl.h> |
8 #include <EGL/eglext.h> | 8 #include <EGL/eglext.h> |
9 | 9 |
10 #include "base/android/build_info.h" | 10 #include "base/android/build_info.h" |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 // matter. The only way to use this texture is to schedule it as an overlay. | 161 // matter. The only way to use this texture is to schedule it as an overlay. |
162 const gpu::gles2::Texture::ImageState image_state = | 162 const gpu::gles2::Texture::ImageState image_state = |
163 surface_texture_ ? gpu::gles2::Texture::UNBOUND | 163 surface_texture_ ? gpu::gles2::Texture::UNBOUND |
164 : gpu::gles2::Texture::BOUND; | 164 : gpu::gles2::Texture::BOUND; |
165 texture_manager->SetLevelStreamTextureImage(texture_ref, GetTextureTarget(), | 165 texture_manager->SetLevelStreamTextureImage(texture_ref, GetTextureTarget(), |
166 0, image.get(), image_state); | 166 0, image.get(), image_state); |
167 } | 167 } |
168 | 168 |
169 void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer( | 169 void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer( |
170 int32_t codec_buf_index, | 170 int32_t codec_buf_index, |
171 const media::PictureBuffer& picture_buffer) { | 171 const media::PictureBuffer& picture_buffer, |
| 172 const std::vector<int32_t>& pictures_out_for_display) { |
172 // Make sure that the decoder is available. | 173 // Make sure that the decoder is available. |
173 RETURN_IF_NULL(state_provider_->GetGlDecoder()); | 174 RETURN_IF_NULL(state_provider_->GetGlDecoder()); |
174 | 175 |
175 // Notify the AVDACodecImage for picture_buffer that it should use the | 176 // Notify the AVDACodecImage for picture_buffer that it should use the |
176 // decoded buffer codec_buf_index to render this frame. | 177 // decoded buffer codec_buf_index to render this frame. |
177 AVDACodecImage* avda_image = | 178 AVDACodecImage* avda_image = |
178 shared_state_->GetImageForPicture(picture_buffer.id()); | 179 shared_state_->GetImageForPicture(picture_buffer.id()); |
179 RETURN_IF_NULL(avda_image); | 180 RETURN_IF_NULL(avda_image); |
180 DCHECK_EQ(avda_image->GetMediaCodecBufferIndex(), -1); | 181 |
181 // Note that this is not a race, since we do not re-use a PictureBuffer | 182 // Note that this is not a race, since we do not re-use a PictureBuffer |
182 // until after the CC is done drawing it. | 183 // until after the CC is done drawing it. |
183 avda_image->SetMediaCodecBufferIndex(codec_buf_index); | 184 avda_image->SetMediaCodecBufferIndex(codec_buf_index); |
184 avda_image->SetSize(state_provider_->GetSize()); | 185 avda_image->SetSize(state_provider_->GetSize()); |
| 186 |
| 187 MaybeRenderEarly(pictures_out_for_display); |
185 } | 188 } |
186 | 189 |
187 void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer( | 190 void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer( |
188 const media::PictureBuffer& picture_buffer, | 191 const media::PictureBuffer& picture_buffer, |
189 bool have_context) { | 192 bool have_context) { |
190 // Attach a GLImage to each texture that will use the surface texture. | 193 // Attach a GLImage to each texture that will use the surface texture. |
191 // We use a refptr here in case SetImageForPicture fails. | 194 // We use a refptr here in case SetImageForPicture fails. |
192 scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image = | 195 scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image = |
193 new AVDACodecImage(shared_state_, media_codec_, | 196 new AVDACodecImage(shared_state_, media_codec_, |
194 state_provider_->GetGlDecoder(), surface_texture_); | 197 state_provider_->GetGlDecoder(), surface_texture_); |
(...skipping 16 matching lines...) Expand all Loading... |
211 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, | 214 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, |
212 GL_RGBA, GL_UNSIGNED_BYTE, rgba); | 215 GL_RGBA, GL_UNSIGNED_BYTE, rgba); |
213 } | 216 } |
214 } | 217 } |
215 | 218 |
216 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture( | 219 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture( |
217 const media::PictureBuffer& picture_buffer) { | 220 const media::PictureBuffer& picture_buffer) { |
218 AVDACodecImage* avda_image = | 221 AVDACodecImage* avda_image = |
219 shared_state_->GetImageForPicture(picture_buffer.id()); | 222 shared_state_->GetImageForPicture(picture_buffer.id()); |
220 RETURN_IF_NULL(avda_image); | 223 RETURN_IF_NULL(avda_image); |
221 | 224 avda_image->ReleaseOutputBuffer(AVDACodecImage::ReleaseMode::SKIP_RENDER); |
222 // See if there is a media codec buffer still attached to this image. | |
223 const int32_t codec_buffer = avda_image->GetMediaCodecBufferIndex(); | |
224 | |
225 if (codec_buffer >= 0) { | |
226 // PictureBuffer wasn't displayed, so release the buffer. | |
227 media_codec_->ReleaseOutputBuffer(codec_buffer, false); | |
228 avda_image->SetMediaCodecBufferIndex(-1); | |
229 } | |
230 } | 225 } |
231 | 226 |
232 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer( | 227 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer( |
233 const media::PictureBuffer& picture_buffer) { | 228 const media::PictureBuffer& picture_buffer, |
| 229 const std::vector<int32_t>& pictures_out_for_display) { |
234 // At this point, the CC must be done with the picture. We can't really | 230 // At this point, the CC must be done with the picture. We can't really |
235 // check for that here directly. it's guaranteed in gpu_video_decoder.cc, | 231 // check for that here directly. it's guaranteed in gpu_video_decoder.cc, |
236 // when it waits on the sync point before releasing the mailbox. That sync | 232 // when it waits on the sync point before releasing the mailbox. That sync |
237 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw. | 233 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw. |
238 ReleaseCodecBufferForPicture(picture_buffer); | 234 ReleaseCodecBufferForPicture(picture_buffer); |
| 235 MaybeRenderEarly(pictures_out_for_display); |
| 236 } |
| 237 |
| 238 void AndroidDeferredRenderingBackingStrategy::MaybeRenderEarly( |
| 239 const std::vector<int32_t>& pictures_out_for_display) { |
| 240 // See if we can consume the front buffer / render to the SurfaceView. |
| 241 if (pictures_out_for_display.size() == 1u) { |
| 242 AVDACodecImage* avda_image = |
| 243 shared_state_->GetImageForPicture(*pictures_out_for_display.begin()); |
| 244 RETURN_IF_NULL(avda_image); |
| 245 avda_image->ReleaseOutputBuffer( |
| 246 AVDACodecImage::ReleaseMode::RENDER_AND_UPDATE); |
| 247 return; |
| 248 } |
| 249 |
| 250 // Back buffer rendering is only available for surface textures. |
| 251 if (!surface_texture_) |
| 252 return; |
| 253 |
| 254 // See if the back buffer is free. If so, then render the earliest frame. The |
| 255 // listing is in render order, so we can just use the first unrendered frame |
| 256 // if there is back buffer space. |
| 257 AVDACodecImage* first_renderable_image = nullptr; |
| 258 for (int id : pictures_out_for_display) { |
| 259 AVDACodecImage* avda_image = shared_state_->GetImageForPicture(id); |
| 260 if (!avda_image) |
| 261 continue; |
| 262 |
| 263 // If the back buffer is unavailable, there's nothing left to do. |
| 264 if (avda_image->is_rendered_to_back_buffer()) |
| 265 return; |
| 266 |
| 267 // If the image is rendered to the front buffer or has been dropped, it is |
| 268 // not valid for rendering. |
| 269 if (avda_image->is_rendered()) |
| 270 continue; |
| 271 |
| 272 if (!first_renderable_image) |
| 273 first_renderable_image = avda_image; |
| 274 } |
| 275 |
| 276 if (first_renderable_image) { |
| 277 first_renderable_image->ReleaseOutputBuffer( |
| 278 AVDACodecImage::ReleaseMode::RENDER_ONLY); |
| 279 } |
239 } | 280 } |
240 | 281 |
241 void AndroidDeferredRenderingBackingStrategy::CodecChanged( | 282 void AndroidDeferredRenderingBackingStrategy::CodecChanged( |
242 media::VideoCodecBridge* codec) { | 283 media::VideoCodecBridge* codec) { |
243 media_codec_ = codec; | 284 media_codec_ = codec; |
244 shared_state_->CodecChanged(codec); | 285 shared_state_->CodecChanged(codec); |
245 } | 286 } |
246 | 287 |
247 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { | 288 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { |
248 shared_state_->SignalFrameAvailable(); | 289 shared_state_->SignalFrameAvailable(); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 return !feature_info->workarounds().avda_dont_copy_pictures; | 424 return !feature_info->workarounds().avda_dont_copy_pictures; |
384 } | 425 } |
385 } | 426 } |
386 } | 427 } |
387 | 428 |
388 // Assume so. | 429 // Assume so. |
389 return true; | 430 return true; |
390 } | 431 } |
391 | 432 |
392 } // namespace content | 433 } // namespace content |
OLD | NEW |