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 "media/renderers/skcanvas_video_renderer.h" | 5 #include "media/renderers/skcanvas_video_renderer.h" |
6 | 6 |
7 #include <GLES3/gl3.h> | 7 #include <GLES3/gl3.h> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
12 #include "cc/paint/paint_canvas.h" | 12 #include "cc/paint/paint_canvas.h" |
13 #include "cc/paint/paint_flags.h" | 13 #include "cc/paint/paint_flags.h" |
14 #include "gpu/GLES2/gl2extchromium.h" | 14 #include "gpu/GLES2/gl2extchromium.h" |
15 #include "gpu/command_buffer/client/gles2_interface.h" | 15 #include "gpu/command_buffer/client/gles2_interface.h" |
| 16 #include "gpu/command_buffer/common/capabilities.h" |
16 #include "gpu/command_buffer/common/mailbox_holder.h" | 17 #include "gpu/command_buffer/common/mailbox_holder.h" |
17 #include "media/base/data_buffer.h" | 18 #include "media/base/data_buffer.h" |
18 #include "media/base/video_frame.h" | 19 #include "media/base/video_frame.h" |
19 #include "skia/ext/texture_handle.h" | 20 #include "skia/ext/texture_handle.h" |
20 #include "third_party/libyuv/include/libyuv.h" | 21 #include "third_party/libyuv/include/libyuv.h" |
21 #include "third_party/skia/include/core/SkImage.h" | 22 #include "third_party/skia/include/core/SkImage.h" |
22 #include "third_party/skia/include/core/SkImageGenerator.h" | 23 #include "third_party/skia/include/core/SkImageGenerator.h" |
23 #include "third_party/skia/include/gpu/GrContext.h" | 24 #include "third_party/skia/include/gpu/GrContext.h" |
24 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" | 25 #include "third_party/skia/include/gpu/gl/GrGLTypes.h" |
25 #include "ui/gfx/geometry/rect_f.h" | 26 #include "ui/gfx/geometry/rect_f.h" |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
615 | 616 |
616 size_t output_row_bytes = | 617 size_t output_row_bytes = |
617 frame->visible_rect().width() * output_bytes_per_pixel; | 618 frame->visible_rect().width() * output_bytes_per_pixel; |
618 *temp_buffer = | 619 *temp_buffer = |
619 new DataBuffer(output_row_bytes * frame->visible_rect().height()); | 620 new DataBuffer(output_row_bytes * frame->visible_rect().height()); |
620 FlipAndConvertY16(frame, (*temp_buffer)->writable_data(), format, type, | 621 FlipAndConvertY16(frame, (*temp_buffer)->writable_data(), format, type, |
621 flip_y, output_row_bytes); | 622 flip_y, output_row_bytes); |
622 return true; | 623 return true; |
623 } | 624 } |
624 | 625 |
| 626 // Upload the |frame| data to temporary texture of |temp_format|, |
| 627 // |temp_internalformat| and |temp_type| and then copy intermediate texture |
| 628 // subimage to destination |texture|. The destination |texture| is bound to the |
| 629 // |target| before the call. |
| 630 void TextureSubImageUsingIntermediate(unsigned target, |
| 631 unsigned texture, |
| 632 gpu::gles2::GLES2Interface* gl, |
| 633 VideoFrame* frame, |
| 634 int temp_internalformat, |
| 635 unsigned temp_format, |
| 636 unsigned temp_type, |
| 637 int level, |
| 638 int xoffset, |
| 639 int yoffset, |
| 640 bool flip_y, |
| 641 bool premultiply_alpha) { |
| 642 unsigned temp_texture = 0; |
| 643 gl->GenTextures(1, &temp_texture); |
| 644 gl->BindTexture(target, temp_texture); |
| 645 gl->TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 646 gl->TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 647 gl->TexImage2D(target, 0, temp_internalformat, frame->visible_rect().width(), |
| 648 frame->visible_rect().height(), 0, temp_format, temp_type, |
| 649 frame->visible_data(0)); |
| 650 gl->BindTexture(target, texture); |
| 651 gl->CopySubTextureCHROMIUM(temp_texture, 0, target, texture, level, 0, 0, |
| 652 xoffset, yoffset, frame->visible_rect().width(), |
| 653 frame->visible_rect().height(), flip_y, |
| 654 premultiply_alpha, false); |
| 655 gl->DeleteTextures(1, &temp_texture); |
| 656 } |
| 657 |
625 } // anonymous namespace | 658 } // anonymous namespace |
626 | 659 |
627 // static | 660 // static |
628 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( | 661 void SkCanvasVideoRenderer::ConvertVideoFrameToRGBPixels( |
629 const VideoFrame* video_frame, | 662 const VideoFrame* video_frame, |
630 void* rgb_pixels, | 663 void* rgb_pixels, |
631 size_t row_bytes) { | 664 size_t row_bytes) { |
632 if (!video_frame->IsMappable()) { | 665 if (!video_frame->IsMappable()) { |
633 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; | 666 NOTREACHED() << "Cannot extract pixels from non-CPU frame formats."; |
634 return; | 667 return; |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 SyncTokenClientImpl client(canvas_gl); | 888 SyncTokenClientImpl client(canvas_gl); |
856 video_frame->UpdateReleaseSyncToken(&client); | 889 video_frame->UpdateReleaseSyncToken(&client); |
857 } else { | 890 } else { |
858 CopyVideoFrameSingleTextureToGLTexture(destination_gl, video_frame.get(), | 891 CopyVideoFrameSingleTextureToGLTexture(destination_gl, video_frame.get(), |
859 texture, premultiply_alpha, flip_y); | 892 texture, premultiply_alpha, flip_y); |
860 } | 893 } |
861 | 894 |
862 return true; | 895 return true; |
863 } | 896 } |
864 | 897 |
865 bool SkCanvasVideoRenderer::TexImage2D(unsigned target, | 898 bool SkCanvasVideoRenderer::TexImage2D( |
866 gpu::gles2::GLES2Interface* gl, | 899 unsigned target, |
867 VideoFrame* frame, | 900 unsigned texture, |
868 int level, | 901 gpu::gles2::GLES2Interface* gl, |
869 int internalformat, | 902 const gpu::Capabilities& gpu_capabilities, |
870 unsigned format, | 903 VideoFrame* frame, |
871 unsigned type, | 904 int level, |
872 bool flip_y, | 905 int internalformat, |
873 bool premultiply_alpha) { | 906 unsigned format, |
| 907 unsigned type, |
| 908 bool flip_y, |
| 909 bool premultiply_alpha) { |
874 DCHECK(frame); | 910 DCHECK(frame); |
875 DCHECK(!frame->HasTextures()); | 911 DCHECK(!frame->HasTextures()); |
876 | 912 |
| 913 // Note: CopyTextureCHROMIUM uses mediump for color computation. Don't use |
| 914 // it if the precision would lead to data loss when converting 16-bit |
| 915 // normalized to float. medium_float.precision > 15 means that the approach |
| 916 // bellow is not used on Android, where the extension EXT_texture_norm16 is |
| 917 // not widely supported. It is used on Windows, Linux and OSX. |
| 918 // Android support is not required for now because Tango depth camera already |
| 919 // provides floating point data (projected point cloud). See crbug.com/674440. |
| 920 if (gpu_capabilities.texture_norm16 && |
| 921 gpu_capabilities.fragment_shader_precisions.medium_float.precision > 15 && |
| 922 target == GL_TEXTURE_2D && |
| 923 (type == GL_FLOAT || type == GL_UNSIGNED_BYTE)) { |
| 924 // TODO(aleksandar.stojiljkovic): Extend the approach to TexSubImage2D |
| 925 // implementation and other types. See https://crbug.com/624436. |
| 926 |
| 927 // Allocate the destination texture. |
| 928 gl->TexImage2D(target, level, internalformat, frame->visible_rect().width(), |
| 929 frame->visible_rect().height(), 0, format, type, nullptr); |
| 930 // We use sized internal format GL_R16_EXT instead of unsized GL_RED. |
| 931 // See angleproject:1952 |
| 932 TextureSubImageUsingIntermediate(target, texture, gl, frame, GL_R16_EXT, |
| 933 GL_RED, GL_UNSIGNED_SHORT, level, 0, 0, |
| 934 flip_y, premultiply_alpha); |
| 935 return true; |
| 936 } |
877 scoped_refptr<DataBuffer> temp_buffer; | 937 scoped_refptr<DataBuffer> temp_buffer; |
878 if (!TexImageHelper(frame, format, type, flip_y, &temp_buffer)) | 938 if (!TexImageHelper(frame, format, type, flip_y, &temp_buffer)) |
879 return false; | 939 return false; |
880 | 940 |
881 gl->TexImage2D(target, level, internalformat, frame->visible_rect().width(), | 941 gl->TexImage2D(target, level, internalformat, frame->visible_rect().width(), |
882 frame->visible_rect().height(), 0, format, type, | 942 frame->visible_rect().height(), 0, format, type, |
883 temp_buffer->data()); | 943 temp_buffer->data()); |
884 return true; | 944 return true; |
885 } | 945 } |
886 | 946 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
957 last_image_->bounds().contains(visible_rect)) { | 1017 last_image_->bounds().contains(visible_rect)) { |
958 last_image_ = last_image_->makeSubset(visible_rect); | 1018 last_image_ = last_image_->makeSubset(visible_rect); |
959 } | 1019 } |
960 } | 1020 } |
961 | 1021 |
962 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { | 1022 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { |
963 return last_image_dimensions_for_testing_; | 1023 return last_image_dimensions_for_testing_; |
964 } | 1024 } |
965 | 1025 |
966 } // namespace media | 1026 } // namespace media |
OLD | NEW |