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

Side by Side Diff: content/common/gpu/client/gl_helper.cc

Issue 11234008: Enable texture readback support for Android (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments Created 8 years, 2 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 "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 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 } 226 }
227 227
228 void SignalWaitableEvent(base::WaitableEvent* event) { 228 void SignalWaitableEvent(base::WaitableEvent* event) {
229 event->Signal(); 229 event->Signal();
230 } 230 }
231 231
232 } // namespace 232 } // namespace
233 233
234 namespace content { 234 namespace content {
235 235
236 // Implements GLHelper::CopyTextureTo and encapsulates the data needed for it. 236 // Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates the
237 // data needed for it.
237 class GLHelper::CopyTextureToImpl { 238 class GLHelper::CopyTextureToImpl {
238 public: 239 public:
239 CopyTextureToImpl(WebGraphicsContext3D* context, 240 CopyTextureToImpl(WebGraphicsContext3D* context,
240 WebGraphicsContext3D* context_for_thread, 241 WebGraphicsContext3D* context_for_thread,
241 GLHelper* helper) 242 GLHelper* helper)
242 : context_(context), 243 : context_(context),
243 context_for_thread_(context_for_thread), 244 context_for_thread_(context_for_thread),
244 helper_(helper), 245 helper_(helper),
245 flush_(context), 246 flush_(context),
246 program_(context, context->createProgram()), 247 program_(context, context->createProgram()),
247 vertex_attributes_buffer_(context_, context_->createBuffer()) { 248 vertex_attributes_buffer_(context_, context_->createBuffer()) {
248 InitBuffer(); 249 InitBuffer();
249 InitProgram(); 250 InitProgram();
250 } 251 }
251 ~CopyTextureToImpl() { 252 ~CopyTextureToImpl() {
252 CancelRequests(); 253 CancelRequests();
253 DeleteContextForThread(); 254 DeleteContextForThread();
254 } 255 }
255 256
256 void InitBuffer(); 257 void InitBuffer();
257 void InitProgram(); 258 void InitProgram();
258 259
259 void CopyTextureTo(WebGLId src_texture, 260 void CropScaleReadbackAndCleanTexture(
260 const gfx::Size& src_size, 261 WebGLId src_texture,
261 const gfx::Rect& src_subrect, 262 const gfx::Size& src_size,
262 const gfx::Size& dst_size, 263 const gfx::Rect& src_subrect,
263 unsigned char* out, 264 const gfx::Size& dst_size,
264 const base::Callback<void(bool)>& callback); 265 unsigned char* out,
266 const base::Callback<void(bool)>& callback);
265 267
266 WebKit::WebGLId CopyTexture(WebGLId src_texture, const gfx::Size& size); 268 void ReadbackTextureSync(WebGLId texture,
269 const gfx::Size& size,
270 unsigned char* out);
271
272 WebKit::WebGLId CopyAndScaleTexture(WebGLId texture,
273 const gfx::Size& src_size,
274 const gfx::Size& dst_size);
267 275
268 private: 276 private:
269 // A single request to CopyTextureTo. 277 // A single request to CropScaleReadbackAndCleanTexture.
270 // Thread-safety notes: the main thread creates instances of this class. The 278 // Thread-safety notes: the main thread creates instances of this class. The
271 // main thread can cancel the request, before it's handled by the helper 279 // main thread can cancel the request, before it's handled by the helper
272 // thread, by resetting the texture and pixels fields. Alternatively, the 280 // thread, by resetting the texture and pixels fields. Alternatively, the
273 // thread marks that it handles the request by resetting the pixels field 281 // thread marks that it handles the request by resetting the pixels field
274 // (meaning it guarantees that the callback with be called). 282 // (meaning it guarantees that the callback with be called).
275 // In either case, the callback must be called exactly once, and the texture 283 // In either case, the callback must be called exactly once, and the texture
276 // must be deleted by the main thread context. 284 // must be deleted by the main thread context.
277 struct Request : public base::RefCountedThreadSafe<Request> { 285 struct Request : public base::RefCountedThreadSafe<Request> {
278 Request(CopyTextureToImpl* impl, 286 Request(CopyTextureToImpl* impl,
279 WebGLId texture_, 287 WebGLId texture_,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 WebGraphicsContext3D* context, 325 WebGraphicsContext3D* context,
318 scoped_refptr<base::TaskRunner> reply_loop); 326 scoped_refptr<base::TaskRunner> reply_loop);
319 static void ReadBackFramebufferComplete(scoped_refptr<Request> request, 327 static void ReadBackFramebufferComplete(scoped_refptr<Request> request,
320 bool result); 328 bool result);
321 void FinishRequest(scoped_refptr<Request> request); 329 void FinishRequest(scoped_refptr<Request> request);
322 void CancelRequests(); 330 void CancelRequests();
323 331
324 // Interleaved array of 2-dimentional vertex positions (x, y) and 332 // Interleaved array of 2-dimentional vertex positions (x, y) and
325 // 2-dimentional texture coordinates (s, t). 333 // 2-dimentional texture coordinates (s, t).
326 static const WebKit::WGC3Dfloat kVertexAttributes[]; 334 static const WebKit::WGC3Dfloat kVertexAttributes[];
327 // Shader sources used for GLHelper::CopyTextureTo 335 // Shader sources used for GLHelper::CropScaleReadbackAndCleanTexture and
336 // GLHelper::ReadbackTextureSync
328 static const WebKit::WGC3Dchar kCopyVertexShader[]; 337 static const WebKit::WGC3Dchar kCopyVertexShader[];
329 static const WebKit::WGC3Dchar kCopyFragmentShader[]; 338 static const WebKit::WGC3Dchar kCopyFragmentShader[];
330 339
331 WebGraphicsContext3D* context_; 340 WebGraphicsContext3D* context_;
332 WebGraphicsContext3D* context_for_thread_; 341 WebGraphicsContext3D* context_for_thread_;
333 GLHelper* helper_; 342 GLHelper* helper_;
334 343
335 // A scoped flush that will ensure all resource deletions are flushed when 344 // A scoped flush that will ensure all resource deletions are flushed when
336 // this object is destroyed. Must be declared before other Scoped* fields. 345 // this object is destroyed. Must be declared before other Scoped* fields.
337 ScopedFlush flush_; 346 ScopedFlush flush_;
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 if (!context_for_thread_) 494 if (!context_for_thread_)
486 return; 495 return;
487 496
488 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask( 497 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(
489 FROM_HERE, 498 FROM_HERE,
490 base::Bind(&DeleteContext, 499 base::Bind(&DeleteContext,
491 context_for_thread_)); 500 context_for_thread_));
492 context_for_thread_ = NULL; 501 context_for_thread_ = NULL;
493 } 502 }
494 503
495 void GLHelper::CopyTextureToImpl::CopyTextureTo( 504 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture(
496 WebGLId src_texture, 505 WebGLId src_texture,
497 const gfx::Size& src_size, 506 const gfx::Size& src_size,
498 const gfx::Rect& src_subrect, 507 const gfx::Rect& src_subrect,
499 const gfx::Size& dst_size, 508 const gfx::Size& dst_size,
500 unsigned char* out, 509 unsigned char* out,
501 const base::Callback<void(bool)>& callback) { 510 const base::Callback<void(bool)>& callback) {
502 if (!context_for_thread_) { 511 if (!context_for_thread_) {
503 callback.Run(false); 512 callback.Run(false);
504 return; 513 return;
505 } 514 }
506 515
507 WebGLId texture = ScaleTexture(src_texture, src_size, src_subrect, dst_size); 516 WebGLId texture = ScaleTexture(src_texture, src_size, src_subrect, dst_size);
508 context_->flush(); 517 context_->flush();
509 scoped_refptr<Request> request = 518 scoped_refptr<Request> request =
510 new Request(this, texture, dst_size, out, callback); 519 new Request(this, texture, dst_size, out, callback);
511 request_queue_.push(request); 520 request_queue_.push(request);
512 521
513 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE, 522 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE,
514 base::Bind(&ReadBackFramebuffer, 523 base::Bind(&ReadBackFramebuffer,
515 request, 524 request,
516 context_for_thread_, 525 context_for_thread_,
517 base::MessageLoopProxy::current())); 526 base::MessageLoopProxy::current()));
518 } 527 }
519 528
520 WebKit::WebGLId GLHelper::CopyTextureToImpl::CopyTexture( 529 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(WebGLId texture,
530 const gfx::Size& size,
531 unsigned char* out) {
532 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
533 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
534 context_, dst_framebuffer);
535 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture);
536 context_->framebufferTexture2D(GL_FRAMEBUFFER,
537 GL_COLOR_ATTACHMENT0,
538 GL_TEXTURE_2D,
539 texture,
540 0);
541 context_->readPixels(0,
542 0,
543 size.width(),
544 size.height(),
545 GL_RGBA,
546 GL_UNSIGNED_BYTE,
547 out);
548 }
549
550 WebKit::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture(
521 WebGLId src_texture, 551 WebGLId src_texture,
522 const gfx::Size& size) { 552 const gfx::Size& src_size,
523 if (!context_for_thread_) 553 const gfx::Size& dst_size) {
524 return 0; 554 return ScaleTexture(src_texture, src_size, gfx::Rect(src_size), dst_size);
525 return ScaleTexture(src_texture, size, gfx::Rect(size), size);
526 } 555 }
527 556
528 void GLHelper::CopyTextureToImpl::ReadBackFramebuffer( 557 void GLHelper::CopyTextureToImpl::ReadBackFramebuffer(
529 scoped_refptr<Request> request, 558 scoped_refptr<Request> request,
530 WebGraphicsContext3D* context, 559 WebGraphicsContext3D* context,
531 scoped_refptr<base::TaskRunner> reply_loop) { 560 scoped_refptr<base::TaskRunner> reply_loop) {
532 DCHECK(context); 561 DCHECK(context);
533 if (!context->makeContextCurrent() || context->isContextLost()) { 562 if (!context->makeContextCurrent() || context->isContextLost()) {
534 base::AutoLock auto_lock(request->lock); 563 base::AutoLock auto_lock(request->lock);
535 if (request->pixels) { 564 if (request->pixels) {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 // http://crbug.com/125415 680 // http://crbug.com/125415
652 base::ThreadRestrictions::ScopedAllowWait allow_wait; 681 base::ThreadRestrictions::ScopedAllowWait allow_wait;
653 event.Wait(); 682 event.Wait();
654 } 683 }
655 } 684 }
656 685
657 WebGraphicsContext3D* GLHelper::context() const { 686 WebGraphicsContext3D* GLHelper::context() const {
658 return context_; 687 return context_;
659 } 688 }
660 689
661 void GLHelper::CopyTextureTo(WebGLId src_texture, 690 void GLHelper::CropScaleReadbackAndCleanTexture(
662 const gfx::Size& src_size, 691 WebGLId src_texture,
663 const gfx::Rect& src_subrect, 692 const gfx::Size& src_size,
664 const gfx::Size& dst_size, 693 const gfx::Rect& src_subrect,
665 unsigned char* out, 694 const gfx::Size& dst_size,
666 const base::Callback<void(bool)>& callback) { 695 unsigned char* out,
696 const base::Callback<void(bool)>& callback) {
667 InitCopyTextToImpl(); 697 InitCopyTextToImpl();
668 copy_texture_to_impl_->CopyTextureTo(src_texture, 698 copy_texture_to_impl_->CropScaleReadbackAndCleanTexture(src_texture,
669 src_size, 699 src_size,
670 src_subrect, 700 src_subrect,
671 dst_size, 701 dst_size,
672 out, 702 out,
673 callback); 703 callback);
704 }
705
706 void GLHelper::ReadbackTextureSync(WebKit::WebGLId texture,
707 const gfx::Size& size,
708 unsigned char* out) {
709 InitCopyTextToImpl();
710 copy_texture_to_impl_->ReadbackTextureSync(texture,
711 size,
712 out);
674 } 713 }
675 714
676 WebKit::WebGLId GLHelper::CopyTexture(WebKit::WebGLId texture, 715 WebKit::WebGLId GLHelper::CopyTexture(WebKit::WebGLId texture,
677 const gfx::Size& size) { 716 const gfx::Size& size) {
678 InitCopyTextToImpl(); 717 InitCopyTextToImpl();
679 return copy_texture_to_impl_->CopyTexture(texture, size); 718 return copy_texture_to_impl_->CopyAndScaleTexture(texture, size, size);
719 }
720
721 WebKit::WebGLId GLHelper::CopyAndScaleTexture(WebKit::WebGLId texture,
722 const gfx::Size& src_size,
723 const gfx::Size& dst_size) {
724 InitCopyTextToImpl();
725 return copy_texture_to_impl_->CopyAndScaleTexture(texture,
726 src_size,
727 dst_size);
680 } 728 }
681 729
682 WebGLId GLHelper::CompileShaderFromSource( 730 WebGLId GLHelper::CompileShaderFromSource(
683 const WebKit::WGC3Dchar* source, 731 const WebKit::WGC3Dchar* source,
684 WebKit::WGC3Denum type) { 732 WebKit::WGC3Denum type) {
685 ScopedShader shader(context_, context_->createShader(type)); 733 ScopedShader shader(context_, context_->createShader(type));
686 context_->shaderSource(shader, source); 734 context_->shaderSource(shader, source);
687 context_->compileShader(shader); 735 context_->compileShader(shader);
688 WebKit::WGC3Dint compile_status = 0; 736 WebKit::WGC3Dint compile_status = 0;
689 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compile_status); 737 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
690 if (!compile_status) { 738 if (!compile_status) {
691 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8()); 739 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8());
692 return 0; 740 return 0;
693 } 741 }
694 return shader.Detach(); 742 return shader.Detach();
695 } 743 }
696 744
697 void GLHelper::InitCopyTextToImpl() { 745 void GLHelper::InitCopyTextToImpl() {
698 // Lazily initialize |copy_texture_to_impl_| 746 // Lazily initialize |copy_texture_to_impl_|
699 if (!copy_texture_to_impl_.get()) 747 if (!copy_texture_to_impl_.get())
700 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, 748 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_,
701 context_for_thread_, 749 context_for_thread_,
702 this)); 750 this));
703 751
704 } 752 }
705 753
706 } // namespace content 754 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698