Chromium Code Reviews| 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 // Make sure that the decoder is available. | 172 // Make sure that the decoder is available. |
| 173 RETURN_IF_NULL(state_provider_->GetGlDecoder()); | 173 RETURN_IF_NULL(state_provider_->GetGlDecoder()); |
| 174 | 174 |
| 175 // Notify the AVDACodecImage for picture_buffer that it should use the | 175 // Notify the AVDACodecImage for picture_buffer that it should use the |
| 176 // decoded buffer codec_buf_index to render this frame. | 176 // decoded buffer codec_buf_index to render this frame. |
| 177 AVDACodecImage* avda_image = | 177 AVDACodecImage* avda_image = |
| 178 shared_state_->GetImageForPicture(picture_buffer.id()); | 178 shared_state_->GetImageForPicture(picture_buffer.id()); |
| 179 RETURN_IF_NULL(avda_image); | 179 RETURN_IF_NULL(avda_image); |
| 180 DCHECK_EQ(avda_image->GetMediaCodecBufferIndex(), -1); | 180 |
| 181 // Note that this is not a race, since we do not re-use a PictureBuffer | 181 // Note that this is not a race, since we do not re-use a PictureBuffer |
| 182 // until after the CC is done drawing it. | 182 // until after the CC is done drawing it. |
| 183 pictures_out_for_display_.push_back(picture_buffer.id()); | |
| 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(); | |
| 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(picture_buffer.id(), shared_state_, media_codec_, | 196 new AVDACodecImage(picture_buffer.id(), shared_state_, media_codec_, |
| 194 state_provider_->GetGlDecoder(), surface_texture_); | 197 state_provider_->GetGlDecoder(), surface_texture_); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 209 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, | 212 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, |
| 210 GL_RGBA, GL_UNSIGNED_BYTE, rgba); | 213 GL_RGBA, GL_UNSIGNED_BYTE, rgba); |
| 211 } | 214 } |
| 212 } | 215 } |
| 213 | 216 |
| 214 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture( | 217 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture( |
| 215 const media::PictureBuffer& picture_buffer) { | 218 const media::PictureBuffer& picture_buffer) { |
| 216 AVDACodecImage* avda_image = | 219 AVDACodecImage* avda_image = |
| 217 shared_state_->GetImageForPicture(picture_buffer.id()); | 220 shared_state_->GetImageForPicture(picture_buffer.id()); |
| 218 RETURN_IF_NULL(avda_image); | 221 RETURN_IF_NULL(avda_image); |
| 219 | 222 avda_image->UpdateSurface(AVDACodecImage::UpdateMode::DISCARD_CODEC_BUFFER); |
| 220 // See if there is a media codec buffer still attached to this image. | |
| 221 const int32_t codec_buffer = avda_image->GetMediaCodecBufferIndex(); | |
| 222 | |
| 223 if (codec_buffer >= 0) { | |
| 224 // PictureBuffer wasn't displayed, so release the buffer. | |
| 225 media_codec_->ReleaseOutputBuffer(codec_buffer, false); | |
| 226 avda_image->SetMediaCodecBufferIndex(-1); | |
| 227 } | |
| 228 } | 223 } |
| 229 | 224 |
| 230 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer( | 225 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer( |
| 231 const media::PictureBuffer& picture_buffer) { | 226 const media::PictureBuffer& picture_buffer) { |
| 227 pictures_out_for_display_.erase( | |
| 228 std::remove(pictures_out_for_display_.begin(), | |
|
liberato (no reviews please)
2016/04/22 20:25:08
i don't understand what this does. std::remove()
DaleCurtis
2016/04/22 20:58:02
https://en.wikipedia.org/wiki/Erase%E2%80%93remove
| |
| 229 pictures_out_for_display_.end(), picture_buffer.id()), | |
| 230 pictures_out_for_display_.end()); | |
| 231 | |
| 232 // At this point, the CC must be done with the picture. We can't really | 232 // At this point, the CC must be done with the picture. We can't really |
| 233 // check for that here directly. it's guaranteed in gpu_video_decoder.cc, | 233 // check for that here directly. it's guaranteed in gpu_video_decoder.cc, |
| 234 // when it waits on the sync point before releasing the mailbox. That sync | 234 // when it waits on the sync point before releasing the mailbox. That sync |
| 235 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw. | 235 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw. |
| 236 ReleaseCodecBufferForPicture(picture_buffer); | 236 ReleaseCodecBufferForPicture(picture_buffer); |
| 237 MaybeRenderEarly(); | |
| 238 } | |
| 239 | |
| 240 void AndroidDeferredRenderingBackingStrategy::MaybeRenderEarly() { | |
| 241 // See if we can consume the front buffer / render to the SurfaceView. | |
| 242 if (pictures_out_for_display_.size() == 1u) { | |
| 243 AVDACodecImage* avda_image = | |
| 244 shared_state_->GetImageForPicture(*pictures_out_for_display_.begin()); | |
| 245 RETURN_IF_NULL(avda_image); | |
| 246 avda_image->UpdateSurface( | |
| 247 AVDACodecImage::UpdateMode::RENDER_TO_FRONT_BUFFER); | |
| 248 return; | |
| 249 } | |
| 250 | |
| 251 // Back buffer rendering is only available for surface textures. | |
| 252 if (!surface_texture_) | |
| 253 return; | |
| 254 | |
| 255 // See if the back buffer is free. If so, then render the earliest frame. The | |
| 256 // listing is in render order, so we can just use the first unrendered frame | |
| 257 // if there is back buffer space. | |
| 258 AVDACodecImage* first_renderable_image = nullptr; | |
| 259 for (int id : pictures_out_for_display_) { | |
| 260 AVDACodecImage* avda_image = shared_state_->GetImageForPicture(id); | |
| 261 if (!avda_image) | |
| 262 continue; | |
| 263 | |
| 264 // If the back buffer is unavailable, there's nothing left to do. | |
| 265 if (avda_image->is_rendered_to_back_buffer()) | |
| 266 return; | |
| 267 | |
| 268 // If the image is rendered to the front buffer or has been dropped, it is | |
| 269 // not valid for rendering. | |
| 270 if (avda_image->is_rendered()) | |
| 271 continue; | |
| 272 | |
| 273 if (!first_renderable_image) | |
| 274 first_renderable_image = avda_image; | |
| 275 } | |
| 276 | |
| 277 if (first_renderable_image) { | |
| 278 first_renderable_image->UpdateSurface( | |
| 279 AVDACodecImage::UpdateMode::RENDER_TO_BACK_BUFFER); | |
| 280 } | |
| 237 } | 281 } |
| 238 | 282 |
| 239 void AndroidDeferredRenderingBackingStrategy::CodecChanged( | 283 void AndroidDeferredRenderingBackingStrategy::CodecChanged( |
| 240 media::VideoCodecBridge* codec) { | 284 media::VideoCodecBridge* codec) { |
| 241 media_codec_ = codec; | 285 media_codec_ = codec; |
| 242 shared_state_->CodecChanged(codec); | 286 shared_state_->CodecChanged(codec); |
| 243 } | 287 } |
| 244 | 288 |
| 245 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { | 289 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { |
| 246 shared_state_->SignalFrameAvailable(); | 290 shared_state_->SignalFrameAvailable(); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 381 return !feature_info->workarounds().avda_dont_copy_pictures; | 425 return !feature_info->workarounds().avda_dont_copy_pictures; |
| 382 } | 426 } |
| 383 } | 427 } |
| 384 } | 428 } |
| 385 | 429 |
| 386 // Assume so. | 430 // Assume so. |
| 387 return true; | 431 return true; |
| 388 } | 432 } |
| 389 | 433 |
| 390 } // namespace content | 434 } // namespace content |
| OLD | NEW |