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

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: Created 8 years, 5 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;"
352 "void main() {" 359 "void main() {"
353 " gl_Position = vec4(a_position, 0.0, 1.0);" 360 " gl_Position = vec4(a_position, 0.0, 1.0);"
354 " v_texcoord = a_texcoord;" 361 " v_texcoord = a_texcoord;"
355 "}"; 362 "}";
356 363
357 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] = 364 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] =
358 "precision mediump float;" 365 "precision mediump float;"
359 "varying vec2 v_texcoord;" 366 "varying vec2 v_texcoord;"
367 "uniform vec4 src_subrect;"
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,"
371 " src_subrect.xy + v_texcoord * src_subrect.zw);"
piman 2012/07/26 00:04:51 It would be better to do the UV transformation in
mazda 2012/07/26 02:20:04 Oh, that's right. Fixed.
363 "}"; 372 "}";
364 373
365 void GLHelper::CopyTextureToImpl::InitBuffer() { 374 void GLHelper::CopyTextureToImpl::InitBuffer() {
366 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder( 375 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
367 context_, vertex_attributes_buffer_); 376 context_, vertex_attributes_buffer_);
368 context_->bufferData(GL_ARRAY_BUFFER, 377 context_->bufferData(GL_ARRAY_BUFFER,
369 sizeof(kVertexAttributes), 378 sizeof(kVertexAttributes),
370 kVertexAttributes, 379 kVertexAttributes,
371 GL_STATIC_DRAW); 380 GL_STATIC_DRAW);
372 } 381 }
(...skipping 13 matching lines...) Expand all
386 WebKit::WGC3Dint link_status = 0; 395 WebKit::WGC3Dint link_status = 0;
387 context_->getProgramiv(program_, GL_LINK_STATUS, &link_status); 396 context_->getProgramiv(program_, GL_LINK_STATUS, &link_status);
388 if (!link_status) { 397 if (!link_status) {
389 LOG(ERROR) << std::string(context_->getProgramInfoLog(program_).utf8()); 398 LOG(ERROR) << std::string(context_->getProgramInfoLog(program_).utf8());
390 return; 399 return;
391 } 400 }
392 401
393 position_location_ = context_->getAttribLocation(program_, "a_position"); 402 position_location_ = context_->getAttribLocation(program_, "a_position");
394 texcoord_location_ = context_->getAttribLocation(program_, "a_texcoord"); 403 texcoord_location_ = context_->getAttribLocation(program_, "a_texcoord");
395 texture_location_ = context_->getUniformLocation(program_, "s_texture"); 404 texture_location_ = context_->getUniformLocation(program_, "s_texture");
405 src_subrect_location_ = context_->getUniformLocation(program_, "src_subrect");
396 } 406 }
397 407
398 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( 408 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture(
399 WebGLId src_texture, 409 WebGLId src_texture,
400 const gfx::Size& src_size, 410 const gfx::Size& src_size,
411 const gfx::Rect& src_subrect,
401 const gfx::Size& dst_size) { 412 const gfx::Size& dst_size) {
402 WebGLId dst_texture = context_->createTexture(); 413 WebGLId dst_texture = context_->createTexture();
403 { 414 {
404 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); 415 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
405 ScopedFramebufferBinder<GL_DRAW_FRAMEBUFFER> framebuffer_binder( 416 ScopedFramebufferBinder<GL_DRAW_FRAMEBUFFER> framebuffer_binder(
406 context_, dst_framebuffer); 417 context_, dst_framebuffer);
407 { 418 {
408 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder( 419 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
409 context_, dst_texture); 420 context_, dst_texture);
410 context_->texImage2D(GL_TEXTURE_2D, 421 context_->texImage2D(GL_TEXTURE_2D,
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 context_->vertexAttribPointer(texcoord_location_, 454 context_->vertexAttribPointer(texcoord_location_,
444 2, 455 2,
445 GL_FLOAT, 456 GL_FLOAT,
446 GL_FALSE, 457 GL_FALSE,
447 4 * sizeof(WebKit::WGC3Dfloat), 458 4 * sizeof(WebKit::WGC3Dfloat),
448 offset); 459 offset);
449 context_->enableVertexAttribArray(texcoord_location_); 460 context_->enableVertexAttribArray(texcoord_location_);
450 461
451 context_->uniform1i(texture_location_, 0); 462 context_->uniform1i(texture_location_, 0);
452 463
464 // Convert |src_subrect| to texture coordinates.
465 GLfloat src_subrect_texcoord[] = {
466 static_cast<float>(src_subrect.x()) / src_size.width(),
467 static_cast<float>(src_subrect.y()) / src_size.height(),
468 static_cast<float>(src_subrect.width()) / src_size.width(),
469 static_cast<float>(src_subrect.height()) / src_size.height(),
470 };
471 context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord);
472
453 // Conduct texture mapping by drawing a quad composed of two triangles. 473 // Conduct texture mapping by drawing a quad composed of two triangles.
454 context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4); 474 context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4);
455 } 475 }
456 return dst_texture; 476 return dst_texture;
457 } 477 }
458 478
459 void GLHelper::CopyTextureToImpl::DeleteContextForThread() { 479 void GLHelper::CopyTextureToImpl::DeleteContextForThread() {
460 if (!context_for_thread_) 480 if (!context_for_thread_)
461 return; 481 return;
462 482
463 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask( 483 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(
464 FROM_HERE, 484 FROM_HERE,
465 base::Bind(&DeleteContext, 485 base::Bind(&DeleteContext,
466 context_for_thread_)); 486 context_for_thread_));
467 context_for_thread_ = NULL; 487 context_for_thread_ = NULL;
468 } 488 }
469 489
470 void GLHelper::CopyTextureToImpl::CopyTextureTo( 490 void GLHelper::CopyTextureToImpl::CopyTextureTo(
471 WebGLId src_texture, 491 WebGLId src_texture,
472 const gfx::Size& src_size, 492 const gfx::Size& src_size,
493 const gfx::Rect& src_subrect,
473 const gfx::Size& dst_size, 494 const gfx::Size& dst_size,
474 unsigned char* out, 495 unsigned char* out,
475 const base::Callback<void(bool)>& callback) { 496 const base::Callback<void(bool)>& callback) {
476 if (!context_for_thread_) { 497 if (!context_for_thread_) {
477 callback.Run(false); 498 callback.Run(false);
478 return; 499 return;
479 } 500 }
480 501
481 WebGLId texture = ScaleTexture(src_texture, src_size, dst_size); 502 WebGLId texture = ScaleTexture(src_texture, src_size, src_subrect, dst_size);
482 context_->flush(); 503 context_->flush();
483 scoped_refptr<Request> request = 504 scoped_refptr<Request> request =
484 new Request(this, texture, dst_size, out, callback); 505 new Request(this, texture, dst_size, out, callback);
485 request_queue_.push(request); 506 request_queue_.push(request);
486 507
487 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE, 508 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE,
488 base::Bind(&ReadBackFramebuffer, 509 base::Bind(&ReadBackFramebuffer,
489 request, 510 request,
490 context_for_thread_, 511 context_for_thread_,
491 base::MessageLoopProxy::current())); 512 base::MessageLoopProxy::current()));
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 event.Wait(); 640 event.Wait();
620 } 641 }
621 } 642 }
622 643
623 WebGraphicsContext3D* GLHelper::context() const { 644 WebGraphicsContext3D* GLHelper::context() const {
624 return context_; 645 return context_;
625 } 646 }
626 647
627 void GLHelper::CopyTextureTo(WebGLId src_texture, 648 void GLHelper::CopyTextureTo(WebGLId src_texture,
628 const gfx::Size& src_size, 649 const gfx::Size& src_size,
650 const gfx::Rect& src_subrect,
629 const gfx::Size& dst_size, 651 const gfx::Size& dst_size,
630 unsigned char* out, 652 unsigned char* out,
631 const base::Callback<void(bool)>& callback) { 653 const base::Callback<void(bool)>& callback) {
632 // Lazily initialize |copy_texture_to_impl_| 654 // Lazily initialize |copy_texture_to_impl_|
633 if (!copy_texture_to_impl_.get()) 655 if (!copy_texture_to_impl_.get())
634 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, 656 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_,
635 context_for_thread_, 657 context_for_thread_,
636 this)); 658 this));
637 659
638 copy_texture_to_impl_->CopyTextureTo(src_texture, 660 copy_texture_to_impl_->CopyTextureTo(src_texture,
639 src_size, 661 src_size,
662 src_subrect,
640 dst_size, 663 dst_size,
641 out, 664 out,
642 callback); 665 callback);
643 } 666 }
644 667
645 WebGLId GLHelper::CompileShaderFromSource( 668 WebGLId GLHelper::CompileShaderFromSource(
646 const WebKit::WGC3Dchar* source, 669 const WebKit::WGC3Dchar* source,
647 WebKit::WGC3Denum type) { 670 WebKit::WGC3Denum type) {
648 ScopedShader shader(context_, context_->createShader(type)); 671 ScopedShader shader(context_, context_->createShader(type));
649 context_->shaderSource(shader, source); 672 context_->shaderSource(shader, source);
650 context_->compileShader(shader); 673 context_->compileShader(shader);
651 WebKit::WGC3Dint compile_status = 0; 674 WebKit::WGC3Dint compile_status = 0;
652 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compile_status); 675 context_->getShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
653 if (!compile_status) { 676 if (!compile_status) {
654 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8()); 677 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8());
655 return 0; 678 return 0;
656 } 679 }
657 return shader.Detach(); 680 return shader.Detach();
658 } 681 }
659 682
660 } // namespace content 683 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698