| 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 |