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/browser/compositor/gl_helper.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <queue> | 10 #include <queue> |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/lazy_instance.h" | 14 #include "base/lazy_instance.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
17 #include "base/memory/ref_counted.h" | 17 #include "base/memory/ref_counted.h" |
18 #include "base/message_loop/message_loop.h" | 18 #include "base/message_loop/message_loop.h" |
19 #include "base/strings/string_util.h" | 19 #include "base/strings/string_util.h" |
20 #include "base/time/time.h" | 20 #include "base/time/time.h" |
21 #include "base/trace_event/trace_event.h" | 21 #include "base/trace_event/trace_event.h" |
22 #include "content/common/gpu/client/gl_helper_readback_support.h" | 22 #include "content/browser/compositor/gl_helper_readback_support.h" |
23 #include "content/common/gpu/client/gl_helper_scaling.h" | 23 #include "content/browser/compositor/gl_helper_scaling.h" |
24 #include "gpu/GLES2/gl2extchromium.h" | 24 #include "gpu/GLES2/gl2extchromium.h" |
25 #include "gpu/command_buffer/client/context_support.h" | 25 #include "gpu/command_buffer/client/context_support.h" |
26 #include "gpu/command_buffer/common/mailbox.h" | 26 #include "gpu/command_buffer/common/mailbox.h" |
27 #include "gpu/command_buffer/common/mailbox_holder.h" | 27 #include "gpu/command_buffer/common/mailbox_holder.h" |
28 #include "media/base/video_frame.h" | 28 #include "media/base/video_frame.h" |
29 #include "media/base/video_util.h" | 29 #include "media/base/video_util.h" |
30 #include "third_party/skia/include/core/SkRegion.h" | 30 #include "third_party/skia/include/core/SkRegion.h" |
31 #include "ui/gfx/geometry/point.h" | 31 #include "ui/gfx/geometry/point.h" |
32 #include "ui/gfx/geometry/rect.h" | 32 #include "ui/gfx/geometry/rect.h" |
33 #include "ui/gfx/geometry/size.h" | 33 #include "ui/gfx/geometry/size.h" |
(...skipping 14 matching lines...) Expand all Loading... |
48 DISALLOW_COPY_AND_ASSIGN(ScopedFlush); | 48 DISALLOW_COPY_AND_ASSIGN(ScopedFlush); |
49 }; | 49 }; |
50 | 50 |
51 // Helper class for allocating and holding an RGBA texture of a given | 51 // Helper class for allocating and holding an RGBA texture of a given |
52 // size and an associated framebuffer. | 52 // size and an associated framebuffer. |
53 class TextureFrameBufferPair { | 53 class TextureFrameBufferPair { |
54 public: | 54 public: |
55 TextureFrameBufferPair(GLES2Interface* gl, gfx::Size size) | 55 TextureFrameBufferPair(GLES2Interface* gl, gfx::Size size) |
56 : texture_(gl), framebuffer_(gl), size_(size) { | 56 : texture_(gl), framebuffer_(gl), size_(size) { |
57 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, texture_); | 57 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, texture_); |
58 gl->TexImage2D(GL_TEXTURE_2D, | 58 gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, |
59 0, | 59 GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
60 GL_RGBA, | |
61 size.width(), | |
62 size.height(), | |
63 0, | |
64 GL_RGBA, | |
65 GL_UNSIGNED_BYTE, | |
66 NULL); | |
67 content::ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( | 60 content::ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( |
68 gl, framebuffer_); | 61 gl, framebuffer_); |
69 gl->FramebufferTexture2D( | 62 gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, |
70 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0); | 63 GL_TEXTURE_2D, texture_, 0); |
71 } | 64 } |
72 | 65 |
73 GLuint texture() const { return texture_.id(); } | 66 GLuint texture() const { return texture_.id(); } |
74 GLuint framebuffer() const { return framebuffer_.id(); } | 67 GLuint framebuffer() const { return framebuffer_.id(); } |
75 gfx::Size size() const { return size_; } | 68 gfx::Size size() const { return size_; } |
76 | 69 |
77 private: | 70 private: |
78 content::ScopedTexture texture_; | 71 content::ScopedTexture texture_; |
79 content::ScopedFramebuffer framebuffer_; | 72 content::ScopedFramebuffer framebuffer_; |
80 gfx::Size size_; | 73 gfx::Size size_; |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 public: | 241 public: |
249 FinishRequestHelper() {} | 242 FinishRequestHelper() {} |
250 ~FinishRequestHelper() { | 243 ~FinishRequestHelper() { |
251 while (!requests_.empty()) { | 244 while (!requests_.empty()) { |
252 Request* request = requests_.front(); | 245 Request* request = requests_.front(); |
253 requests_.pop(); | 246 requests_.pop(); |
254 request->callback.Run(request->result); | 247 request->callback.Run(request->result); |
255 delete request; | 248 delete request; |
256 } | 249 } |
257 } | 250 } |
258 void Add(Request* r) { | 251 void Add(Request* r) { requests_.push(r); } |
259 requests_.push(r); | 252 |
260 } | |
261 private: | 253 private: |
262 std::queue<Request*> requests_; | 254 std::queue<Request*> requests_; |
263 DISALLOW_COPY_AND_ASSIGN(FinishRequestHelper); | 255 DISALLOW_COPY_AND_ASSIGN(FinishRequestHelper); |
264 }; | 256 }; |
265 | 257 |
266 // A readback pipeline that also converts the data to YUV before | 258 // A readback pipeline that also converts the data to YUV before |
267 // reading it back. | 259 // reading it back. |
268 class ReadbackYUVImpl : public ReadbackYUVInterface { | 260 class ReadbackYUVImpl : public ReadbackYUVInterface { |
269 public: | 261 public: |
270 ReadbackYUVImpl(GLES2Interface* gl, | 262 ReadbackYUVImpl(GLES2Interface* gl, |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 // useful data. | 355 // useful data. |
364 // If swizzle is set to true, the transformed pixels are reordered: | 356 // If swizzle is set to true, the transformed pixels are reordered: |
365 // R1G1B1A1 R2G2B2A2 R3G3B3A3 R4G4B4A4 -> X3X2X1X4. | 357 // R1G1B1A1 R2G2B2A2 R3G3B3A3 R4G4B4A4 -> X3X2X1X4. |
366 GLuint EncodeTextureAsGrayscale(GLuint src_texture, | 358 GLuint EncodeTextureAsGrayscale(GLuint src_texture, |
367 const gfx::Size& src_size, | 359 const gfx::Size& src_size, |
368 gfx::Size* const encoded_texture_size, | 360 gfx::Size* const encoded_texture_size, |
369 bool vertically_flip_texture, | 361 bool vertically_flip_texture, |
370 bool swizzle); | 362 bool swizzle); |
371 | 363 |
372 static void nullcallback(bool success) {} | 364 static void nullcallback(bool success) {} |
373 void ReadbackDone(Request *request, int bytes_per_pixel); | 365 void ReadbackDone(Request* request, int bytes_per_pixel); |
374 void FinishRequest(Request* request, | 366 void FinishRequest(Request* request, |
375 bool result, | 367 bool result, |
376 FinishRequestHelper* helper); | 368 FinishRequestHelper* helper); |
377 void CancelRequests(); | 369 void CancelRequests(); |
378 | 370 |
379 static const float kRGBtoYColorWeights[]; | 371 static const float kRGBtoYColorWeights[]; |
380 static const float kRGBtoUColorWeights[]; | 372 static const float kRGBtoUColorWeights[]; |
381 static const float kRGBtoVColorWeights[]; | 373 static const float kRGBtoVColorWeights[]; |
382 static const float kRGBtoGrayscaleColorWeights[]; | 374 static const float kRGBtoGrayscaleColorWeights[]; |
383 | 375 |
384 GLES2Interface* gl_; | 376 GLES2Interface* gl_; |
385 gpu::ContextSupport* context_support_; | 377 gpu::ContextSupport* context_support_; |
386 GLHelper* helper_; | 378 GLHelper* helper_; |
387 | 379 |
388 // A scoped flush that will ensure all resource deletions are flushed when | 380 // A scoped flush that will ensure all resource deletions are flushed when |
389 // this object is destroyed. Must be declared before other Scoped* fields. | 381 // this object is destroyed. Must be declared before other Scoped* fields. |
390 ScopedFlush flush_; | 382 ScopedFlush flush_; |
391 | 383 |
392 std::queue<Request*> request_queue_; | 384 std::queue<Request*> request_queue_; |
393 GLint max_draw_buffers_; | 385 GLint max_draw_buffers_; |
394 }; | 386 }; |
395 | 387 |
396 GLHelper::ScalerInterface* GLHelper::CreateScaler(ScalerQuality quality, | 388 GLHelper::ScalerInterface* GLHelper::CreateScaler(ScalerQuality quality, |
397 const gfx::Size& src_size, | 389 const gfx::Size& src_size, |
398 const gfx::Rect& src_subrect, | 390 const gfx::Rect& src_subrect, |
399 const gfx::Size& dst_size, | 391 const gfx::Size& dst_size, |
400 bool vertically_flip_texture, | 392 bool vertically_flip_texture, |
401 bool swizzle) { | 393 bool swizzle) { |
402 InitScalerImpl(); | 394 InitScalerImpl(); |
403 return scaler_impl_->CreateScaler(quality, | 395 return scaler_impl_->CreateScaler(quality, src_size, src_subrect, dst_size, |
404 src_size, | 396 vertically_flip_texture, swizzle); |
405 src_subrect, | |
406 dst_size, | |
407 vertically_flip_texture, | |
408 swizzle); | |
409 } | 397 } |
410 | 398 |
411 GLuint GLHelper::CopyTextureToImpl::ScaleTexture( | 399 GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
412 GLuint src_texture, | 400 GLuint src_texture, |
413 const gfx::Size& src_size, | 401 const gfx::Size& src_size, |
414 const gfx::Rect& src_subrect, | 402 const gfx::Rect& src_subrect, |
415 const gfx::Size& dst_size, | 403 const gfx::Size& dst_size, |
416 bool vertically_flip_texture, | 404 bool vertically_flip_texture, |
417 bool swizzle, | 405 bool swizzle, |
418 SkColorType color_type, | 406 SkColorType color_type, |
419 GLHelper::ScalerQuality quality) { | 407 GLHelper::ScalerQuality quality) { |
420 GLuint dst_texture = 0u; | 408 GLuint dst_texture = 0u; |
421 gl_->GenTextures(1, &dst_texture); | 409 gl_->GenTextures(1, &dst_texture); |
422 { | 410 { |
423 GLenum format = GL_RGBA, type = GL_UNSIGNED_BYTE; | 411 GLenum format = GL_RGBA, type = GL_UNSIGNED_BYTE; |
424 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); | 412 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
425 | 413 |
426 // Use GL_RGBA for destination/temporary texture unless we're working with | 414 // Use GL_RGBA for destination/temporary texture unless we're working with |
427 // 16-bit data | 415 // 16-bit data |
428 if (color_type == kRGB_565_SkColorType) { | 416 if (color_type == kRGB_565_SkColorType) { |
429 format = GL_RGB; | 417 format = GL_RGB; |
430 type = GL_UNSIGNED_SHORT_5_6_5; | 418 type = GL_UNSIGNED_SHORT_5_6_5; |
431 } | 419 } |
432 | 420 |
433 gl_->TexImage2D(GL_TEXTURE_2D, | 421 gl_->TexImage2D(GL_TEXTURE_2D, 0, format, dst_size.width(), |
434 0, | 422 dst_size.height(), 0, format, type, NULL); |
435 format, | |
436 dst_size.width(), | |
437 dst_size.height(), | |
438 0, | |
439 format, | |
440 type, | |
441 NULL); | |
442 } | 423 } |
443 scoped_ptr<ScalerInterface> scaler( | 424 scoped_ptr<ScalerInterface> scaler( |
444 helper_->CreateScaler(quality, | 425 helper_->CreateScaler(quality, src_size, src_subrect, dst_size, |
445 src_size, | 426 vertically_flip_texture, swizzle)); |
446 src_subrect, | |
447 dst_size, | |
448 vertically_flip_texture, | |
449 swizzle)); | |
450 scaler->Scale(src_texture, dst_texture); | 427 scaler->Scale(src_texture, dst_texture); |
451 return dst_texture; | 428 return dst_texture; |
452 } | 429 } |
453 | 430 |
454 GLuint GLHelper::CopyTextureToImpl::EncodeTextureAsGrayscale( | 431 GLuint GLHelper::CopyTextureToImpl::EncodeTextureAsGrayscale( |
455 GLuint src_texture, | 432 GLuint src_texture, |
456 const gfx::Size& src_size, | 433 const gfx::Size& src_size, |
457 gfx::Size* const encoded_texture_size, | 434 gfx::Size* const encoded_texture_size, |
458 bool vertically_flip_texture, | 435 bool vertically_flip_texture, |
459 bool swizzle) { | 436 bool swizzle) { |
460 GLuint dst_texture = 0u; | 437 GLuint dst_texture = 0u; |
461 gl_->GenTextures(1, &dst_texture); | 438 gl_->GenTextures(1, &dst_texture); |
462 // The size of the encoded texture. | 439 // The size of the encoded texture. |
463 *encoded_texture_size = | 440 *encoded_texture_size = |
464 gfx::Size((src_size.width() + 3) / 4, src_size.height()); | 441 gfx::Size((src_size.width() + 3) / 4, src_size.height()); |
465 { | 442 { |
466 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); | 443 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
467 gl_->TexImage2D(GL_TEXTURE_2D, | 444 gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, encoded_texture_size->width(), |
468 0, | 445 encoded_texture_size->height(), 0, GL_RGBA, |
469 GL_RGBA, | 446 GL_UNSIGNED_BYTE, NULL); |
470 encoded_texture_size->width(), | |
471 encoded_texture_size->height(), | |
472 0, | |
473 GL_RGBA, | |
474 GL_UNSIGNED_BYTE, | |
475 NULL); | |
476 } | 447 } |
477 | 448 |
478 helper_->InitScalerImpl(); | 449 helper_->InitScalerImpl(); |
479 scoped_ptr<ScalerInterface> grayscale_scaler( | 450 scoped_ptr<ScalerInterface> grayscale_scaler( |
480 helper_->scaler_impl_.get()->CreatePlanarScaler( | 451 helper_->scaler_impl_.get()->CreatePlanarScaler( |
481 src_size, | 452 src_size, |
482 gfx::Rect(0, 0, (src_size.width() + 3) & ~3, src_size.height()), | 453 gfx::Rect(0, 0, (src_size.width() + 3) & ~3, src_size.height()), |
483 *encoded_texture_size, | 454 *encoded_texture_size, vertically_flip_texture, swizzle, |
484 vertically_flip_texture, | |
485 swizzle, | |
486 kRGBtoGrayscaleColorWeights)); | 455 kRGBtoGrayscaleColorWeights)); |
487 grayscale_scaler->Scale(src_texture, dst_texture); | 456 grayscale_scaler->Scale(src_texture, dst_texture); |
488 return dst_texture; | 457 return dst_texture; |
489 } | 458 } |
490 | 459 |
491 void GLHelper::CopyTextureToImpl::ReadbackAsync( | 460 void GLHelper::CopyTextureToImpl::ReadbackAsync( |
492 const gfx::Size& dst_size, | 461 const gfx::Size& dst_size, |
493 int32_t bytes_per_row, | 462 int32_t bytes_per_row, |
494 int32_t row_stride_bytes, | 463 int32_t row_stride_bytes, |
495 unsigned char* out, | 464 unsigned char* out, |
496 GLenum format, | 465 GLenum format, |
497 GLenum type, | 466 GLenum type, |
498 size_t bytes_per_pixel, | 467 size_t bytes_per_pixel, |
499 const base::Callback<void(bool)>& callback) { | 468 const base::Callback<void(bool)>& callback) { |
500 TRACE_EVENT0("gpu.capture", "GLHelper::CopyTextureToImpl::ReadbackAsync"); | 469 TRACE_EVENT0("gpu.capture", "GLHelper::CopyTextureToImpl::ReadbackAsync"); |
501 Request* request = | 470 Request* request = |
502 new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback); | 471 new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback); |
503 request_queue_.push(request); | 472 request_queue_.push(request); |
504 request->buffer = 0u; | 473 request->buffer = 0u; |
505 | 474 |
506 gl_->GenBuffers(1, &request->buffer); | 475 gl_->GenBuffers(1, &request->buffer); |
507 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); | 476 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
508 gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 477 gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
509 bytes_per_pixel * dst_size.GetArea(), | 478 bytes_per_pixel * dst_size.GetArea(), NULL, GL_STREAM_READ); |
510 NULL, | |
511 GL_STREAM_READ); | |
512 | 479 |
513 request->query = 0u; | 480 request->query = 0u; |
514 gl_->GenQueriesEXT(1, &request->query); | 481 gl_->GenQueriesEXT(1, &request->query); |
515 gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query); | 482 gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query); |
516 gl_->ReadPixels(0, | 483 gl_->ReadPixels(0, 0, dst_size.width(), dst_size.height(), format, type, |
517 0, | |
518 dst_size.width(), | |
519 dst_size.height(), | |
520 format, | |
521 type, | |
522 NULL); | 484 NULL); |
523 gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); | 485 gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); |
524 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); | 486 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
525 context_support_->SignalQuery( | 487 context_support_->SignalQuery( |
526 request->query, | 488 request->query, base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), |
527 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), | 489 request, bytes_per_pixel)); |
528 request, bytes_per_pixel)); | |
529 } | 490 } |
530 | 491 |
531 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( | 492 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
532 GLuint src_texture, | 493 GLuint src_texture, |
533 const gfx::Size& src_size, | 494 const gfx::Size& src_size, |
534 const gfx::Rect& src_subrect, | 495 const gfx::Rect& src_subrect, |
535 const gfx::Size& dst_size, | 496 const gfx::Size& dst_size, |
536 unsigned char* out, | 497 unsigned char* out, |
537 const SkColorType out_color_type, | 498 const SkColorType out_color_type, |
538 const base::Callback<void(bool)>& callback, | 499 const base::Callback<void(bool)>& callback, |
539 GLHelper::ScalerQuality quality) { | 500 GLHelper::ScalerQuality quality) { |
540 GLenum format, type; | 501 GLenum format, type; |
541 size_t bytes_per_pixel; | 502 size_t bytes_per_pixel; |
542 SkColorType readback_color_type = out_color_type; | 503 SkColorType readback_color_type = out_color_type; |
543 // Single-component textures are not supported by all GPUs, so we implement | 504 // Single-component textures are not supported by all GPUs, so we implement |
544 // kAlpha_8_SkColorType support here via a special encoding (see below) using | 505 // kAlpha_8_SkColorType support here via a special encoding (see below) using |
545 // a 32-bit texture to represent an 8-bit image. | 506 // a 32-bit texture to represent an 8-bit image. |
546 // Thus we use generic 32-bit readback in this case. | 507 // Thus we use generic 32-bit readback in this case. |
547 if (out_color_type == kAlpha_8_SkColorType) { | 508 if (out_color_type == kAlpha_8_SkColorType) { |
548 readback_color_type = kRGBA_8888_SkColorType; | 509 readback_color_type = kRGBA_8888_SkColorType; |
549 } | 510 } |
550 | 511 |
551 FormatSupport supported = GetReadbackConfig( | 512 FormatSupport supported = GetReadbackConfig(readback_color_type, true, |
552 readback_color_type, true, &format, &type, &bytes_per_pixel); | 513 &format, &type, &bytes_per_pixel); |
553 | 514 |
554 if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { | 515 if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { |
555 callback.Run(false); | 516 callback.Run(false); |
556 return; | 517 return; |
557 } | 518 } |
558 | 519 |
559 GLuint texture = src_texture; | 520 GLuint texture = src_texture; |
560 | 521 |
561 // Scale texture if needed | 522 // Scale texture if needed |
562 // Optimization: SCALER_QUALITY_FAST is just a single bilinear pass, which we | 523 // Optimization: SCALER_QUALITY_FAST is just a single bilinear pass, which we |
563 // can do just as well in EncodeTextureAsGrayscale, which we will do if | 524 // can do just as well in EncodeTextureAsGrayscale, which we will do if |
564 // out_color_type is kAlpha_8_SkColorType, so let's skip the scaling step | 525 // out_color_type is kAlpha_8_SkColorType, so let's skip the scaling step |
565 // in that case. | 526 // in that case. |
566 bool scale_texture = out_color_type != kAlpha_8_SkColorType || | 527 bool scale_texture = out_color_type != kAlpha_8_SkColorType || |
567 quality != GLHelper::SCALER_QUALITY_FAST; | 528 quality != GLHelper::SCALER_QUALITY_FAST; |
568 if (scale_texture) { | 529 if (scale_texture) { |
569 // Don't swizzle during the scale step for kAlpha_8_SkColorType. | 530 // Don't swizzle during the scale step for kAlpha_8_SkColorType. |
570 // We will swizzle in the encode step below if needed. | 531 // We will swizzle in the encode step below if needed. |
571 bool scale_swizzle = out_color_type == kAlpha_8_SkColorType | 532 bool scale_swizzle = out_color_type == kAlpha_8_SkColorType |
572 ? false | 533 ? false |
573 : supported == GLHelperReadbackSupport::SWIZZLE; | 534 : supported == GLHelperReadbackSupport::SWIZZLE; |
574 texture = | 535 texture = ScaleTexture(src_texture, src_size, src_subrect, dst_size, true, |
575 ScaleTexture(src_texture, | 536 scale_swizzle, out_color_type == kAlpha_8_SkColorType |
576 src_size, | 537 ? kN32_SkColorType |
577 src_subrect, | 538 : out_color_type, |
578 dst_size, | 539 quality); |
579 true, | |
580 scale_swizzle, | |
581 out_color_type == kAlpha_8_SkColorType ? kN32_SkColorType | |
582 : out_color_type, | |
583 quality); | |
584 DCHECK(texture); | 540 DCHECK(texture); |
585 } | 541 } |
586 | 542 |
587 gfx::Size readback_texture_size = dst_size; | 543 gfx::Size readback_texture_size = dst_size; |
588 // Encode texture to grayscale if needed. | 544 // Encode texture to grayscale if needed. |
589 if (out_color_type == kAlpha_8_SkColorType) { | 545 if (out_color_type == kAlpha_8_SkColorType) { |
590 // Do the vertical flip here if we haven't already done it when we scaled | 546 // Do the vertical flip here if we haven't already done it when we scaled |
591 // the texture. | 547 // the texture. |
592 bool encode_as_grayscale_vertical_flip = !scale_texture; | 548 bool encode_as_grayscale_vertical_flip = !scale_texture; |
593 // EncodeTextureAsGrayscale by default creates a texture which should be | 549 // EncodeTextureAsGrayscale by default creates a texture which should be |
594 // read back as RGBA, so need to swizzle if the readback format is BGRA. | 550 // read back as RGBA, so need to swizzle if the readback format is BGRA. |
595 bool encode_as_grayscale_swizzle = format == GL_BGRA_EXT; | 551 bool encode_as_grayscale_swizzle = format == GL_BGRA_EXT; |
596 GLuint tmp_texture = | 552 GLuint tmp_texture = EncodeTextureAsGrayscale( |
597 EncodeTextureAsGrayscale(texture, | 553 texture, dst_size, &readback_texture_size, |
598 dst_size, | 554 encode_as_grayscale_vertical_flip, encode_as_grayscale_swizzle); |
599 &readback_texture_size, | |
600 encode_as_grayscale_vertical_flip, | |
601 encode_as_grayscale_swizzle); | |
602 // If the scaled texture was created - delete it | 555 // If the scaled texture was created - delete it |
603 if (scale_texture) | 556 if (scale_texture) |
604 gl_->DeleteTextures(1, &texture); | 557 gl_->DeleteTextures(1, &texture); |
605 texture = tmp_texture; | 558 texture = tmp_texture; |
606 DCHECK(texture); | 559 DCHECK(texture); |
607 } | 560 } |
608 | 561 |
609 // Readback the pixels of the resulting texture | 562 // Readback the pixels of the resulting texture |
610 ScopedFramebuffer dst_framebuffer(gl_); | 563 ScopedFramebuffer dst_framebuffer(gl_); |
611 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, | 564 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
612 dst_framebuffer); | 565 dst_framebuffer); |
613 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 566 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
614 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, | 567 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, |
615 GL_COLOR_ATTACHMENT0, | 568 texture, 0); |
616 GL_TEXTURE_2D, | |
617 texture, | |
618 0); | |
619 | 569 |
620 int32_t bytes_per_row = out_color_type == kAlpha_8_SkColorType | 570 int32_t bytes_per_row = out_color_type == kAlpha_8_SkColorType |
621 ? dst_size.width() | 571 ? dst_size.width() |
622 : dst_size.width() * bytes_per_pixel; | 572 : dst_size.width() * bytes_per_pixel; |
623 | 573 |
624 ReadbackAsync(readback_texture_size, | 574 ReadbackAsync(readback_texture_size, bytes_per_row, bytes_per_row, out, |
625 bytes_per_row, | 575 format, type, bytes_per_pixel, callback); |
626 bytes_per_row, | |
627 out, | |
628 format, | |
629 type, | |
630 bytes_per_pixel, | |
631 callback); | |
632 gl_->DeleteTextures(1, &texture); | 576 gl_->DeleteTextures(1, &texture); |
633 } | 577 } |
634 | 578 |
635 void GLHelper::CopyTextureToImpl::ReadbackTextureSync( | 579 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(GLuint texture, |
636 GLuint texture, | 580 const gfx::Rect& src_rect, |
637 const gfx::Rect& src_rect, | 581 unsigned char* out, |
638 unsigned char* out, | 582 SkColorType color_type) { |
639 SkColorType color_type) { | |
640 GLenum format, type; | 583 GLenum format, type; |
641 size_t bytes_per_pixel; | 584 size_t bytes_per_pixel; |
642 FormatSupport supported = | 585 FormatSupport supported = |
643 GetReadbackConfig(color_type, false, &format, &type, &bytes_per_pixel); | 586 GetReadbackConfig(color_type, false, &format, &type, &bytes_per_pixel); |
644 if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { | 587 if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { |
645 return; | 588 return; |
646 } | 589 } |
647 | 590 |
648 ScopedFramebuffer dst_framebuffer(gl_); | 591 ScopedFramebuffer dst_framebuffer(gl_); |
649 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, | 592 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
650 dst_framebuffer); | 593 dst_framebuffer); |
651 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 594 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
652 gl_->FramebufferTexture2D( | 595 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, |
653 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); | 596 texture, 0); |
654 gl_->ReadPixels(src_rect.x(), | 597 gl_->ReadPixels(src_rect.x(), src_rect.y(), src_rect.width(), |
655 src_rect.y(), | 598 src_rect.height(), format, type, out); |
656 src_rect.width(), | |
657 src_rect.height(), | |
658 format, | |
659 type, | |
660 out); | |
661 } | 599 } |
662 | 600 |
663 void GLHelper::CopyTextureToImpl::ReadbackTextureAsync( | 601 void GLHelper::CopyTextureToImpl::ReadbackTextureAsync( |
664 GLuint texture, | 602 GLuint texture, |
665 const gfx::Size& dst_size, | 603 const gfx::Size& dst_size, |
666 unsigned char* out, | 604 unsigned char* out, |
667 SkColorType color_type, | 605 SkColorType color_type, |
668 const base::Callback<void(bool)>& callback) { | 606 const base::Callback<void(bool)>& callback) { |
669 GLenum format, type; | 607 GLenum format, type; |
670 size_t bytes_per_pixel; | 608 size_t bytes_per_pixel; |
671 FormatSupport supported = | 609 FormatSupport supported = |
672 GetReadbackConfig(color_type, false, &format, &type, &bytes_per_pixel); | 610 GetReadbackConfig(color_type, false, &format, &type, &bytes_per_pixel); |
673 if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { | 611 if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { |
674 callback.Run(false); | 612 callback.Run(false); |
675 return; | 613 return; |
676 } | 614 } |
677 | 615 |
678 ScopedFramebuffer dst_framebuffer(gl_); | 616 ScopedFramebuffer dst_framebuffer(gl_); |
679 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, | 617 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
680 dst_framebuffer); | 618 dst_framebuffer); |
681 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 619 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
682 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, | 620 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, |
683 GL_COLOR_ATTACHMENT0, | 621 texture, 0); |
684 GL_TEXTURE_2D, | 622 ReadbackAsync(dst_size, dst_size.width() * bytes_per_pixel, |
685 texture, | 623 dst_size.width() * bytes_per_pixel, out, format, type, |
686 0); | 624 bytes_per_pixel, callback); |
687 ReadbackAsync(dst_size, | |
688 dst_size.width() * bytes_per_pixel, | |
689 dst_size.width() * bytes_per_pixel, | |
690 out, | |
691 format, | |
692 type, | |
693 bytes_per_pixel, | |
694 callback); | |
695 } | 625 } |
696 | 626 |
697 GLuint GLHelper::CopyTextureToImpl::CopyAndScaleTexture( | 627 GLuint GLHelper::CopyTextureToImpl::CopyAndScaleTexture( |
698 GLuint src_texture, | 628 GLuint src_texture, |
699 const gfx::Size& src_size, | 629 const gfx::Size& src_size, |
700 const gfx::Size& dst_size, | 630 const gfx::Size& dst_size, |
701 bool vertically_flip_texture, | 631 bool vertically_flip_texture, |
702 GLHelper::ScalerQuality quality) { | 632 GLHelper::ScalerQuality quality) { |
703 return ScaleTexture(src_texture, | 633 return ScaleTexture(src_texture, src_size, gfx::Rect(src_size), dst_size, |
704 src_size, | 634 vertically_flip_texture, false, |
705 gfx::Rect(src_size), | |
706 dst_size, | |
707 vertically_flip_texture, | |
708 false, | |
709 kRGBA_8888_SkColorType, // GL_RGBA | 635 kRGBA_8888_SkColorType, // GL_RGBA |
710 quality); | 636 quality); |
711 } | 637 } |
712 | 638 |
713 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request, | 639 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request, |
714 int bytes_per_pixel) { | 640 int bytes_per_pixel) { |
715 TRACE_EVENT0("gpu.capture", | 641 TRACE_EVENT0("gpu.capture", |
716 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); | 642 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); |
717 finished_request->done = true; | 643 finished_request->done = true; |
718 | 644 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 void GLHelper::CropScaleReadbackAndCleanTexture( | 727 void GLHelper::CropScaleReadbackAndCleanTexture( |
802 GLuint src_texture, | 728 GLuint src_texture, |
803 const gfx::Size& src_size, | 729 const gfx::Size& src_size, |
804 const gfx::Rect& src_subrect, | 730 const gfx::Rect& src_subrect, |
805 const gfx::Size& dst_size, | 731 const gfx::Size& dst_size, |
806 unsigned char* out, | 732 unsigned char* out, |
807 const SkColorType out_color_type, | 733 const SkColorType out_color_type, |
808 const base::Callback<void(bool)>& callback, | 734 const base::Callback<void(bool)>& callback, |
809 GLHelper::ScalerQuality quality) { | 735 GLHelper::ScalerQuality quality) { |
810 InitCopyTextToImpl(); | 736 InitCopyTextToImpl(); |
811 copy_texture_to_impl_->CropScaleReadbackAndCleanTexture(src_texture, | 737 copy_texture_to_impl_->CropScaleReadbackAndCleanTexture( |
812 src_size, | 738 src_texture, src_size, src_subrect, dst_size, out, out_color_type, |
813 src_subrect, | 739 callback, quality); |
814 dst_size, | |
815 out, | |
816 out_color_type, | |
817 callback, | |
818 quality); | |
819 } | 740 } |
820 | 741 |
821 void GLHelper::CropScaleReadbackAndCleanMailbox( | 742 void GLHelper::CropScaleReadbackAndCleanMailbox( |
822 const gpu::Mailbox& src_mailbox, | 743 const gpu::Mailbox& src_mailbox, |
823 const gpu::SyncToken& sync_token, | 744 const gpu::SyncToken& sync_token, |
824 const gfx::Size& src_size, | 745 const gfx::Size& src_size, |
825 const gfx::Rect& src_subrect, | 746 const gfx::Rect& src_subrect, |
826 const gfx::Size& dst_size, | 747 const gfx::Size& dst_size, |
827 unsigned char* out, | 748 unsigned char* out, |
828 const SkColorType out_color_type, | 749 const SkColorType out_color_type, |
829 const base::Callback<void(bool)>& callback, | 750 const base::Callback<void(bool)>& callback, |
830 GLHelper::ScalerQuality quality) { | 751 GLHelper::ScalerQuality quality) { |
831 GLuint mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_token); | 752 GLuint mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_token); |
832 CropScaleReadbackAndCleanTexture(mailbox_texture, | 753 CropScaleReadbackAndCleanTexture(mailbox_texture, src_size, src_subrect, |
833 src_size, | 754 dst_size, out, out_color_type, callback, |
834 src_subrect, | |
835 dst_size, | |
836 out, | |
837 out_color_type, | |
838 callback, | |
839 quality); | 755 quality); |
840 gl_->DeleteTextures(1, &mailbox_texture); | 756 gl_->DeleteTextures(1, &mailbox_texture); |
841 } | 757 } |
842 | 758 |
843 void GLHelper::ReadbackTextureSync(GLuint texture, | 759 void GLHelper::ReadbackTextureSync(GLuint texture, |
844 const gfx::Rect& src_rect, | 760 const gfx::Rect& src_rect, |
845 unsigned char* out, | 761 unsigned char* out, |
846 SkColorType format) { | 762 SkColorType format) { |
847 InitCopyTextToImpl(); | 763 InitCopyTextToImpl(); |
848 copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out, format); | 764 copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out, format); |
849 } | 765 } |
850 | 766 |
851 void GLHelper::ReadbackTextureAsync( | 767 void GLHelper::ReadbackTextureAsync( |
852 GLuint texture, | 768 GLuint texture, |
853 const gfx::Size& dst_size, | 769 const gfx::Size& dst_size, |
854 unsigned char* out, | 770 unsigned char* out, |
855 SkColorType color_type, | 771 SkColorType color_type, |
856 const base::Callback<void(bool)>& callback) { | 772 const base::Callback<void(bool)>& callback) { |
857 InitCopyTextToImpl(); | 773 InitCopyTextToImpl(); |
858 copy_texture_to_impl_->ReadbackTextureAsync(texture, | 774 copy_texture_to_impl_->ReadbackTextureAsync(texture, dst_size, out, |
859 dst_size, | 775 color_type, callback); |
860 out, | |
861 color_type, | |
862 callback); | |
863 } | 776 } |
864 | 777 |
865 GLuint GLHelper::CopyTexture(GLuint texture, const gfx::Size& size) { | 778 GLuint GLHelper::CopyTexture(GLuint texture, const gfx::Size& size) { |
866 InitCopyTextToImpl(); | 779 InitCopyTextToImpl(); |
867 return copy_texture_to_impl_->CopyAndScaleTexture( | 780 return copy_texture_to_impl_->CopyAndScaleTexture( |
868 texture, size, size, false, GLHelper::SCALER_QUALITY_FAST); | 781 texture, size, size, false, GLHelper::SCALER_QUALITY_FAST); |
869 } | 782 } |
870 | 783 |
871 GLuint GLHelper::CopyAndScaleTexture(GLuint texture, | 784 GLuint GLHelper::CopyAndScaleTexture(GLuint texture, |
872 const gfx::Size& src_size, | 785 const gfx::Size& src_size, |
(...skipping 11 matching lines...) Expand all Loading... |
884 gl_->ShaderSource(shader, 1, &source, &length); | 797 gl_->ShaderSource(shader, 1, &source, &length); |
885 gl_->CompileShader(shader); | 798 gl_->CompileShader(shader); |
886 GLint compile_status = 0; | 799 GLint compile_status = 0; |
887 gl_->GetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); | 800 gl_->GetShaderiv(shader, GL_COMPILE_STATUS, &compile_status); |
888 if (!compile_status) { | 801 if (!compile_status) { |
889 GLint log_length = 0; | 802 GLint log_length = 0; |
890 gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); | 803 gl_->GetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); |
891 if (log_length) { | 804 if (log_length) { |
892 scoped_ptr<GLchar[]> log(new GLchar[log_length]); | 805 scoped_ptr<GLchar[]> log(new GLchar[log_length]); |
893 GLsizei returned_log_length = 0; | 806 GLsizei returned_log_length = 0; |
894 gl_->GetShaderInfoLog( | 807 gl_->GetShaderInfoLog(shader, log_length, &returned_log_length, |
895 shader, log_length, &returned_log_length, log.get()); | 808 log.get()); |
896 LOG(ERROR) << std::string(log.get(), returned_log_length); | 809 LOG(ERROR) << std::string(log.get(), returned_log_length); |
897 } | 810 } |
898 gl_->DeleteShader(shader); | 811 gl_->DeleteShader(shader); |
899 return 0; | 812 return 0; |
900 } | 813 } |
901 return shader; | 814 return shader; |
902 } | 815 } |
903 | 816 |
904 void GLHelper::InitCopyTextToImpl() { | 817 void GLHelper::InitCopyTextToImpl() { |
905 // Lazily initialize |copy_texture_to_impl_| | 818 // Lazily initialize |copy_texture_to_impl_| |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
985 return 0; | 898 return 0; |
986 if (sync_token.HasData()) | 899 if (sync_token.HasData()) |
987 WaitSyncToken(sync_token); | 900 WaitSyncToken(sync_token); |
988 GLuint texture = | 901 GLuint texture = |
989 gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); | 902 gl_->CreateAndConsumeTextureCHROMIUM(GL_TEXTURE_2D, mailbox.name); |
990 return texture; | 903 return texture; |
991 } | 904 } |
992 | 905 |
993 void GLHelper::ResizeTexture(GLuint texture, const gfx::Size& size) { | 906 void GLHelper::ResizeTexture(GLuint texture, const gfx::Size& size) { |
994 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 907 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
995 gl_->TexImage2D(GL_TEXTURE_2D, | 908 gl_->TexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, |
996 0, | 909 GL_RGB, GL_UNSIGNED_BYTE, NULL); |
997 GL_RGB, | |
998 size.width(), | |
999 size.height(), | |
1000 0, | |
1001 GL_RGB, | |
1002 GL_UNSIGNED_BYTE, | |
1003 NULL); | |
1004 } | 910 } |
1005 | 911 |
1006 void GLHelper::CopyTextureSubImage(GLuint texture, const gfx::Rect& rect) { | 912 void GLHelper::CopyTextureSubImage(GLuint texture, const gfx::Rect& rect) { |
1007 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 913 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
1008 gl_->CopyTexSubImage2D(GL_TEXTURE_2D, | 914 gl_->CopyTexSubImage2D(GL_TEXTURE_2D, 0, rect.x(), rect.y(), rect.x(), |
1009 0, | 915 rect.y(), rect.width(), rect.height()); |
1010 rect.x(), | |
1011 rect.y(), | |
1012 rect.x(), | |
1013 rect.y(), | |
1014 rect.width(), | |
1015 rect.height()); | |
1016 } | 916 } |
1017 | 917 |
1018 void GLHelper::CopyTextureFullImage(GLuint texture, const gfx::Size& size) { | 918 void GLHelper::CopyTextureFullImage(GLuint texture, const gfx::Size& size) { |
1019 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 919 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
1020 gl_->CopyTexImage2D( | 920 gl_->CopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, size.width(), |
1021 GL_TEXTURE_2D, 0, GL_RGB, 0, 0, size.width(), size.height(), 0); | 921 size.height(), 0); |
1022 } | 922 } |
1023 | 923 |
1024 void GLHelper::Flush() { | 924 void GLHelper::Flush() { |
1025 gl_->Flush(); | 925 gl_->Flush(); |
1026 } | 926 } |
1027 | 927 |
1028 void GLHelper::InsertOrderingBarrier() { | 928 void GLHelper::InsertOrderingBarrier() { |
1029 gl_->OrderingBarrierCHROMIUM(); | 929 gl_->OrderingBarrierCHROMIUM(); |
1030 } | 930 } |
1031 | 931 |
1032 void GLHelper::CopyTextureToImpl::ReadbackPlane( | 932 void GLHelper::CopyTextureToImpl::ReadbackPlane( |
1033 TextureFrameBufferPair* source, | 933 TextureFrameBufferPair* source, |
1034 const scoped_refptr<media::VideoFrame>& target, | 934 const scoped_refptr<media::VideoFrame>& target, |
1035 int plane, | 935 int plane, |
1036 int size_shift, | 936 int size_shift, |
1037 const gfx::Rect& paste_rect, | 937 const gfx::Rect& paste_rect, |
1038 ReadbackSwizzle swizzle, | 938 ReadbackSwizzle swizzle, |
1039 const base::Callback<void(bool)>& callback) { | 939 const base::Callback<void(bool)>& callback) { |
1040 gl_->BindFramebuffer(GL_FRAMEBUFFER, source->framebuffer()); | 940 gl_->BindFramebuffer(GL_FRAMEBUFFER, source->framebuffer()); |
1041 const size_t offset = target->stride(plane) * (paste_rect.y() >> size_shift) + | 941 const size_t offset = target->stride(plane) * (paste_rect.y() >> size_shift) + |
1042 (paste_rect.x() >> size_shift); | 942 (paste_rect.x() >> size_shift); |
1043 ReadbackAsync(source->size(), | 943 ReadbackAsync(source->size(), paste_rect.width() >> size_shift, |
1044 paste_rect.width() >> size_shift, | 944 target->stride(plane), target->data(plane) + offset, |
1045 target->stride(plane), | |
1046 target->data(plane) + offset, | |
1047 (swizzle == kSwizzleBGRA) ? GL_BGRA_EXT : GL_RGBA, | 945 (swizzle == kSwizzleBGRA) ? GL_BGRA_EXT : GL_RGBA, |
1048 GL_UNSIGNED_BYTE, | 946 GL_UNSIGNED_BYTE, 4, callback); |
1049 4, | |
1050 callback); | |
1051 } | 947 } |
1052 | 948 |
1053 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { | 949 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { |
1054 0.257f, 0.504f, 0.098f, 0.0625f}; | 950 0.257f, 0.504f, 0.098f, 0.0625f}; |
1055 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { | 951 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { |
1056 -0.148f, -0.291f, 0.439f, 0.5f}; | 952 -0.148f, -0.291f, 0.439f, 0.5f}; |
1057 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { | 953 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { |
1058 0.439f, -0.368f, -0.071f, 0.5f}; | 954 0.439f, -0.368f, -0.071f, 0.5f}; |
1059 const float GLHelper::CopyTextureToImpl::kRGBtoGrayscaleColorWeights[] = { | 955 const float GLHelper::CopyTextureToImpl::kRGBtoGrayscaleColorWeights[] = { |
1060 0.213f, 0.715f, 0.072f, 0.0f}; | 956 0.213f, 0.715f, 0.072f, 0.0f}; |
(...skipping 17 matching lines...) Expand all Loading... |
1078 scaler_(gl, | 974 scaler_(gl, |
1079 scaler_impl->CreateScaler(quality, | 975 scaler_impl->CreateScaler(quality, |
1080 src_size, | 976 src_size, |
1081 src_subrect, | 977 src_subrect, |
1082 dst_size, | 978 dst_size, |
1083 flip_vertically, | 979 flip_vertically, |
1084 false)), | 980 false)), |
1085 y_(gl, | 981 y_(gl, |
1086 scaler_impl->CreatePlanarScaler( | 982 scaler_impl->CreatePlanarScaler( |
1087 dst_size, | 983 dst_size, |
1088 gfx::Rect(0, | 984 gfx::Rect(0, 0, (dst_size.width() + 3) & ~3, dst_size.height()), |
1089 0, | |
1090 (dst_size.width() + 3) & ~3, | |
1091 dst_size.height()), | |
1092 gfx::Size((dst_size.width() + 3) / 4, dst_size.height()), | 985 gfx::Size((dst_size.width() + 3) / 4, dst_size.height()), |
1093 false, | 986 false, |
1094 (swizzle == kSwizzleBGRA), | 987 (swizzle == kSwizzleBGRA), |
1095 kRGBtoYColorWeights)), | 988 kRGBtoYColorWeights)), |
1096 u_(gl, | 989 u_(gl, |
1097 scaler_impl->CreatePlanarScaler( | 990 scaler_impl->CreatePlanarScaler( |
1098 dst_size, | 991 dst_size, |
1099 gfx::Rect(0, | 992 gfx::Rect(0, |
1100 0, | 993 0, |
1101 (dst_size.width() + 7) & ~7, | 994 (dst_size.width() + 7) & ~7, |
1102 (dst_size.height() + 1) & ~1), | 995 (dst_size.height() + 1) & ~1), |
1103 gfx::Size((dst_size.width() + 7) / 8, | 996 gfx::Size((dst_size.width() + 7) / 8, (dst_size.height() + 1) / 2), |
1104 (dst_size.height() + 1) / 2), | |
1105 false, | 997 false, |
1106 (swizzle == kSwizzleBGRA), | 998 (swizzle == kSwizzleBGRA), |
1107 kRGBtoUColorWeights)), | 999 kRGBtoUColorWeights)), |
1108 v_(gl, | 1000 v_(gl, |
1109 scaler_impl->CreatePlanarScaler( | 1001 scaler_impl->CreatePlanarScaler( |
1110 dst_size, | 1002 dst_size, |
1111 gfx::Rect(0, | 1003 gfx::Rect(0, |
1112 0, | 1004 0, |
1113 (dst_size.width() + 7) & ~7, | 1005 (dst_size.width() + 7) & ~7, |
1114 (dst_size.height() + 1) & ~1), | 1006 (dst_size.height() + 1) & ~1), |
1115 gfx::Size((dst_size.width() + 7) / 8, | 1007 gfx::Size((dst_size.width() + 7) / 8, (dst_size.height() + 1) / 2), |
1116 (dst_size.height() + 1) / 2), | |
1117 false, | 1008 false, |
1118 (swizzle == kSwizzleBGRA), | 1009 (swizzle == kSwizzleBGRA), |
1119 kRGBtoVColorWeights)) { | 1010 kRGBtoVColorWeights)) { |
1120 DCHECK(!(dst_size.width() & 1)); | 1011 DCHECK(!(dst_size.width() & 1)); |
1121 DCHECK(!(dst_size.height() & 1)); | 1012 DCHECK(!(dst_size.height() & 1)); |
1122 } | 1013 } |
1123 | 1014 |
1124 static void CallbackKeepingVideoFrameAlive( | 1015 static void CallbackKeepingVideoFrameAlive( |
1125 scoped_refptr<media::VideoFrame> video_frame, | 1016 scoped_refptr<media::VideoFrame> video_frame, |
1126 const base::Callback<void(bool)>& callback, | 1017 const base::Callback<void(bool)>& callback, |
(...skipping 24 matching lines...) Expand all Loading... |
1151 | 1042 |
1152 const gfx::Rect paste_rect(paste_location, dst_size_); | 1043 const gfx::Rect paste_rect(paste_location, dst_size_); |
1153 if (!target->visible_rect().Contains(paste_rect)) { | 1044 if (!target->visible_rect().Contains(paste_rect)) { |
1154 LOG(DFATAL) << "Paste rect not inside VideoFrame's visible rect!"; | 1045 LOG(DFATAL) << "Paste rect not inside VideoFrame's visible rect!"; |
1155 callback.Run(false); | 1046 callback.Run(false); |
1156 return; | 1047 return; |
1157 } | 1048 } |
1158 | 1049 |
1159 // Read back planes, one at a time. Keep the video frame alive while doing the | 1050 // Read back planes, one at a time. Keep the video frame alive while doing the |
1160 // readback. | 1051 // readback. |
1161 copy_impl_->ReadbackPlane(y_.texture_and_framebuffer(), | 1052 copy_impl_->ReadbackPlane(y_.texture_and_framebuffer(), target, |
1162 target, | 1053 media::VideoFrame::kYPlane, 0, paste_rect, swizzle_, |
1163 media::VideoFrame::kYPlane, | |
1164 0, | |
1165 paste_rect, | |
1166 swizzle_, | |
1167 base::Bind(&nullcallback)); | 1054 base::Bind(&nullcallback)); |
1168 copy_impl_->ReadbackPlane(u_.texture_and_framebuffer(), | 1055 copy_impl_->ReadbackPlane(u_.texture_and_framebuffer(), target, |
1169 target, | 1056 media::VideoFrame::kUPlane, 1, paste_rect, swizzle_, |
1170 media::VideoFrame::kUPlane, | |
1171 1, | |
1172 paste_rect, | |
1173 swizzle_, | |
1174 base::Bind(&nullcallback)); | 1057 base::Bind(&nullcallback)); |
1175 copy_impl_->ReadbackPlane( | 1058 copy_impl_->ReadbackPlane( |
1176 v_.texture_and_framebuffer(), | 1059 v_.texture_and_framebuffer(), target, media::VideoFrame::kVPlane, 1, |
1177 target, | 1060 paste_rect, swizzle_, |
1178 media::VideoFrame::kVPlane, | |
1179 1, | |
1180 paste_rect, | |
1181 swizzle_, | |
1182 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); | 1061 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); |
1183 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); | 1062 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); |
1184 media::LetterboxYUV(target.get(), paste_rect); | 1063 media::LetterboxYUV(target.get(), paste_rect); |
1185 } | 1064 } |
1186 | 1065 |
1187 // YUV readback constructors. Initiates the main scaler pipeline and | 1066 // YUV readback constructors. Initiates the main scaler pipeline and |
1188 // one planar scaler for each of the Y, U and V planes. | 1067 // one planar scaler for each of the Y, U and V planes. |
1189 GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV_MRT( | 1068 GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV_MRT( |
1190 GLES2Interface* gl, | 1069 GLES2Interface* gl, |
1191 CopyTextureToImpl* copy_impl, | 1070 CopyTextureToImpl* copy_impl, |
(...skipping 18 matching lines...) Expand all Loading... |
1210 false)), | 1089 false)), |
1211 pass1_shader_(scaler_impl->CreateYuvMrtShader( | 1090 pass1_shader_(scaler_impl->CreateYuvMrtShader( |
1212 dst_size, | 1091 dst_size, |
1213 gfx::Rect(0, 0, (dst_size.width() + 3) & ~3, dst_size.height()), | 1092 gfx::Rect(0, 0, (dst_size.width() + 3) & ~3, dst_size.height()), |
1214 gfx::Size((dst_size.width() + 3) / 4, dst_size.height()), | 1093 gfx::Size((dst_size.width() + 3) / 4, dst_size.height()), |
1215 flip_vertically, | 1094 flip_vertically, |
1216 (swizzle == kSwizzleBGRA), | 1095 (swizzle == kSwizzleBGRA), |
1217 GLHelperScaling::SHADER_YUV_MRT_PASS1)), | 1096 GLHelperScaling::SHADER_YUV_MRT_PASS1)), |
1218 pass2_shader_(scaler_impl->CreateYuvMrtShader( | 1097 pass2_shader_(scaler_impl->CreateYuvMrtShader( |
1219 gfx::Size((dst_size.width() + 3) / 4, dst_size.height()), | 1098 gfx::Size((dst_size.width() + 3) / 4, dst_size.height()), |
1220 gfx::Rect(0, | 1099 gfx::Rect(0, 0, (dst_size.width() + 7) / 8 * 2, dst_size.height()), |
1221 0, | 1100 gfx::Size((dst_size.width() + 7) / 8, (dst_size.height() + 1) / 2), |
1222 (dst_size.width() + 7) / 8 * 2, | |
1223 dst_size.height()), | |
1224 gfx::Size((dst_size.width() + 7) / 8, | |
1225 (dst_size.height() + 1) / 2), | |
1226 false, | 1101 false, |
1227 (swizzle == kSwizzleBGRA), | 1102 (swizzle == kSwizzleBGRA), |
1228 GLHelperScaling::SHADER_YUV_MRT_PASS2)), | 1103 GLHelperScaling::SHADER_YUV_MRT_PASS2)), |
1229 y_(gl, gfx::Size((dst_size.width() + 3) / 4, dst_size.height())), | 1104 y_(gl, gfx::Size((dst_size.width() + 3) / 4, dst_size.height())), |
1230 uv_(gl), | 1105 uv_(gl), |
1231 u_(gl, | 1106 u_(gl, |
1232 gfx::Size((dst_size.width() + 7) / 8, | 1107 gfx::Size((dst_size.width() + 7) / 8, (dst_size.height() + 1) / 2)), |
1233 (dst_size.height() + 1) / 2)), | |
1234 v_(gl, | 1108 v_(gl, |
1235 gfx::Size((dst_size.width() + 7) / 8, | 1109 gfx::Size((dst_size.width() + 7) / 8, (dst_size.height() + 1) / 2)) { |
1236 (dst_size.height() + 1) / 2)) { | |
1237 DCHECK(!(dst_size.width() & 1)); | 1110 DCHECK(!(dst_size.width() & 1)); |
1238 DCHECK(!(dst_size.height() & 1)); | 1111 DCHECK(!(dst_size.height() & 1)); |
1239 | 1112 |
1240 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, uv_); | 1113 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl, uv_); |
1241 gl->TexImage2D(GL_TEXTURE_2D, | 1114 gl->TexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (dst_size.width() + 3) / 4, |
1242 0, | 1115 dst_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
1243 GL_RGBA, | |
1244 (dst_size.width() + 3) / 4, | |
1245 dst_size.height(), | |
1246 0, | |
1247 GL_RGBA, | |
1248 GL_UNSIGNED_BYTE, | |
1249 NULL); | |
1250 } | 1116 } |
1251 | 1117 |
1252 void GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV( | 1118 void GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV( |
1253 const gpu::Mailbox& mailbox, | 1119 const gpu::Mailbox& mailbox, |
1254 const gpu::SyncToken& sync_token, | 1120 const gpu::SyncToken& sync_token, |
1255 const scoped_refptr<media::VideoFrame>& target, | 1121 const scoped_refptr<media::VideoFrame>& target, |
1256 const gfx::Point& paste_location, | 1122 const gfx::Point& paste_location, |
1257 const base::Callback<void(bool)>& callback) { | 1123 const base::Callback<void(bool)>& callback) { |
1258 DCHECK(!(paste_location.x() & 1)); | 1124 DCHECK(!(paste_location.x() & 1)); |
1259 DCHECK(!(paste_location.y() & 1)); | 1125 DCHECK(!(paste_location.y() & 1)); |
(...skipping 26 matching lines...) Expand all Loading... |
1286 pass2_shader_->Execute(uv_, outputs); | 1152 pass2_shader_->Execute(uv_, outputs); |
1287 | 1153 |
1288 const gfx::Rect paste_rect(paste_location, dst_size_); | 1154 const gfx::Rect paste_rect(paste_location, dst_size_); |
1289 if (!target->visible_rect().Contains(paste_rect)) { | 1155 if (!target->visible_rect().Contains(paste_rect)) { |
1290 LOG(DFATAL) << "Paste rect not inside VideoFrame's visible rect!"; | 1156 LOG(DFATAL) << "Paste rect not inside VideoFrame's visible rect!"; |
1291 callback.Run(false); | 1157 callback.Run(false); |
1292 return; | 1158 return; |
1293 } | 1159 } |
1294 | 1160 |
1295 // Read back planes, one at a time. | 1161 // Read back planes, one at a time. |
1296 copy_impl_->ReadbackPlane(&y_, | 1162 copy_impl_->ReadbackPlane(&y_, target, media::VideoFrame::kYPlane, 0, |
1297 target, | 1163 paste_rect, swizzle_, base::Bind(&nullcallback)); |
1298 media::VideoFrame::kYPlane, | 1164 copy_impl_->ReadbackPlane(&u_, target, media::VideoFrame::kUPlane, 1, |
1299 0, | 1165 paste_rect, swizzle_, base::Bind(&nullcallback)); |
1300 paste_rect, | |
1301 swizzle_, | |
1302 base::Bind(&nullcallback)); | |
1303 copy_impl_->ReadbackPlane(&u_, | |
1304 target, | |
1305 media::VideoFrame::kUPlane, | |
1306 1, | |
1307 paste_rect, | |
1308 swizzle_, | |
1309 base::Bind(&nullcallback)); | |
1310 copy_impl_->ReadbackPlane( | 1166 copy_impl_->ReadbackPlane( |
1311 &v_, | 1167 &v_, target, media::VideoFrame::kVPlane, 1, paste_rect, swizzle_, |
1312 target, | |
1313 media::VideoFrame::kVPlane, | |
1314 1, | |
1315 paste_rect, | |
1316 swizzle_, | |
1317 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); | 1168 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); |
1318 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); | 1169 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); |
1319 media::LetterboxYUV(target.get(), paste_rect); | 1170 media::LetterboxYUV(target.get(), paste_rect); |
1320 } | 1171 } |
1321 | 1172 |
1322 bool GLHelper::IsReadbackConfigSupported(SkColorType color_type) { | 1173 bool GLHelper::IsReadbackConfigSupported(SkColorType color_type) { |
1323 DCHECK(readback_support_.get()); | 1174 DCHECK(readback_support_.get()); |
1324 GLenum format, type; | 1175 GLenum format, type; |
1325 size_t bytes_per_pixel; | 1176 size_t bytes_per_pixel; |
1326 FormatSupport support = readback_support_->GetReadbackConfig( | 1177 FormatSupport support = readback_support_->GetReadbackConfig( |
1327 color_type, false, &format, &type, &bytes_per_pixel); | 1178 color_type, false, &format, &type, &bytes_per_pixel); |
1328 | 1179 |
1329 return (support == GLHelperReadbackSupport::SUPPORTED); | 1180 return (support == GLHelperReadbackSupport::SUPPORTED); |
1330 } | 1181 } |
1331 | 1182 |
1332 ReadbackYUVInterface* GLHelper::CopyTextureToImpl::CreateReadbackPipelineYUV( | 1183 ReadbackYUVInterface* GLHelper::CopyTextureToImpl::CreateReadbackPipelineYUV( |
1333 GLHelper::ScalerQuality quality, | 1184 GLHelper::ScalerQuality quality, |
1334 const gfx::Size& src_size, | 1185 const gfx::Size& src_size, |
1335 const gfx::Rect& src_subrect, | 1186 const gfx::Rect& src_subrect, |
1336 const gfx::Size& dst_size, | 1187 const gfx::Size& dst_size, |
1337 bool flip_vertically, | 1188 bool flip_vertically, |
1338 bool use_mrt) { | 1189 bool use_mrt) { |
1339 helper_->InitScalerImpl(); | 1190 helper_->InitScalerImpl(); |
1340 // Just query if the best readback configuration needs a swizzle In | 1191 // Just query if the best readback configuration needs a swizzle In |
1341 // ReadbackPlane() we will choose GL_RGBA/GL_BGRA_EXT based on swizzle | 1192 // ReadbackPlane() we will choose GL_RGBA/GL_BGRA_EXT based on swizzle |
1342 GLenum format, type; | 1193 GLenum format, type; |
1343 size_t bytes_per_pixel; | 1194 size_t bytes_per_pixel; |
1344 FormatSupport supported = GetReadbackConfig( | 1195 FormatSupport supported = GetReadbackConfig(kRGBA_8888_SkColorType, true, |
1345 kRGBA_8888_SkColorType, true, &format, &type, &bytes_per_pixel); | 1196 &format, &type, &bytes_per_pixel); |
1346 DCHECK((format == GL_RGBA || format == GL_BGRA_EXT) && | 1197 DCHECK((format == GL_RGBA || format == GL_BGRA_EXT) && |
1347 type == GL_UNSIGNED_BYTE); | 1198 type == GL_UNSIGNED_BYTE); |
1348 | 1199 |
1349 ReadbackSwizzle swizzle = kSwizzleNone; | 1200 ReadbackSwizzle swizzle = kSwizzleNone; |
1350 if (supported == GLHelperReadbackSupport::SWIZZLE) | 1201 if (supported == GLHelperReadbackSupport::SWIZZLE) |
1351 swizzle = kSwizzleBGRA; | 1202 swizzle = kSwizzleBGRA; |
1352 | 1203 |
1353 if (max_draw_buffers_ >= 2 && use_mrt) { | 1204 if (max_draw_buffers_ >= 2 && use_mrt) { |
1354 return new ReadbackYUV_MRT(gl_, | 1205 return new ReadbackYUV_MRT(gl_, this, helper_->scaler_impl_.get(), quality, |
1355 this, | 1206 src_size, src_subrect, dst_size, flip_vertically, |
1356 helper_->scaler_impl_.get(), | |
1357 quality, | |
1358 src_size, | |
1359 src_subrect, | |
1360 dst_size, | |
1361 flip_vertically, | |
1362 swizzle); | 1207 swizzle); |
1363 } | 1208 } |
1364 return new ReadbackYUVImpl(gl_, | 1209 return new ReadbackYUVImpl(gl_, this, helper_->scaler_impl_.get(), quality, |
1365 this, | 1210 src_size, src_subrect, dst_size, flip_vertically, |
1366 helper_->scaler_impl_.get(), | |
1367 quality, | |
1368 src_size, | |
1369 src_subrect, | |
1370 dst_size, | |
1371 flip_vertically, | |
1372 swizzle); | 1211 swizzle); |
1373 } | 1212 } |
1374 | 1213 |
1375 ReadbackYUVInterface* GLHelper::CreateReadbackPipelineYUV( | 1214 ReadbackYUVInterface* GLHelper::CreateReadbackPipelineYUV( |
1376 ScalerQuality quality, | 1215 ScalerQuality quality, |
1377 const gfx::Size& src_size, | 1216 const gfx::Size& src_size, |
1378 const gfx::Rect& src_subrect, | 1217 const gfx::Rect& src_subrect, |
1379 const gfx::Size& dst_size, | 1218 const gfx::Size& dst_size, |
1380 bool flip_vertically, | 1219 bool flip_vertically, |
1381 bool use_mrt) { | 1220 bool use_mrt) { |
1382 InitCopyTextToImpl(); | 1221 InitCopyTextToImpl(); |
1383 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality, | 1222 return copy_texture_to_impl_->CreateReadbackPipelineYUV( |
1384 src_size, | 1223 quality, src_size, src_subrect, dst_size, flip_vertically, use_mrt); |
1385 src_subrect, | |
1386 dst_size, | |
1387 flip_vertically, | |
1388 use_mrt); | |
1389 } | 1224 } |
1390 | 1225 |
1391 } // namespace content | 1226 } // namespace content |
OLD | NEW |