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 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
312 // |src_size| is the size of |src_texture|. | 312 // |src_size| is the size of |src_texture|. |
313 GLuint ScaleTexture(GLuint src_texture, | 313 GLuint ScaleTexture(GLuint src_texture, |
314 const gfx::Size& src_size, | 314 const gfx::Size& src_size, |
315 const gfx::Rect& src_subrect, | 315 const gfx::Rect& src_subrect, |
316 const gfx::Size& dst_size, | 316 const gfx::Size& dst_size, |
317 bool vertically_flip_texture, | 317 bool vertically_flip_texture, |
318 bool swizzle, | 318 bool swizzle, |
319 SkBitmap::Config config, | 319 SkBitmap::Config config, |
320 GLHelper::ScalerQuality quality); | 320 GLHelper::ScalerQuality quality); |
321 | 321 |
322 // Converts each four consecutive pixels of the source texture into one pixel | |
323 // in the result texture with each pixel channel representing the grayscale | |
324 // color of one of the four original pixels: | |
325 // R1B1G1A1 R2B2G2A2 R3B3G3A3 R4G4B4A4 -> X1X2X3X4 | |
326 // The resulting texture is an RGBA texture which is 4 times narrower than the | |
327 // original, but when read back the pixel data can be used to construct the | |
danakj
2014/07/10 19:13:02
just drop the reference to bitmaps here, this func
mfomitchev
2014/07/11 19:46:08
Done. See if you like the new version.
| |
328 // kA8_Config bitmap representing the grayscale version of the original | |
329 // texture. | |
330 GLuint TransformTextureToA8(GLuint src_texture, | |
danakj
2014/07/10 19:13:03
TransformTextureToGrayscale. There's no A8 bitmaps
mfomitchev
2014/07/11 19:46:07
Done.
| |
331 const gfx::Size& src_size, | |
332 const gfx::Rect& src_subrect, | |
333 gfx::Size* const result_size, | |
334 bool swizzle); | |
335 | |
322 static void nullcallback(bool success) {} | 336 static void nullcallback(bool success) {} |
323 void ReadbackDone(Request *request, int bytes_per_pixel); | 337 void ReadbackDone(Request *request, int bytes_per_pixel); |
324 void FinishRequest(Request* request, bool result); | 338 void FinishRequest(Request* request, bool result); |
325 void CancelRequests(); | 339 void CancelRequests(); |
326 | 340 |
327 static const float kRGBtoYColorWeights[]; | 341 static const float kRGBtoYColorWeights[]; |
328 static const float kRGBtoUColorWeights[]; | 342 static const float kRGBtoUColorWeights[]; |
329 static const float kRGBtoVColorWeights[]; | 343 static const float kRGBtoVColorWeights[]; |
344 static const float kRGBtoA8ColorWeights[]; | |
danakj
2014/07/10 19:13:03
toGrayscale
mfomitchev
2014/07/11 19:46:07
Done.
| |
330 | 345 |
331 GLES2Interface* gl_; | 346 GLES2Interface* gl_; |
332 gpu::ContextSupport* context_support_; | 347 gpu::ContextSupport* context_support_; |
333 GLHelper* helper_; | 348 GLHelper* helper_; |
334 | 349 |
335 // A scoped flush that will ensure all resource deletions are flushed when | 350 // A scoped flush that will ensure all resource deletions are flushed when |
336 // this object is destroyed. Must be declared before other Scoped* fields. | 351 // this object is destroyed. Must be declared before other Scoped* fields. |
337 ScopedFlush flush_; | 352 ScopedFlush flush_; |
338 | 353 |
339 std::queue<Request*> request_queue_; | 354 std::queue<Request*> request_queue_; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
400 dst_size.height(), | 415 dst_size.height(), |
401 0, | 416 0, |
402 format, | 417 format, |
403 type, | 418 type, |
404 NULL); | 419 NULL); |
405 } | 420 } |
406 scaler->Scale(src_texture, dst_texture); | 421 scaler->Scale(src_texture, dst_texture); |
407 return dst_texture; | 422 return dst_texture; |
408 } | 423 } |
409 | 424 |
425 GLuint GLHelper::CopyTextureToImpl::TransformTextureToA8( | |
426 GLuint src_texture, | |
427 const gfx::Size& src_size, | |
428 const gfx::Rect& src_subrect, | |
429 gfx::Size* const result_size, | |
430 bool swizzle) { | |
431 | |
432 LOG(ERROR) << "GLHelper::CopyTextureToImpl::TransformTextureToA8"; | |
433 | |
434 GLuint dst_texture = 1u; | |
435 gl_->GenTextures(1, &dst_texture); | |
436 { | |
437 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); | |
438 gl_->TexImage2D(GL_TEXTURE_2D, | |
439 0, | |
440 GL_BGRA_EXT, | |
441 src_size.width(), | |
442 src_size.height(), | |
443 0, | |
444 GL_BGRA_EXT, | |
445 GL_UNSIGNED_BYTE, | |
446 NULL); | |
447 } | |
448 | |
449 // The size of the transformed texture size | |
450 *result_size = gfx::Size((src_size.width() + 3) / 4, src_size.height()); | |
danakj
2014/07/10 19:13:02
hm, doing this here feels awkward, cuz there's som
mfomitchev
2014/07/11 19:46:07
Got rid of result_size.
| |
451 helper_->InitScalerImpl(); | |
452 scoped_ptr<ScalerInterface> | |
453 a8_scaler(helper_->scaler_impl_.get()->CreatePlanarScaler( | |
454 src_size, | |
455 gfx::Rect(0, 0, (src_size.width() + 3) & ~3, src_size.height()), | |
456 *result_size, | |
457 false, | |
458 (swizzle == kSwizzleBGRA), | |
459 kRGBtoA8ColorWeights)); | |
460 a8_scaler->Scale(src_texture, dst_texture); | |
461 return dst_texture; | |
462 } | |
463 | |
410 void GLHelper::CopyTextureToImpl::ReadbackAsync( | 464 void GLHelper::CopyTextureToImpl::ReadbackAsync( |
411 const gfx::Size& dst_size, | 465 const gfx::Size& dst_size, |
412 int32 bytes_per_row, | 466 int32 bytes_per_row, |
413 int32 row_stride_bytes, | 467 int32 row_stride_bytes, |
414 unsigned char* out, | 468 unsigned char* out, |
415 const SkBitmap::Config bitmap_config, | 469 const SkBitmap::Config bitmap_config, |
416 ReadbackSwizzle swizzle, | 470 ReadbackSwizzle swizzle, |
417 const base::Callback<void(bool)>& callback) { | 471 const base::Callback<void(bool)>& callback) { |
418 if (!IsReadbackConfigSupported(bitmap_config)) { | 472 if (!IsReadbackConfigSupported(bitmap_config)) { |
419 callback.Run(false); | 473 callback.Run(false); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
468 } | 522 } |
469 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( | 523 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
470 GLuint src_texture, | 524 GLuint src_texture, |
471 const gfx::Size& src_size, | 525 const gfx::Size& src_size, |
472 const gfx::Rect& src_subrect, | 526 const gfx::Rect& src_subrect, |
473 const gfx::Size& dst_size, | 527 const gfx::Size& dst_size, |
474 unsigned char* out, | 528 unsigned char* out, |
475 const SkBitmap::Config bitmap_config, | 529 const SkBitmap::Config bitmap_config, |
476 const base::Callback<void(bool)>& callback, | 530 const base::Callback<void(bool)>& callback, |
477 GLHelper::ScalerQuality quality) { | 531 GLHelper::ScalerQuality quality) { |
478 if (!IsReadbackConfigSupported(bitmap_config)) { | 532 if (bitmap_config != SkBitmap::kA8_Config && |
danakj
2014/07/10 19:13:02
why is this here instead of deciding A8 is ok insi
mfomitchev
2014/07/11 19:46:07
Responded separately in the reply.
| |
533 !IsReadbackConfigSupported(bitmap_config)) { | |
479 callback.Run(false); | 534 callback.Run(false); |
480 return; | 535 return; |
481 } | 536 } |
537 | |
538 SkBitmap::Config texture_config = bitmap_config; | |
539 if (bitmap_config == SkBitmap::kA8_Config) { | |
540 // For readback purposes, treat the resulting texture as ARGB of smaller | |
danakj
2014/07/10 19:13:02
What does it look like if you teach ReadbackAsync
mfomitchev
2014/07/11 19:46:07
Done. If the new version looks ok, I will make sim
| |
541 // size. | |
542 texture_config = SkBitmap::kARGB_8888_Config; | |
543 } | |
544 | |
545 bool swizzle = | |
546 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | |
547 true; | |
548 #else | |
549 false; | |
550 #endif | |
551 | |
482 GLuint texture = ScaleTexture(src_texture, | 552 GLuint texture = ScaleTexture(src_texture, |
483 src_size, | 553 src_size, |
484 src_subrect, | 554 src_subrect, |
485 dst_size, | 555 dst_size, |
486 true, | 556 true, |
487 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 557 swizzle, |
488 true, | 558 texture_config, |
489 #else | |
490 false, | |
491 #endif | |
492 bitmap_config, | |
493 quality); | 559 quality); |
494 DCHECK(texture); | 560 |
561 gfx::Size texture_size = dst_size; | |
562 if (bitmap_config == SkBitmap::kA8_Config) { | |
563 texture = TransformTextureToA8(texture, | |
564 src_size, | |
danakj
2014/07/10 19:13:03
git cl format
mfomitchev
2014/07/11 19:46:08
Done.
| |
565 src_subrect, | |
566 &texture_size, | |
567 swizzle); | |
568 | |
569 DCHECK(texture); | |
570 } | |
495 ScopedFramebuffer dst_framebuffer(gl_); | 571 ScopedFramebuffer dst_framebuffer(gl_); |
496 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, | 572 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
497 dst_framebuffer); | 573 dst_framebuffer); |
498 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 574 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
499 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, | 575 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, |
500 GL_COLOR_ATTACHMENT0, | 576 GL_COLOR_ATTACHMENT0, |
501 GL_TEXTURE_2D, | 577 GL_TEXTURE_2D, |
502 texture, | 578 texture, |
503 0); | 579 0); |
504 int bytes_per_pixel = 4; | 580 int bytes_per_pixel = 4; |
581 | |
505 switch (bitmap_config) { | 582 switch (bitmap_config) { |
506 case SkBitmap::kARGB_8888_Config: | 583 case SkBitmap::kARGB_8888_Config: |
507 // Do nothing params already set. | 584 // Do nothing params already set. |
508 break; | 585 break; |
509 case SkBitmap::kRGB_565_Config: | 586 case SkBitmap::kRGB_565_Config: |
510 bytes_per_pixel = 2; | 587 bytes_per_pixel = 2; |
511 break; | 588 break; |
589 case SkBitmap::kA8_Config: | |
590 bytes_per_pixel = 1; | |
591 break; | |
512 default: | 592 default: |
513 NOTREACHED(); | 593 NOTREACHED(); |
514 break; | 594 break; |
515 } | 595 } |
516 ReadbackAsync(dst_size, | 596 |
597 ReadbackAsync(texture_size, | |
517 dst_size.width() * bytes_per_pixel, | 598 dst_size.width() * bytes_per_pixel, |
518 dst_size.width() * bytes_per_pixel, | 599 dst_size.width() * bytes_per_pixel, |
519 out, | 600 out, |
520 bitmap_config, | 601 texture_config, |
521 kSwizzleNone, | 602 kSwizzleBGRA, |
mfomitchev
2014/07/09 18:02:10
The config and swizzle for the A8 case are picked
danakj
2014/07/10 19:13:03
This None->BGRA will affect more than the A8 path.
mfomitchev
2014/07/11 19:46:07
Good point, changed it back. I will separate this
| |
522 callback); | 603 callback); |
523 gl_->DeleteTextures(1, &texture); | 604 gl_->DeleteTextures(1, &texture); |
524 } | 605 } |
525 | 606 |
526 void GLHelper::CopyTextureToImpl::ReadbackTextureSync( | 607 void GLHelper::CopyTextureToImpl::ReadbackTextureSync( |
527 GLuint texture, | 608 GLuint texture, |
528 const gfx::Rect& src_rect, | 609 const gfx::Rect& src_rect, |
529 unsigned char* out, | 610 unsigned char* out, |
530 SkBitmap::Config bitmap_config) { | 611 SkBitmap::Config bitmap_config) { |
531 if (!IsReadbackConfigSupported(bitmap_config)) | 612 if (!IsReadbackConfigSupported(bitmap_config)) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
618 break; | 699 break; |
619 } | 700 } |
620 | 701 |
621 bool result = false; | 702 bool result = false; |
622 if (request->buffer != 0) { | 703 if (request->buffer != 0) { |
623 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); | 704 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
624 unsigned char* data = static_cast<unsigned char*>(gl_->MapBufferCHROMIUM( | 705 unsigned char* data = static_cast<unsigned char*>(gl_->MapBufferCHROMIUM( |
625 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); | 706 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); |
626 if (data) { | 707 if (data) { |
627 result = true; | 708 result = true; |
709 | |
628 if (request->bytes_per_row == request->size.width() * bytes_per_pixel && | 710 if (request->bytes_per_row == request->size.width() * bytes_per_pixel && |
629 request->bytes_per_row == request->row_stride_bytes) { | 711 request->bytes_per_row == request->row_stride_bytes) { |
630 memcpy(request->pixels, data, | 712 memcpy(request->pixels, data, |
631 request->size.GetArea() * bytes_per_pixel); | 713 request->size.GetArea() * bytes_per_pixel); |
632 } else { | 714 } else { |
633 unsigned char* out = request->pixels; | 715 unsigned char* out = request->pixels; |
634 for (int y = 0; y < request->size.height(); y++) { | 716 for (int y = 0; y < request->size.height(); y++) { |
635 memcpy(out, data, request->bytes_per_row); | 717 memcpy(out, data, request->bytes_per_row); |
636 out += request->row_stride_bytes; | 718 out += request->row_stride_bytes; |
637 data += request->size.width() * bytes_per_pixel; | 719 data += request->size.width() * bytes_per_pixel; |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
921 swizzle, | 1003 swizzle, |
922 callback); | 1004 callback); |
923 } | 1005 } |
924 | 1006 |
925 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { | 1007 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { |
926 0.257f, 0.504f, 0.098f, 0.0625f}; | 1008 0.257f, 0.504f, 0.098f, 0.0625f}; |
927 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { | 1009 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { |
928 -0.148f, -0.291f, 0.439f, 0.5f}; | 1010 -0.148f, -0.291f, 0.439f, 0.5f}; |
929 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { | 1011 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { |
930 0.439f, -0.368f, -0.071f, 0.5f}; | 1012 0.439f, -0.368f, -0.071f, 0.5f}; |
1013 const float GLHelper::CopyTextureToImpl::kRGBtoA8ColorWeights[] = { | |
1014 0.213f, 0.715f, 0.072f, 0.0f}; | |
931 | 1015 |
932 // YUV readback constructors. Initiates the main scaler pipeline and | 1016 // YUV readback constructors. Initiates the main scaler pipeline and |
933 // one planar scaler for each of the Y, U and V planes. | 1017 // one planar scaler for each of the Y, U and V planes. |
934 GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUVImpl( | 1018 GLHelper::CopyTextureToImpl::ReadbackYUVImpl::ReadbackYUVImpl( |
935 GLES2Interface* gl, | 1019 GLES2Interface* gl, |
936 CopyTextureToImpl* copy_impl, | 1020 CopyTextureToImpl* copy_impl, |
937 GLHelperScaling* scaler_impl, | 1021 GLHelperScaling* scaler_impl, |
938 GLHelper::ScalerQuality quality, | 1022 GLHelper::ScalerQuality quality, |
939 const gfx::Size& src_size, | 1023 const gfx::Size& src_size, |
940 const gfx::Rect& src_subrect, | 1024 const gfx::Rect& src_subrect, |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1253 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality, | 1337 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality, |
1254 src_size, | 1338 src_size, |
1255 src_subrect, | 1339 src_subrect, |
1256 dst_size, | 1340 dst_size, |
1257 dst_subrect, | 1341 dst_subrect, |
1258 flip_vertically, | 1342 flip_vertically, |
1259 use_mrt); | 1343 use_mrt); |
1260 } | 1344 } |
1261 | 1345 |
1262 } // namespace content | 1346 } // namespace content |
OLD | NEW |