Chromium Code Reviews| 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 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 unsigned char* out, | 155 unsigned char* out, |
| 156 SkColorType color_type, | 156 SkColorType color_type, |
| 157 const base::Callback<void(bool)>& callback); | 157 const base::Callback<void(bool)>& callback); |
| 158 | 158 |
| 159 // Reads back bytes from the currently bound frame buffer. | 159 // Reads back bytes from the currently bound frame buffer. |
| 160 // Note that dst_size is specified in bytes, not pixels. | 160 // Note that dst_size is specified in bytes, not pixels. |
| 161 void ReadbackAsync(const gfx::Size& dst_size, | 161 void ReadbackAsync(const gfx::Size& dst_size, |
| 162 int32 bytes_per_row, // generally dst_size.width() * 4 | 162 int32 bytes_per_row, // generally dst_size.width() * 4 |
| 163 int32 row_stride_bytes, // generally dst_size.width() * 4 | 163 int32 row_stride_bytes, // generally dst_size.width() * 4 |
| 164 unsigned char* out, | 164 unsigned char* out, |
| 165 const SkColorType color_type, | 165 GLenum format, |
| 166 ReadbackSwizzle swizzle, | 166 GLenum type, |
| 167 int32 bytes_per_pixel, | |
| 167 const base::Callback<void(bool)>& callback); | 168 const base::Callback<void(bool)>& callback); |
| 168 | 169 |
| 169 void ReadbackPlane(TextureFrameBufferPair* source, | 170 void ReadbackPlane(TextureFrameBufferPair* source, |
| 170 const scoped_refptr<media::VideoFrame>& target, | 171 const scoped_refptr<media::VideoFrame>& target, |
| 171 int plane, | 172 int plane, |
| 172 int size_shift, | 173 int size_shift, |
| 173 const gfx::Rect& dst_subrect, | 174 const gfx::Rect& dst_subrect, |
| 174 ReadbackSwizzle swizzle, | |
| 175 const base::Callback<void(bool)>& callback); | 175 const base::Callback<void(bool)>& callback); |
| 176 | 176 |
| 177 GLuint CopyAndScaleTexture(GLuint texture, | 177 GLuint CopyAndScaleTexture(GLuint texture, |
| 178 const gfx::Size& src_size, | 178 const gfx::Size& src_size, |
| 179 const gfx::Size& dst_size, | 179 const gfx::Size& dst_size, |
| 180 bool vertically_flip_texture, | 180 bool vertically_flip_texture, |
| 181 GLHelper::ScalerQuality quality); | 181 GLHelper::ScalerQuality quality); |
| 182 | 182 |
| 183 ReadbackYUVInterface* CreateReadbackPipelineYUV( | 183 ReadbackYUVInterface* CreateReadbackPipelineYUV( |
| 184 GLHelper::ScalerQuality quality, | 184 GLHelper::ScalerQuality quality, |
| 185 const gfx::Size& src_size, | 185 const gfx::Size& src_size, |
| 186 const gfx::Rect& src_subrect, | 186 const gfx::Rect& src_subrect, |
| 187 const gfx::Size& dst_size, | 187 const gfx::Size& dst_size, |
| 188 const gfx::Rect& dst_subrect, | 188 const gfx::Rect& dst_subrect, |
| 189 bool flip_vertically, | 189 bool flip_vertically, |
| 190 bool use_mrt); | 190 bool use_mrt); |
| 191 | 191 |
| 192 // Returns the maximum number of draw buffers available, | 192 // Returns the maximum number of draw buffers available, |
| 193 // 0 if GL_EXT_draw_buffers is not available. | 193 // 0 if GL_EXT_draw_buffers is not available. |
| 194 GLint MaxDrawBuffers() const { return max_draw_buffers_; } | 194 GLint MaxDrawBuffers() const { return max_draw_buffers_; } |
| 195 | 195 |
| 196 bool IsReadbackConfigSupported(SkColorType color_type); | 196 FormatSupport ReadbackConfig(SkColorType color_type, |
|
piman
2014/07/22 19:57:55
nit: naming... GetReadbackConfig ?
robert.bradford
2014/07/23 16:58:45
Done.
| |
| 197 | 197 const bool& can_swizzle, |
|
piman
2014/07/22 19:57:54
use bool instead of const bool&
robert.bradford
2014/07/23 16:58:44
Done.
| |
| 198 GLint& format, | |
|
piman
2014/07/22 19:57:55
non-const references are forbidden by style guide.
robert.bradford
2014/07/23 16:58:44
Done.
| |
| 199 GLint& type, | |
|
piman
2014/07/22 19:57:54
GLenum
robert.bradford
2014/07/23 16:58:45
Done.
| |
| 200 int32& bytes_per_pixel); | |
|
piman
2014/07/22 19:57:55
nit: size_t instead of int32.
robert.bradford
2014/07/23 16:58:45
Done.
| |
| 198 private: | 201 private: |
| 199 // A single request to CropScaleReadbackAndCleanTexture. | 202 // A single request to CropScaleReadbackAndCleanTexture. |
| 200 // The main thread can cancel the request, before it's handled by the helper | 203 // The main thread can cancel the request, before it's handled by the helper |
| 201 // thread, by resetting the texture and pixels fields. Alternatively, the | 204 // thread, by resetting the texture and pixels fields. Alternatively, the |
| 202 // thread marks that it handles the request by resetting the pixels field | 205 // thread marks that it handles the request by resetting the pixels field |
| 203 // (meaning it guarantees that the callback with be called). | 206 // (meaning it guarantees that the callback with be called). |
| 204 // In either case, the callback must be called exactly once, and the texture | 207 // In either case, the callback must be called exactly once, and the texture |
| 205 // must be deleted by the main thread gl. | 208 // must be deleted by the main thread gl. |
| 206 struct Request { | 209 struct Request { |
| 207 Request(const gfx::Size& size_, | 210 Request(const gfx::Size& size_, |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 357 | 360 |
| 358 GLuint GLHelper::CopyTextureToImpl::ScaleTexture( | 361 GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
| 359 GLuint src_texture, | 362 GLuint src_texture, |
| 360 const gfx::Size& src_size, | 363 const gfx::Size& src_size, |
| 361 const gfx::Rect& src_subrect, | 364 const gfx::Rect& src_subrect, |
| 362 const gfx::Size& dst_size, | 365 const gfx::Size& dst_size, |
| 363 bool vertically_flip_texture, | 366 bool vertically_flip_texture, |
| 364 bool swizzle, | 367 bool swizzle, |
| 365 SkColorType color_type, | 368 SkColorType color_type, |
| 366 GLHelper::ScalerQuality quality) { | 369 GLHelper::ScalerQuality quality) { |
| 367 if (!IsReadbackConfigSupported(color_type)) | |
| 368 return 0; | |
| 369 | |
| 370 scoped_ptr<ScalerInterface> scaler( | |
| 371 helper_->CreateScaler(quality, | |
| 372 src_size, | |
| 373 src_subrect, | |
| 374 dst_size, | |
| 375 vertically_flip_texture, | |
| 376 swizzle)); | |
| 377 GLuint dst_texture = 0u; | 370 GLuint dst_texture = 0u; |
| 378 // Start with ARGB8888 params as any other format which is not | |
| 379 // supported is already asserted above. | |
| 380 GLenum format = GL_RGBA , type = GL_UNSIGNED_BYTE; | |
| 381 gl_->GenTextures(1, &dst_texture); | 371 gl_->GenTextures(1, &dst_texture); |
| 382 { | 372 { |
| 373 GLenum format = GL_RGBA , type = GL_UNSIGNED_BYTE; | |
|
piman
2014/07/22 19:57:54
nit: no space before ,
robert.bradford
2014/07/23 16:58:44
Done.
| |
| 383 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); | 374 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
| 384 switch (color_type) { | 375 switch (color_type) { |
| 385 case kN32_SkColorType: | 376 // For creating the scaled texture the layout should be GL_RGBA |
| 377 // independent of any desired readback layout | |
|
piman
2014/07/22 19:57:55
I don't understand this comment. Does it only appl
robert.bradford
2014/07/23 16:58:45
This is the initialisation of the texture for the
| |
| 378 case kRGBA_8888_SkColorType: | |
| 379 case kBGRA_8888_SkColorType: | |
| 386 // Do nothing params already set. | 380 // Do nothing params already set. |
| 387 break; | 381 break; |
| 388 case kRGB_565_SkColorType: | 382 case kRGB_565_SkColorType: |
| 389 format = GL_RGB; | 383 format = GL_RGB; |
| 390 type = GL_UNSIGNED_SHORT_5_6_5; | 384 type = GL_UNSIGNED_SHORT_5_6_5; |
| 391 break; | 385 break; |
| 392 default: | 386 default: |
| 393 NOTREACHED(); | 387 return 0; |
| 394 break; | |
| 395 } | 388 } |
| 396 gl_->TexImage2D(GL_TEXTURE_2D, | 389 gl_->TexImage2D(GL_TEXTURE_2D, |
| 397 0, | 390 0, |
| 398 format, | 391 format, |
| 399 dst_size.width(), | 392 dst_size.width(), |
| 400 dst_size.height(), | 393 dst_size.height(), |
| 401 0, | 394 0, |
| 402 format, | 395 format, |
| 403 type, | 396 type, |
| 404 NULL); | 397 NULL); |
| 405 } | 398 } |
| 399 scoped_ptr<ScalerInterface> scaler( | |
| 400 helper_->CreateScaler(quality, | |
| 401 src_size, | |
| 402 src_subrect, | |
| 403 dst_size, | |
| 404 vertically_flip_texture, | |
| 405 swizzle)); | |
| 406 scaler->Scale(src_texture, dst_texture); | 406 scaler->Scale(src_texture, dst_texture); |
| 407 return dst_texture; | 407 return dst_texture; |
| 408 } | 408 } |
| 409 | 409 |
| 410 void GLHelper::CopyTextureToImpl::ReadbackAsync( | 410 void GLHelper::CopyTextureToImpl::ReadbackAsync( |
| 411 const gfx::Size& dst_size, | 411 const gfx::Size& dst_size, |
| 412 int32 bytes_per_row, | 412 int32 bytes_per_row, |
| 413 int32 row_stride_bytes, | 413 int32 row_stride_bytes, |
| 414 unsigned char* out, | 414 unsigned char* out, |
| 415 const SkColorType color_type, | 415 GLenum format, |
| 416 ReadbackSwizzle swizzle, | 416 GLenum type, |
| 417 int32 bytes_per_pixel, | |
|
piman
2014/07/22 19:57:54
size_t
robert.bradford
2014/07/23 16:58:44
Done.
| |
| 417 const base::Callback<void(bool)>& callback) { | 418 const base::Callback<void(bool)>& callback) { |
| 418 if (!IsReadbackConfigSupported(color_type)) { | |
| 419 callback.Run(false); | |
| 420 return; | |
| 421 } | |
| 422 Request* request = | 419 Request* request = |
| 423 new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback); | 420 new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback); |
| 424 request_queue_.push(request); | 421 request_queue_.push(request); |
| 425 request->buffer = 0u; | 422 request->buffer = 0u; |
| 426 // Start with ARGB8888 params as any other format which is not | |
| 427 // supported is already asserted above. | |
| 428 GLenum format = GL_RGBA, type = GL_UNSIGNED_BYTE; | |
| 429 int bytes_per_pixel = 4; | |
| 430 | 423 |
| 431 switch (color_type) { | |
| 432 case kN32_SkColorType: | |
| 433 if (swizzle == kSwizzleBGRA) | |
| 434 format = GL_BGRA_EXT; | |
| 435 break; | |
| 436 case kRGB_565_SkColorType: | |
| 437 format = GL_RGB; | |
| 438 type = GL_UNSIGNED_SHORT_5_6_5; | |
| 439 bytes_per_pixel = 2; | |
| 440 break; | |
| 441 default: | |
| 442 NOTREACHED(); | |
| 443 break; | |
| 444 } | |
| 445 gl_->GenBuffers(1, &request->buffer); | 424 gl_->GenBuffers(1, &request->buffer); |
| 446 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); | 425 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
| 447 gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 426 gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| 448 bytes_per_pixel * dst_size.GetArea(), | 427 bytes_per_pixel * dst_size.GetArea(), |
| 449 NULL, | 428 NULL, |
| 450 GL_STREAM_READ); | 429 GL_STREAM_READ); |
| 451 | 430 |
| 452 request->query = 0u; | 431 request->query = 0u; |
| 453 gl_->GenQueriesEXT(1, &request->query); | 432 gl_->GenQueriesEXT(1, &request->query); |
| 454 gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query); | 433 gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 468 } | 447 } |
| 469 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( | 448 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
| 470 GLuint src_texture, | 449 GLuint src_texture, |
| 471 const gfx::Size& src_size, | 450 const gfx::Size& src_size, |
| 472 const gfx::Rect& src_subrect, | 451 const gfx::Rect& src_subrect, |
| 473 const gfx::Size& dst_size, | 452 const gfx::Size& dst_size, |
| 474 unsigned char* out, | 453 unsigned char* out, |
| 475 const SkColorType color_type, | 454 const SkColorType color_type, |
| 476 const base::Callback<void(bool)>& callback, | 455 const base::Callback<void(bool)>& callback, |
| 477 GLHelper::ScalerQuality quality) { | 456 GLHelper::ScalerQuality quality) { |
| 478 if (!IsReadbackConfigSupported(color_type)) { | 457 GLint format, type, bytes_per_pixel; |
| 458 FormatSupport supported = ReadbackConfig(color_type, | |
| 459 true, | |
| 460 format, | |
| 461 type, | |
| 462 bytes_per_pixel); | |
| 463 if (supported == kReadbackNotSupported) { | |
| 479 callback.Run(false); | 464 callback.Run(false); |
| 480 return; | 465 return; |
| 481 } | 466 } |
| 467 | |
| 482 GLuint texture = ScaleTexture(src_texture, | 468 GLuint texture = ScaleTexture(src_texture, |
| 483 src_size, | 469 src_size, |
| 484 src_subrect, | 470 src_subrect, |
| 485 dst_size, | 471 dst_size, |
| 486 true, | 472 true, |
| 487 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 473 (supported == kReadbackSwizzle ? true : false), |
|
piman
2014/07/22 19:57:55
? true : false unneeded. (supported == kReadbackSw
robert.bradford
2014/07/23 16:58:45
Done.
| |
| 488 true, | |
| 489 #else | |
| 490 false, | |
| 491 #endif | |
| 492 color_type, | 474 color_type, |
| 493 quality); | 475 quality); |
| 494 DCHECK(texture); | 476 DCHECK(texture); |
| 495 ScopedFramebuffer dst_framebuffer(gl_); | 477 ScopedFramebuffer dst_framebuffer(gl_); |
| 496 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, | 478 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| 497 dst_framebuffer); | 479 dst_framebuffer); |
| 498 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 480 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 499 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, | 481 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, |
| 500 GL_COLOR_ATTACHMENT0, | 482 GL_COLOR_ATTACHMENT0, |
| 501 GL_TEXTURE_2D, | 483 GL_TEXTURE_2D, |
| 502 texture, | 484 texture, |
| 503 0); | 485 0); |
| 504 int bytes_per_pixel = 4; | |
| 505 switch (color_type) { | |
| 506 case kN32_SkColorType: | |
| 507 // Do nothing params already set. | |
| 508 break; | |
| 509 case kRGB_565_SkColorType: | |
| 510 bytes_per_pixel = 2; | |
| 511 break; | |
| 512 default: | |
| 513 NOTREACHED(); | |
| 514 break; | |
| 515 } | |
| 516 ReadbackAsync(dst_size, | 486 ReadbackAsync(dst_size, |
| 517 dst_size.width() * bytes_per_pixel, | 487 dst_size.width() * bytes_per_pixel, |
| 518 dst_size.width() * bytes_per_pixel, | 488 dst_size.width() * bytes_per_pixel, |
| 519 out, | 489 out, |
| 520 color_type, | 490 format, |
| 521 kSwizzleNone, | 491 type, |
| 492 bytes_per_pixel, | |
| 522 callback); | 493 callback); |
| 523 gl_->DeleteTextures(1, &texture); | 494 gl_->DeleteTextures(1, &texture); |
| 524 } | 495 } |
| 525 | 496 |
| 526 void GLHelper::CopyTextureToImpl::ReadbackTextureSync( | 497 void GLHelper::CopyTextureToImpl::ReadbackTextureSync( |
| 527 GLuint texture, | 498 GLuint texture, |
| 528 const gfx::Rect& src_rect, | 499 const gfx::Rect& src_rect, |
| 529 unsigned char* out, | 500 unsigned char* out, |
| 530 SkColorType color_type) { | 501 SkColorType color_type) { |
| 531 if (!IsReadbackConfigSupported(color_type)) | 502 GLint format, type, bytes_per_pixel; |
| 503 FormatSupport supported = ReadbackConfig(color_type, | |
| 504 false, | |
| 505 format, | |
| 506 type, | |
| 507 bytes_per_pixel); | |
| 508 if (supported == kReadbackNotSupported) { | |
| 532 return; | 509 return; |
| 510 } | |
| 533 | 511 |
| 534 ScopedFramebuffer dst_framebuffer(gl_); | 512 ScopedFramebuffer dst_framebuffer(gl_); |
| 535 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, | 513 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| 536 dst_framebuffer); | 514 dst_framebuffer); |
| 537 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 515 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 538 gl_->FramebufferTexture2D( | 516 gl_->FramebufferTexture2D( |
| 539 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); | 517 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); |
| 540 GLenum format = | |
| 541 (color_type == kRGB_565_SkColorType) ? GL_RGB : GL_RGBA; | |
| 542 GLenum type = (color_type == kRGB_565_SkColorType) | |
| 543 ? GL_UNSIGNED_SHORT_5_6_5 | |
| 544 : GL_UNSIGNED_BYTE; | |
| 545 gl_->ReadPixels(src_rect.x(), | 518 gl_->ReadPixels(src_rect.x(), |
| 546 src_rect.y(), | 519 src_rect.y(), |
| 547 src_rect.width(), | 520 src_rect.width(), |
| 548 src_rect.height(), | 521 src_rect.height(), |
| 549 format, | 522 format, |
| 550 type, | 523 type, |
| 551 out); | 524 out); |
| 552 } | 525 } |
| 553 | 526 |
| 554 void GLHelper::CopyTextureToImpl::ReadbackTextureAsync( | 527 void GLHelper::CopyTextureToImpl::ReadbackTextureAsync( |
| 555 GLuint texture, | 528 GLuint texture, |
| 556 const gfx::Size& dst_size, | 529 const gfx::Size& dst_size, |
| 557 unsigned char* out, | 530 unsigned char* out, |
| 558 SkColorType color_type, | 531 SkColorType color_type, |
| 559 const base::Callback<void(bool)>& callback) { | 532 const base::Callback<void(bool)>& callback) { |
| 560 if (!IsReadbackConfigSupported(color_type)) | 533 GLint format, type, bytes_per_pixel; |
| 534 FormatSupport supported = ReadbackConfig(color_type, | |
| 535 false, | |
| 536 format, | |
| 537 type, | |
| 538 bytes_per_pixel); | |
| 539 if (supported == kReadbackNotSupported) { | |
| 540 callback.Run(false); | |
| 561 return; | 541 return; |
| 542 } | |
| 562 | 543 |
| 563 ScopedFramebuffer dst_framebuffer(gl_); | 544 ScopedFramebuffer dst_framebuffer(gl_); |
| 564 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, | 545 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| 565 dst_framebuffer); | 546 dst_framebuffer); |
| 566 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 547 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 567 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, | 548 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, |
| 568 GL_COLOR_ATTACHMENT0, | 549 GL_COLOR_ATTACHMENT0, |
| 569 GL_TEXTURE_2D, | 550 GL_TEXTURE_2D, |
| 570 texture, | 551 texture, |
| 571 0); | 552 0); |
| 572 int bytes_per_pixel = (color_type == kRGB_565_SkColorType) ? 2 : 4; | |
| 573 ReadbackAsync(dst_size, | 553 ReadbackAsync(dst_size, |
| 574 dst_size.width() * bytes_per_pixel, | 554 dst_size.width() * bytes_per_pixel, |
| 575 dst_size.width() * bytes_per_pixel, | 555 dst_size.width() * bytes_per_pixel, |
| 576 out, | 556 out, |
| 577 color_type, | 557 format, |
| 578 kSwizzleNone, | 558 type, |
| 559 bytes_per_pixel, | |
| 579 callback); | 560 callback); |
| 580 } | 561 } |
| 581 | 562 |
| 582 GLuint GLHelper::CopyTextureToImpl::CopyAndScaleTexture( | 563 GLuint GLHelper::CopyTextureToImpl::CopyAndScaleTexture( |
| 583 GLuint src_texture, | 564 GLuint src_texture, |
| 584 const gfx::Size& src_size, | 565 const gfx::Size& src_size, |
| 585 const gfx::Size& dst_size, | 566 const gfx::Size& dst_size, |
| 586 bool vertically_flip_texture, | 567 bool vertically_flip_texture, |
| 587 GLHelper::ScalerQuality quality) { | 568 GLHelper::ScalerQuality quality) { |
| 588 return ScaleTexture(src_texture, | 569 return ScaleTexture(src_texture, |
| 589 src_size, | 570 src_size, |
| 590 gfx::Rect(src_size), | 571 gfx::Rect(src_size), |
| 591 dst_size, | 572 dst_size, |
| 592 vertically_flip_texture, | 573 vertically_flip_texture, |
| 593 false, | 574 false, |
| 594 kN32_SkColorType, | 575 kRGBA_8888_SkColorType, // GL_RGBA |
|
piman
2014/07/22 19:57:54
nit: 2 spaces before //
robert.bradford
2014/07/23 16:58:45
Done.
| |
| 595 quality); | 576 quality); |
| 596 } | 577 } |
| 597 | 578 |
| 598 bool GLHelper::CopyTextureToImpl::IsReadbackConfigSupported( | |
| 599 SkColorType color_type) { | |
| 600 if (!helper_) { | |
| 601 DCHECK(helper_); | |
| 602 return false; | |
| 603 } | |
| 604 return helper_->IsReadbackConfigSupported(color_type); | |
| 605 } | |
| 606 | |
| 607 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request, | 579 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request, |
| 608 int bytes_per_pixel) { | 580 int bytes_per_pixel) { |
| 609 TRACE_EVENT0("mirror", | 581 TRACE_EVENT0("mirror", |
| 610 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); | 582 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); |
| 611 finished_request->done = true; | 583 finished_request->done = true; |
| 612 | 584 |
| 613 // We process transfer requests in the order they were received, regardless | 585 // We process transfer requests in the order they were received, regardless |
| 614 // of the order we get the callbacks in. | 586 // of the order we get the callbacks in. |
| 615 while (!request_queue_.empty()) { | 587 while (!request_queue_.empty()) { |
| 616 Request* request = request_queue_.front(); | 588 Request* request = request_queue_.front(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 662 delete request; | 634 delete request; |
| 663 } | 635 } |
| 664 | 636 |
| 665 void GLHelper::CopyTextureToImpl::CancelRequests() { | 637 void GLHelper::CopyTextureToImpl::CancelRequests() { |
| 666 while (!request_queue_.empty()) { | 638 while (!request_queue_.empty()) { |
| 667 Request* request = request_queue_.front(); | 639 Request* request = request_queue_.front(); |
| 668 FinishRequest(request, false); | 640 FinishRequest(request, false); |
| 669 } | 641 } |
| 670 } | 642 } |
| 671 | 643 |
| 644 | |
| 645 FormatSupport GLHelper::CopyTextureToImpl::ReadbackConfig( | |
| 646 SkColorType color_type, | |
| 647 const bool& can_swizzle, | |
| 648 GLint& format, | |
| 649 GLint& type, | |
| 650 int32& bytes_per_pixel) { | |
| 651 return helper_->readback_support_->ReadbackConfig( | |
| 652 color_type, | |
| 653 can_swizzle, | |
| 654 format, | |
| 655 type, | |
| 656 bytes_per_pixel); | |
| 657 } | |
| 658 | |
| 672 GLHelper::GLHelper(GLES2Interface* gl, gpu::ContextSupport* context_support) | 659 GLHelper::GLHelper(GLES2Interface* gl, gpu::ContextSupport* context_support) |
| 673 : gl_(gl), | 660 : gl_(gl), |
| 674 context_support_(context_support), | 661 context_support_(context_support), |
| 675 readback_support_(new GLHelperReadbackSupport(gl)) {} | 662 readback_support_(new GLHelperReadbackSupport(gl)) {} |
| 676 | 663 |
| 677 GLHelper::~GLHelper() {} | 664 GLHelper::~GLHelper() {} |
| 678 | 665 |
| 679 void GLHelper::CropScaleReadbackAndCleanTexture( | 666 void GLHelper::CropScaleReadbackAndCleanTexture( |
| 680 GLuint src_texture, | 667 GLuint src_texture, |
| 681 const gfx::Size& src_size, | 668 const gfx::Size& src_size, |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 899 void GLHelper::Flush() { | 886 void GLHelper::Flush() { |
| 900 gl_->Flush(); | 887 gl_->Flush(); |
| 901 } | 888 } |
| 902 | 889 |
| 903 void GLHelper::CopyTextureToImpl::ReadbackPlane( | 890 void GLHelper::CopyTextureToImpl::ReadbackPlane( |
| 904 TextureFrameBufferPair* source, | 891 TextureFrameBufferPair* source, |
| 905 const scoped_refptr<media::VideoFrame>& target, | 892 const scoped_refptr<media::VideoFrame>& target, |
| 906 int plane, | 893 int plane, |
| 907 int size_shift, | 894 int size_shift, |
| 908 const gfx::Rect& dst_subrect, | 895 const gfx::Rect& dst_subrect, |
| 909 ReadbackSwizzle swizzle, | |
| 910 const base::Callback<void(bool)>& callback) { | 896 const base::Callback<void(bool)>& callback) { |
| 911 gl_->BindFramebuffer(GL_FRAMEBUFFER, source->framebuffer()); | 897 gl_->BindFramebuffer(GL_FRAMEBUFFER, source->framebuffer()); |
| 912 size_t offset = target->stride(plane) * (dst_subrect.y() >> size_shift) + | 898 size_t offset = target->stride(plane) * (dst_subrect.y() >> size_shift) + |
| 913 (dst_subrect.x() >> size_shift); | 899 (dst_subrect.x() >> size_shift); |
| 900 GLint format, type, bytes_per_pixel; | |
| 901 // Pass true in for swizzle to match earlier call | |
|
piman
2014/07/22 19:57:55
What does this comment mean?
robert.bradford
2014/07/23 16:58:45
By adopting your proposed solution in the YUVReadb
| |
| 902 ReadbackConfig(kRGBA_8888_SkColorType, | |
| 903 true, | |
| 904 format, | |
| 905 type, | |
| 906 bytes_per_pixel); | |
| 914 ReadbackAsync(source->size(), | 907 ReadbackAsync(source->size(), |
| 915 dst_subrect.width() >> size_shift, | 908 dst_subrect.width() >> size_shift, |
| 916 target->stride(plane), | 909 target->stride(plane), |
| 917 target->data(plane) + offset, | 910 target->data(plane) + offset, |
| 918 kN32_SkColorType, | 911 format, |
| 919 swizzle, | 912 type, |
| 913 bytes_per_pixel, | |
| 920 callback); | 914 callback); |
| 921 } | 915 } |
| 922 | 916 |
| 923 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { | 917 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { |
| 924 0.257f, 0.504f, 0.098f, 0.0625f}; | 918 0.257f, 0.504f, 0.098f, 0.0625f}; |
| 925 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { | 919 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { |
| 926 -0.148f, -0.291f, 0.439f, 0.5f}; | 920 -0.148f, -0.291f, 0.439f, 0.5f}; |
| 927 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { | 921 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { |
| 928 0.439f, -0.368f, -0.071f, 0.5f}; | 922 0.439f, -0.368f, -0.071f, 0.5f}; |
| 929 | 923 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1026 return; | 1020 return; |
| 1027 } | 1021 } |
| 1028 | 1022 |
| 1029 // Read back planes, one at a time. Keep the video frame alive while doing the | 1023 // Read back planes, one at a time. Keep the video frame alive while doing the |
| 1030 // readback. | 1024 // readback. |
| 1031 copy_impl_->ReadbackPlane(y_.texture_and_framebuffer(), | 1025 copy_impl_->ReadbackPlane(y_.texture_and_framebuffer(), |
| 1032 target, | 1026 target, |
| 1033 media::VideoFrame::kYPlane, | 1027 media::VideoFrame::kYPlane, |
| 1034 0, | 1028 0, |
| 1035 dst_subrect_, | 1029 dst_subrect_, |
| 1036 swizzle_, | |
|
piman
2014/07/22 19:57:54
I would prefer if we didn't query ReadbackConfig t
robert.bradford
2014/07/23 16:58:45
I implemented option 1. here.
| |
| 1037 base::Bind(&nullcallback)); | 1030 base::Bind(&nullcallback)); |
| 1038 copy_impl_->ReadbackPlane(u_.texture_and_framebuffer(), | 1031 copy_impl_->ReadbackPlane(u_.texture_and_framebuffer(), |
| 1039 target, | 1032 target, |
| 1040 media::VideoFrame::kUPlane, | 1033 media::VideoFrame::kUPlane, |
| 1041 1, | 1034 1, |
| 1042 dst_subrect_, | 1035 dst_subrect_, |
| 1043 swizzle_, | |
| 1044 base::Bind(&nullcallback)); | 1036 base::Bind(&nullcallback)); |
| 1045 copy_impl_->ReadbackPlane( | 1037 copy_impl_->ReadbackPlane( |
| 1046 v_.texture_and_framebuffer(), | 1038 v_.texture_and_framebuffer(), |
| 1047 target, | 1039 target, |
| 1048 media::VideoFrame::kVPlane, | 1040 media::VideoFrame::kVPlane, |
| 1049 1, | 1041 1, |
| 1050 dst_subrect_, | 1042 dst_subrect_, |
| 1051 swizzle_, | |
| 1052 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); | 1043 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); |
| 1053 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); | 1044 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); |
| 1054 media::LetterboxYUV(target, dst_subrect_); | 1045 media::LetterboxYUV(target, dst_subrect_); |
| 1055 } | 1046 } |
| 1056 | 1047 |
| 1057 // YUV readback constructors. Initiates the main scaler pipeline and | 1048 // YUV readback constructors. Initiates the main scaler pipeline and |
| 1058 // one planar scaler for each of the Y, U and V planes. | 1049 // one planar scaler for each of the Y, U and V planes. |
| 1059 GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV_MRT( | 1050 GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV_MRT( |
| 1060 GLES2Interface* gl, | 1051 GLES2Interface* gl, |
| 1061 CopyTextureToImpl* copy_impl, | 1052 CopyTextureToImpl* copy_impl, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1164 callback.Run(false); | 1155 callback.Run(false); |
| 1165 return; | 1156 return; |
| 1166 } | 1157 } |
| 1167 | 1158 |
| 1168 // Read back planes, one at a time. | 1159 // Read back planes, one at a time. |
| 1169 copy_impl_->ReadbackPlane(&y_, | 1160 copy_impl_->ReadbackPlane(&y_, |
| 1170 target, | 1161 target, |
| 1171 media::VideoFrame::kYPlane, | 1162 media::VideoFrame::kYPlane, |
| 1172 0, | 1163 0, |
| 1173 dst_subrect_, | 1164 dst_subrect_, |
| 1174 swizzle_, | |
| 1175 base::Bind(&nullcallback)); | 1165 base::Bind(&nullcallback)); |
| 1176 copy_impl_->ReadbackPlane(&u_, | 1166 copy_impl_->ReadbackPlane(&u_, |
| 1177 target, | 1167 target, |
| 1178 media::VideoFrame::kUPlane, | 1168 media::VideoFrame::kUPlane, |
| 1179 1, | 1169 1, |
| 1180 dst_subrect_, | 1170 dst_subrect_, |
| 1181 swizzle_, | |
| 1182 base::Bind(&nullcallback)); | 1171 base::Bind(&nullcallback)); |
| 1183 copy_impl_->ReadbackPlane( | 1172 copy_impl_->ReadbackPlane( |
| 1184 &v_, | 1173 &v_, |
| 1185 target, | 1174 target, |
| 1186 media::VideoFrame::kVPlane, | 1175 media::VideoFrame::kVPlane, |
| 1187 1, | 1176 1, |
| 1188 dst_subrect_, | 1177 dst_subrect_, |
| 1189 swizzle_, | |
| 1190 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); | 1178 base::Bind(&CallbackKeepingVideoFrameAlive, target, callback)); |
| 1191 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); | 1179 gl_->BindFramebuffer(GL_FRAMEBUFFER, 0); |
| 1192 media::LetterboxYUV(target, dst_subrect_); | 1180 media::LetterboxYUV(target, dst_subrect_); |
| 1193 } | 1181 } |
| 1194 | 1182 |
| 1195 bool GLHelper::IsReadbackConfigSupported(SkColorType texture_format) { | 1183 bool GLHelper::IsReadbackConfigSupported(SkColorType color_type) { |
| 1196 DCHECK(readback_support_.get()); | 1184 DCHECK(readback_support_.get()); |
| 1197 return readback_support_.get()->IsReadbackConfigSupported(texture_format); | 1185 GLint format, type, bytes_per_pixel; |
| 1186 FormatSupport support = readback_support_->ReadbackConfig(color_type, | |
| 1187 false, | |
| 1188 format, | |
| 1189 type, | |
| 1190 bytes_per_pixel); | |
| 1191 | |
| 1192 return (support == kReadbackSupported); | |
| 1198 } | 1193 } |
| 1199 | 1194 |
| 1200 ReadbackYUVInterface* GLHelper::CopyTextureToImpl::CreateReadbackPipelineYUV( | 1195 ReadbackYUVInterface* GLHelper::CopyTextureToImpl::CreateReadbackPipelineYUV( |
| 1201 GLHelper::ScalerQuality quality, | 1196 GLHelper::ScalerQuality quality, |
| 1202 const gfx::Size& src_size, | 1197 const gfx::Size& src_size, |
| 1203 const gfx::Rect& src_subrect, | 1198 const gfx::Rect& src_subrect, |
| 1204 const gfx::Size& dst_size, | 1199 const gfx::Size& dst_size, |
| 1205 const gfx::Rect& dst_subrect, | 1200 const gfx::Rect& dst_subrect, |
| 1206 bool flip_vertically, | 1201 bool flip_vertically, |
| 1207 bool use_mrt) { | 1202 bool use_mrt) { |
| 1208 helper_->InitScalerImpl(); | 1203 helper_->InitScalerImpl(); |
| 1209 // Query preferred format for glReadPixels, if is is GL_BGRA then use that | 1204 // Just query if the best readback configuration needs a swizzle In |
| 1210 // and trigger the appropriate swizzle in the YUV shaders. | 1205 // ReadbackPlane() we make the same request but use the format and type |
| 1211 GLint format = 0, type = 0; | 1206 // returned |
| 1207 GLint format, type, bytes_per_pixel; | |
| 1208 FormatSupport supported = ReadbackConfig(kRGBA_8888_SkColorType, | |
| 1209 true, | |
| 1210 format, | |
| 1211 type, | |
| 1212 bytes_per_pixel); | |
| 1213 | |
| 1212 ReadbackSwizzle swizzle = kSwizzleNone; | 1214 ReadbackSwizzle swizzle = kSwizzleNone; |
| 1213 helper_->readback_support_.get()->GetAdditionalFormat(GL_RGBA, | 1215 if (supported == kReadbackSwizzle) |
| 1214 GL_UNSIGNED_BYTE, | |
| 1215 &format, &type); | |
| 1216 if (format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) | |
| 1217 swizzle = kSwizzleBGRA; | 1216 swizzle = kSwizzleBGRA; |
| 1217 | |
| 1218 if (max_draw_buffers_ >= 2 && use_mrt) { | 1218 if (max_draw_buffers_ >= 2 && use_mrt) { |
| 1219 return new ReadbackYUV_MRT(gl_, | 1219 return new ReadbackYUV_MRT(gl_, |
| 1220 this, | 1220 this, |
| 1221 helper_->scaler_impl_.get(), | 1221 helper_->scaler_impl_.get(), |
| 1222 quality, | 1222 quality, |
| 1223 src_size, | 1223 src_size, |
| 1224 src_subrect, | 1224 src_subrect, |
| 1225 dst_size, | 1225 dst_size, |
| 1226 dst_subrect, | 1226 dst_subrect, |
| 1227 flip_vertically, | 1227 flip_vertically, |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 1251 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality, | 1251 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality, |
| 1252 src_size, | 1252 src_size, |
| 1253 src_subrect, | 1253 src_subrect, |
| 1254 dst_size, | 1254 dst_size, |
| 1255 dst_subrect, | 1255 dst_subrect, |
| 1256 flip_vertically, | 1256 flip_vertically, |
| 1257 use_mrt); | 1257 use_mrt); |
| 1258 } | 1258 } |
| 1259 | 1259 |
| 1260 } // namespace content | 1260 } // namespace content |
| OLD | NEW |