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

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

Issue 388953002: Improving GestureNav screenshotting performance - Part 1 - gl_helper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding consts for YUV test. Created 6 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
« no previous file with comments | « content/common/gpu/client/gl_helper.h ('k') | content/common/gpu/client/gl_helper_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 uint32 sync_point) { 135 uint32 sync_point) {
136 return helper_->ConsumeMailboxToTexture(mailbox, sync_point); 136 return helper_->ConsumeMailboxToTexture(mailbox, sync_point);
137 } 137 }
138 138
139 void CropScaleReadbackAndCleanTexture( 139 void CropScaleReadbackAndCleanTexture(
140 GLuint src_texture, 140 GLuint src_texture,
141 const gfx::Size& src_size, 141 const gfx::Size& src_size,
142 const gfx::Rect& src_subrect, 142 const gfx::Rect& src_subrect,
143 const gfx::Size& dst_size, 143 const gfx::Size& dst_size,
144 unsigned char* out, 144 unsigned char* out,
145 const SkColorType color_type, 145 const SkColorType out_color_type,
146 const base::Callback<void(bool)>& callback, 146 const base::Callback<void(bool)>& callback,
147 GLHelper::ScalerQuality quality); 147 GLHelper::ScalerQuality quality);
148 148
149 void ReadbackTextureSync(GLuint texture, 149 void ReadbackTextureSync(GLuint texture,
150 const gfx::Rect& src_rect, 150 const gfx::Rect& src_rect,
151 unsigned char* out, 151 unsigned char* out,
152 SkColorType format); 152 SkColorType format);
153 153
154 void ReadbackTextureAsync(GLuint texture, 154 void ReadbackTextureAsync(GLuint texture,
155 const gfx::Size& dst_size, 155 const gfx::Size& dst_size,
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 // |src_size| is the size of |src_texture|. 318 // |src_size| is the size of |src_texture|.
319 GLuint ScaleTexture(GLuint src_texture, 319 GLuint ScaleTexture(GLuint src_texture,
320 const gfx::Size& src_size, 320 const gfx::Size& src_size,
321 const gfx::Rect& src_subrect, 321 const gfx::Rect& src_subrect,
322 const gfx::Size& dst_size, 322 const gfx::Size& dst_size,
323 bool vertically_flip_texture, 323 bool vertically_flip_texture,
324 bool swizzle, 324 bool swizzle,
325 SkColorType color_type, 325 SkColorType color_type,
326 GLHelper::ScalerQuality quality); 326 GLHelper::ScalerQuality quality);
327 327
328 // Converts each four consecutive pixels of the source texture into one pixel
329 // in the result texture with each pixel channel representing the grayscale
330 // color of one of the four original pixels:
331 // R1G1B1A1 R2G2B2A2 R3G3B3A3 R4G4B4A4 -> X1X2X3X4
332 // The resulting texture is still an RGBA texture (which is ~4 times narrower
333 // than the original). If rendered directly, it wouldn't show anything useful,
334 // but the data in it can be used to construct a grayscale image.
335 // |encoded_texture_size| is the exact size of the resulting RGBA texture. It
336 // is equal to src_size.width()/4 rounded upwards. Some channels in the last
337 // pixel ((-src_size.width()) % 4) to be exact) are padding and don't contain
338 // useful data.
339 // If swizzle is set to true, the transformed pixels are reordered:
340 // R1G1B1A1 R2G2B2A2 R3G3B3A3 R4G4B4A4 -> X3X2X1X4.
341 GLuint EncodeTextureAsGrayscale(GLuint src_texture,
342 const gfx::Size& src_size,
343 gfx::Size* const encoded_texture_size,
344 bool vertically_flip_texture,
345 bool swizzle);
346
328 static void nullcallback(bool success) {} 347 static void nullcallback(bool success) {}
329 void ReadbackDone(Request *request, int bytes_per_pixel); 348 void ReadbackDone(Request *request, int bytes_per_pixel);
330 void FinishRequest(Request* request, bool result); 349 void FinishRequest(Request* request, bool result);
331 void CancelRequests(); 350 void CancelRequests();
332 351
333 static const float kRGBtoYColorWeights[]; 352 static const float kRGBtoYColorWeights[];
334 static const float kRGBtoUColorWeights[]; 353 static const float kRGBtoUColorWeights[];
335 static const float kRGBtoVColorWeights[]; 354 static const float kRGBtoVColorWeights[];
355 static const float kRGBtoGrayscaleColorWeights[];
336 356
337 GLES2Interface* gl_; 357 GLES2Interface* gl_;
338 gpu::ContextSupport* context_support_; 358 gpu::ContextSupport* context_support_;
339 GLHelper* helper_; 359 GLHelper* helper_;
340 360
341 // A scoped flush that will ensure all resource deletions are flushed when 361 // A scoped flush that will ensure all resource deletions are flushed when
342 // this object is destroyed. Must be declared before other Scoped* fields. 362 // this object is destroyed. Must be declared before other Scoped* fields.
343 ScopedFlush flush_; 363 ScopedFlush flush_;
344 364
345 std::queue<Request*> request_queue_; 365 std::queue<Request*> request_queue_;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 helper_->CreateScaler(quality, 417 helper_->CreateScaler(quality,
398 src_size, 418 src_size,
399 src_subrect, 419 src_subrect,
400 dst_size, 420 dst_size,
401 vertically_flip_texture, 421 vertically_flip_texture,
402 swizzle)); 422 swizzle));
403 scaler->Scale(src_texture, dst_texture); 423 scaler->Scale(src_texture, dst_texture);
404 return dst_texture; 424 return dst_texture;
405 } 425 }
406 426
427 GLuint GLHelper::CopyTextureToImpl::EncodeTextureAsGrayscale(
428 GLuint src_texture,
429 const gfx::Size& src_size,
430 gfx::Size* const encoded_texture_size,
431 bool vertically_flip_texture,
432 bool swizzle) {
433 GLuint dst_texture = 0u;
434 gl_->GenTextures(1, &dst_texture);
435 // The size of the encoded texture.
436 *encoded_texture_size =
437 gfx::Size((src_size.width() + 3) / 4, src_size.height());
438 {
439 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture);
440 gl_->TexImage2D(GL_TEXTURE_2D,
441 0,
442 GL_RGBA,
443 encoded_texture_size->width(),
444 encoded_texture_size->height(),
445 0,
446 GL_RGBA,
447 GL_UNSIGNED_BYTE,
448 NULL);
449 }
450
451 helper_->InitScalerImpl();
452 scoped_ptr<ScalerInterface> grayscale_scaler(
453 helper_->scaler_impl_.get()->CreatePlanarScaler(
454 src_size,
455 gfx::Rect(0, 0, (src_size.width() + 3) & ~3, src_size.height()),
456 *encoded_texture_size,
457 vertically_flip_texture,
458 swizzle,
459 kRGBtoGrayscaleColorWeights));
460 grayscale_scaler->Scale(src_texture, dst_texture);
461 return dst_texture;
462 }
463
407 void GLHelper::CopyTextureToImpl::ReadbackAsync( 464 void GLHelper::CopyTextureToImpl::ReadbackAsync(
408 const gfx::Size& dst_size, 465 const gfx::Size& dst_size,
409 int32 bytes_per_row, 466 int32 bytes_per_row,
410 int32 row_stride_bytes, 467 int32 row_stride_bytes,
411 unsigned char* out, 468 unsigned char* out,
412 GLenum format, 469 GLenum format,
413 GLenum type, 470 GLenum type,
414 size_t bytes_per_pixel, 471 size_t bytes_per_pixel,
415 const base::Callback<void(bool)>& callback) { 472 const base::Callback<void(bool)>& callback) {
416 TRACE_EVENT0("mirror", "GLHelper::CopyTextureToImpl::ReadbackAsync"); 473 TRACE_EVENT0("mirror", "GLHelper::CopyTextureToImpl::ReadbackAsync");
(...skipping 19 matching lines...) Expand all
436 format, 493 format,
437 type, 494 type,
438 NULL); 495 NULL);
439 gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); 496 gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM);
440 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); 497 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
441 context_support_->SignalQuery( 498 context_support_->SignalQuery(
442 request->query, 499 request->query,
443 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), 500 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(),
444 request, bytes_per_pixel)); 501 request, bytes_per_pixel));
445 } 502 }
503
446 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( 504 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture(
447 GLuint src_texture, 505 GLuint src_texture,
448 const gfx::Size& src_size, 506 const gfx::Size& src_size,
449 const gfx::Rect& src_subrect, 507 const gfx::Rect& src_subrect,
450 const gfx::Size& dst_size, 508 const gfx::Size& dst_size,
451 unsigned char* out, 509 unsigned char* out,
452 const SkColorType color_type, 510 const SkColorType out_color_type,
453 const base::Callback<void(bool)>& callback, 511 const base::Callback<void(bool)>& callback,
454 GLHelper::ScalerQuality quality) { 512 GLHelper::ScalerQuality quality) {
455 GLenum format, type; 513 GLenum format, type;
456 size_t bytes_per_pixel; 514 size_t bytes_per_pixel;
457 FormatSupport supported = 515 SkColorType readback_color_type = out_color_type;
458 GetReadbackConfig(color_type, true, &format, &type, &bytes_per_pixel); 516 // Single-component textures are not supported by all GPUs, so we implement
517 // kAlpha_8_SkColorType support here via a special encoding (see below) using
518 // a 32-bit texture to represent an 8-bit image.
519 // Thus we use generic 32-bit readback in this case.
520 if (out_color_type == kAlpha_8_SkColorType) {
521 readback_color_type = kRGBA_8888_SkColorType;
522 }
523
524 FormatSupport supported = GetReadbackConfig(
525 readback_color_type, true, &format, &type, &bytes_per_pixel);
526
459 if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { 527 if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) {
460 callback.Run(false); 528 callback.Run(false);
461 return; 529 return;
462 } 530 }
463 531
464 GLuint texture = ScaleTexture(src_texture, 532 GLuint texture = src_texture;
465 src_size, 533
466 src_subrect, 534 // Scale texture if needed
467 dst_size, 535 // Optimization: SCALER_QUALITY_FAST is just a single bilinear pass, which we
468 true, 536 // can do just as well in EncodeTextureAsGrayscale, which we will do if
469 (supported == GLHelperReadbackSupport::SWIZZLE), 537 // out_color_type is kAlpha_8_SkColorType, so let's skip the scaling step
470 color_type, 538 // in that case.
471 quality); 539 bool scale_texture = out_color_type != kAlpha_8_SkColorType ||
472 DCHECK(texture); 540 quality != GLHelper::SCALER_QUALITY_FAST;
541 if (scale_texture) {
542 // Don't swizzle during the scale step for kAlpha_8_SkColorType.
543 // We will swizzle in the encode step below if needed.
544 bool scale_swizzle = out_color_type == kAlpha_8_SkColorType
545 ? false
546 : supported == GLHelperReadbackSupport::SWIZZLE;
547 texture =
548 ScaleTexture(src_texture,
549 src_size,
550 src_subrect,
551 dst_size,
552 true,
553 scale_swizzle,
554 out_color_type == kAlpha_8_SkColorType ? kN32_SkColorType
555 : out_color_type,
556 quality);
557 DCHECK(texture);
558 }
559
560 gfx::Size readback_texture_size = dst_size;
561 // Encode texture to grayscale if needed.
562 if (out_color_type == kAlpha_8_SkColorType) {
563 // Do the vertical flip here if we haven't already done it when we scaled
564 // the texture.
565 bool encode_as_grayscale_vertical_flip = !scale_texture;
566 // EncodeTextureAsGrayscale by default creates a texture which should be
567 // read back as RGBA, so need to swizzle if the readback format is BGRA.
568 bool encode_as_grayscale_swizzle = format == GL_BGRA_EXT;
569 GLuint tmp_texture =
570 EncodeTextureAsGrayscale(texture,
571 dst_size,
572 &readback_texture_size,
573 encode_as_grayscale_vertical_flip,
574 encode_as_grayscale_swizzle);
575 // If the scaled texture was created - delete it
576 if (scale_texture)
577 gl_->DeleteTextures(1, &texture);
578 texture = tmp_texture;
579 DCHECK(texture);
580 }
581
582 // Readback the pixels of the resulting texture
473 ScopedFramebuffer dst_framebuffer(gl_); 583 ScopedFramebuffer dst_framebuffer(gl_);
474 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, 584 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_,
475 dst_framebuffer); 585 dst_framebuffer);
476 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); 586 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture);
477 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, 587 gl_->FramebufferTexture2D(GL_FRAMEBUFFER,
478 GL_COLOR_ATTACHMENT0, 588 GL_COLOR_ATTACHMENT0,
479 GL_TEXTURE_2D, 589 GL_TEXTURE_2D,
480 texture, 590 texture,
481 0); 591 0);
482 ReadbackAsync(dst_size, 592
483 dst_size.width() * bytes_per_pixel, 593 int32 bytes_per_row = out_color_type == kAlpha_8_SkColorType
484 dst_size.width() * bytes_per_pixel, 594 ? dst_size.width()
595 : dst_size.width() * bytes_per_pixel;
596
597 ReadbackAsync(readback_texture_size,
598 bytes_per_row,
599 bytes_per_row,
485 out, 600 out,
486 format, 601 format,
487 type, 602 type,
488 bytes_per_pixel, 603 bytes_per_pixel,
489 callback); 604 callback);
490 gl_->DeleteTextures(1, &texture); 605 gl_->DeleteTextures(1, &texture);
491 } 606 }
492 607
493 void GLHelper::CopyTextureToImpl::ReadbackTextureSync( 608 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(
494 GLuint texture, 609 GLuint texture,
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 readback_support_(new GLHelperReadbackSupport(gl)) {} 764 readback_support_(new GLHelperReadbackSupport(gl)) {}
650 765
651 GLHelper::~GLHelper() {} 766 GLHelper::~GLHelper() {}
652 767
653 void GLHelper::CropScaleReadbackAndCleanTexture( 768 void GLHelper::CropScaleReadbackAndCleanTexture(
654 GLuint src_texture, 769 GLuint src_texture,
655 const gfx::Size& src_size, 770 const gfx::Size& src_size,
656 const gfx::Rect& src_subrect, 771 const gfx::Rect& src_subrect,
657 const gfx::Size& dst_size, 772 const gfx::Size& dst_size,
658 unsigned char* out, 773 unsigned char* out,
659 const SkColorType color_type, 774 const SkColorType out_color_type,
660 const base::Callback<void(bool)>& callback, 775 const base::Callback<void(bool)>& callback,
661 GLHelper::ScalerQuality quality) { 776 GLHelper::ScalerQuality quality) {
662 InitCopyTextToImpl(); 777 InitCopyTextToImpl();
663 copy_texture_to_impl_->CropScaleReadbackAndCleanTexture( 778 copy_texture_to_impl_->CropScaleReadbackAndCleanTexture(src_texture,
664 src_texture, 779 src_size,
665 src_size, 780 src_subrect,
666 src_subrect, 781 dst_size,
667 dst_size, 782 out,
668 out, 783 out_color_type,
669 color_type, 784 callback,
670 callback, 785 quality);
671 quality);
672 } 786 }
673 787
674 void GLHelper::CropScaleReadbackAndCleanMailbox( 788 void GLHelper::CropScaleReadbackAndCleanMailbox(
675 const gpu::Mailbox& src_mailbox, 789 const gpu::Mailbox& src_mailbox,
676 uint32 sync_point, 790 uint32 sync_point,
677 const gfx::Size& src_size, 791 const gfx::Size& src_size,
678 const gfx::Rect& src_subrect, 792 const gfx::Rect& src_subrect,
679 const gfx::Size& dst_size, 793 const gfx::Size& dst_size,
680 unsigned char* out, 794 unsigned char* out,
681 const SkColorType color_type, 795 const SkColorType out_color_type,
682 const base::Callback<void(bool)>& callback, 796 const base::Callback<void(bool)>& callback,
683 GLHelper::ScalerQuality quality) { 797 GLHelper::ScalerQuality quality) {
684 GLuint mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_point); 798 GLuint mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_point);
685 CropScaleReadbackAndCleanTexture( 799 CropScaleReadbackAndCleanTexture(mailbox_texture,
686 mailbox_texture, src_size, src_subrect, dst_size, out, 800 src_size,
687 color_type, 801 src_subrect,
688 callback, 802 dst_size,
689 quality); 803 out,
804 out_color_type,
805 callback,
806 quality);
690 gl_->DeleteTextures(1, &mailbox_texture); 807 gl_->DeleteTextures(1, &mailbox_texture);
691 } 808 }
692 809
693 void GLHelper::ReadbackTextureSync(GLuint texture, 810 void GLHelper::ReadbackTextureSync(GLuint texture,
694 const gfx::Rect& src_rect, 811 const gfx::Rect& src_rect,
695 unsigned char* out, 812 unsigned char* out,
696 SkColorType format) { 813 SkColorType format) {
697 InitCopyTextToImpl(); 814 InitCopyTextToImpl();
698 copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out, format); 815 copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out, format);
699 } 816 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
894 4, 1011 4,
895 callback); 1012 callback);
896 } 1013 }
897 1014
898 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { 1015 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = {
899 0.257f, 0.504f, 0.098f, 0.0625f}; 1016 0.257f, 0.504f, 0.098f, 0.0625f};
900 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { 1017 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = {
901 -0.148f, -0.291f, 0.439f, 0.5f}; 1018 -0.148f, -0.291f, 0.439f, 0.5f};
902 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { 1019 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = {
903 0.439f, -0.368f, -0.071f, 0.5f}; 1020 0.439f, -0.368f, -0.071f, 0.5f};
1021 const float GLHelper::CopyTextureToImpl::kRGBtoGrayscaleColorWeights[] = {
1022 0.213f, 0.715f, 0.072f, 0.0f};
904 1023
905 // YUV readback constructors. Initiates the main scaler pipeline and 1024 // YUV readback constructors. Initiates the main scaler pipeline and
906 // one planar scaler for each of the Y, U and V planes. 1025 // one planar scaler for each of the Y, U and V planes.
907 GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUVImpl( 1026 GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUVImpl(
908 GLES2Interface* gl, 1027 GLES2Interface* gl,
909 CopyTextureToImpl* copy_impl, 1028 CopyTextureToImpl* copy_impl,
910 GLHelperScaling* scaler_impl, 1029 GLHelperScaling* scaler_impl,
911 GLHelper::ScalerQuality quality, 1030 GLHelper::ScalerQuality quality,
912 const gfx::Size& src_size, 1031 const gfx::Size& src_size,
913 const gfx::Rect& src_subrect, 1032 const gfx::Rect& src_subrect,
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
1235 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality, 1354 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality,
1236 src_size, 1355 src_size,
1237 src_subrect, 1356 src_subrect,
1238 dst_size, 1357 dst_size,
1239 dst_subrect, 1358 dst_subrect,
1240 flip_vertically, 1359 flip_vertically,
1241 use_mrt); 1360 use_mrt);
1242 } 1361 }
1243 1362
1244 } // namespace content 1363 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/client/gl_helper.h ('k') | content/common/gpu/client/gl_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698