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

Side by Side Diff: content/common/gpu/media/android_video_decode_accelerator.cc

Issue 1680213002: Start using deferred rendering for WebView on L. Base URL: https://chromium.googlesource.com/chromium/src.git@measure_copy
Patch Set: cleanup Created 4 years, 9 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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_video_decode_accelerator.h" 5 #include "content/common/gpu/media/android_video_decode_accelerator.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/android/build_info.h" 9 #include "base/android/build_info.h"
10 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 // we take care that the AVDA that wants them still exists. A WeakPtr to 120 // we take care that the AVDA that wants them still exists. A WeakPtr to
121 // the AVDA would be preferable, except that OnFrameAvailable callbacks can 121 // the AVDA would be preferable, except that OnFrameAvailable callbacks can
122 // occur off the gpu main thread. We also can't guarantee when the 122 // occur off the gpu main thread. We also can't guarantee when the
123 // SurfaceTexture will quit sending callbacks to coordinate with the 123 // SurfaceTexture will quit sending callbacks to coordinate with the
124 // destruction of the AVDA, so we have a separate object that the cb can own. 124 // destruction of the AVDA, so we have a separate object that the cb can own.
125 class AndroidVideoDecodeAccelerator::OnFrameAvailableHandler 125 class AndroidVideoDecodeAccelerator::OnFrameAvailableHandler
126 : public base::RefCountedThreadSafe<OnFrameAvailableHandler> { 126 : public base::RefCountedThreadSafe<OnFrameAvailableHandler> {
127 public: 127 public:
128 // We do not retain ownership of |owner|. It must remain valid until 128 // We do not retain ownership of |owner|. It must remain valid until
129 // after ClearOwner() is called. This will register with 129 // after ClearOwner() is called. This will register with
130 // |surface_texture| to receive OnFrameAvailable callbacks. 130 // |surface_texture| to receive OnFrameAvailable callbacks. If
131 // |use_separate_thread| is true, then we'll request that the callback happens
132 // on a thread that is dedicated to SurfaceTexture callbacks.
131 OnFrameAvailableHandler( 133 OnFrameAvailableHandler(
132 AndroidVideoDecodeAccelerator* owner, 134 AndroidVideoDecodeAccelerator* owner,
133 const scoped_refptr<gfx::SurfaceTexture>& surface_texture) 135 const scoped_refptr<gfx::SurfaceTexture>& surface_texture,
136 bool use_separate_thread)
134 : owner_(owner) { 137 : owner_(owner) {
135 // Note that the callback owns a strong ref to us. 138 // Note that the callback owns a strong ref to us.
136 surface_texture->SetFrameAvailableCallbackOnAnyThread( 139 base::Closure cb = base::Bind(&OnFrameAvailableHandler::OnFrameAvailable,
137 base::Bind(&OnFrameAvailableHandler::OnFrameAvailable, 140 scoped_refptr<OnFrameAvailableHandler>(this));
138 scoped_refptr<OnFrameAvailableHandler>(this))); 141
142 if (use_separate_thread)
143 surface_texture->SetFrameAvailableCallbackOnSeparateThread(cb);
144 else
145 surface_texture->SetFrameAvailableCallbackOnAnyThread(cb);
139 } 146 }
140 147
141 // Forget about our owner, which is required before one deletes it. 148 // Forget about our owner, which is required before one deletes it.
142 // No further callbacks will happen once this completes. 149 // No further callbacks will happen once this completes.
143 void ClearOwner() { 150 void ClearOwner() {
144 base::AutoLock lock(lock_); 151 base::AutoLock lock(lock_);
145 // No callback can happen until we release the lock. 152 // No callback can happen until we release the lock.
146 owner_ = nullptr; 153 owner_ = nullptr;
147 } 154 }
148 155
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 picturebuffers_requested_(false), 257 picturebuffers_requested_(false),
251 gl_decoder_(decoder), 258 gl_decoder_(decoder),
252 cdm_registration_id_(0), 259 cdm_registration_id_(0),
253 pending_input_buf_index_(-1), 260 pending_input_buf_index_(-1),
254 error_sequence_token_(0), 261 error_sequence_token_(0),
255 defer_errors_(false), 262 defer_errors_(false),
256 weak_this_factory_(this) { 263 weak_this_factory_(this) {
257 if (UseDeferredRenderingStrategy()) { 264 if (UseDeferredRenderingStrategy()) {
258 // TODO(liberato, watk): Figure out what we want to do about zero copy for 265 // TODO(liberato, watk): Figure out what we want to do about zero copy for
259 // fullscreen external SurfaceView in WebView. http://crbug.com/582170. 266 // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
260 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync()); 267
268 // Make sure that we're making a copy in sync mode, to verify that our
269 // guess about whether we're in sync mode in NeedsBrowserCopy is correct.
270 // Also make sure that, if we're in sync mode, that we're using a threaded
271 // callback so that it doesn't deadlock with the main thread.
272 DCHECK(!gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync() ||
273 (DeferredStrategyNeedsBrowserCopy() && IsCallbackThreadable()));
274
261 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy."; 275 DVLOG(1) << __FUNCTION__ << ", using deferred rendering strategy.";
262 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this)); 276 strategy_.reset(new AndroidDeferredRenderingBackingStrategy(this));
263 } else { 277 } else {
264 DVLOG(1) << __FUNCTION__ << ", using copy back strategy."; 278 DVLOG(1) << __FUNCTION__ << ", using copy back strategy.";
265 strategy_.reset(new AndroidCopyingBackingStrategy(this)); 279 strategy_.reset(new AndroidCopyingBackingStrategy(this));
266 } 280 }
267 } 281 }
268 282
269 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() { 283 AndroidVideoDecodeAccelerator::~AndroidVideoDecodeAccelerator() {
270 DCHECK(thread_checker_.CalledOnValidThread()); 284 DCHECK(thread_checker_.CalledOnValidThread());
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 if (surface_.IsEmpty()) { 342 if (surface_.IsEmpty()) {
329 LOG(ERROR) << "Failed to initialize the backing strategy. The returned " 343 LOG(ERROR) << "Failed to initialize the backing strategy. The returned "
330 "Java surface is empty."; 344 "Java surface is empty.";
331 return false; 345 return false;
332 } 346 }
333 347
334 // TODO(watk,liberato): move this into the strategy. 348 // TODO(watk,liberato): move this into the strategy.
335 scoped_refptr<gfx::SurfaceTexture> surface_texture = 349 scoped_refptr<gfx::SurfaceTexture> surface_texture =
336 strategy_->GetSurfaceTexture(); 350 strategy_->GetSurfaceTexture();
337 if (surface_texture) { 351 if (surface_texture) {
352 // The deferred strategy requires threading the callback if we're using
353 // the sync compositor.
354 bool use_separate_thread =
355 gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync() &&
356 UseDeferredRenderingStrategy();
357 DCHECK(!use_separate_thread || IsCallbackThreadable());
338 on_frame_available_handler_ = 358 on_frame_available_handler_ =
339 new OnFrameAvailableHandler(this, surface_texture); 359 new OnFrameAvailableHandler(this, surface_texture, use_separate_thread);
340 } 360 }
341 361
342 // For encrypted streams we postpone configuration until MediaCrypto is 362 // For encrypted streams we postpone configuration until MediaCrypto is
343 // available. 363 // available.
344 if (is_encrypted_) 364 if (is_encrypted_)
345 return true; 365 return true;
346 366
347 return ConfigureMediaCodec(); 367 return ConfigureMediaCodec();
348 } 368 }
349 369
(...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 } 1115 }
1096 1116
1097 if (should_be_running) 1117 if (should_be_running)
1098 g_avda_timer.Pointer()->StartTimer(this); 1118 g_avda_timer.Pointer()->StartTimer(this);
1099 else 1119 else
1100 g_avda_timer.Pointer()->StopTimer(this); 1120 g_avda_timer.Pointer()->StopTimer(this);
1101 } 1121 }
1102 1122
1103 // static 1123 // static
1104 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy() { 1124 bool AndroidVideoDecodeAccelerator::UseDeferredRenderingStrategy() {
1105 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
1106 // TODO(liberato, watk): Figure out what we want to do about zero copy for 1125 // TODO(liberato, watk): Figure out what we want to do about zero copy for
1107 // fullscreen external SurfaceView in WebView. http://crbug.com/582170. 1126 // fullscreen external SurfaceView in WebView. http://crbug.com/582170.
1108 return !cmd_line->HasSwitch(switches::kEnableThreadedTextureMailboxes); 1127 // If we are at API 21, we can use this any time. Otherwise, we cannot use
1128 // it for webview, since we cannot set the callback thread, causing a
1129 // deadlock with the compositor.
1130 return IsCallbackThreadable() || !DeferredStrategyNeedsBrowserCopy();
1109 } 1131 }
1110 1132
1111 // static 1133 // static
1134 bool AndroidVideoDecodeAccelerator::DeferredStrategyNeedsBrowserCopy() {
1135 // If we're using the synchronous mailbox mechanism and the deferred
1136 // rendering strategy, then we need to force a copy before sending to
1137 // the browser compositor.
1138 // The copy is required because SurfaceTexture client textures can't be
1139 // shared across unrelated GL contexts. By deferring the copy until the
1140 // frame is sent to the browser compositor, we can limit the number of
1141 // outstanding copies to be ~2, regardless of how many the pipeline wants
1142 // for better playback.
1143 // In practice, all of that means "WebView requires a copy".
1144
1145 // We'd really like to check
1146 // gl_decoder_->GetContextGroup()->mailbox_manager()->UsesSync() here, but
1147 // we're called too early in start-up for that to be set properly.
1148 // Instead, we use this switch and verify it later.
1149 const base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
1150 return cmd_line->HasSwitch(switches::kEnableThreadedTextureMailboxes);
1151 }
1152
1153 // static
1154 bool AndroidVideoDecodeAccelerator::IsCallbackThreadable() {
1155 return base::android::BuildInfo::GetInstance()->sdk_int() >= 21;
1156 }
1157
1158 // static
1112 media::VideoDecodeAccelerator::Capabilities 1159 media::VideoDecodeAccelerator::Capabilities
1113 AndroidVideoDecodeAccelerator::GetCapabilities() { 1160 AndroidVideoDecodeAccelerator::GetCapabilities() {
1114 Capabilities capabilities; 1161 Capabilities capabilities;
1115 SupportedProfiles& profiles = capabilities.supported_profiles; 1162 SupportedProfiles& profiles = capabilities.supported_profiles;
1116 1163
1117 SupportedProfile profile; 1164 SupportedProfile profile;
1118 1165
1119 if (media::MediaCodecUtil::IsVp8DecoderAvailable()) { 1166 if (media::MediaCodecUtil::IsVp8DecoderAvailable()) {
1120 profile.profile = media::VP8PROFILE_ANY; 1167 profile.profile = media::VP8PROFILE_ANY;
1121 profile.min_resolution.SetSize(0, 0); 1168 profile.min_resolution.SetSize(0, 0);
(...skipping 17 matching lines...) Expand all
1139 // software fallback for H264 on Android anyway. 1186 // software fallback for H264 on Android anyway.
1140 profile.max_resolution.SetSize(3840, 2160); 1187 profile.max_resolution.SetSize(3840, 2160);
1141 profiles.push_back(profile); 1188 profiles.push_back(profile);
1142 } 1189 }
1143 1190
1144 if (UseDeferredRenderingStrategy()) { 1191 if (UseDeferredRenderingStrategy()) {
1145 capabilities.flags = media::VideoDecodeAccelerator::Capabilities:: 1192 capabilities.flags = media::VideoDecodeAccelerator::Capabilities::
1146 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE | 1193 NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE |
1147 media::VideoDecodeAccelerator::Capabilities:: 1194 media::VideoDecodeAccelerator::Capabilities::
1148 SUPPORTS_EXTERNAL_OUTPUT_SURFACE; 1195 SUPPORTS_EXTERNAL_OUTPUT_SURFACE;
1196 if (DeferredStrategyNeedsBrowserCopy())
1197 capabilities.flags |=
1198 media::VideoDecodeAccelerator::Capabilities::COPY_REQUIRED;
1149 } 1199 }
1150 1200
1151 return capabilities; 1201 return capabilities;
1152 } 1202 }
1153 1203
1154 } // namespace content 1204 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/media/android_video_decode_accelerator.h ('k') | media/filters/gpu_video_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698