| 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 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 const { | 112 const { |
| 113 // For SurfaceView, request a 1x1 2D texture to reduce memory during | 113 // For SurfaceView, request a 1x1 2D texture to reduce memory during |
| 114 // initialization. For SurfaceTexture, allocate a picture buffer that is the | 114 // initialization. For SurfaceTexture, allocate a picture buffer that is the |
| 115 // actual frame size. Note that it will be an external texture anyway, so it | 115 // actual frame size. Note that it will be an external texture anyway, so it |
| 116 // doesn't allocate an image of that size. However, it's still important to | 116 // doesn't allocate an image of that size. However, it's still important to |
| 117 // get the coded size right, so that VideoLayerImpl doesn't try to scale the | 117 // get the coded size right, so that VideoLayerImpl doesn't try to scale the |
| 118 // texture when building the quad for it. | 118 // texture when building the quad for it. |
| 119 return surface_texture_ ? state_provider_->GetSize() : gfx::Size(1, 1); | 119 return surface_texture_ ? state_provider_->GetSize() : gfx::Size(1, 1); |
| 120 } | 120 } |
| 121 | 121 |
| 122 AVDACodecImage* AndroidDeferredRenderingBackingStrategy::GetImageForPicture( | |
| 123 const media::PictureBuffer& picture_buffer) { | |
| 124 gpu::gles2::TextureRef* texture_ref = | |
| 125 state_provider_->GetTextureForPicture(picture_buffer); | |
| 126 RETURN_NULL_IF_NULL(texture_ref); | |
| 127 gl::GLImage* image = | |
| 128 texture_ref->texture()->GetLevelImage(GetTextureTarget(), 0); | |
| 129 return static_cast<AVDACodecImage*>(image); | |
| 130 } | |
| 131 | |
| 132 void AndroidDeferredRenderingBackingStrategy::SetImageForPicture( | 122 void AndroidDeferredRenderingBackingStrategy::SetImageForPicture( |
| 133 const media::PictureBuffer& picture_buffer, | 123 const media::PictureBuffer& picture_buffer, |
| 134 const scoped_refptr<gpu::gles2::GLStreamTextureImage>& image) { | 124 const scoped_refptr<gpu::gles2::GLStreamTextureImage>& image) { |
| 135 gpu::gles2::TextureRef* texture_ref = | 125 gpu::gles2::TextureRef* texture_ref = |
| 136 state_provider_->GetTextureForPicture(picture_buffer); | 126 state_provider_->GetTextureForPicture(picture_buffer); |
| 137 RETURN_IF_NULL(texture_ref); | 127 RETURN_IF_NULL(texture_ref); |
| 138 | 128 |
| 139 gpu::gles2::TextureManager* texture_manager = | 129 gpu::gles2::TextureManager* texture_manager = |
| 140 state_provider_->GetGlDecoder()->GetContextGroup()->texture_manager(); | 130 state_provider_->GetGlDecoder()->GetContextGroup()->texture_manager(); |
| 141 RETURN_IF_NULL(texture_manager); | 131 RETURN_IF_NULL(texture_manager); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 } | 167 } |
| 178 | 168 |
| 179 void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer( | 169 void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer( |
| 180 int32_t codec_buf_index, | 170 int32_t codec_buf_index, |
| 181 const media::PictureBuffer& picture_buffer) { | 171 const media::PictureBuffer& picture_buffer) { |
| 182 // Make sure that the decoder is available. | 172 // Make sure that the decoder is available. |
| 183 RETURN_IF_NULL(state_provider_->GetGlDecoder()); | 173 RETURN_IF_NULL(state_provider_->GetGlDecoder()); |
| 184 | 174 |
| 185 // Notify the AVDACodecImage for picture_buffer that it should use the | 175 // Notify the AVDACodecImage for picture_buffer that it should use the |
| 186 // decoded buffer codec_buf_index to render this frame. | 176 // decoded buffer codec_buf_index to render this frame. |
| 187 AVDACodecImage* avda_image = GetImageForPicture(picture_buffer); | 177 AVDACodecImage* avda_image = |
| 178 shared_state_->GetImageForPicture(picture_buffer.id()); |
| 188 RETURN_IF_NULL(avda_image); | 179 RETURN_IF_NULL(avda_image); |
| 189 DCHECK_EQ(avda_image->GetMediaCodecBufferIndex(), -1); | 180 DCHECK_EQ(avda_image->GetMediaCodecBufferIndex(), -1); |
| 190 // 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 |
| 191 // until after the CC is done drawing it. | 182 // until after the CC is done drawing it. |
| 192 avda_image->SetMediaCodecBufferIndex(codec_buf_index); | 183 avda_image->SetMediaCodecBufferIndex(codec_buf_index); |
| 193 avda_image->SetSize(state_provider_->GetSize()); | 184 avda_image->SetSize(state_provider_->GetSize()); |
| 194 } | 185 } |
| 195 | 186 |
| 196 void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer( | 187 void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer( |
| 197 const media::PictureBuffer& picture_buffer, | 188 const media::PictureBuffer& picture_buffer, |
| 198 bool have_context) { | 189 bool have_context) { |
| 199 // Attach a GLImage to each texture that will use the surface texture. | 190 // Attach a GLImage to each texture that will use the surface texture. |
| 200 // We use a refptr here in case SetImageForPicture fails. | 191 // We use a refptr here in case SetImageForPicture fails. |
| 201 scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image = | 192 scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image = |
| 202 new AVDACodecImage(shared_state_, media_codec_, | 193 new AVDACodecImage(picture_buffer.id(), shared_state_, media_codec_, |
| 203 state_provider_->GetGlDecoder(), surface_texture_); | 194 state_provider_->GetGlDecoder(), surface_texture_); |
| 204 SetImageForPicture(picture_buffer, gl_image); | 195 SetImageForPicture(picture_buffer, gl_image); |
| 205 | 196 |
| 206 if (!surface_texture_ && have_context) { | 197 if (!surface_texture_ && have_context) { |
| 207 // To make devtools work, we're using a 2D texture. Make it transparent, | 198 // To make devtools work, we're using a 2D texture. Make it transparent, |
| 208 // so that it draws a hole for the SV to show through. This is only | 199 // so that it draws a hole for the SV to show through. This is only |
| 209 // because devtools draws and reads back, which skips overlay processing. | 200 // because devtools draws and reads back, which skips overlay processing. |
| 210 // It's unclear why devtools renders twice -- once normally, and once | 201 // It's unclear why devtools renders twice -- once normally, and once |
| 211 // including a readback layer. The result is that the device screen | 202 // including a readback layer. The result is that the device screen |
| 212 // flashes as we alternately draw the overlay hole and this texture, | 203 // flashes as we alternately draw the overlay hole and this texture, |
| 213 // unless we make the texture transparent. | 204 // unless we make the texture transparent. |
| 214 static const uint8_t rgba[] = {0, 0, 0, 0}; | 205 static const uint8_t rgba[] = {0, 0, 0, 0}; |
| 215 const gfx::Size size(1, 1); | 206 const gfx::Size size(1, 1); |
| 216 DCHECK_LE(1u, picture_buffer.texture_ids().size()); | 207 DCHECK_LE(1u, picture_buffer.texture_ids().size()); |
| 217 glBindTexture(GL_TEXTURE_2D, picture_buffer.texture_ids()[0]); | 208 glBindTexture(GL_TEXTURE_2D, picture_buffer.texture_ids()[0]); |
| 218 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, | 209 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, |
| 219 GL_RGBA, GL_UNSIGNED_BYTE, rgba); | 210 GL_RGBA, GL_UNSIGNED_BYTE, rgba); |
| 220 } | 211 } |
| 221 } | 212 } |
| 222 | 213 |
| 223 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture( | 214 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture( |
| 224 const media::PictureBuffer& picture_buffer) { | 215 const media::PictureBuffer& picture_buffer) { |
| 225 AVDACodecImage* avda_image = GetImageForPicture(picture_buffer); | 216 AVDACodecImage* avda_image = |
| 217 shared_state_->GetImageForPicture(picture_buffer.id()); |
| 218 RETURN_IF_NULL(avda_image); |
| 226 | 219 |
| 227 // See if there is a media codec buffer still attached to this image. | 220 // See if there is a media codec buffer still attached to this image. |
| 228 const int32_t codec_buffer = avda_image->GetMediaCodecBufferIndex(); | 221 const int32_t codec_buffer = avda_image->GetMediaCodecBufferIndex(); |
| 229 | 222 |
| 230 if (codec_buffer >= 0) { | 223 if (codec_buffer >= 0) { |
| 231 // PictureBuffer wasn't displayed, so release the buffer. | 224 // PictureBuffer wasn't displayed, so release the buffer. |
| 232 media_codec_->ReleaseOutputBuffer(codec_buffer, false); | 225 media_codec_->ReleaseOutputBuffer(codec_buffer, false); |
| 233 avda_image->SetMediaCodecBufferIndex(-1); | 226 avda_image->SetMediaCodecBufferIndex(-1); |
| 234 } | 227 } |
| 235 } | 228 } |
| 236 | 229 |
| 237 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer( | 230 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer( |
| 238 const media::PictureBuffer& picture_buffer) { | 231 const media::PictureBuffer& picture_buffer) { |
| 239 // 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 |
| 240 // 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, |
| 241 // 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 |
| 242 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw. | 235 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw. |
| 243 ReleaseCodecBufferForPicture(picture_buffer); | 236 ReleaseCodecBufferForPicture(picture_buffer); |
| 244 } | 237 } |
| 245 | 238 |
| 246 void AndroidDeferredRenderingBackingStrategy::CodecChanged( | 239 void AndroidDeferredRenderingBackingStrategy::CodecChanged( |
| 247 media::VideoCodecBridge* codec, | 240 media::VideoCodecBridge* codec) { |
| 248 const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) { | |
| 249 // Clear any outstanding codec buffer indices, since the new codec (if any) | |
| 250 // doesn't know about them. | |
| 251 media_codec_ = codec; | 241 media_codec_ = codec; |
| 252 for (const std::pair<int, media::PictureBuffer>& entry : buffers) { | 242 shared_state_->CodecChanged(codec); |
| 253 AVDACodecImage* avda_image = GetImageForPicture(entry.second); | |
| 254 avda_image->SetMediaCodec(codec); | |
| 255 avda_image->SetMediaCodecBufferIndex(-1); | |
| 256 } | |
| 257 } | 243 } |
| 258 | 244 |
| 259 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { | 245 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { |
| 260 shared_state_->SignalFrameAvailable(); | 246 shared_state_->SignalFrameAvailable(); |
| 261 } | 247 } |
| 262 | 248 |
| 263 bool AndroidDeferredRenderingBackingStrategy::ArePicturesOverlayable() { | 249 bool AndroidDeferredRenderingBackingStrategy::ArePicturesOverlayable() { |
| 264 // SurfaceView frames are always overlayable because that's the only way to | 250 // SurfaceView frames are always overlayable because that's the only way to |
| 265 // display them. | 251 // display them. |
| 266 return !surface_texture_; | 252 return !surface_texture_; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 296 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, tmp_texture_id); | 282 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, tmp_texture_id); |
| 297 // The target texture's size will exactly match the source. | 283 // The target texture's size will exactly match the source. |
| 298 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 284 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 299 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 285 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 301 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 302 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, | 288 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, |
| 303 GL_RGBA, GL_UNSIGNED_BYTE, nullptr); | 289 GL_RGBA, GL_UNSIGNED_BYTE, nullptr); |
| 304 } | 290 } |
| 305 | 291 |
| 306 | |
| 307 | |
| 308 float transform_matrix[16]; | 292 float transform_matrix[16]; |
| 309 surface_texture_->GetTransformMatrix(transform_matrix); | 293 surface_texture_->GetTransformMatrix(transform_matrix); |
| 310 | 294 |
| 311 gpu::CopyTextureCHROMIUMResourceManager copier; | 295 gpu::CopyTextureCHROMIUMResourceManager copier; |
| 312 copier.Initialize( | 296 copier.Initialize( |
| 313 gl_decoder, | 297 gl_decoder, |
| 314 gl_decoder->GetContextGroup()->feature_info()->feature_flags()); | 298 gl_decoder->GetContextGroup()->feature_info()->feature_flags()); |
| 315 copier.DoCopyTextureWithTransform(gl_decoder, GL_TEXTURE_EXTERNAL_OES, | 299 copier.DoCopyTextureWithTransform(gl_decoder, GL_TEXTURE_EXTERNAL_OES, |
| 316 shared_state_->surface_texture_service_id(), | 300 shared_state_->surface_texture_service_id(), |
| 317 GL_TEXTURE_2D, tmp_texture_id, size.width(), | 301 GL_TEXTURE_2D, tmp_texture_id, size.width(), |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 397 return !feature_info->workarounds().avda_dont_copy_pictures; | 381 return !feature_info->workarounds().avda_dont_copy_pictures; |
| 398 } | 382 } |
| 399 } | 383 } |
| 400 } | 384 } |
| 401 | 385 |
| 402 // Assume so. | 386 // Assume so. |
| 403 return true; | 387 return true; |
| 404 } | 388 } |
| 405 | 389 |
| 406 } // namespace content | 390 } // namespace content |
| OLD | NEW |