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