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. | |
Ken Russell (switch to Gerrit)
2017/03/31 23:39:30
EXT_texture_norm16 is supported on recent Qualcomm
aleksandar.stojiljkovic
2017/04/02 11:28:29
Tested it with highp and it works fine on Adreno 4
| |
918 if (gpu_capabilities.texture_norm16 && | |
919 gpu_capabilities.fragment_shader_precisions.medium_float.precision > 15 && | |
920 target == GL_TEXTURE_2D && | |
921 (type == GL_FLOAT || type == GL_UNSIGNED_BYTE)) { | |
922 // TODO(aleksandar.stojiljkovic): Extend the approach to TexSubImage2D | |
923 // implementation and other types. See https://crbug.com/624436. | |
924 | |
925 // Allocate the destination texture. | |
926 gl->TexImage2D(target, level, internalformat, frame->visible_rect().width(), | |
927 frame->visible_rect().height(), 0, format, type, nullptr); | |
928 // We use sized internal format (0x822A) instead of GL_RED. | |
929 // See angleproject:1952 | |
930 TextureSubImageUsingIntermediate( | |
931 target, texture, gl, frame, 0x822A /*GL_R16_EXT*/, GL_RED, | |
hubbe
2017/03/31 17:05:27
I think we need to add GL_R16_EXT to the right hea
aleksandar.stojiljkovic
2017/04/02 11:28:29
Done.
| |
932 GL_UNSIGNED_SHORT, level, 0, 0, flip_y, premultiply_alpha); | |
933 return true; | |
934 } | |
877 scoped_refptr<DataBuffer> temp_buffer; | 935 scoped_refptr<DataBuffer> temp_buffer; |
878 if (!TexImageHelper(frame, format, type, flip_y, &temp_buffer)) | 936 if (!TexImageHelper(frame, format, type, flip_y, &temp_buffer)) |
879 return false; | 937 return false; |
880 | 938 |
881 gl->TexImage2D(target, level, internalformat, frame->visible_rect().width(), | 939 gl->TexImage2D(target, level, internalformat, frame->visible_rect().width(), |
882 frame->visible_rect().height(), 0, format, type, | 940 frame->visible_rect().height(), 0, format, type, |
883 temp_buffer->data()); | 941 temp_buffer->data()); |
884 return true; | 942 return true; |
885 } | 943 } |
886 | 944 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
957 last_image_->bounds().contains(visible_rect)) { | 1015 last_image_->bounds().contains(visible_rect)) { |
958 last_image_ = last_image_->makeSubset(visible_rect); | 1016 last_image_ = last_image_->makeSubset(visible_rect); |
959 } | 1017 } |
960 } | 1018 } |
961 | 1019 |
962 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { | 1020 SkISize SkCanvasVideoRenderer::LastImageDimensionsForTesting() { |
963 return last_image_dimensions_for_testing_; | 1021 return last_image_dimensions_for_testing_; |
964 } | 1022 } |
965 | 1023 |
966 } // namespace media | 1024 } // namespace media |
OLD | NEW |