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(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); |
196 shared_state_->SetImageForPicture( | |
liberato (no reviews please)
2016/04/21 23:39:54
perhaps pass in the picture buffer id into the cod
DaleCurtis
2016/04/22 00:11:19
Yup looks much better. Also removed Erase() entire
| |
197 picture_buffer.id(), static_cast<AVDACodecImage*>(gl_image.get())); | |
205 | 198 |
206 if (!surface_texture_ && have_context) { | 199 if (!surface_texture_ && have_context) { |
207 // To make devtools work, we're using a 2D texture. Make it transparent, | 200 // 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 | 201 // 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. | 202 // because devtools draws and reads back, which skips overlay processing. |
210 // It's unclear why devtools renders twice -- once normally, and once | 203 // It's unclear why devtools renders twice -- once normally, and once |
211 // including a readback layer. The result is that the device screen | 204 // including a readback layer. The result is that the device screen |
212 // flashes as we alternately draw the overlay hole and this texture, | 205 // flashes as we alternately draw the overlay hole and this texture, |
213 // unless we make the texture transparent. | 206 // unless we make the texture transparent. |
214 static const uint8_t rgba[] = {0, 0, 0, 0}; | 207 static const uint8_t rgba[] = {0, 0, 0, 0}; |
215 const gfx::Size size(1, 1); | 208 const gfx::Size size(1, 1); |
216 DCHECK_LE(1u, picture_buffer.texture_ids().size()); | 209 DCHECK_LE(1u, picture_buffer.texture_ids().size()); |
217 glBindTexture(GL_TEXTURE_2D, picture_buffer.texture_ids()[0]); | 210 glBindTexture(GL_TEXTURE_2D, picture_buffer.texture_ids()[0]); |
218 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, | 211 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, |
219 GL_RGBA, GL_UNSIGNED_BYTE, rgba); | 212 GL_RGBA, GL_UNSIGNED_BYTE, rgba); |
220 } | 213 } |
221 } | 214 } |
222 | 215 |
223 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture( | 216 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture( |
224 const media::PictureBuffer& picture_buffer) { | 217 const media::PictureBuffer& picture_buffer) { |
225 AVDACodecImage* avda_image = GetImageForPicture(picture_buffer); | 218 AVDACodecImage* avda_image = |
219 shared_state_->GetImageForPicture(picture_buffer.id()); | |
220 RETURN_IF_NULL(avda_image); | |
226 | 221 |
227 // See if there is a media codec buffer still attached to this image. | 222 // See if there is a media codec buffer still attached to this image. |
228 const int32_t codec_buffer = avda_image->GetMediaCodecBufferIndex(); | 223 const int32_t codec_buffer = avda_image->GetMediaCodecBufferIndex(); |
229 | 224 |
230 if (codec_buffer >= 0) { | 225 if (codec_buffer >= 0) { |
231 // PictureBuffer wasn't displayed, so release the buffer. | 226 // PictureBuffer wasn't displayed, so release the buffer. |
232 media_codec_->ReleaseOutputBuffer(codec_buffer, false); | 227 media_codec_->ReleaseOutputBuffer(codec_buffer, false); |
233 avda_image->SetMediaCodecBufferIndex(-1); | 228 avda_image->SetMediaCodecBufferIndex(-1); |
234 } | 229 } |
235 } | 230 } |
236 | 231 |
237 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer( | 232 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer( |
238 const media::PictureBuffer& picture_buffer) { | 233 const media::PictureBuffer& picture_buffer) { |
239 // At this point, the CC must be done with the picture. We can't really | 234 // 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, | 235 // 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 | 236 // when it waits on the sync point before releasing the mailbox. That sync |
242 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw. | 237 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw. |
243 ReleaseCodecBufferForPicture(picture_buffer); | 238 ReleaseCodecBufferForPicture(picture_buffer); |
244 } | 239 } |
245 | 240 |
246 void AndroidDeferredRenderingBackingStrategy::CodecChanged( | 241 void AndroidDeferredRenderingBackingStrategy::CodecChanged( |
247 media::VideoCodecBridge* codec, | 242 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; | 243 media_codec_ = codec; |
252 for (const std::pair<int, media::PictureBuffer>& entry : buffers) { | 244 shared_state_->CodecChanged(codec); |
253 AVDACodecImage* avda_image = GetImageForPicture(entry.second); | |
254 avda_image->SetMediaCodec(codec); | |
255 avda_image->SetMediaCodecBufferIndex(-1); | |
256 } | |
257 } | 245 } |
258 | 246 |
259 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { | 247 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { |
260 shared_state_->SignalFrameAvailable(); | 248 shared_state_->SignalFrameAvailable(); |
261 } | 249 } |
262 | 250 |
263 bool AndroidDeferredRenderingBackingStrategy::ArePicturesOverlayable() { | 251 bool AndroidDeferredRenderingBackingStrategy::ArePicturesOverlayable() { |
264 // SurfaceView frames are always overlayable because that's the only way to | 252 // SurfaceView frames are always overlayable because that's the only way to |
265 // display them. | 253 // display them. |
266 return !surface_texture_; | 254 return !surface_texture_; |
(...skipping 29 matching lines...) Expand all Loading... | |
296 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, tmp_texture_id); | 284 gfx::ScopedTextureBinder texture_binder(GL_TEXTURE_2D, tmp_texture_id); |
297 // The target texture's size will exactly match the source. | 285 // The target texture's size will exactly match the source. |
298 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 286 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
299 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 287 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
300 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 288 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); | 289 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, | 290 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, |
303 GL_RGBA, GL_UNSIGNED_BYTE, nullptr); | 291 GL_RGBA, GL_UNSIGNED_BYTE, nullptr); |
304 } | 292 } |
305 | 293 |
306 | |
307 | |
308 float transform_matrix[16]; | 294 float transform_matrix[16]; |
309 surface_texture_->GetTransformMatrix(transform_matrix); | 295 surface_texture_->GetTransformMatrix(transform_matrix); |
310 | 296 |
311 gpu::CopyTextureCHROMIUMResourceManager copier; | 297 gpu::CopyTextureCHROMIUMResourceManager copier; |
312 copier.Initialize( | 298 copier.Initialize( |
313 gl_decoder, | 299 gl_decoder, |
314 gl_decoder->GetContextGroup()->feature_info()->feature_flags()); | 300 gl_decoder->GetContextGroup()->feature_info()->feature_flags()); |
315 copier.DoCopyTextureWithTransform(gl_decoder, GL_TEXTURE_EXTERNAL_OES, | 301 copier.DoCopyTextureWithTransform(gl_decoder, GL_TEXTURE_EXTERNAL_OES, |
316 shared_state_->surface_texture_service_id(), | 302 shared_state_->surface_texture_service_id(), |
317 GL_TEXTURE_2D, tmp_texture_id, size.width(), | 303 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; | 383 return !feature_info->workarounds().avda_dont_copy_pictures; |
398 } | 384 } |
399 } | 385 } |
400 } | 386 } |
401 | 387 |
402 // Assume so. | 388 // Assume so. |
403 return true; | 389 return true; |
404 } | 390 } |
405 | 391 |
406 } // namespace content | 392 } // namespace content |
OLD | NEW |