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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 uint32 sync_point) { | 121 uint32 sync_point) { |
122 return helper_->ConsumeMailboxToTexture(mailbox, sync_point); | 122 return helper_->ConsumeMailboxToTexture(mailbox, sync_point); |
123 } | 123 } |
124 | 124 |
125 void CropScaleReadbackAndCleanTexture( | 125 void CropScaleReadbackAndCleanTexture( |
126 GLuint src_texture, | 126 GLuint src_texture, |
127 const gfx::Size& src_size, | 127 const gfx::Size& src_size, |
128 const gfx::Rect& src_subrect, | 128 const gfx::Rect& src_subrect, |
129 const gfx::Size& dst_size, | 129 const gfx::Size& dst_size, |
130 unsigned char* out, | 130 unsigned char* out, |
| 131 bool readback_config_rgb565, |
131 const base::Callback<void(bool)>& callback, | 132 const base::Callback<void(bool)>& callback, |
132 GLHelper::ScalerQuality quality); | 133 GLHelper::ScalerQuality quality); |
133 | 134 |
134 void ReadbackTextureSync(GLuint texture, | 135 void ReadbackTextureSync(GLuint texture, |
135 const gfx::Rect& src_rect, | 136 const gfx::Rect& src_rect, |
136 unsigned char* out); | 137 unsigned char* out, |
| 138 SkBitmap::Config format); |
137 | 139 |
138 // Reads back bytes from the currently bound frame buffer. | 140 // Reads back bytes from the currently bound frame buffer. |
139 // Note that dst_size is specified in bytes, not pixels. | 141 // Note that dst_size is specified in bytes, not pixels. |
140 void ReadbackAsync(const gfx::Size& dst_size, | 142 void ReadbackAsync(const gfx::Size& dst_size, |
141 int32 bytes_per_row, // generally dst_size.width() * 4 | 143 int32 bytes_per_row, // generally dst_size.width() * 4 |
142 int32 row_stride_bytes, // generally dst_size.width() * 4 | 144 int32 row_stride_bytes, // generally dst_size.width() * 4 |
143 unsigned char* out, | 145 unsigned char* out, |
| 146 bool readback_config_rgb565, |
144 const base::Callback<void(bool)>& callback); | 147 const base::Callback<void(bool)>& callback); |
145 | 148 |
146 void ReadbackPlane(TextureFrameBufferPair* source, | 149 void ReadbackPlane(TextureFrameBufferPair* source, |
147 const scoped_refptr<media::VideoFrame>& target, | 150 const scoped_refptr<media::VideoFrame>& target, |
148 int plane, | 151 int plane, |
149 int size_shift, | 152 int size_shift, |
150 const gfx::Rect& dst_subrect, | 153 const gfx::Rect& dst_subrect, |
151 const base::Callback<void(bool)>& callback); | 154 const base::Callback<void(bool)>& callback); |
152 | 155 |
153 GLuint CopyAndScaleTexture(GLuint texture, | 156 GLuint CopyAndScaleTexture(GLuint texture, |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 | 282 |
280 // Copies the block of pixels specified with |src_subrect| from |src_texture|, | 283 // Copies the block of pixels specified with |src_subrect| from |src_texture|, |
281 // scales it to |dst_size|, writes it into a texture, and returns its ID. | 284 // scales it to |dst_size|, writes it into a texture, and returns its ID. |
282 // |src_size| is the size of |src_texture|. | 285 // |src_size| is the size of |src_texture|. |
283 GLuint ScaleTexture(GLuint src_texture, | 286 GLuint ScaleTexture(GLuint src_texture, |
284 const gfx::Size& src_size, | 287 const gfx::Size& src_size, |
285 const gfx::Rect& src_subrect, | 288 const gfx::Rect& src_subrect, |
286 const gfx::Size& dst_size, | 289 const gfx::Size& dst_size, |
287 bool vertically_flip_texture, | 290 bool vertically_flip_texture, |
288 bool swizzle, | 291 bool swizzle, |
| 292 bool readback_config_rgb565, |
289 GLHelper::ScalerQuality quality); | 293 GLHelper::ScalerQuality quality); |
290 | 294 |
291 static void nullcallback(bool success) {} | 295 static void nullcallback(bool success) {} |
292 void ReadbackDone(Request* request); | 296 void ReadbackDone(Request *request, int bytes_per_pixel); |
293 void FinishRequest(Request* request, bool result); | 297 void FinishRequest(Request* request, bool result); |
294 void CancelRequests(); | 298 void CancelRequests(); |
295 | 299 |
296 static const float kRGBtoYColorWeights[]; | 300 static const float kRGBtoYColorWeights[]; |
297 static const float kRGBtoUColorWeights[]; | 301 static const float kRGBtoUColorWeights[]; |
298 static const float kRGBtoVColorWeights[]; | 302 static const float kRGBtoVColorWeights[]; |
299 | 303 |
300 GLES2Interface* gl_; | 304 GLES2Interface* gl_; |
301 gpu::ContextSupport* context_support_; | 305 gpu::ContextSupport* context_support_; |
302 GLHelper* helper_; | 306 GLHelper* helper_; |
(...skipping 21 matching lines...) Expand all Loading... |
324 swizzle); | 328 swizzle); |
325 } | 329 } |
326 | 330 |
327 GLuint GLHelper::CopyTextureToImpl::ScaleTexture( | 331 GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
328 GLuint src_texture, | 332 GLuint src_texture, |
329 const gfx::Size& src_size, | 333 const gfx::Size& src_size, |
330 const gfx::Rect& src_subrect, | 334 const gfx::Rect& src_subrect, |
331 const gfx::Size& dst_size, | 335 const gfx::Size& dst_size, |
332 bool vertically_flip_texture, | 336 bool vertically_flip_texture, |
333 bool swizzle, | 337 bool swizzle, |
| 338 bool readback_config_rgb565, |
334 GLHelper::ScalerQuality quality) { | 339 GLHelper::ScalerQuality quality) { |
335 scoped_ptr<ScalerInterface> scaler( | 340 scoped_ptr<ScalerInterface> scaler( |
336 helper_->CreateScaler(quality, | 341 helper_->CreateScaler(quality, |
337 src_size, | 342 src_size, |
338 src_subrect, | 343 src_subrect, |
339 dst_size, | 344 dst_size, |
340 vertically_flip_texture, | 345 vertically_flip_texture, |
341 swizzle)); | 346 swizzle)); |
342 | 347 |
343 GLuint dst_texture = 0u; | 348 GLuint dst_texture = 0u; |
344 gl_->GenTextures(1, &dst_texture); | 349 gl_->GenTextures(1, &dst_texture); |
345 { | 350 { |
346 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); | 351 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
| 352 GLenum format = readback_config_rgb565 ? GL_RGB : GL_RGBA; |
| 353 GLenum type = readback_config_rgb565 ? |
| 354 GL_UNSIGNED_SHORT_5_6_5 : |
| 355 GL_UNSIGNED_BYTE; |
347 gl_->TexImage2D(GL_TEXTURE_2D, | 356 gl_->TexImage2D(GL_TEXTURE_2D, |
348 0, | 357 0, |
349 GL_RGBA, | 358 format, |
350 dst_size.width(), | 359 dst_size.width(), |
351 dst_size.height(), | 360 dst_size.height(), |
352 0, | 361 0, |
353 GL_RGBA, | 362 format, |
354 GL_UNSIGNED_BYTE, | 363 type, |
355 NULL); | 364 NULL); |
356 } | 365 } |
357 scaler->Scale(src_texture, dst_texture); | 366 scaler->Scale(src_texture, dst_texture); |
358 return dst_texture; | 367 return dst_texture; |
359 } | 368 } |
360 | 369 |
361 void GLHelper::CopyTextureToImpl::ReadbackAsync( | 370 void GLHelper::CopyTextureToImpl::ReadbackAsync( |
362 const gfx::Size& dst_size, | 371 const gfx::Size& dst_size, |
363 int32 bytes_per_row, | 372 int32 bytes_per_row, |
364 int32 row_stride_bytes, | 373 int32 row_stride_bytes, |
365 unsigned char* out, | 374 unsigned char* out, |
| 375 bool readback_config_rgb565, |
366 const base::Callback<void(bool)>& callback) { | 376 const base::Callback<void(bool)>& callback) { |
367 Request* request = | 377 Request* request = |
368 new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback); | 378 new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback); |
369 request_queue_.push(request); | 379 request_queue_.push(request); |
370 request->buffer = 0u; | 380 request->buffer = 0u; |
| 381 int bytes_per_pixel = readback_config_rgb565 ? 2 : 4; |
371 gl_->GenBuffers(1, &request->buffer); | 382 gl_->GenBuffers(1, &request->buffer); |
372 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); | 383 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
373 gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, | 384 gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
374 4 * dst_size.GetArea(), | 385 bytes_per_pixel * dst_size.GetArea(), |
375 NULL, | 386 NULL, |
376 GL_STREAM_READ); | 387 GL_STREAM_READ); |
377 | 388 |
378 request->query = 0u; | 389 request->query = 0u; |
379 gl_->GenQueriesEXT(1, &request->query); | 390 gl_->GenQueriesEXT(1, &request->query); |
380 gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query); | 391 gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query); |
| 392 GLenum format = readback_config_rgb565 ? GL_RGB : GL_RGBA; |
| 393 GLenum type = readback_config_rgb565 ? |
| 394 GL_UNSIGNED_SHORT_5_6_5 : |
| 395 GL_UNSIGNED_BYTE; |
381 gl_->ReadPixels(0, | 396 gl_->ReadPixels(0, |
382 0, | 397 0, |
383 dst_size.width(), | 398 dst_size.width(), |
384 dst_size.height(), | 399 dst_size.height(), |
385 GL_RGBA, | 400 format, |
386 GL_UNSIGNED_BYTE, | 401 type, |
387 NULL); | 402 NULL); |
388 gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); | 403 gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); |
389 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); | 404 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
390 context_support_->SignalQuery( | 405 context_support_->SignalQuery( |
391 request->query, | 406 request->query, |
392 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), request)); | 407 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), |
| 408 request, bytes_per_pixel)); |
393 } | 409 } |
394 | |
395 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( | 410 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
396 GLuint src_texture, | 411 GLuint src_texture, |
397 const gfx::Size& src_size, | 412 const gfx::Size& src_size, |
398 const gfx::Rect& src_subrect, | 413 const gfx::Rect& src_subrect, |
399 const gfx::Size& dst_size, | 414 const gfx::Size& dst_size, |
400 unsigned char* out, | 415 unsigned char* out, |
| 416 bool readback_config_rgb565, |
401 const base::Callback<void(bool)>& callback, | 417 const base::Callback<void(bool)>& callback, |
402 GLHelper::ScalerQuality quality) { | 418 GLHelper::ScalerQuality quality) { |
403 GLuint texture = ScaleTexture(src_texture, | 419 GLuint texture = ScaleTexture(src_texture, |
404 src_size, | 420 src_size, |
405 src_subrect, | 421 src_subrect, |
406 dst_size, | 422 dst_size, |
407 true, | 423 true, |
408 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 424 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
409 true, | 425 true, |
410 #else | 426 #else |
411 false, | 427 false, |
412 #endif | 428 #endif |
| 429 readback_config_rgb565, |
413 quality); | 430 quality); |
414 ScopedFramebuffer dst_framebuffer(gl_); | 431 ScopedFramebuffer dst_framebuffer(gl_); |
415 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, | 432 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
416 dst_framebuffer); | 433 dst_framebuffer); |
417 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 434 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| 435 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, |
| 436 GL_COLOR_ATTACHMENT0, |
| 437 GL_TEXTURE_2D, |
| 438 texture, |
| 439 0); |
| 440 int bytes_per_pixel = readback_config_rgb565 ? 2 : 4; |
| 441 ReadbackAsync(dst_size, |
| 442 dst_size.width() * bytes_per_pixel, |
| 443 dst_size.width() * bytes_per_pixel, |
| 444 out, |
| 445 readback_config_rgb565, |
| 446 callback); |
| 447 gl_->DeleteTextures(1, &texture); |
| 448 } |
| 449 |
| 450 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(GLuint texture, |
| 451 const gfx::Rect& src_rect, |
| 452 unsigned char* out, |
| 453 SkBitmap::Config config) { |
| 454 ScopedFramebuffer dst_framebuffer(gl_); |
| 455 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| 456 dst_framebuffer); |
| 457 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
418 gl_->FramebufferTexture2D( | 458 gl_->FramebufferTexture2D( |
419 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); | 459 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); |
420 ReadbackAsync( | 460 DCHECK((config == SkBitmap::kRGB_565_Config) || |
421 dst_size, dst_size.width() * 4, dst_size.width() * 4, out, callback); | 461 (config == SkBitmap::kARGB_8888_Config)); |
422 gl_->DeleteTextures(1, &texture); | 462 GLenum format = (config == SkBitmap::kRGB_565_Config) ? |
423 } | 463 GL_RGB : |
424 | 464 GL_RGBA; |
425 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(GLuint texture, | 465 GLenum type = (config == SkBitmap::kRGB_565_Config) ? |
426 const gfx::Rect& src_rect, | 466 GL_UNSIGNED_SHORT_5_6_5 : |
427 unsigned char* out) { | 467 GL_UNSIGNED_BYTE; |
428 ScopedFramebuffer dst_framebuffer(gl_); | |
429 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, | |
430 dst_framebuffer); | |
431 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | |
432 gl_->FramebufferTexture2D( | |
433 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); | |
434 gl_->ReadPixels(src_rect.x(), | 468 gl_->ReadPixels(src_rect.x(), |
435 src_rect.y(), | 469 src_rect.y(), |
436 src_rect.width(), | 470 src_rect.width(), |
437 src_rect.height(), | 471 src_rect.height(), |
438 GL_RGBA, | 472 format, |
439 GL_UNSIGNED_BYTE, | 473 type, |
440 out); | 474 out); |
441 } | 475 } |
442 | 476 |
443 GLuint GLHelper::CopyTextureToImpl::CopyAndScaleTexture( | 477 GLuint GLHelper::CopyTextureToImpl::CopyAndScaleTexture( |
444 GLuint src_texture, | 478 GLuint src_texture, |
445 const gfx::Size& src_size, | 479 const gfx::Size& src_size, |
446 const gfx::Size& dst_size, | 480 const gfx::Size& dst_size, |
447 bool vertically_flip_texture, | 481 bool vertically_flip_texture, |
448 GLHelper::ScalerQuality quality) { | 482 GLHelper::ScalerQuality quality) { |
449 return ScaleTexture(src_texture, | 483 return ScaleTexture(src_texture, |
450 src_size, | 484 src_size, |
451 gfx::Rect(src_size), | 485 gfx::Rect(src_size), |
452 dst_size, | 486 dst_size, |
453 vertically_flip_texture, | 487 vertically_flip_texture, |
454 false, | 488 false, |
| 489 false, |
455 quality); | 490 quality); |
456 } | 491 } |
457 | 492 |
458 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request) { | 493 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request, |
| 494 int bytes_per_pixel) { |
459 TRACE_EVENT0("mirror", | 495 TRACE_EVENT0("mirror", |
460 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); | 496 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); |
461 finished_request->done = true; | 497 finished_request->done = true; |
462 | 498 |
463 // We process transfer requests in the order they were received, regardless | 499 // We process transfer requests in the order they were received, regardless |
464 // of the order we get the callbacks in. | 500 // of the order we get the callbacks in. |
465 while (!request_queue_.empty()) { | 501 while (!request_queue_.empty()) { |
466 Request* request = request_queue_.front(); | 502 Request* request = request_queue_.front(); |
467 if (!request->done) { | 503 if (!request->done) { |
468 break; | 504 break; |
469 } | 505 } |
470 | 506 |
471 bool result = false; | 507 bool result = false; |
472 if (request->buffer != 0) { | 508 if (request->buffer != 0) { |
473 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); | 509 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
474 unsigned char* data = static_cast<unsigned char*>(gl_->MapBufferCHROMIUM( | 510 unsigned char* data = static_cast<unsigned char*>(gl_->MapBufferCHROMIUM( |
475 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); | 511 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); |
476 if (data) { | 512 if (data) { |
477 result = true; | 513 result = true; |
478 if (request->bytes_per_row == request->size.width() * 4 && | 514 if (request->bytes_per_row == request->size.width() * bytes_per_pixel && |
479 request->bytes_per_row == request->row_stride_bytes) { | 515 request->bytes_per_row == request->row_stride_bytes) { |
480 memcpy(request->pixels, data, request->size.GetArea() * 4); | 516 memcpy(request->pixels, data, |
| 517 request->size.GetArea() * bytes_per_pixel); |
481 } else { | 518 } else { |
482 unsigned char* out = request->pixels; | 519 unsigned char* out = request->pixels; |
483 for (int y = 0; y < request->size.height(); y++) { | 520 for (int y = 0; y < request->size.height(); y++) { |
484 memcpy(out, data, request->bytes_per_row); | 521 memcpy(out, data, request->bytes_per_row); |
485 out += request->row_stride_bytes; | 522 out += request->row_stride_bytes; |
486 data += request->size.width() * 4; | 523 data += request->size.width() * bytes_per_pixel; |
487 } | 524 } |
488 } | 525 } |
489 gl_->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); | 526 gl_->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); |
490 } | 527 } |
491 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); | 528 gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
492 } | 529 } |
493 | |
494 FinishRequest(request, result); | 530 FinishRequest(request, result); |
495 } | 531 } |
496 } | 532 } |
497 | 533 |
498 void GLHelper::CopyTextureToImpl::FinishRequest(Request* request, bool result) { | 534 void GLHelper::CopyTextureToImpl::FinishRequest(Request* request, bool result) { |
499 TRACE_EVENT0("mirror", "GLHelper::CopyTextureToImpl::FinishRequest"); | 535 TRACE_EVENT0("mirror", "GLHelper::CopyTextureToImpl::FinishRequest"); |
500 DCHECK(request_queue_.front() == request); | 536 DCHECK(request_queue_.front() == request); |
501 request_queue_.pop(); | 537 request_queue_.pop(); |
502 request->callback.Run(result); | 538 request->callback.Run(result); |
503 ScopedFlush flush(gl_); | 539 ScopedFlush flush(gl_); |
504 if (request->query != 0) { | 540 if (request->query != 0) { |
505 gl_->DeleteQueriesEXT(1, &request->query); | 541 gl_->DeleteQueriesEXT(1, &request->query); |
506 request->query = 0; | 542 request->query = 0; |
507 } | 543 } |
508 if (request->buffer != 0) { | 544 if (request->buffer != 0) { |
509 gl_->DeleteBuffers(1, &request->buffer); | 545 gl_->DeleteBuffers(1, &request->buffer); |
510 request->buffer = 0; | 546 request->buffer = 0; |
511 } | 547 } |
512 delete request; | 548 delete request; |
513 } | 549 } |
514 | 550 |
515 void GLHelper::CopyTextureToImpl::CancelRequests() { | 551 void GLHelper::CopyTextureToImpl::CancelRequests() { |
516 while (!request_queue_.empty()) { | 552 while (!request_queue_.empty()) { |
517 Request* request = request_queue_.front(); | 553 Request* request = request_queue_.front(); |
518 FinishRequest(request, false); | 554 FinishRequest(request, false); |
519 } | 555 } |
520 } | 556 } |
521 | 557 |
522 GLHelper::GLHelper(GLES2Interface* gl, gpu::ContextSupport* context_support) | 558 GLHelper::GLHelper(GLES2Interface* gl, gpu::ContextSupport* context_support) |
523 : gl_(gl), context_support_(context_support) {} | 559 : gl_(gl), |
| 560 context_support_(context_support), |
| 561 initialized_565_format_check_(false), |
| 562 support_565_format_(false) {} |
524 | 563 |
525 GLHelper::~GLHelper() {} | 564 GLHelper::~GLHelper() {} |
526 | 565 |
527 void GLHelper::CropScaleReadbackAndCleanTexture( | 566 void GLHelper::CropScaleReadbackAndCleanTexture( |
528 GLuint src_texture, | 567 GLuint src_texture, |
529 const gfx::Size& src_size, | 568 const gfx::Size& src_size, |
530 const gfx::Rect& src_subrect, | 569 const gfx::Rect& src_subrect, |
531 const gfx::Size& dst_size, | 570 const gfx::Size& dst_size, |
532 unsigned char* out, | 571 unsigned char* out, |
| 572 bool readback_config_rgb565, |
533 const base::Callback<void(bool)>& callback) { | 573 const base::Callback<void(bool)>& callback) { |
534 InitCopyTextToImpl(); | 574 InitCopyTextToImpl(); |
535 copy_texture_to_impl_->CropScaleReadbackAndCleanTexture( | 575 copy_texture_to_impl_->CropScaleReadbackAndCleanTexture( |
536 src_texture, | 576 src_texture, |
537 src_size, | 577 src_size, |
538 src_subrect, | 578 src_subrect, |
539 dst_size, | 579 dst_size, |
540 out, | 580 out, |
| 581 readback_config_rgb565, |
541 callback, | 582 callback, |
542 GLHelper::SCALER_QUALITY_FAST); | 583 GLHelper::SCALER_QUALITY_FAST); |
543 } | 584 } |
544 | 585 |
545 void GLHelper::CropScaleReadbackAndCleanMailbox( | 586 void GLHelper::CropScaleReadbackAndCleanMailbox( |
546 const gpu::Mailbox& src_mailbox, | 587 const gpu::Mailbox& src_mailbox, |
547 uint32 sync_point, | 588 uint32 sync_point, |
548 const gfx::Size& src_size, | 589 const gfx::Size& src_size, |
549 const gfx::Rect& src_subrect, | 590 const gfx::Rect& src_subrect, |
550 const gfx::Size& dst_size, | 591 const gfx::Size& dst_size, |
551 unsigned char* out, | 592 unsigned char* out, |
| 593 bool readback_config_rgb565, |
552 const base::Callback<void(bool)>& callback) { | 594 const base::Callback<void(bool)>& callback) { |
553 GLuint mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_point); | 595 GLuint mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_point); |
554 CropScaleReadbackAndCleanTexture( | 596 CropScaleReadbackAndCleanTexture( |
555 mailbox_texture, src_size, src_subrect, dst_size, out, callback); | 597 mailbox_texture, src_size, src_subrect, dst_size, out, |
| 598 readback_config_rgb565, |
| 599 callback); |
556 gl_->DeleteTextures(1, &mailbox_texture); | 600 gl_->DeleteTextures(1, &mailbox_texture); |
557 } | 601 } |
558 | 602 |
559 void GLHelper::ReadbackTextureSync(GLuint texture, | 603 void GLHelper::ReadbackTextureSync(GLuint texture, |
560 const gfx::Rect& src_rect, | 604 const gfx::Rect& src_rect, |
561 unsigned char* out) { | 605 unsigned char* out, |
| 606 SkBitmap::Config format) { |
562 InitCopyTextToImpl(); | 607 InitCopyTextToImpl(); |
563 copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out); | 608 copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out, format); |
564 } | 609 } |
565 | 610 |
566 GLuint GLHelper::CopyTexture(GLuint texture, const gfx::Size& size) { | 611 GLuint GLHelper::CopyTexture(GLuint texture, const gfx::Size& size) { |
567 InitCopyTextToImpl(); | 612 InitCopyTextToImpl(); |
568 return copy_texture_to_impl_->CopyAndScaleTexture( | 613 return copy_texture_to_impl_->CopyAndScaleTexture( |
569 texture, size, size, false, GLHelper::SCALER_QUALITY_FAST); | 614 texture, size, size, false, GLHelper::SCALER_QUALITY_FAST); |
570 } | 615 } |
571 | 616 |
572 GLuint GLHelper::CopyAndScaleTexture(GLuint texture, | 617 GLuint GLHelper::CopyAndScaleTexture(GLuint texture, |
573 const gfx::Size& src_size, | 618 const gfx::Size& src_size, |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
718 rect.width(), | 763 rect.width(), |
719 rect.height()); | 764 rect.height()); |
720 } | 765 } |
721 | 766 |
722 void GLHelper::CopyTextureFullImage(GLuint texture, const gfx::Size& size) { | 767 void GLHelper::CopyTextureFullImage(GLuint texture, const gfx::Size& size) { |
723 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); | 768 content::ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
724 gl_->CopyTexImage2D( | 769 gl_->CopyTexImage2D( |
725 GL_TEXTURE_2D, 0, GL_RGB, 0, 0, size.width(), size.height(), 0); | 770 GL_TEXTURE_2D, 0, GL_RGB, 0, 0, size.width(), size.height(), 0); |
726 } | 771 } |
727 | 772 |
| 773 bool GLHelper::CanUseRgb565Readback() { |
| 774 if(initialized_565_format_check_){ |
| 775 return support_565_format_; |
| 776 } |
| 777 const int kTestSize = 64; |
| 778 GLuint dst_texture = 0u; |
| 779 gl_->GenTextures(1, &dst_texture); |
| 780 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
| 781 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 782 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 783 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 784 gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 785 gl_->TexImage2D(GL_TEXTURE_2D, |
| 786 0, |
| 787 GL_RGB, |
| 788 kTestSize, |
| 789 kTestSize, |
| 790 0, |
| 791 GL_RGB, |
| 792 GL_UNSIGNED_SHORT_5_6_5, |
| 793 NULL); |
| 794 ScopedFramebuffer dst_framebuffer(gl_); |
| 795 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| 796 dst_framebuffer); |
| 797 gl_->FramebufferTexture2D(GL_FRAMEBUFFER, |
| 798 GL_COLOR_ATTACHMENT0, |
| 799 GL_TEXTURE_2D, |
| 800 dst_texture, |
| 801 0); |
| 802 GLint ext_format = 0, ext_type = 0; |
| 803 gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &ext_format); |
| 804 gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &ext_type); |
| 805 gl_->DeleteTextures(1, &dst_texture); |
| 806 if ((ext_format == GL_RGB) && (ext_type == GL_UNSIGNED_SHORT_5_6_5)) { |
| 807 support_565_format_ = true; |
| 808 } |
| 809 initialized_565_format_check_ = true; |
| 810 return support_565_format_; |
| 811 } |
| 812 |
728 void GLHelper::CopyTextureToImpl::ReadbackPlane( | 813 void GLHelper::CopyTextureToImpl::ReadbackPlane( |
729 TextureFrameBufferPair* source, | 814 TextureFrameBufferPair* source, |
730 const scoped_refptr<media::VideoFrame>& target, | 815 const scoped_refptr<media::VideoFrame>& target, |
731 int plane, | 816 int plane, |
732 int size_shift, | 817 int size_shift, |
733 const gfx::Rect& dst_subrect, | 818 const gfx::Rect& dst_subrect, |
734 const base::Callback<void(bool)>& callback) { | 819 const base::Callback<void(bool)>& callback) { |
735 gl_->BindFramebuffer(GL_FRAMEBUFFER, source->framebuffer()); | 820 gl_->BindFramebuffer(GL_FRAMEBUFFER, source->framebuffer()); |
736 size_t offset = target->stride(plane) * (dst_subrect.y() >> size_shift) + | 821 size_t offset = target->stride(plane) * (dst_subrect.y() >> size_shift) + |
737 (dst_subrect.x() >> size_shift); | 822 (dst_subrect.x() >> size_shift); |
738 ReadbackAsync(source->size(), | 823 ReadbackAsync(source->size(), |
739 dst_subrect.width() >> size_shift, | 824 dst_subrect.width() >> size_shift, |
740 target->stride(plane), | 825 target->stride(plane), |
741 target->data(plane) + offset, | 826 target->data(plane) + offset, |
| 827 false, |
742 callback); | 828 callback); |
743 } | 829 } |
744 | 830 |
745 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { | 831 const float GLHelper::CopyTextureToImpl::kRGBtoYColorWeights[] = { |
746 0.257f, 0.504f, 0.098f, 0.0625f}; | 832 0.257f, 0.504f, 0.098f, 0.0625f}; |
747 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { | 833 const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { |
748 -0.148f, -0.291f, 0.439f, 0.5f}; | 834 -0.148f, -0.291f, 0.439f, 0.5f}; |
749 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { | 835 const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { |
750 0.439f, -0.368f, -0.071f, 0.5f}; | 836 0.439f, -0.368f, -0.071f, 0.5f}; |
751 | 837 |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality, | 1128 return copy_texture_to_impl_->CreateReadbackPipelineYUV(quality, |
1043 src_size, | 1129 src_size, |
1044 src_subrect, | 1130 src_subrect, |
1045 dst_size, | 1131 dst_size, |
1046 dst_subrect, | 1132 dst_subrect, |
1047 flip_vertically, | 1133 flip_vertically, |
1048 use_mrt); | 1134 use_mrt); |
1049 } | 1135 } |
1050 | 1136 |
1051 } // namespace content | 1137 } // namespace content |
OLD | NEW |