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

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

Issue 12213073: Re-land: Mark async texture uploads as completed from the upload thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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 | Annotate | Revision Log
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/threading/thread.h" 16 #include "base/threading/thread.h"
17 #include "build/build_config.h" 17 #include "build/build_config.h"
18 #include "gpu/command_buffer/common/gles2_cmd_format.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 25
25 // TODO(epenner): Move thread priorities to base. (crbug.com/170549) 26 // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
26 #include <sys/resource.h> 27 #include <sys/resource.h>
27 28
28 using base::SharedMemory; 29 using base::SharedMemory;
29 using base::SharedMemoryHandle; 30 using base::SharedMemoryHandle;
30 31
31 namespace gfx { 32 namespace gfx {
32 33
33 namespace { 34 namespace {
34 35
36 class TextureUploadStats
epenner 2013/02/07 20:36:34 Can this be another change? I don't understand how
reveman 2013/02/07 21:30:52 I can't get rid of the replies and keep collecting
epenner 2013/02/07 21:59:47 I see, let's not get rid of the reply then? We sho
37 : public base::RefCountedThreadSafe<TextureUploadStats> {
38 public:
39 TextureUploadStats() : texture_upload_count_(0) {}
40
41 void AddUpload(base::TimeDelta transfer_time) {
42 base::AutoLock scoped_lock(lock_);
43 texture_upload_count_++;
44 total_texture_upload_time_ += transfer_time;
45 }
46
47 int GetStats(base::TimeDelta* total_texture_upload_time) {
48 base::AutoLock scoped_lock(lock_);
49 if (total_texture_upload_time)
50 *total_texture_upload_time = total_texture_upload_time_;
51 return texture_upload_count_;
52 }
53
54 private:
55 friend class RefCountedThreadSafe<TextureUploadStats>;
56
57 ~TextureUploadStats() {}
58
59 int texture_upload_count_;
60 base::TimeDelta total_texture_upload_time_;
61 base::Lock lock_;
62 };
63
35 const char kAsyncTransferThreadName[] = "AsyncTransferThread"; 64 const char kAsyncTransferThreadName[] = "AsyncTransferThread";
36 65
37 bool CheckErrors(const char* file, int line) { 66 bool CheckErrors(const char* file, int line) {
38 EGLint eglerror; 67 EGLint eglerror;
39 GLenum glerror; 68 GLenum glerror;
40 bool success = true; 69 bool success = true;
41 while ((eglerror = eglGetError()) != EGL_SUCCESS) { 70 while ((eglerror = eglGetError()) != EGL_SUCCESS) {
42 LOG(ERROR) << "Async transfer EGL error at " 71 LOG(ERROR) << "Async transfer EGL error at "
43 << file << ":" << line << " " << eglerror; 72 << file << ":" << line << " " << eglerror;
44 success = false; 73 success = false;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 transfer_in_progress_(false), 174 transfer_in_progress_(false),
146 egl_image_(EGL_NO_IMAGE_KHR), 175 egl_image_(EGL_NO_IMAGE_KHR),
147 wait_for_uploads_(wait_for_uploads), 176 wait_for_uploads_(wait_for_uploads),
148 wait_for_egl_images_(wait_for_egl_images) { 177 wait_for_egl_images_(wait_for_egl_images) {
149 static const AsyncTexImage2DParams zero_params = {0, 0, 0, 0, 0, 0, 0, 0}; 178 static const AsyncTexImage2DParams zero_params = {0, 0, 0, 0, 0, 0, 0, 0};
150 late_bind_define_params_ = zero_params; 179 late_bind_define_params_ = zero_params;
151 } 180 }
152 181
153 // Implement AsyncPixelTransferState: 182 // Implement AsyncPixelTransferState:
154 bool TransferIsInProgress() { 183 bool TransferIsInProgress() {
184 base::AutoLock scoped_lock(transfer_in_progress_lock_);
155 return transfer_in_progress_; 185 return transfer_in_progress_;
156 } 186 }
157 187
158 void BindTransfer(AsyncTexImage2DParams* bound_params) { 188 void BindTransfer(AsyncTexImage2DParams* bound_params) {
159 TRACE_EVENT2("gpu", "BindAsyncTransfer glEGLImageTargetTexture2DOES", 189 TRACE_EVENT2("gpu", "BindAsyncTransfer glEGLImageTargetTexture2DOES",
160 "width", late_bind_define_params_.width, 190 "width", late_bind_define_params_.width,
161 "height", late_bind_define_params_.height); 191 "height", late_bind_define_params_.height);
162 192
163 DCHECK(bound_params); 193 DCHECK(bound_params);
164 DCHECK(texture_id_); 194 DCHECK(texture_id_);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 // This glFinish is just a safe-guard for if uploads have some 256 // This glFinish is just a safe-guard for if uploads have some
227 // GPU action that needs to occur. We could use fences and try 257 // GPU action that needs to occur. We could use fences and try
228 // to do this less often. However, on older drivers fences are 258 // to do this less often. However, on older drivers fences are
229 // not always reliable (eg. Mali-400 just blocks forever). 259 // not always reliable (eg. Mali-400 just blocks forever).
230 if (wait_for_uploads_) { 260 if (wait_for_uploads_) {
231 TRACE_EVENT0("gpu", "glFinish"); 261 TRACE_EVENT0("gpu", "glFinish");
232 glFinish(); 262 glFinish();
233 } 263 }
234 } 264 }
235 265
266 void MarkAsCompleted() {
267 base::AutoLock scoped_lock(transfer_in_progress_lock_);
268 DCHECK(transfer_in_progress_);
269 transfer_in_progress_ = false;
270 }
271
236 protected: 272 protected:
237 friend class base::RefCountedThreadSafe<TransferStateInternal>; 273 friend class base::RefCountedThreadSafe<TransferStateInternal>;
238 friend class AsyncPixelTransferDelegateAndroid; 274 friend class AsyncPixelTransferDelegateAndroid;
239 275
240 static void DeleteTexture(GLuint id) { 276 static void DeleteTexture(GLuint id) {
241 glDeleteTextures(1, &id); 277 glDeleteTextures(1, &id);
242 } 278 }
243 279
244 virtual ~TransferStateInternal() { 280 virtual ~TransferStateInternal() {
245 if (egl_image_ != EGL_NO_IMAGE_KHR) { 281 if (egl_image_ != EGL_NO_IMAGE_KHR) {
(...skipping 14 matching lines...) Expand all
260 296
261 // Indicates there is a new EGLImage and the 'real' 297 // Indicates there is a new EGLImage and the 'real'
262 // texture needs to be bound to it as an EGLImage target. 298 // texture needs to be bound to it as an EGLImage target.
263 bool needs_late_bind_; 299 bool needs_late_bind_;
264 300
265 // Definition params for texture that needs binding. 301 // Definition params for texture that needs binding.
266 AsyncTexImage2DParams late_bind_define_params_; 302 AsyncTexImage2DParams late_bind_define_params_;
267 303
268 // Indicates that an async transfer is in progress. 304 // Indicates that an async transfer is in progress.
269 bool transfer_in_progress_; 305 bool transfer_in_progress_;
306 base::Lock transfer_in_progress_lock_;
reveman 2013/02/07 19:59:02 we could use base::subtle::Atomic32 here instead i
epenner 2013/02/07 20:22:56 Can you explain a bit why we need a lock or atomic
reveman 2013/02/07 21:30:52 Both threads will access this. Main thread to dete
epenner 2013/02/07 21:59:47 That's what atomic ints are used for yes, but I'm
270 307
271 // It would be nice if we could just create a new EGLImage for 308 // It would be nice if we could just create a new EGLImage for
272 // every upload, but I found that didn't work, so this stores 309 // every upload, but I found that didn't work, so this stores
273 // one for the lifetime of the texture. 310 // one for the lifetime of the texture.
274 EGLImageKHR egl_image_; 311 EGLImageKHR egl_image_;
275 312
276 // Time spent performing last transfer.
277 base::TimeDelta last_transfer_time_;
278
279 // Customize when we block on fences (these are work-arounds). 313 // Customize when we block on fences (these are work-arounds).
280 bool wait_for_uploads_; 314 bool wait_for_uploads_;
281 bool wait_for_egl_images_; 315 bool wait_for_egl_images_;
282 }; 316 };
283 317
284 // Android needs thread-safe ref-counting, so this just wraps 318 // Android needs thread-safe ref-counting, so this just wraps
285 // an internal thread-safe ref-counted state object. 319 // an internal thread-safe ref-counted state object.
286 class AsyncTransferStateAndroid : public AsyncPixelTransferState { 320 class AsyncTransferStateAndroid : public AsyncPixelTransferState {
287 public: 321 public:
288 explicit AsyncTransferStateAndroid(GLuint texture_id, 322 explicit AsyncTransferStateAndroid(GLuint texture_id,
289 bool wait_for_uploads, 323 bool wait_for_uploads,
290 bool wait_for_egl_images) 324 bool wait_for_egl_images)
291 : internal_(new TransferStateInternal(texture_id, 325 : internal_(new TransferStateInternal(texture_id,
292 wait_for_uploads, 326 wait_for_uploads,
293 wait_for_egl_images)) { 327 wait_for_egl_images)) {
294 } 328 }
295 virtual ~AsyncTransferStateAndroid() {} 329 virtual ~AsyncTransferStateAndroid() {}
296 virtual bool TransferIsInProgress() { 330 virtual bool TransferIsInProgress() {
297 return internal_->TransferIsInProgress(); 331 return internal_->TransferIsInProgress();
298 } 332 }
299 virtual void BindTransfer(AsyncTexImage2DParams* bound_params) { 333 virtual void BindTransfer(AsyncTexImage2DParams* bound_params) {
300 internal_->BindTransfer(bound_params); 334 internal_->BindTransfer(bound_params);
301 } 335 }
302 scoped_refptr<TransferStateInternal> internal_; 336 scoped_refptr<TransferStateInternal> internal_;
303 }; 337 };
304 338
305 // Class which handles async pixel transfers on Android (using 339 // Class which handles async pixel transfers on Android (using
306 // EGLImageKHR and another upload thread) 340 // EGLImageKHR and another upload thread)
307 class AsyncPixelTransferDelegateAndroid 341 class AsyncPixelTransferDelegateAndroid : public AsyncPixelTransferDelegate {
308 : public AsyncPixelTransferDelegate,
309 public base::SupportsWeakPtr<AsyncPixelTransferDelegateAndroid> {
310 public: 342 public:
311 AsyncPixelTransferDelegateAndroid(); 343 AsyncPixelTransferDelegateAndroid();
312 virtual ~AsyncPixelTransferDelegateAndroid(); 344 virtual ~AsyncPixelTransferDelegateAndroid();
313 345
314 // implement AsyncPixelTransferDelegate: 346 // implement AsyncPixelTransferDelegate:
315 virtual void AsyncNotifyCompletion( 347 virtual void AsyncNotifyCompletion(
316 const base::Closure& task) OVERRIDE; 348 const AsyncMemoryParams& mem_params,
349 uint32 submit_count) OVERRIDE;
317 virtual void AsyncTexImage2D( 350 virtual void AsyncTexImage2D(
318 AsyncPixelTransferState* state, 351 AsyncPixelTransferState* state,
319 const AsyncTexImage2DParams& tex_params, 352 const AsyncTexImage2DParams& tex_params,
320 const AsyncMemoryParams& mem_params) OVERRIDE; 353 const AsyncMemoryParams& mem_params) OVERRIDE;
321 virtual void AsyncTexSubImage2D( 354 virtual void AsyncTexSubImage2D(
322 AsyncPixelTransferState* state, 355 AsyncPixelTransferState* state,
323 const AsyncTexSubImage2DParams& tex_params, 356 const AsyncTexSubImage2DParams& tex_params,
324 const AsyncMemoryParams& mem_params) OVERRIDE; 357 const AsyncMemoryParams& mem_params) OVERRIDE;
325 virtual uint32 GetTextureUploadCount() OVERRIDE; 358 virtual uint32 GetTextureUploadCount() OVERRIDE;
326 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE; 359 virtual base::TimeDelta GetTotalTextureUploadTime() OVERRIDE;
327 360
328 private: 361 private:
329 // implement AsyncPixelTransferDelegate: 362 // implement AsyncPixelTransferDelegate:
330 virtual AsyncPixelTransferState* 363 virtual AsyncPixelTransferState*
331 CreateRawPixelTransferState(GLuint texture_id) OVERRIDE; 364 CreateRawPixelTransferState(GLuint texture_id) OVERRIDE;
332 365
333 void AsyncTexImage2DCompleted(scoped_refptr<TransferStateInternal> state);
334 void AsyncTexSubImage2DCompleted(scoped_refptr<TransferStateInternal> state);
335
336 static void PerformAsyncTexImage2D( 366 static void PerformAsyncTexImage2D(
337 TransferStateInternal* state, 367 TransferStateInternal* state,
338 AsyncTexImage2DParams tex_params, 368 AsyncTexImage2DParams tex_params,
339 base::SharedMemory* shared_memory, 369 base::SharedMemory* shared_memory,
340 uint32 shared_memory_data_offset); 370 uint32 shared_memory_data_offset);
341 static void PerformAsyncTexSubImage2D( 371 static void PerformAsyncTexSubImage2D(
342 TransferStateInternal* state, 372 TransferStateInternal* state,
343 AsyncTexSubImage2DParams tex_params, 373 AsyncTexSubImage2DParams tex_params,
344 base::SharedMemory* shared_memory, 374 base::SharedMemory* shared_memory,
345 uint32 shared_memory_data_offset); 375 uint32 shared_memory_data_offset,
376 scoped_refptr<TextureUploadStats> texture_upload_stats);
377 static void PerformNotifyCompletion(
378 base::SharedMemory* shared_memory,
379 uint32 shared_memory_data_offset,
380 uint32 submit_count);
346 381
347 // Returns true if a work-around was used. 382 // Returns true if a work-around was used.
348 bool WorkAroundAsyncTexImage2D( 383 bool WorkAroundAsyncTexImage2D(
349 TransferStateInternal* state, 384 TransferStateInternal* state,
350 const AsyncTexImage2DParams& tex_params, 385 const AsyncTexImage2DParams& tex_params,
351 const AsyncMemoryParams& mem_params); 386 const AsyncMemoryParams& mem_params);
352 bool WorkAroundAsyncTexSubImage2D( 387 bool WorkAroundAsyncTexSubImage2D(
353 TransferStateInternal* state, 388 TransferStateInternal* state,
354 const AsyncTexSubImage2DParams& tex_params, 389 const AsyncTexSubImage2DParams& tex_params,
355 const AsyncMemoryParams& mem_params); 390 const AsyncMemoryParams& mem_params);
356 391
357 int texture_upload_count_; 392 scoped_refptr<TextureUploadStats> texture_upload_stats_;
358 base::TimeDelta total_texture_upload_time_;
359 bool is_imagination_; 393 bool is_imagination_;
360 bool is_qualcomm_; 394 bool is_qualcomm_;
361 395
362 DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateAndroid); 396 DISALLOW_COPY_AND_ASSIGN(AsyncPixelTransferDelegateAndroid);
363 }; 397 };
364 398
365 namespace { 399 namespace {
366 // Imagination has some odd problems still. 400 // Imagination has some odd problems still.
367 bool IsImagination() { 401 bool IsImagination() {
368 std::string vendor; 402 std::string vendor;
(...skipping 19 matching lines...) Expand all
388 static_cast<AsyncPixelTransferDelegate*>( 422 static_cast<AsyncPixelTransferDelegate*>(
389 new AsyncPixelTransferDelegateAndroid())); 423 new AsyncPixelTransferDelegateAndroid()));
390 } else { 424 } else {
391 LOG(INFO) << "Async pixel transfers not supported"; 425 LOG(INFO) << "Async pixel transfers not supported";
392 return make_scoped_ptr( 426 return make_scoped_ptr(
393 static_cast<AsyncPixelTransferDelegate*>( 427 static_cast<AsyncPixelTransferDelegate*>(
394 new AsyncPixelTransferDelegateStub())); 428 new AsyncPixelTransferDelegateStub()));
395 } 429 }
396 } 430 }
397 431
398 AsyncPixelTransferDelegateAndroid::AsyncPixelTransferDelegateAndroid() 432 AsyncPixelTransferDelegateAndroid::AsyncPixelTransferDelegateAndroid() {
399 : texture_upload_count_(0) {
400 std::string vendor; 433 std::string vendor;
401 vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); 434 vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
402 is_imagination_ = vendor.find("Imagination") != std::string::npos; 435 is_imagination_ = vendor.find("Imagination") != std::string::npos;
403 is_qualcomm_ = vendor.find("Qualcomm") != std::string::npos; 436 is_qualcomm_ = vendor.find("Qualcomm") != std::string::npos;
437 // TODO(reveman): Skip this if --enable-gpu-benchmarking is not present.
438 texture_upload_stats_ = make_scoped_refptr(new TextureUploadStats);
404 } 439 }
405 440
406 AsyncPixelTransferDelegateAndroid::~AsyncPixelTransferDelegateAndroid() { 441 AsyncPixelTransferDelegateAndroid::~AsyncPixelTransferDelegateAndroid() {
407 } 442 }
408 443
409 AsyncPixelTransferState* 444 AsyncPixelTransferState*
410 AsyncPixelTransferDelegateAndroid:: 445 AsyncPixelTransferDelegateAndroid::
411 CreateRawPixelTransferState(GLuint texture_id) { 446 CreateRawPixelTransferState(GLuint texture_id) {
412 447
413 // We can't wait on uploads on imagination (it can take 200ms+). 448 // We can't wait on uploads on imagination (it can take 200ms+).
414 bool wait_for_uploads = !is_imagination_; 449 bool wait_for_uploads = !is_imagination_;
415 450
416 // We need to wait for EGLImage creation on Qualcomm. 451 // We need to wait for EGLImage creation on Qualcomm.
417 bool wait_for_egl_images = is_qualcomm_; 452 bool wait_for_egl_images = is_qualcomm_;
418 453
419 return static_cast<AsyncPixelTransferState*>( 454 return static_cast<AsyncPixelTransferState*>(
420 new AsyncTransferStateAndroid(texture_id, 455 new AsyncTransferStateAndroid(texture_id,
421 wait_for_uploads, 456 wait_for_uploads,
422 wait_for_egl_images)); 457 wait_for_egl_images));
423 } 458 }
424 459
425 namespace {
426 // Dummy function to measure completion on
427 // the upload thread.
428 void NoOp() {}
429 } // namespace
430
431 void AsyncPixelTransferDelegateAndroid::AsyncNotifyCompletion( 460 void AsyncPixelTransferDelegateAndroid::AsyncNotifyCompletion(
432 const base::Closure& task) { 461 const AsyncMemoryParams& mem_params,
433 // Post a no-op task to the upload thread followed 462 uint32 submit_count) {
434 // by a reply to the callback. The reply will then occur after 463 DCHECK(mem_params.shared_memory);
435 // all async transfers are complete. 464 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
436 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE, 465 mem_params.shm_size);
437 base::Bind(&NoOp), task); 466 // Post a PerformNotifyCompletion task to the upload thread. This task
467 // will run after all async transfers are complete and mark the QuerySync as
468 // completed.
469 transfer_message_loop_proxy()->PostTask(
470 FROM_HERE,
471 base::Bind(&AsyncPixelTransferDelegateAndroid::PerformNotifyCompletion,
472 base::Owned(DuplicateSharedMemory(mem_params.shared_memory,
473 mem_params.shm_size)),
474 mem_params.shm_data_offset,
475 submit_count));
438 } 476 }
439 477
440 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D( 478 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2D(
441 AsyncPixelTransferState* transfer_state, 479 AsyncPixelTransferState* transfer_state,
442 const AsyncTexImage2DParams& tex_params, 480 const AsyncTexImage2DParams& tex_params,
443 const AsyncMemoryParams& mem_params) { 481 const AsyncMemoryParams& mem_params) {
444 scoped_refptr<TransferStateInternal> state = 482 scoped_refptr<TransferStateInternal> state =
445 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get(); 483 static_cast<AsyncTransferStateAndroid*>(transfer_state)->internal_.get();
446 DCHECK(mem_params.shared_memory); 484 DCHECK(mem_params.shared_memory);
447 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size, 485 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
448 mem_params.shm_size); 486 mem_params.shm_size);
449 DCHECK(state); 487 DCHECK(state);
450 DCHECK(state->texture_id_); 488 DCHECK(state->texture_id_);
451 DCHECK(!state->needs_late_bind_); 489 DCHECK(!state->needs_late_bind_);
452 DCHECK(!state->transfer_in_progress_); 490 DCHECK(!state->transfer_in_progress_);
453 DCHECK_EQ(state->egl_image_, EGL_NO_IMAGE_KHR); 491 DCHECK_EQ(state->egl_image_, EGL_NO_IMAGE_KHR);
454 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target); 492 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
455 DCHECK_EQ(tex_params.level, 0); 493 DCHECK_EQ(tex_params.level, 0);
456 494
457 if (WorkAroundAsyncTexImage2D(state, tex_params, mem_params)) 495 if (WorkAroundAsyncTexImage2D(state, tex_params, mem_params))
458 return; 496 return;
459 497
460 // Mark the transfer in progress and save define params for lazy binding. 498 // Mark the transfer in progress and save define params for lazy binding.
499 state->needs_late_bind_ = true;
461 state->transfer_in_progress_ = true; 500 state->transfer_in_progress_ = true;
462 state->late_bind_define_params_ = tex_params; 501 state->late_bind_define_params_ = tex_params;
463 502
464 // Duplicate the shared memory so there are no way we can get 503 // Duplicate the shared memory so there are no way we can get
465 // a use-after-free of the raw pixels. 504 // a use-after-free of the raw pixels.
466 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE, 505 transfer_message_loop_proxy()->PostTask(FROM_HERE,
467 base::Bind( 506 base::Bind(&AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D,
468 &AsyncPixelTransferDelegateAndroid::PerformAsyncTexImage2D, 507 state,
469 base::Unretained(state.get()), // This is referenced in reply below. 508 tex_params,
470 tex_params, 509 base::Owned(DuplicateSharedMemory(mem_params.shared_memory,
471 base::Owned(DuplicateSharedMemory(mem_params.shared_memory, 510 mem_params.shm_size)),
472 mem_params.shm_size)), 511 mem_params.shm_data_offset));
473 mem_params.shm_data_offset),
474 base::Bind(
475 &AsyncPixelTransferDelegateAndroid::AsyncTexImage2DCompleted,
476 AsWeakPtr(),
477 state));
478 512
479 DCHECK(CHECK_GL()); 513 DCHECK(CHECK_GL());
480 } 514 }
481 515
482 void AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2D( 516 void AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2D(
483 AsyncPixelTransferState* transfer_state, 517 AsyncPixelTransferState* transfer_state,
484 const AsyncTexSubImage2DParams& tex_params, 518 const AsyncTexSubImage2DParams& tex_params,
485 const AsyncMemoryParams& mem_params) { 519 const AsyncMemoryParams& mem_params) {
486 TRACE_EVENT2("gpu", "AsyncTexSubImage2D", 520 TRACE_EVENT2("gpu", "AsyncTexSubImage2D",
487 "width", tex_params.width, 521 "width", tex_params.width,
(...skipping 13 matching lines...) Expand all
501 535
502 // Mark the transfer in progress. 536 // Mark the transfer in progress.
503 state->transfer_in_progress_ = true; 537 state->transfer_in_progress_ = true;
504 538
505 // If this wasn't async allocated, we don't have an EGLImage yet. 539 // If this wasn't async allocated, we don't have an EGLImage yet.
506 // Create the EGLImage if it hasn't already been created. 540 // Create the EGLImage if it hasn't already been created.
507 state->CreateEglImageOnMainThreadIfNeeded(); 541 state->CreateEglImageOnMainThreadIfNeeded();
508 542
509 // Duplicate the shared memory so there are no way we can get 543 // Duplicate the shared memory so there are no way we can get
510 // a use-after-free of the raw pixels. 544 // a use-after-free of the raw pixels.
511 transfer_message_loop_proxy()->PostTaskAndReply(FROM_HERE, 545 transfer_message_loop_proxy()->PostTask(FROM_HERE,
512 base::Bind( 546 base::Bind(&AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D,
513 &AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D, 547 state,
514 base::Unretained(state.get()), // This is referenced in reply below. 548 tex_params,
515 tex_params, 549 base::Owned(DuplicateSharedMemory(mem_params.shared_memory,
516 base::Owned(DuplicateSharedMemory(mem_params.shared_memory, 550 mem_params.shm_size)),
517 mem_params.shm_size)), 551 mem_params.shm_data_offset,
518 mem_params.shm_data_offset), 552 texture_upload_stats_));
519 base::Bind(
520 &AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2DCompleted,
521 AsWeakPtr(),
522 state));
523 553
524 DCHECK(CHECK_GL()); 554 DCHECK(CHECK_GL());
525 } 555 }
526 556
527 uint32 AsyncPixelTransferDelegateAndroid::GetTextureUploadCount() { 557 uint32 AsyncPixelTransferDelegateAndroid::GetTextureUploadCount() {
528 return texture_upload_count_; 558 CHECK(texture_upload_stats_);
559 return texture_upload_stats_->GetStats(NULL);
529 } 560 }
530 561
531 base::TimeDelta AsyncPixelTransferDelegateAndroid::GetTotalTextureUploadTime() { 562 base::TimeDelta AsyncPixelTransferDelegateAndroid::GetTotalTextureUploadTime() {
532 return total_texture_upload_time_; 563 CHECK(texture_upload_stats_);
533 } 564 base::TimeDelta total_texture_upload_time;
534 565 texture_upload_stats_->GetStats(&total_texture_upload_time);
535 void AsyncPixelTransferDelegateAndroid::AsyncTexImage2DCompleted( 566 return total_texture_upload_time;
536 scoped_refptr<TransferStateInternal> state) {
537 state->needs_late_bind_ = true;
538 state->transfer_in_progress_ = false;
539 }
540
541 void AsyncPixelTransferDelegateAndroid::AsyncTexSubImage2DCompleted(
542 scoped_refptr<TransferStateInternal> state) {
543 state->transfer_in_progress_ = false;
544 texture_upload_count_++;
545 total_texture_upload_time_ += state->last_transfer_time_;
546 } 567 }
547 568
548 namespace { 569 namespace {
549 void SetGlParametersForEglImageTexture() { 570 void SetGlParametersForEglImageTexture() {
550 // These params are needed for EGLImage creation to succeed on several 571 // These params are needed for EGLImage creation to succeed on several
551 // Android devices. I couldn't find this requirement in the EGLImage 572 // Android devices. I couldn't find this requirement in the EGLImage
552 // extension spec, but several devices fail without it. 573 // extension spec, but several devices fail without it.
553 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 574 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
554 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 575 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
555 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 576 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 0, 624 0,
604 0, 625 0,
605 tex_params.width, 626 tex_params.width,
606 tex_params.height, 627 tex_params.height,
607 tex_params.format, 628 tex_params.format,
608 tex_params.type, 629 tex_params.type,
609 data); 630 data);
610 } 631 }
611 632
612 state->WaitForLastUpload(); 633 state->WaitForLastUpload();
634 state->MarkAsCompleted();
635
613 DCHECK(CHECK_GL()); 636 DCHECK(CHECK_GL());
614 } 637 }
615 638
616 void AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D( 639 void AsyncPixelTransferDelegateAndroid::PerformAsyncTexSubImage2D(
617 TransferStateInternal* state, 640 TransferStateInternal* state,
618 AsyncTexSubImage2DParams tex_params, 641 AsyncTexSubImage2DParams tex_params,
619 base::SharedMemory* shared_memory, 642 base::SharedMemory* shared_memory,
620 uint32 shared_memory_data_offset) { 643 uint32 shared_memory_data_offset,
644 scoped_refptr<TextureUploadStats> texture_upload_stats) {
621 TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D", 645 TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D",
622 "width", tex_params.width, 646 "width", tex_params.width,
623 "height", tex_params.height); 647 "height", tex_params.height);
624 648
625 DCHECK(state); 649 DCHECK(state);
626 DCHECK_NE(EGL_NO_IMAGE_KHR, state->egl_image_); 650 DCHECK_NE(EGL_NO_IMAGE_KHR, state->egl_image_);
627 DCHECK_EQ(0, tex_params.level); 651 DCHECK_EQ(0, tex_params.level);
628 652
629 state->WaitOnEglImageCreation(); 653 state->WaitOnEglImageCreation();
630 654
631 void* data = GetAddress(shared_memory, shared_memory_data_offset); 655 void* data = GetAddress(shared_memory, shared_memory_data_offset);
632 656
633 base::TimeTicks begin_time(base::TimeTicks::HighResNow()); 657 base::TimeTicks begin_time;
658 if (texture_upload_stats)
659 begin_time = base::TimeTicks::HighResNow();
660
634 if (!state->thread_texture_id_) { 661 if (!state->thread_texture_id_) {
635 TRACE_EVENT0("gpu", "glEGLImageTargetTexture2DOES"); 662 TRACE_EVENT0("gpu", "glEGLImageTargetTexture2DOES");
636 glGenTextures(1, &state->thread_texture_id_); 663 glGenTextures(1, &state->thread_texture_id_);
637 glActiveTexture(GL_TEXTURE0); 664 glActiveTexture(GL_TEXTURE0);
638 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_); 665 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_);
639 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, state->egl_image_); 666 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, state->egl_image_);
640 } else { 667 } else {
641 glActiveTexture(GL_TEXTURE0); 668 glActiveTexture(GL_TEXTURE0);
642 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_); 669 glBindTexture(GL_TEXTURE_2D, state->thread_texture_id_);
643 } 670 }
644 { 671 {
645 TRACE_EVENT0("gpu", "glTexSubImage2D"); 672 TRACE_EVENT0("gpu", "glTexSubImage2D");
646 glTexSubImage2D( 673 glTexSubImage2D(
647 GL_TEXTURE_2D, 674 GL_TEXTURE_2D,
648 tex_params.level, 675 tex_params.level,
649 tex_params.xoffset, 676 tex_params.xoffset,
650 tex_params.yoffset, 677 tex_params.yoffset,
651 tex_params.width, 678 tex_params.width,
652 tex_params.height, 679 tex_params.height,
653 tex_params.format, 680 tex_params.format,
654 tex_params.type, 681 tex_params.type,
655 data); 682 data);
656 } 683 }
657 state->WaitForLastUpload(); 684 state->WaitForLastUpload();
685 state->MarkAsCompleted();
658 686
659 DCHECK(CHECK_GL()); 687 DCHECK(CHECK_GL());
660 state->last_transfer_time_ = base::TimeTicks::HighResNow() - begin_time; 688
689 if (texture_upload_stats) {
690 texture_upload_stats->AddUpload(
691 base::TimeTicks::HighResNow() - begin_time);
692 }
661 } 693 }
662 694
695 void AsyncPixelTransferDelegateAndroid::PerformNotifyCompletion(
696 base::SharedMemory* shared_memory,
697 uint32 shared_memory_data_offset,
698 uint32 submit_count) {
699 TRACE_EVENT0("gpu", "PerformNotifyCompletion");
700
701 gpu::gles2::QuerySync* sync = static_cast<gpu::gles2::QuerySync*>(
702 GetAddress(shared_memory, shared_memory_data_offset));
703 if (!sync)
704 return;
705 sync->process_count = submit_count;
706 }
663 707
664 namespace { 708 namespace {
665 bool IsPowerOfTwo (unsigned int x) { 709 bool IsPowerOfTwo (unsigned int x) {
666 return ((x != 0) && !(x & (x - 1))); 710 return ((x != 0) && !(x & (x - 1)));
667 } 711 }
668 712
669 bool IsMultipleOfEight(unsigned int x) { 713 bool IsMultipleOfEight(unsigned int x) {
670 return (x & 7) == 0; 714 return (x & 7) == 0;
671 } 715 }
672 716
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 return false; 791 return false;
748 792
749 // If the dimensions support fast async uploads, we can use the 793 // If the dimensions support fast async uploads, we can use the
750 // normal async upload path for uploads. 794 // normal async upload path for uploads.
751 if (DimensionsSupportImgFastPath(tex_params.width, tex_params.height)) 795 if (DimensionsSupportImgFastPath(tex_params.width, tex_params.height))
752 return false; 796 return false;
753 797
754 // Fall back on a synchronous stub as we don't have a known fast path. 798 // Fall back on a synchronous stub as we don't have a known fast path.
755 void* data = GetAddress(mem_params.shared_memory, 799 void* data = GetAddress(mem_params.shared_memory,
756 mem_params.shm_data_offset); 800 mem_params.shm_data_offset);
757 base::TimeTicks begin_time(base::TimeTicks::HighResNow()); 801 base::TimeTicks begin_time;
802 if (texture_upload_stats_)
803 begin_time = base::TimeTicks::HighResNow();
758 { 804 {
759 TRACE_EVENT0("gpu", "glTexSubImage2D"); 805 TRACE_EVENT0("gpu", "glTexSubImage2D");
760 glTexSubImage2D( 806 glTexSubImage2D(
761 tex_params.target, 807 tex_params.target,
762 tex_params.level, 808 tex_params.level,
763 tex_params.xoffset, 809 tex_params.xoffset,
764 tex_params.yoffset, 810 tex_params.yoffset,
765 tex_params.width, 811 tex_params.width,
766 tex_params.height, 812 tex_params.height,
767 tex_params.format, 813 tex_params.format,
768 tex_params.type, 814 tex_params.type,
769 data); 815 data);
770 } 816 }
771 texture_upload_count_++; 817 if (texture_upload_stats_) {
772 total_texture_upload_time_ += base::TimeTicks::HighResNow() - begin_time; 818 texture_upload_stats_->AddUpload(
819 base::TimeTicks::HighResNow() - begin_time);
820 }
773 821
774 DCHECK(CHECK_GL()); 822 DCHECK(CHECK_GL());
775 return true; 823 return true;
776 } 824 }
777 825
778 } // namespace gfx 826 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698