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

Side by Side Diff: ui/gl/async_pixel_transfer_delegate_android.cc

Issue 12210129: gpu: Add the ability to wait on upload completion. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix logging. Created 7 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
« no previous file with comments | « ui/gl/async_pixel_transfer_delegate.h ('k') | ui/gl/async_pixel_transfer_delegate_stub.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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/gl/async_pixel_transfer_delegate_android.h" 5 #include "ui/gl/async_pixel_transfer_delegate_android.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
14 #include "base/process_util.h" 14 #include "base/process_util.h"
15 #include "base/shared_memory.h" 15 #include "base/shared_memory.h"
16 #include "base/synchronization/waitable_event.h"
16 #include "base/threading/thread.h" 17 #include "base/threading/thread.h"
17 #include "build/build_config.h" 18 #include "build/build_config.h"
18 #include "ui/gl/async_pixel_transfer_delegate.h" 19 #include "ui/gl/async_pixel_transfer_delegate.h"
19 #include "ui/gl/async_pixel_transfer_delegate_stub.h" 20 #include "ui/gl/async_pixel_transfer_delegate_stub.h"
20 #include "ui/gl/egl_util.h" 21 #include "ui/gl/egl_util.h"
21 #include "ui/gl/gl_bindings.h" 22 #include "ui/gl/gl_bindings.h"
22 #include "ui/gl/gl_context.h" 23 #include "ui/gl/gl_context.h"
23 #include "ui/gl/gl_surface_egl.h" 24 #include "ui/gl/gl_surface_egl.h"
24 #include "ui/gl/safe_shared_memory_pool.h" 25 #include "ui/gl/safe_shared_memory_pool.h"
25 26
26 // TODO(epenner): Move thread priorities to base. (crbug.com/170549) 27 // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
27 #include <sys/resource.h> 28 #include <sys/resource.h>
28 29
29 using base::SharedMemory; 30 using base::SharedMemory;
30 using base::SharedMemoryHandle; 31 using base::SharedMemoryHandle;
31 32
32 namespace gfx { 33 namespace gfx {
33 34
34 namespace { 35 namespace {
35 36
36 // Quick and dirty Atomic flag, that we use for
37 // marking completion from the upload thread.
38 class AtomicFlag {
39 public:
40 AtomicFlag() {
41 base::subtle::Acquire_Store(&value_, 0);
42 }
43 void Set() {
44 base::subtle::Atomic32 old_value = base::subtle::Acquire_CompareAndSwap(
45 &value_, 0, 1);
46 DCHECK_EQ(old_value, 0);
47 }
48 void Unset() {
49 base::subtle::Atomic32 old_value = base::subtle::Release_CompareAndSwap(
50 &value_, 1, 0);
51 DCHECK_EQ(old_value, 1);
52 }
53 bool IsSet() {
54 return base::subtle::Acquire_Load(&value_) == 1;
55 }
56 private:
57 base::subtle::Atomic32 value_;
58 DISALLOW_COPY_AND_ASSIGN(AtomicFlag);
59 };
60
61
62 class TextureUploadStats 37 class TextureUploadStats
63 : public base::RefCountedThreadSafe<TextureUploadStats> { 38 : public base::RefCountedThreadSafe<TextureUploadStats> {
64 public: 39 public:
65 TextureUploadStats() : texture_upload_count_(0) {} 40 TextureUploadStats() : texture_upload_count_(0) {}
66 41
67 void AddUpload(base::TimeDelta transfer_time) { 42 void AddUpload(base::TimeDelta transfer_time) {
68 base::AutoLock scoped_lock(lock_); 43 base::AutoLock scoped_lock(lock_);
69 texture_upload_count_++; 44 texture_upload_count_++;
70 total_texture_upload_time_ += transfer_time; 45 total_texture_upload_time_ += transfer_time;
71 } 46 }
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 // else accessed only on the main thread. 181 // else accessed only on the main thread.
207 class TransferStateInternal 182 class TransferStateInternal
208 : public base::RefCountedThreadSafe<TransferStateInternal> { 183 : public base::RefCountedThreadSafe<TransferStateInternal> {
209 public: 184 public:
210 explicit TransferStateInternal(GLuint texture_id, 185 explicit TransferStateInternal(GLuint texture_id,
211 bool wait_for_uploads, 186 bool wait_for_uploads,
212 bool use_image_preserved) 187 bool use_image_preserved)
213 : texture_id_(texture_id), 188 : texture_id_(texture_id),
214 thread_texture_id_(0), 189 thread_texture_id_(0),
215 needs_late_bind_(false), 190 needs_late_bind_(false),
191 transfer_completion_(true, true),
216 egl_image_(EGL_NO_IMAGE_KHR), 192 egl_image_(EGL_NO_IMAGE_KHR),
217 wait_for_uploads_(wait_for_uploads), 193 wait_for_uploads_(wait_for_uploads),
218 use_image_preserved_(use_image_preserved) { 194 use_image_preserved_(use_image_preserved) {
219 static const AsyncTexImage2DParams zero_params = {0, 0, 0, 0, 0, 0, 0, 0}; 195 static const AsyncTexImage2DParams zero_params = {0, 0, 0, 0, 0, 0, 0, 0};
220 late_bind_define_params_ = zero_params; 196 late_bind_define_params_ = zero_params;
221 } 197 }
222 198
223 // Implement AsyncPixelTransferState: 199 // Implement AsyncPixelTransferState:
224 bool TransferIsInProgress() { 200 bool TransferIsInProgress() {
225 return transfer_in_progress_.IsSet(); 201 return !transfer_completion_.IsSignaled();
226 } 202 }
227 203
228 void BindTransfer(AsyncTexImage2DParams* bound_params) { 204 void BindTransfer(AsyncTexImage2DParams* bound_params) {
229 TRACE_EVENT2("gpu", "BindAsyncTransfer glEGLImageTargetTexture2DOES", 205 TRACE_EVENT2("gpu", "BindAsyncTransfer glEGLImageTargetTexture2DOES",
230 "width", late_bind_define_params_.width, 206 "width", late_bind_define_params_.width,
231 "height", late_bind_define_params_.height); 207 "height", late_bind_define_params_.height);
232 DCHECK(bound_params); 208 DCHECK(bound_params);
233 DCHECK(texture_id_); 209 DCHECK(texture_id_);
234 *bound_params = late_bind_define_params_; 210 *bound_params = late_bind_define_params_;
235 if (!needs_late_bind_) 211 if (!needs_late_bind_)
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 // GPU action that needs to occur. We could use fences and try 263 // GPU action that needs to occur. We could use fences and try
288 // to do this less often. However, on older drivers fences are 264 // to do this less often. However, on older drivers fences are
289 // not always reliable (eg. Mali-400 just blocks forever). 265 // not always reliable (eg. Mali-400 just blocks forever).
290 if (wait_for_uploads_) { 266 if (wait_for_uploads_) {
291 TRACE_EVENT0("gpu", "glFinish"); 267 TRACE_EVENT0("gpu", "glFinish");
292 glFinish(); 268 glFinish();
293 } 269 }
294 } 270 }
295 271
296 void MarkAsTransferIsInProgress() { 272 void MarkAsTransferIsInProgress() {
297 transfer_in_progress_.Set(); 273 transfer_completion_.Reset();
298 } 274 }
299 275
300 void MarkAsCompleted() { 276 void MarkAsCompleted() {
301 transfer_in_progress_.Unset(); 277 transfer_completion_.Signal();
278 }
279
280 void WaitForTransferCompletion() {
281 transfer_completion_.Wait();
302 } 282 }
303 283
304 protected: 284 protected:
305 friend class base::RefCountedThreadSafe<TransferStateInternal>; 285 friend class base::RefCountedThreadSafe<TransferStateInternal>;
306 friend class AsyncPixelTransferDelegateAndroid; 286 friend class AsyncPixelTransferDelegateAndroid;
307 287
308 static void DeleteTexture(GLuint id) { 288 static void DeleteTexture(GLuint id) {
309 glDeleteTextures(1, &id); 289 glDeleteTextures(1, &id);
310 } 290 }
311 291
(...skipping 15 matching lines...) Expand all
327 GLuint thread_texture_id_; 307 GLuint thread_texture_id_;
328 308
329 // Indicates there is a new EGLImage and the 'real' 309 // Indicates there is a new EGLImage and the 'real'
330 // texture needs to be bound to it as an EGLImage target. 310 // texture needs to be bound to it as an EGLImage target.
331 bool needs_late_bind_; 311 bool needs_late_bind_;
332 312
333 // Definition params for texture that needs binding. 313 // Definition params for texture that needs binding.
334 AsyncTexImage2DParams late_bind_define_params_; 314 AsyncTexImage2DParams late_bind_define_params_;
335 315
336 // Indicates that an async transfer is in progress. 316 // Indicates that an async transfer is in progress.
337 AtomicFlag transfer_in_progress_; 317 base::WaitableEvent transfer_completion_;
338 318
339 // It would be nice if we could just create a new EGLImage for 319 // It would be nice if we could just create a new EGLImage for
340 // every upload, but I found that didn't work, so this stores 320 // every upload, but I found that didn't work, so this stores
341 // one for the lifetime of the texture. 321 // one for the lifetime of the texture.
342 EGLImageKHR egl_image_; 322 EGLImageKHR egl_image_;
343 323
344 // Customize when we block on fences (these are work-arounds). 324 // Customize when we block on fences (these are work-arounds).
345 bool wait_for_uploads_; 325 bool wait_for_uploads_;
346 bool use_image_preserved_; 326 bool use_image_preserved_;
347 }; 327 };
348 328
349 // Android needs thread-safe ref-counting, so this just wraps 329 // Android needs thread-safe ref-counting, so this just wraps
350 // an internal thread-safe ref-counted state object. 330 // an internal thread-safe ref-counted state object.
351 class AsyncTransferStateAndroid : public AsyncPixelTransferState { 331 class AsyncTransferStateAndroid : public AsyncPixelTransferState {
352 public: 332 public:
353 explicit AsyncTransferStateAndroid(GLuint texture_id, 333 explicit AsyncTransferStateAndroid(GLuint texture_id,
354 bool wait_for_uploads, 334 bool wait_for_uploads,
355 bool use_image_preserved) 335 bool use_image_preserved)
356 : internal_(new TransferStateInternal(texture_id, 336 : internal_(new TransferStateInternal(texture_id,
357 wait_for_uploads, 337 wait_for_uploads,
358 use_image_preserved)) { 338 use_image_preserved)) {
359 } 339 }
360 virtual ~AsyncTransferStateAndroid() {} 340 virtual ~AsyncTransferStateAndroid() {}
361 virtual bool TransferIsInProgress() { 341 virtual bool TransferIsInProgress() OVERRIDE {
362 return internal_->TransferIsInProgress(); 342 return internal_->TransferIsInProgress();
363 } 343 }
364 virtual void BindTransfer(AsyncTexImage2DParams* bound_params) { 344 virtual void BindTransfer(AsyncTexImage2DParams* bound_params) OVERRIDE {
365 internal_->BindTransfer(bound_params); 345 internal_->BindTransfer(bound_params);
366 } 346 }
367 scoped_refptr<TransferStateInternal> internal_; 347 scoped_refptr<TransferStateInternal> internal_;
368 }; 348 };
369 349
370 // Class which handles async pixel transfers on Android (using 350 // Class which handles async pixel transfers on Android (using
371 // EGLImageKHR and another upload thread) 351 // EGLImageKHR and another upload thread)
372 class AsyncPixelTransferDelegateAndroid 352 class AsyncPixelTransferDelegateAndroid
373 : public AsyncPixelTransferDelegate, 353 : public AsyncPixelTransferDelegate,
374 public base::SupportsWeakPtr<AsyncPixelTransferDelegateAndroid> { 354 public base::SupportsWeakPtr<AsyncPixelTransferDelegateAndroid> {
375 public: 355 public:
376 AsyncPixelTransferDelegateAndroid(); 356 AsyncPixelTransferDelegateAndroid();
377 virtual ~AsyncPixelTransferDelegateAndroid(); 357 virtual ~AsyncPixelTransferDelegateAndroid();
378 358
379 // implement AsyncPixelTransferDelegate: 359 // implement AsyncPixelTransferDelegate:
380 virtual void AsyncNotifyCompletion( 360 virtual void AsyncNotifyCompletion(
381 const AsyncMemoryParams& mem_params, 361 const AsyncMemoryParams& mem_params,
382 const CompletionCallback& callback) OVERRIDE; 362 const CompletionCallback& callback) OVERRIDE;
383 virtual void AsyncTexImage2D( 363 virtual void AsyncTexImage2D(
384 AsyncPixelTransferState* state, 364 AsyncPixelTransferState* state,
385 const AsyncTexImage2DParams& tex_params, 365 const AsyncTexImage2DParams& tex_params,
386 const AsyncMemoryParams& mem_params) OVERRIDE; 366 const AsyncMemoryParams& mem_params) OVERRIDE;
387 virtual void AsyncTexSubImage2D( 367 virtual void AsyncTexSubImage2D(
388 AsyncPixelTransferState* state, 368 AsyncPixelTransferState* state,
389 const AsyncTexSubImage2DParams& tex_params, 369 const AsyncTexSubImage2DParams& tex_params,
390 const AsyncMemoryParams& mem_params) OVERRIDE; 370 const AsyncMemoryParams& mem_params) OVERRIDE;
371 virtual void WaitForTransferCompletion(
372 AsyncPixelTransferState* state) OVERRIDE;
391 virtual uint32 GetTextureUploadCount() OVERRIDE; 373 virtual uint32 GetTextureUploadCount() OVERRIDE;
392 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; 374 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
393 375
394 private: 376 private:
395 // implement AsyncPixelTransferDelegate: 377 // implement AsyncPixelTransferDelegate:
396 virtual AsyncPixelTransferState* 378 virtual AsyncPixelTransferState*
397 CreateRawPixelTransferState(GLuint texture_id) OVERRIDE; 379 CreateRawPixelTransferState(GLuint texture_id) OVERRIDE;
398 380
399 static void PerformNotifyCompletion( 381 static void PerformNotifyCompletion(
400 AsyncMemoryParams mem_params, 382 AsyncMemoryParams mem_params,
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 FROM_HERE, 479 FROM_HERE,
498 base::Bind(&AsyncPixelTransferDelegateAndroid::PerformNotifyCompletion, 480 base::Bind(&AsyncPixelTransferDelegateAndroid::PerformNotifyCompletion,
499 mem_params, 481 mem_params,
500 base::Owned( 482 base::Owned(
501 new ScopedSafeSharedMemory(safe_shared_memory_pool(), 483 new ScopedSafeSharedMemory(safe_shared_memory_pool(),
502 mem_params.shared_memory, 484 mem_params.shared_memory,
503 mem_params.shm_size)), 485 mem_params.shm_size)),
504 callback)); 486 callback));
505 } 487 }
506 488
489 void AsyncPixelTransferDelegateAndroid::WaitForTransferCompletion(
490 AsyncPixelTransferState* transfer_state) {
491 TRACE_EVENT0("gpu", "WaitForTransferCompletion");
492 scoped_refptr<TransferStateInternal> state =
493 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get();
494 DCHECK(state);
495 DCHECK(state->texture_id_);
496
497 if (state->TransferIsInProgress()) {
498 // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
499 int default_nice_value = 0; // Default priority.
500 int idle_nice_value = 10; // Idle priority.
501 setpriority(PRIO_PROCESS,
502 g_transfer_thread.Pointer()->thread_id(),
503 default_nice_value);
504
505 state->WaitForTransferCompletion();
506 DCHECK(!state->TransferIsInProgress());
507
508 // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
509 setpriority(PRIO_PROCESS,
510 g_transfer_thread.Pointer()->thread_id(),
511 idle_nice_value);
512 }
513 }
514
507 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D( 515 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D(
508 AsyncPixelTransferState* transfer_state, 516 AsyncPixelTransferState* transfer_state,
509 const AsyncTexImage2DParams& tex_params, 517 const AsyncTexImage2DParams& tex_params,
510 const AsyncMemoryParams& mem_params) { 518 const AsyncMemoryParams& mem_params) {
511 scoped_refptr<TransferStateInternal> state = 519 scoped_refptr<TransferStateInternal> state =
512 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get(); 520 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get();
513 DCHECK(mem_params.shared_memory); 521 DCHECK(mem_params.shared_memory);
514 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size, 522 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
515 mem_params.shm_size); 523 mem_params.shm_size);
516 DCHECK(state); 524 DCHECK(state);
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 if (texture_upload_stats_) { 834 if (texture_upload_stats_) {
827 texture_upload_stats_->AddUpload( 835 texture_upload_stats_->AddUpload(
828 base::TimeTicks::HighResNow() - begin_time); 836 base::TimeTicks::HighResNow() - begin_time);
829 } 837 }
830 838
831 DCHECK(CHECK_GL()); 839 DCHECK(CHECK_GL());
832 return true; 840 return true;
833 } 841 }
834 842
835 } // namespace gfx 843 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gl/async_pixel_transfer_delegate.h ('k') | ui/gl/async_pixel_transfer_delegate_stub.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698