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

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

Issue 10815070: Support copying a partial rectangle region from the compositing surface on Aura and GTK. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address comments Created 8 years, 4 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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ref_counted.h" 12 #include "base/memory/ref_counted.h"
13 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/synchronization/lock.h" 14 #include "base/synchronization/lock.h"
15 #include "base/synchronization/waitable_event.h" 15 #include "base/synchronization/waitable_event.h"
16 #include "base/threading/thread.h" 16 #include "base/threading/thread.h"
17 #include "base/threading/thread_restrictions.h" 17 #include "base/threading/thread_restrictions.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h " 18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h "
19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" 19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
20 #include "ui/gfx/rect.h"
20 #include "ui/gfx/size.h" 21 #include "ui/gfx/size.h"
21 #include "ui/gl/gl_bindings.h" 22 #include "ui/gl/gl_bindings.h"
22 23
23 using WebKit::WebGLId; 24 using WebKit::WebGLId;
24 using WebKit::WebGraphicsContext3D; 25 using WebKit::WebGraphicsContext3D;
25 26
26 namespace { 27 namespace {
27 28
28 const char kGLHelperThreadName[] = "GLHelperThread"; 29 const char kGLHelperThreadName[] = "GLHelperThread";
29 30
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 ~CopyTextureToImpl() { 248 ~CopyTextureToImpl() {
248 CancelRequests(); 249 CancelRequests();
249 DeleteContextForThread(); 250 DeleteContextForThread();
250 } 251 }
251 252
252 void InitBuffer(); 253 void InitBuffer();
253 void InitProgram(); 254 void InitProgram();
254 255
255 void CopyTextureTo(WebGLId src_texture, 256 void CopyTextureTo(WebGLId src_texture,
256 const gfx::Size& src_size, 257 const gfx::Size& src_size,
258 const gfx::Rect& src_subrect,
257 const gfx::Size& dst_size, 259 const gfx::Size& dst_size,
258 unsigned char* out, 260 unsigned char* out,
259 const base::Callback<void(bool)>& callback); 261 const base::Callback<void(bool)>& callback);
260 private: 262 private:
261 // A single request to CopyTextureTo. 263 // A single request to CopyTextureTo.
262 // Thread-safety notes: the main thread creates instances of this class. The 264 // Thread-safety notes: the main thread creates instances of this class. The
263 // main thread can cancel the request, before it's handled by the helper 265 // main thread can cancel the request, before it's handled by the helper
264 // thread, by resetting the texture and pixels fields. Alternatively, the 266 // thread, by resetting the texture and pixels fields. Alternatively, the
265 // thread marks that it handles the request by resetting the pixels field 267 // thread marks that it handles the request by resetting the pixels field
266 // (meaning it guarantees that the callback with be called). 268 // (meaning it guarantees that the callback with be called).
(...skipping 21 matching lines...) Expand all
288 // Locks access to below members, which can be accessed on any thread. 290 // Locks access to below members, which can be accessed on any thread.
289 base::Lock lock; 291 base::Lock lock;
290 WebGLId texture; 292 WebGLId texture;
291 unsigned char* pixels; 293 unsigned char* pixels;
292 294
293 private: 295 private:
294 friend class base::RefCountedThreadSafe<Request>; 296 friend class base::RefCountedThreadSafe<Request>;
295 ~Request() {} 297 ~Request() {}
296 }; 298 };
297 299
298 // Returns the id of a framebuffer that 300 // Copies the block of pixels specified with |src_subrect| from |src_texture|,
301 // scales it to |dst_size|, writes it into a texture, and returns its ID.
302 // |src_size| is the size of |src_texture|.
299 WebGLId ScaleTexture(WebGLId src_texture, 303 WebGLId ScaleTexture(WebGLId src_texture,
300 const gfx::Size& src_size, 304 const gfx::Size& src_size,
301 const gfx::Size& dst_size); 305 const gfx::Rect& src_subrect,
306 const gfx::Size& dst_size);
302 307
303 // Deletes the context for GLHelperThread. 308 // Deletes the context for GLHelperThread.
304 void DeleteContextForThread(); 309 void DeleteContextForThread();
305 static void ReadBackFramebuffer(scoped_refptr<Request> request, 310 static void ReadBackFramebuffer(scoped_refptr<Request> request,
306 WebGraphicsContext3D* context, 311 WebGraphicsContext3D* context,
307 scoped_refptr<base::TaskRunner> reply_loop); 312 scoped_refptr<base::TaskRunner> reply_loop);
308 static void ReadBackFramebufferComplete(scoped_refptr<Request> request, 313 static void ReadBackFramebufferComplete(scoped_refptr<Request> request,
309 bool result); 314 bool result);
310 void FinishRequest(scoped_refptr<Request> request); 315 void FinishRequest(scoped_refptr<Request> request);
311 void CancelRequests(); 316 void CancelRequests();
(...skipping 16 matching lines...) Expand all
328 ScopedProgram program_; 333 ScopedProgram program_;
329 // The buffer that holds the vertices and the texture coordinates data for 334 // The buffer that holds the vertices and the texture coordinates data for
330 // drawing a quad. 335 // drawing a quad.
331 ScopedBuffer vertex_attributes_buffer_; 336 ScopedBuffer vertex_attributes_buffer_;
332 // The location of the position in the program. 337 // The location of the position in the program.
333 WebKit::WGC3Dint position_location_; 338 WebKit::WGC3Dint position_location_;
334 // The location of the texture coordinate in the program. 339 // The location of the texture coordinate in the program.
335 WebKit::WGC3Dint texcoord_location_; 340 WebKit::WGC3Dint texcoord_location_;
336 // The location of the source texture in the program. 341 // The location of the source texture in the program.
337 WebKit::WGC3Dint texture_location_; 342 WebKit::WGC3Dint texture_location_;
343 // The location of the texture coordinate of the sub-rectangle in the program.
344 WebKit::WGC3Dint src_subrect_location_;
338 std::queue<scoped_refptr<Request> > request_queue_; 345 std::queue<scoped_refptr<Request> > request_queue_;
339 }; 346 };
340 347
341 const WebKit::WGC3Dfloat GLHelper::CopyTextureToImpl::kVertexAttributes[] = { 348 const WebKit::WGC3Dfloat GLHelper::CopyTextureToImpl::kVertexAttributes[] = {
342 -1.0f, -1.0f, 0.0f, 0.0f, 349 -1.0f, -1.0f, 0.0f, 0.0f,
343 1.0f, -1.0f, 1.0f, 0.0f, 350 1.0f, -1.0f, 1.0f, 0.0f,
344 -1.0f, 1.0f, 0.0f, 1.0f, 351 -1.0f, 1.0f, 0.0f, 1.0f,
345 1.0f, 1.0f, 1.0f, 1.0f, 352 1.0f, 1.0f, 1.0f, 1.0f,
346 }; 353 };
347 354
348 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyVertexShader[] = 355 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyVertexShader[] =
349 "attribute vec2 a_position;" 356 "attribute vec2 a_position;"
350 "attribute vec2 a_texcoord;" 357 "attribute vec2 a_texcoord;"
351 "varying vec2 v_texcoord;" 358 "varying vec2 v_texcoord;"
359 "uniform vec4 src_subrect;"
352 "void main() {" 360 "void main() {"
353 " gl_Position = vec4(a_position, 0.0, 1.0);" 361 " gl_Position = vec4(a_position, 0.0, 1.0);"
354 " v_texcoord = a_texcoord;" 362 " v_texcoord = src_subrect.xy + a_texcoord * src_subrect.zw;"
355 "}"; 363 "}";
356 364
357 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] = 365 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] =
358 "precision mediump float;" 366 "precision mediump float;"
359 "varying vec2 v_texcoord;" 367 "varying vec2 v_texcoord;"
360 "uniform sampler2D s_texture;" 368 "uniform sampler2D s_texture;"
361 "void main() {" 369 "void main() {"
362 " gl_FragColor = texture2D(s_texture, v_texcoord);" 370 " gl_FragColor = texture2D(s_texture, v_texcoord);"
363 "}"; 371 "}";
364 372
(...skipping 21 matching lines...) Expand all
386 WebKit::WGC3Dint link_status = 0; 394 WebKit::WGC3Dint link_status = 0;
387 context_->getProgramiv(program_, GL_LINK_STATUS, &link_status); 395 context_->getProgramiv(program_, GL_LINK_STATUS, &link_status);
388 if (!link_status) { 396 if (!link_status) {
389 LOG(ERROR) << std::string(context_->getProgramInfoLog(program_).utf8()); 397 LOG(ERROR) << std::string(context_->getProgramInfoLog(program_).utf8());
390 return; 398 return;
391 } 399 }
392 400
393 position_location_ = context_->getAttribLocation(program_, "a_position"); 401 position_location_ = context_->getAttribLocation(program_, "a_position");
394 texcoord_location_ = context_->getAttribLocation(program_, "a_texcoord"); 402 texcoord_location_ = context_->getAttribLocation(program_, "a_texcoord");
395 texture_location_ = context_->getUniformLocation(program_, "s_texture"); 403 texture_location_ = context_->getUniformLocation(program_, "s_texture");
404 src_subrect_location_ = context_->getUniformLocation(program_, "src_subrect");
396 } 405 }
397 406
398 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( 407 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture(
399 WebGLId src_texture, 408 WebGLId src_texture,
400 const gfx::Size& src_size, 409 const gfx::Size& src_size,
410 const gfx::Rect& src_subrect,
401 const gfx::Size& dst_size) { 411 const gfx::Size& dst_size) {
402 WebGLId dst_texture = context_->createTexture(); 412 WebGLId dst_texture = context_->createTexture();
403 { 413 {
404 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); 414 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
405 ScopedFramebufferBinder<GL_DRAW_FRAMEBUFFER> framebuffer_binder( 415 ScopedFramebufferBinder<GL_DRAW_FRAMEBUFFER> framebuffer_binder(
406 context_, dst_framebuffer); 416 context_, dst_framebuffer);
407 { 417 {
408 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder( 418 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
409 context_, dst_texture); 419 context_, dst_texture);
410 context_->texImage2D(GL_TEXTURE_2D, 420 context_->texImage2D(GL_TEXTURE_2D,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 context_->vertexAttribPointer(texcoord_location_, 453 context_->vertexAttribPointer(texcoord_location_,
444 2, 454 2,
445 GL_FLOAT, 455 GL_FLOAT,
446 GL_FALSE, 456 GL_FALSE,
447 4 * sizeof(WebKit::WGC3Dfloat), 457 4 * sizeof(WebKit::WGC3Dfloat),
448 offset); 458 offset);
449 context_->enableVertexAttribArray(texcoord_location_); 459 context_->enableVertexAttribArray(texcoord_location_);
450 460
451 context_->uniform1i(texture_location_, 0); 461 context_->uniform1i(texture_location_, 0);
452 462
463 // Convert |src_subrect| to texture coordinates.
464 GLfloat src_subrect_texcoord[] = {
465 static_cast<float>(src_subrect.x()) / src_size.width(),
466 static_cast<float>(src_subrect.y()) / src_size.height(),
467 static_cast<float>(src_subrect.width()) / src_size.width(),
468 static_cast<float>(src_subrect.height()) / src_size.height(),
469 };
470 context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord);
471
453 // Conduct texture mapping by drawing a quad composed of two triangles. 472 // Conduct texture mapping by drawing a quad composed of two triangles.
454 context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4); 473 context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4);
455 } 474 }
456 return dst_texture; 475 return dst_texture;
457 } 476 }
458 477
459 void GLHelper::CopyTextureToImpl::DeleteContextForThread() { 478 void GLHelper::CopyTextureToImpl::DeleteContextForThread() {
460 if (!context_for_thread_) 479 if (!context_for_thread_)
461 return; 480 return;
462 481
463 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask( 482 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(
464 FROM_HERE, 483 FROM_HERE,
465 base::Bind(&DeleteContext, 484 base::Bind(&DeleteContext,
466 context_for_thread_)); 485 context_for_thread_));
467 context_for_thread_ = NULL; 486 context_for_thread_ = NULL;
468 } 487 }
469 488
470 void GLHelper::CopyTextureToImpl::CopyTextureTo( 489 void GLHelper::CopyTextureToImpl::CopyTextureTo(
471 WebGLId src_texture, 490 WebGLId src_texture,
472 const gfx::Size& src_size, 491 const gfx::Size& src_size,
492 const gfx::Rect& src_subrect,
473 const gfx::Size& dst_size, 493 const gfx::Size& dst_size,
474 unsigned char* out, 494 unsigned char* out,
475 const base::Callback<void(bool)>& callback) { 495 const base::Callback<void(bool)>& callback) {
476 if (!context_for_thread_) { 496 if (!context_for_thread_) {
477 callback.Run(false); 497 callback.Run(false);
478 return; 498 return;
479 } 499 }
480 500
481 WebGLId texture = ScaleTexture(src_texture, src_size, dst_size); 501 WebGLId texture = ScaleTexture(src_texture, src_size, src_subrect, dst_size);
482 context_->flush(); 502 context_->flush();
483 scoped_refptr<Request> request = 503 scoped_refptr<Request> request =
484 new Request(this, texture, dst_size, out, callback); 504 new Request(this, texture, dst_size, out, callback);
485 request_queue_.push(request); 505 request_queue_.push(request);
486 506
487 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE, 507 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE,
488 base::Bind(&ReadBackFramebuffer, 508 base::Bind(&ReadBackFramebuffer,
489 request, 509 request,
490 context_for_thread_, 510 context_for_thread_,
491 base::MessageLoopProxy::current())); 511 base::MessageLoopProxy::current()));
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 event.Wait(); 639 event.Wait();
620 } 640 }
621 } 641 }
622 642
623 WebGraphicsContext3D* GLHelper::context() const { 643 WebGraphicsContext3D* GLHelper::context() const {
624 return context_; 644 return context_;
625 } 645 }
626 646
627 void GLHelper::CopyTextureTo(WebGLId src_texture, 647 void GLHelper::CopyTextureTo(WebGLId src_texture,
628 const gfx::Size& src_size, 648 const gfx::Size& src_size,
649 const gfx::Rect& src_subrect,
629 const gfx::Size& dst_size, 650 const gfx::Size& dst_size,
630 unsigned char* out, 651 unsigned char* out,
631 const base::Callback<void(bool)>& callback) { 652 const base::Callback<void(bool)>& callback) {
632 // Lazily initialize |copy_texture_to_impl_| 653 // Lazily initialize |copy_texture_to_impl_|
633 if (!copy_texture_to_impl_.get()) 654 if (!copy_texture_to_impl_.get())
634 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, 655 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_,
635 context_for_thread_, 656 context_for_thread_,
636 this)); 657 this));
637 658
638 copy_texture_to_impl_->CopyTextureTo(src_texture, 659 copy_texture_to_impl_->CopyTextureTo(src_texture,
639 src_size, 660 src_size,
661 src_subrect,
640 dst_size, 662 dst_size,
641 out, 663 out,
642 callback); 664 callback);
643 } 665 }
644 666
645 WebGLId GLHelper::CompileShaderFromSource( 667 WebGLId GLHelper::CompileShaderFromSource(
646 const WebKit::WGC3Dchar* source, 668 const WebKit::WGC3Dchar* source,
647 WebKit::WGC3Denum type) { 669 WebKit::WGC3Denum type) {
648 ScopedShader shader(context_, context_->createShader(type)); 670 ScopedShader shader(context_, context_->createShader(type));
649 context_->shaderSource(shader, source); 671 context_->shaderSource(shader, source);
650 context_->compileShader(shader); 672 context_->compileShader(shader);
651 WebKit::WGC3Dint compile_status = 0; 673 WebKit::WGC3Dint compile_status = 0;
652 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compile_status); 674 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
653 if (!compile_status) { 675 if (!compile_status) {
654 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8()); 676 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8());
655 return 0; 677 return 0;
656 } 678 }
657 return shader.Detach(); 679 return shader.Detach();
658 } 680 }
659 681
660 } // namespace content 682 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/client/gl_helper.h ('k') | content/port/browser/render_widget_host_view_port.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698