OLD | NEW |
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 "content/common/gpu/client/gl_helper.h" | 5 #include "content/common/gpu/client/gl_helper.h" |
6 | 6 |
7 #include <queue> | 7 #include <queue> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 const gfx::Size& dst_size, | 264 const gfx::Size& dst_size, |
265 unsigned char* out, | 265 unsigned char* out, |
266 const base::Callback<void(bool)>& callback); | 266 const base::Callback<void(bool)>& callback); |
267 | 267 |
268 void ReadbackTextureSync(WebGLId texture, | 268 void ReadbackTextureSync(WebGLId texture, |
269 const gfx::Size& size, | 269 const gfx::Size& size, |
270 unsigned char* out); | 270 unsigned char* out); |
271 | 271 |
272 WebKit::WebGLId CopyAndScaleTexture(WebGLId texture, | 272 WebKit::WebGLId CopyAndScaleTexture(WebGLId texture, |
273 const gfx::Size& src_size, | 273 const gfx::Size& src_size, |
274 const gfx::Size& dst_size); | 274 const gfx::Size& dst_size, |
| 275 WebKit::WebGLId texture_out = 0); |
275 | 276 |
276 private: | 277 private: |
277 // A single request to CropScaleReadbackAndCleanTexture. | 278 // A single request to CropScaleReadbackAndCleanTexture. |
278 // Thread-safety notes: the main thread creates instances of this class. The | 279 // Thread-safety notes: the main thread creates instances of this class. The |
279 // main thread can cancel the request, before it's handled by the helper | 280 // main thread can cancel the request, before it's handled by the helper |
280 // thread, by resetting the texture and pixels fields. Alternatively, the | 281 // thread, by resetting the texture and pixels fields. Alternatively, the |
281 // thread marks that it handles the request by resetting the pixels field | 282 // thread marks that it handles the request by resetting the pixels field |
282 // (meaning it guarantees that the callback with be called). | 283 // (meaning it guarantees that the callback with be called). |
283 // In either case, the callback must be called exactly once, and the texture | 284 // In either case, the callback must be called exactly once, and the texture |
284 // must be deleted by the main thread context. | 285 // must be deleted by the main thread context. |
(...skipping 25 matching lines...) Expand all Loading... |
310 friend class base::RefCountedThreadSafe<Request>; | 311 friend class base::RefCountedThreadSafe<Request>; |
311 ~Request() {} | 312 ~Request() {} |
312 }; | 313 }; |
313 | 314 |
314 // Copies the block of pixels specified with |src_subrect| from |src_texture|, | 315 // Copies the block of pixels specified with |src_subrect| from |src_texture|, |
315 // scales it to |dst_size|, writes it into a texture, and returns its ID. | 316 // scales it to |dst_size|, writes it into a texture, and returns its ID. |
316 // |src_size| is the size of |src_texture|. | 317 // |src_size| is the size of |src_texture|. |
317 WebGLId ScaleTexture(WebGLId src_texture, | 318 WebGLId ScaleTexture(WebGLId src_texture, |
318 const gfx::Size& src_size, | 319 const gfx::Size& src_size, |
319 const gfx::Rect& src_subrect, | 320 const gfx::Rect& src_subrect, |
320 const gfx::Size& dst_size); | 321 const gfx::Size& dst_size, |
| 322 WebKit::WebGLId texture_out); |
321 | 323 |
322 // Deletes the context for GLHelperThread. | 324 // Deletes the context for GLHelperThread. |
323 void DeleteContextForThread(); | 325 void DeleteContextForThread(); |
324 static void ReadBackFramebuffer(scoped_refptr<Request> request, | 326 static void ReadBackFramebuffer(scoped_refptr<Request> request, |
325 WebGraphicsContext3D* context, | 327 WebGraphicsContext3D* context, |
326 scoped_refptr<base::TaskRunner> reply_loop); | 328 scoped_refptr<base::TaskRunner> reply_loop); |
327 static void ReadBackFramebufferComplete(scoped_refptr<Request> request, | 329 static void ReadBackFramebufferComplete(scoped_refptr<Request> request, |
328 bool result); | 330 bool result); |
329 void FinishRequest(scoped_refptr<Request> request); | 331 void FinishRequest(scoped_refptr<Request> request); |
330 void CancelRequests(); | 332 void CancelRequests(); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 position_location_ = context_->getAttribLocation(program_, "a_position"); | 418 position_location_ = context_->getAttribLocation(program_, "a_position"); |
417 texcoord_location_ = context_->getAttribLocation(program_, "a_texcoord"); | 419 texcoord_location_ = context_->getAttribLocation(program_, "a_texcoord"); |
418 texture_location_ = context_->getUniformLocation(program_, "s_texture"); | 420 texture_location_ = context_->getUniformLocation(program_, "s_texture"); |
419 src_subrect_location_ = context_->getUniformLocation(program_, "src_subrect"); | 421 src_subrect_location_ = context_->getUniformLocation(program_, "src_subrect"); |
420 } | 422 } |
421 | 423 |
422 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( | 424 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( |
423 WebGLId src_texture, | 425 WebGLId src_texture, |
424 const gfx::Size& src_size, | 426 const gfx::Size& src_size, |
425 const gfx::Rect& src_subrect, | 427 const gfx::Rect& src_subrect, |
426 const gfx::Size& dst_size) { | 428 const gfx::Size& dst_size, |
427 WebGLId dst_texture = context_->createTexture(); | 429 WebKit::WebGLId texture_out) { |
| 430 WebGLId dst_texture = texture_out ? texture_out : context_->createTexture(); |
428 { | 431 { |
429 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); | 432 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); |
430 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( | 433 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( |
431 context_, dst_framebuffer); | 434 context_, dst_framebuffer); |
432 { | 435 { |
433 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder( | 436 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder( |
434 context_, dst_texture); | 437 context_, dst_texture); |
435 context_->texImage2D(GL_TEXTURE_2D, | 438 context_->texImage2D(GL_TEXTURE_2D, |
436 0, | 439 0, |
437 GL_RGBA, | 440 GL_RGBA, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 const gfx::Size& src_size, | 509 const gfx::Size& src_size, |
507 const gfx::Rect& src_subrect, | 510 const gfx::Rect& src_subrect, |
508 const gfx::Size& dst_size, | 511 const gfx::Size& dst_size, |
509 unsigned char* out, | 512 unsigned char* out, |
510 const base::Callback<void(bool)>& callback) { | 513 const base::Callback<void(bool)>& callback) { |
511 if (!context_for_thread_) { | 514 if (!context_for_thread_) { |
512 callback.Run(false); | 515 callback.Run(false); |
513 return; | 516 return; |
514 } | 517 } |
515 | 518 |
516 WebGLId texture = ScaleTexture(src_texture, src_size, src_subrect, dst_size); | 519 WebGLId texture = ScaleTexture(src_texture, src_size, src_subrect, dst_size, 0
); |
517 context_->flush(); | 520 context_->flush(); |
518 scoped_refptr<Request> request = | 521 scoped_refptr<Request> request = |
519 new Request(this, texture, dst_size, out, callback); | 522 new Request(this, texture, dst_size, out, callback); |
520 request_queue_.push(request); | 523 request_queue_.push(request); |
521 | 524 |
522 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE, | 525 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE, |
523 base::Bind(&ReadBackFramebuffer, | 526 base::Bind(&ReadBackFramebuffer, |
524 request, | 527 request, |
525 context_for_thread_, | 528 context_for_thread_, |
526 base::MessageLoopProxy::current())); | 529 base::MessageLoopProxy::current())); |
(...skipping 16 matching lines...) Expand all Loading... |
543 size.width(), | 546 size.width(), |
544 size.height(), | 547 size.height(), |
545 GL_RGBA, | 548 GL_RGBA, |
546 GL_UNSIGNED_BYTE, | 549 GL_UNSIGNED_BYTE, |
547 out); | 550 out); |
548 } | 551 } |
549 | 552 |
550 WebKit::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture( | 553 WebKit::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture( |
551 WebGLId src_texture, | 554 WebGLId src_texture, |
552 const gfx::Size& src_size, | 555 const gfx::Size& src_size, |
553 const gfx::Size& dst_size) { | 556 const gfx::Size& dst_size, |
554 return ScaleTexture(src_texture, src_size, gfx::Rect(src_size), dst_size); | 557 WebKit::WebGLId texture_out) { |
| 558 return ScaleTexture(src_texture, src_size, gfx::Rect(src_size), dst_size, |
| 559 texture_out); |
555 } | 560 } |
556 | 561 |
557 void GLHelper::CopyTextureToImpl::ReadBackFramebuffer( | 562 void GLHelper::CopyTextureToImpl::ReadBackFramebuffer( |
558 scoped_refptr<Request> request, | 563 scoped_refptr<Request> request, |
559 WebGraphicsContext3D* context, | 564 WebGraphicsContext3D* context, |
560 scoped_refptr<base::TaskRunner> reply_loop) { | 565 scoped_refptr<base::TaskRunner> reply_loop) { |
561 DCHECK(context); | 566 DCHECK(context); |
562 if (!context->makeContextCurrent() || context->isContextLost()) { | 567 if (!context->makeContextCurrent() || context->isContextLost()) { |
563 base::AutoLock auto_lock(request->lock); | 568 base::AutoLock auto_lock(request->lock); |
564 if (request->pixels) { | 569 if (request->pixels) { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 void GLHelper::ReadbackTextureSync(WebKit::WebGLId texture, | 711 void GLHelper::ReadbackTextureSync(WebKit::WebGLId texture, |
707 const gfx::Size& size, | 712 const gfx::Size& size, |
708 unsigned char* out) { | 713 unsigned char* out) { |
709 InitCopyTextToImpl(); | 714 InitCopyTextToImpl(); |
710 copy_texture_to_impl_->ReadbackTextureSync(texture, | 715 copy_texture_to_impl_->ReadbackTextureSync(texture, |
711 size, | 716 size, |
712 out); | 717 out); |
713 } | 718 } |
714 | 719 |
715 WebKit::WebGLId GLHelper::CopyTexture(WebKit::WebGLId texture, | 720 WebKit::WebGLId GLHelper::CopyTexture(WebKit::WebGLId texture, |
716 const gfx::Size& size) { | 721 const gfx::Size& size, |
| 722 WebKit::WebGLId texture_out) { |
717 InitCopyTextToImpl(); | 723 InitCopyTextToImpl(); |
718 return copy_texture_to_impl_->CopyAndScaleTexture(texture, size, size); | 724 return copy_texture_to_impl_->CopyAndScaleTexture(texture, size, size, |
| 725 texture_out); |
719 } | 726 } |
720 | 727 |
721 WebKit::WebGLId GLHelper::CopyAndScaleTexture(WebKit::WebGLId texture, | 728 WebKit::WebGLId GLHelper::CopyAndScaleTexture(WebKit::WebGLId texture, |
722 const gfx::Size& src_size, | 729 const gfx::Size& src_size, |
723 const gfx::Size& dst_size) { | 730 const gfx::Size& dst_size, |
| 731 WebKit::WebGLId texture_out) { |
724 InitCopyTextToImpl(); | 732 InitCopyTextToImpl(); |
725 return copy_texture_to_impl_->CopyAndScaleTexture(texture, | 733 return copy_texture_to_impl_->CopyAndScaleTexture(texture, |
726 src_size, | 734 src_size, |
727 dst_size); | 735 dst_size, |
| 736 texture_out); |
728 } | 737 } |
729 | 738 |
730 WebGLId GLHelper::CompileShaderFromSource( | 739 WebGLId GLHelper::CompileShaderFromSource( |
731 const WebKit::WGC3Dchar* source, | 740 const WebKit::WGC3Dchar* source, |
732 WebKit::WGC3Denum type) { | 741 WebKit::WGC3Denum type) { |
733 ScopedShader shader(context_, context_->createShader(type)); | 742 ScopedShader shader(context_, context_->createShader(type)); |
734 context_->shaderSource(shader, source); | 743 context_->shaderSource(shader, source); |
735 context_->compileShader(shader); | 744 context_->compileShader(shader); |
736 WebKit::WGC3Dint compile_status = 0; | 745 WebKit::WGC3Dint compile_status = 0; |
737 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compile_status); | 746 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compile_status); |
738 if (!compile_status) { | 747 if (!compile_status) { |
739 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8()); | 748 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8()); |
740 return 0; | 749 return 0; |
741 } | 750 } |
742 return shader.Detach(); | 751 return shader.Detach(); |
743 } | 752 } |
744 | 753 |
745 void GLHelper::InitCopyTextToImpl() { | 754 void GLHelper::InitCopyTextToImpl() { |
746 // Lazily initialize |copy_texture_to_impl_| | 755 // Lazily initialize |copy_texture_to_impl_| |
747 if (!copy_texture_to_impl_.get()) | 756 if (!copy_texture_to_impl_.get()) |
748 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, | 757 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, |
749 context_for_thread_, | 758 context_for_thread_, |
750 this)); | 759 this)); |
751 | 760 |
752 } | 761 } |
753 | 762 |
754 } // namespace content | 763 } // namespace content |
OLD | NEW |