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

Side by Side Diff: media/gpu/android_deferred_rendering_backing_strategy.cc

Issue 1939943002: Increase cases where back/front buffering early rendering occur. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fast_release
Patch Set: Created 4 years, 7 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
« no previous file with comments | « no previous file | media/gpu/avda_codec_image.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "media/gpu/android_deferred_rendering_backing_strategy.h" 5 #include "media/gpu/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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 size.width(), size.height(), 1, 0, GL_RGBA, 140 size.width(), size.height(), 1, 0, GL_RGBA,
141 GL_UNSIGNED_BYTE, gfx::Rect()); 141 GL_UNSIGNED_BYTE, gfx::Rect());
142 142
143 // Override the texture's service_id, so that it will use the one that 143 // Override the texture's service_id, so that it will use the one that
144 // will be / is attached to the SurfaceTexture. 144 // will be / is attached to the SurfaceTexture.
145 DCHECK(shared_state_->surface_texture_service_id()); 145 DCHECK(shared_state_->surface_texture_service_id());
146 texture_ref->texture()->SetUnownedServiceId( 146 texture_ref->texture()->SetUnownedServiceId(
147 shared_state_->surface_texture_service_id()); 147 shared_state_->surface_texture_service_id());
148 148
149 static_cast<AVDACodecImage*>(image.get()) 149 static_cast<AVDACodecImage*>(image.get())
150 ->SetTexture(texture_ref->texture()); 150 ->set_texture(texture_ref->texture());
151 } else { 151 } else {
152 // Clear the unowned service_id, so that this texture is no longer going 152 // Clear the unowned service_id, so that this texture is no longer going
153 // to depend on the surface texture at all. 153 // to depend on the surface texture at all.
154 texture_ref->texture()->SetUnownedServiceId(0); 154 texture_ref->texture()->SetUnownedServiceId(0);
155 } 155 }
156 156
157 // For SurfaceTexture we set the image to UNBOUND so that the implementation 157 // For SurfaceTexture we set the image to UNBOUND so that the implementation
158 // will call CopyTexImage, which is where AVDACodecImage updates the 158 // will call CopyTexImage, which is where AVDACodecImage updates the
159 // SurfaceTexture to the right frame. 159 // SurfaceTexture to the right frame.
160 // For SurfaceView we set the image to be BOUND because ScheduleOverlayPlane 160 // For SurfaceView we set the image to be BOUND because ScheduleOverlayPlane
(...skipping 15 matching lines...) Expand all
176 176
177 // Notify the AVDACodecImage for picture_buffer that it should use the 177 // Notify the AVDACodecImage for picture_buffer that it should use the
178 // decoded buffer codec_buf_index to render this frame. 178 // decoded buffer codec_buf_index to render this frame.
179 AVDACodecImage* avda_image = 179 AVDACodecImage* avda_image =
180 shared_state_->GetImageForPicture(picture_buffer.id()); 180 shared_state_->GetImageForPicture(picture_buffer.id());
181 RETURN_IF_NULL(avda_image); 181 RETURN_IF_NULL(avda_image);
182 182
183 // Note that this is not a race, since we do not re-use a PictureBuffer 183 // Note that this is not a race, since we do not re-use a PictureBuffer
184 // until after the CC is done drawing it. 184 // until after the CC is done drawing it.
185 pictures_out_for_display_.push_back(picture_buffer.id()); 185 pictures_out_for_display_.push_back(picture_buffer.id());
186 avda_image->SetMediaCodecBufferIndex(codec_buf_index); 186 avda_image->set_media_codec_buffer_index(codec_buf_index);
187 avda_image->SetSize(state_provider_->GetSize()); 187 avda_image->set_size(state_provider_->GetSize());
188 188
189 MaybeRenderEarly(); 189 MaybeRenderEarly();
190 } 190 }
191 191
192 void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer( 192 void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer(
193 const media::PictureBuffer& picture_buffer, 193 const media::PictureBuffer& picture_buffer,
194 bool have_context) { 194 bool have_context) {
195 // Attach a GLImage to each texture that will use the surface texture. 195 // Attach a GLImage to each texture that will use the surface texture.
196 // We use a refptr here in case SetImageForPicture fails. 196 // We use a refptr here in case SetImageForPicture fails.
197 scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image = 197 scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image =
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 MaybeRenderEarly(); 239 MaybeRenderEarly();
240 } 240 }
241 241
242 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBuffers( 242 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBuffers(
243 const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) { 243 const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) {
244 for (const std::pair<int, media::PictureBuffer>& entry : buffers) 244 for (const std::pair<int, media::PictureBuffer>& entry : buffers)
245 ReleaseCodecBufferForPicture(entry.second); 245 ReleaseCodecBufferForPicture(entry.second);
246 } 246 }
247 247
248 void AndroidDeferredRenderingBackingStrategy::MaybeRenderEarly() { 248 void AndroidDeferredRenderingBackingStrategy::MaybeRenderEarly() {
249 // See if we can consume the front buffer / render to the SurfaceView. 249 if (pictures_out_for_display_.empty())
250 if (pictures_out_for_display_.size() == 1u) {
251 AVDACodecImage* avda_image =
252 shared_state_->GetImageForPicture(*pictures_out_for_display_.begin());
253 RETURN_IF_NULL(avda_image);
254 avda_image->UpdateSurface(
255 AVDACodecImage::UpdateMode::RENDER_TO_FRONT_BUFFER);
256 return;
257 }
258
259 // Back buffer rendering is only available for surface textures.
260 if (!surface_texture_)
261 return; 250 return;
262 251
263 // See if the back buffer is free. If so, then render the earliest frame. The 252 // See if we can consume the front buffer / render to the SurfaceView. Iterate
264 // listing is in render order, so we can just use the first unrendered frame 253 // in reverse to find the most recent front buffer. If none is found, the
265 // if there is back buffer space. 254 // |front_index| will point to the beginning of the array.
255 size_t front_index = pictures_out_for_display_.size() - 1;
266 AVDACodecImage* first_renderable_image = nullptr; 256 AVDACodecImage* first_renderable_image = nullptr;
267 for (int id : pictures_out_for_display_) { 257 for (int i = front_index; i >= 0; --i) {
258 const int id = pictures_out_for_display_[i];
268 AVDACodecImage* avda_image = shared_state_->GetImageForPicture(id); 259 AVDACodecImage* avda_image = shared_state_->GetImageForPicture(id);
269 if (!avda_image) 260 if (!avda_image)
270 continue; 261 continue;
271 262
272 // If the back buffer is unavailable, there's nothing left to do. 263 // If we find a front buffer, stop and indicate that front buffer rendering
273 if (avda_image->is_rendered_to_back_buffer()) 264 // is not possible since another image is already in the front buffer.
274 return; 265 if (avda_image->was_rendered_to_front_buffer()) {
266 first_renderable_image = nullptr;
267 break;
268 }
275 269
276 // If the image is rendered to the front buffer or has been dropped, it is 270 // Update the front buffer index as we move along to shorten the number of
277 // not valid for rendering. 271 // candidate images we look at for back buffer rendering.
278 if (avda_image->is_rendered()) 272 front_index = i;
279 continue; 273 first_renderable_image = avda_image;
280
281 if (!first_renderable_image)
282 first_renderable_image = avda_image;
283 } 274 }
284 275
285 if (first_renderable_image) { 276 if (first_renderable_image) {
286 first_renderable_image->UpdateSurface( 277 first_renderable_image->UpdateSurface(
287 AVDACodecImage::UpdateMode::RENDER_TO_BACK_BUFFER); 278 AVDACodecImage::UpdateMode::RENDER_TO_FRONT_BUFFER);
288 } 279 }
280
281 // Back buffer rendering is only available for surface textures. We'll always
282 // have at least one front buffer, so the next buffer must be the backbuffer.
283 size_t backbuffer_index = front_index + 1;
284 if (!surface_texture_ || backbuffer_index >= pictures_out_for_display_.size())
285 return;
286
287 // See if the back buffer is free. If so, then render the frame adjacent to
288 // the front buffer. The listing is in render order, so we can just use the
289 // first unrendered frame if there is back buffer space.
290 first_renderable_image = shared_state_->GetImageForPicture(
291 pictures_out_for_display_[backbuffer_index]);
292 if (!first_renderable_image ||
293 first_renderable_image->was_rendered_to_back_buffer()) {
294 return;
295 }
296
297 // Due to the loop in the beginning this should never be true.
298 DCHECK(!first_renderable_image->was_rendered_to_front_buffer());
299 first_renderable_image->UpdateSurface(
liberato (no reviews please) 2016/05/03 15:20:55 this will force a wait for frame available after y
DaleCurtis 2016/05/03 21:13:34 I don't follow. The render to front buffer above a
liberato (no reviews please) 2016/05/03 21:31:49 hrm, my comment was pretty jumbly. sorry about th
DaleCurtis 2016/05/04 00:01:33 So you're advocating that in the case where we hav
liberato (no reviews please) 2016/05/04 00:10:01 hrm, that's unexpected, since we're still releasin
300 AVDACodecImage::UpdateMode::RENDER_TO_BACK_BUFFER);
289 } 301 }
290 302
291 void AndroidDeferredRenderingBackingStrategy::CodecChanged( 303 void AndroidDeferredRenderingBackingStrategy::CodecChanged(
292 media::VideoCodecBridge* codec) { 304 media::VideoCodecBridge* codec) {
293 media_codec_ = codec; 305 media_codec_ = codec;
294 shared_state_->CodecChanged(codec); 306 shared_state_->CodecChanged(codec);
295 } 307 }
296 308
297 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { 309 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() {
298 shared_state_->SignalFrameAvailable(); 310 shared_state_->SignalFrameAvailable();
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 return !feature_info->workarounds().avda_dont_copy_pictures; 444 return !feature_info->workarounds().avda_dont_copy_pictures;
433 } 445 }
434 } 446 }
435 } 447 }
436 448
437 // Assume so. 449 // Assume so.
438 return true; 450 return true;
439 } 451 }
440 452
441 } // namespace media 453 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | media/gpu/avda_codec_image.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698