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 "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 source_y, source_width, source_height); | 610 source_y, source_width, source_height); |
611 } | 611 } |
612 | 612 |
613 decoder->RestoreTextureState(source_id); | 613 decoder->RestoreTextureState(source_id); |
614 decoder->RestoreTextureState(dest_id); | 614 decoder->RestoreTextureState(dest_id); |
615 decoder->RestoreTextureUnitBindings(0); | 615 decoder->RestoreTextureUnitBindings(0); |
616 decoder->RestoreActiveTexture(); | 616 decoder->RestoreActiveTexture(); |
617 decoder->RestoreFramebufferBindings(); | 617 decoder->RestoreFramebufferBindings(); |
618 } | 618 } |
619 | 619 |
| 620 // Convert RGBA/UNSIGNED_BYTE source to RGB/UNSIGNED_BYTE destination. |
| 621 void convertToRGB(const uint8_t* source, |
| 622 uint8_t* destination, |
| 623 unsigned length) { |
| 624 for (unsigned i = 0; i < length; ++i) { |
| 625 destination[0] = source[0]; |
| 626 destination[1] = source[1]; |
| 627 destination[2] = source[2]; |
| 628 source += 4; |
| 629 destination += 3; |
| 630 } |
| 631 } |
| 632 |
| 633 // Convert RGBA/UNSIGNED_BYTE source to RGB/FLOAT destination. |
| 634 void convertToRGBFloat(const uint8_t* source, |
| 635 float* destination, |
| 636 unsigned length) { |
| 637 const float scaleFactor = 1.0f / 255.0f; |
| 638 for (unsigned i = 0; i < length; ++i) { |
| 639 destination[0] = source[0] * scaleFactor; |
| 640 destination[1] = source[1] * scaleFactor; |
| 641 destination[2] = source[2] * scaleFactor; |
| 642 source += 4; |
| 643 destination += 3; |
| 644 } |
| 645 } |
| 646 |
| 647 // Prepare the image data to be uploaded to a texture in pixel unpack buffer. |
| 648 void prepareUnpackBuffer(GLuint buffer[2], |
| 649 bool is_es, |
| 650 GLenum format, |
| 651 GLenum type, |
| 652 GLsizei width, |
| 653 GLsizei height) { |
| 654 uint32_t pixel_num = width * height; |
| 655 |
| 656 // Result of glReadPixels with format == GL_RGB and type == GL_UNSIGNED_BYTE |
| 657 // from read framebuffer in RGBA fromat is not correct on desktop core |
| 658 // profile on both Linux Mesa and Linux NVIDIA. This may be a driver bug. |
| 659 bool is_rgb_unsigned_byte = format == GL_RGB && type == GL_UNSIGNED_BYTE; |
| 660 if ((!is_es && !is_rgb_unsigned_byte) || |
| 661 (format == GL_RGBA && type == GL_UNSIGNED_BYTE)) { |
| 662 uint32_t bytes_per_group = |
| 663 gpu::gles2::GLES2Util::ComputeImageGroupSize(format, type); |
| 664 glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer[0]); |
| 665 glBufferData(GL_PIXEL_PACK_BUFFER, pixel_num * bytes_per_group, 0, |
| 666 GL_STATIC_READ); |
| 667 glReadPixels(0, 0, width, height, format, type, 0); |
| 668 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer[0]); |
| 669 return; |
| 670 } |
| 671 |
| 672 uint32_t bytes_per_group = |
| 673 gpu::gles2::GLES2Util::ComputeImageGroupSize(GL_RGBA, GL_UNSIGNED_BYTE); |
| 674 uint32_t buf_size = pixel_num * bytes_per_group; |
| 675 |
| 676 if (format == GL_RGB && type == GL_FLOAT) { |
| 677 #if defined(OS_ANDROID) |
| 678 // Reading pixels to pbo with glReadPixels will cause random failures of |
| 679 // GLCopyTextureCHROMIUMES3Test.FormatCombinations in gl_tests. This is seen |
| 680 // on Nexus 5 but not Nexus 4. Read pixels to client memory, then upload to |
| 681 // pixel unpack buffer with glBufferData. |
| 682 std::unique_ptr<uint8_t[]> pixels(new uint8_t[width * height * 4]); |
| 683 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.get()); |
| 684 std::unique_ptr<float[]> data(new float[width * height * 3]); |
| 685 convertToRGBFloat(pixels.get(), data.get(), pixel_num); |
| 686 bytes_per_group = |
| 687 gpu::gles2::GLES2Util::ComputeImageGroupSize(format, type); |
| 688 buf_size = pixel_num * bytes_per_group; |
| 689 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer[1]); |
| 690 glBufferData(GL_PIXEL_UNPACK_BUFFER, buf_size, data.get(), GL_STATIC_DRAW); |
| 691 #else |
| 692 glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer[0]); |
| 693 glBufferData(GL_PIXEL_PACK_BUFFER, buf_size, 0, GL_STATIC_READ); |
| 694 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0); |
| 695 void* pixels = |
| 696 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, buf_size, GL_MAP_READ_BIT); |
| 697 |
| 698 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer[1]); |
| 699 bytes_per_group = |
| 700 gpu::gles2::GLES2Util::ComputeImageGroupSize(format, type); |
| 701 buf_size = pixel_num * bytes_per_group; |
| 702 glBufferData(GL_PIXEL_UNPACK_BUFFER, buf_size, 0, GL_STATIC_DRAW); |
| 703 void* data = |
| 704 glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, buf_size, GL_MAP_WRITE_BIT); |
| 705 convertToRGBFloat(static_cast<uint8_t*>(pixels), static_cast<float*>(data), |
| 706 pixel_num); |
| 707 glUnmapBuffer(GL_PIXEL_PACK_BUFFER); |
| 708 glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); |
| 709 #endif |
| 710 return; |
| 711 } |
| 712 |
| 713 if (format == GL_RGB && type == GL_UNSIGNED_BYTE) { |
| 714 glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer[0]); |
| 715 glBufferData(GL_PIXEL_PACK_BUFFER, buf_size, 0, GL_DYNAMIC_DRAW); |
| 716 glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, 0); |
| 717 void* pixels = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, buf_size, |
| 718 GL_MAP_READ_BIT | GL_MAP_WRITE_BIT); |
| 719 void* data = pixels; |
| 720 convertToRGB((uint8_t*)pixels, (uint8_t*)data, pixel_num); |
| 721 glUnmapBuffer(GL_PIXEL_PACK_BUFFER); |
| 722 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer[0]); |
| 723 return; |
| 724 } |
| 725 |
| 726 NOTREACHED(); |
| 727 } |
| 728 |
| 729 enum TexImageCommandType { |
| 730 kTexImage, |
| 731 kTexSubImage, |
| 732 }; |
| 733 |
| 734 void DoReadbackAndTexImage(TexImageCommandType command_type, |
| 735 const gpu::gles2::GLES2Decoder* decoder, |
| 736 GLenum source_target, |
| 737 GLuint source_id, |
| 738 GLint source_level, |
| 739 GLenum dest_target, |
| 740 GLuint dest_id, |
| 741 GLint dest_level, |
| 742 GLenum dest_internal_format, |
| 743 GLint xoffset, |
| 744 GLint yoffset, |
| 745 GLsizei width, |
| 746 GLsizei height, |
| 747 GLuint framebuffer) { |
| 748 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), source_target); |
| 749 GLenum dest_binding_target = |
| 750 gpu::gles2::GLES2Util::GLFaceTargetToTextureTarget(dest_target); |
| 751 DCHECK(dest_binding_target == GL_TEXTURE_2D || |
| 752 dest_binding_target == GL_TEXTURE_CUBE_MAP); |
| 753 DCHECK(source_level == 0 || decoder->GetFeatureInfo()->IsES3Capable()); |
| 754 if (BindFramebufferTexture2D(source_target, source_id, source_level, |
| 755 framebuffer)) { |
| 756 glBindTexture(dest_binding_target, dest_id); |
| 757 glTexParameterf(dest_binding_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 758 glTexParameterf(dest_binding_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 759 glTexParameteri(dest_binding_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 760 glTexParameteri(dest_binding_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 761 |
| 762 GLenum format = GL_RGBA; |
| 763 GLenum type = GL_UNSIGNED_BYTE; |
| 764 switch (dest_internal_format) { |
| 765 case GL_RGB9_E5: |
| 766 format = GL_RGB; |
| 767 type = GL_FLOAT; |
| 768 break; |
| 769 case GL_SRGB_EXT: |
| 770 case GL_SRGB8: |
| 771 format = GL_RGB; |
| 772 break; |
| 773 case GL_RGB5_A1: |
| 774 case GL_SRGB_ALPHA_EXT: |
| 775 case GL_SRGB8_ALPHA8: |
| 776 break; |
| 777 default: |
| 778 NOTREACHED(); |
| 779 break; |
| 780 } |
| 781 |
| 782 // TODO(qiankun.miao@intel.com): PIXEL_PACK_BUFFER and PIXEL_UNPACK_BUFFER |
| 783 // are not supported in ES2. |
| 784 bool is_es = decoder->GetFeatureInfo()->gl_version_info().is_es; |
| 785 DCHECK(!decoder->GetFeatureInfo()->gl_version_info().is_es2); |
| 786 |
| 787 uint32_t buffer_num = is_es && format == GL_RGB && type == GL_FLOAT ? 2 : 1; |
| 788 GLuint buffer[2] = {0u}; |
| 789 glGenBuffersARB(buffer_num, buffer); |
| 790 prepareUnpackBuffer(buffer, is_es, format, type, width, height); |
| 791 |
| 792 if (command_type == kTexImage) { |
| 793 glTexImage2D(dest_target, dest_level, dest_internal_format, width, height, |
| 794 0, format, type, 0); |
| 795 } else { |
| 796 glTexSubImage2D(dest_target, dest_level, xoffset, yoffset, width, height, |
| 797 format, type, 0); |
| 798 } |
| 799 glDeleteBuffersARB(buffer_num, buffer); |
| 800 } |
| 801 |
| 802 decoder->RestoreTextureState(source_id); |
| 803 decoder->RestoreTextureState(dest_id); |
| 804 decoder->RestoreTextureUnitBindings(0); |
| 805 decoder->RestoreActiveTexture(); |
| 806 decoder->RestoreFramebufferBindings(); |
| 807 decoder->RestoreBufferBindings(); |
| 808 } |
| 809 |
620 } // namespace | 810 } // namespace |
621 | 811 |
622 namespace gpu { | 812 namespace gpu { |
623 namespace gles2 { | 813 namespace gles2 { |
624 | 814 |
625 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() | 815 CopyTextureCHROMIUMResourceManager::CopyTextureCHROMIUMResourceManager() |
626 : initialized_(false), | 816 : initialized_(false), |
627 nv_egl_stream_consumer_external_(false), | 817 nv_egl_stream_consumer_external_(false), |
628 vertex_shaders_(kNumVertexShaders, 0u), | 818 vertex_shaders_(kNumVertexShaders, 0u), |
629 fragment_shaders_(kNumFragmentShaders, 0u), | 819 fragment_shaders_(kNumFragmentShaders, 0u), |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 width, height, framebuffer_); | 918 width, height, framebuffer_); |
729 return; | 919 return; |
730 } | 920 } |
731 | 921 |
732 // Draw to level 0 of an intermediate GL_TEXTURE_2D texture. | 922 // Draw to level 0 of an intermediate GL_TEXTURE_2D texture. |
733 GLuint dest_texture = dest_id; | 923 GLuint dest_texture = dest_id; |
734 GLuint intermediate_texture = 0; | 924 GLuint intermediate_texture = 0; |
735 GLint original_dest_level = dest_level; | 925 GLint original_dest_level = dest_level; |
736 GLenum original_dest_target = dest_target; | 926 GLenum original_dest_target = dest_target; |
737 GLenum original_internal_format = dest_internal_format; | 927 GLenum original_internal_format = dest_internal_format; |
738 if (method == DRAW_AND_COPY) { | 928 if (method == DRAW_AND_COPY || method == DRAW_AND_READBACK) { |
739 GLenum adjusted_internal_format = | 929 GLenum adjusted_internal_format = |
740 getIntermediateFormat(dest_internal_format); | 930 method == DRAW_AND_READBACK |
| 931 ? GL_RGBA |
| 932 : getIntermediateFormat(dest_internal_format); |
741 dest_target = GL_TEXTURE_2D; | 933 dest_target = GL_TEXTURE_2D; |
742 glGenTextures(1, &intermediate_texture); | 934 glGenTextures(1, &intermediate_texture); |
743 glBindTexture(dest_target, intermediate_texture); | 935 glBindTexture(dest_target, intermediate_texture); |
744 GLenum format = TextureManager::ExtractFormatFromStorageFormat( | 936 GLenum format = TextureManager::ExtractFormatFromStorageFormat( |
745 adjusted_internal_format); | 937 adjusted_internal_format); |
746 GLenum type = | 938 GLenum type = |
747 TextureManager::ExtractTypeFromStorageFormat(adjusted_internal_format); | 939 TextureManager::ExtractTypeFromStorageFormat(adjusted_internal_format); |
748 | 940 |
749 glTexImage2D(dest_target, 0, adjusted_internal_format, width, height, 0, | 941 glTexImage2D(dest_target, 0, adjusted_internal_format, width, height, 0, |
750 format, type, nullptr); | 942 format, type, nullptr); |
751 dest_texture = intermediate_texture; | 943 dest_texture = intermediate_texture; |
752 dest_level = 0; | 944 dest_level = 0; |
753 dest_internal_format = adjusted_internal_format; | 945 dest_internal_format = adjusted_internal_format; |
754 } | 946 } |
755 // Use kIdentityMatrix if no transform passed in. | 947 // Use kIdentityMatrix if no transform passed in. |
756 DoCopyTextureWithTransform( | 948 DoCopyTextureWithTransform( |
757 decoder, source_target, source_id, source_level, source_internal_format, | 949 decoder, source_target, source_id, source_level, source_internal_format, |
758 dest_target, dest_texture, dest_level, dest_internal_format, width, | 950 dest_target, dest_texture, dest_level, dest_internal_format, width, |
759 height, flip_y, premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); | 951 height, flip_y, premultiply_alpha, unpremultiply_alpha, kIdentityMatrix); |
760 | 952 |
761 if (method == DRAW_AND_COPY) { | 953 if (method == DRAW_AND_COPY || method == DRAW_AND_READBACK) { |
762 source_level = 0; | 954 source_level = 0; |
763 DoCopyTexImage2D(decoder, dest_target, intermediate_texture, source_level, | 955 if (method == DRAW_AND_COPY) { |
764 original_dest_target, dest_id, original_dest_level, | 956 DoCopyTexImage2D(decoder, dest_target, intermediate_texture, source_level, |
765 original_internal_format, width, height, framebuffer_); | 957 original_dest_target, dest_id, original_dest_level, |
| 958 original_internal_format, width, height, framebuffer_); |
| 959 } else if (method == DRAW_AND_READBACK) { |
| 960 DoReadbackAndTexImage( |
| 961 kTexImage, decoder, dest_target, intermediate_texture, source_level, |
| 962 original_dest_target, dest_id, original_dest_level, |
| 963 original_internal_format, 0, 0, width, height, framebuffer_); |
| 964 } |
766 glDeleteTextures(1, &intermediate_texture); | 965 glDeleteTextures(1, &intermediate_texture); |
767 } | 966 } |
768 } | 967 } |
769 | 968 |
770 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( | 969 void CopyTextureCHROMIUMResourceManager::DoCopySubTexture( |
771 const gles2::GLES2Decoder* decoder, | 970 const gles2::GLES2Decoder* decoder, |
772 GLenum source_target, | 971 GLenum source_target, |
773 GLuint source_id, | 972 GLuint source_id, |
774 GLint source_level, | 973 GLint source_level, |
775 GLenum source_internal_format, | 974 GLenum source_internal_format, |
(...skipping 22 matching lines...) Expand all Loading... |
798 return; | 997 return; |
799 } | 998 } |
800 | 999 |
801 // Draw to level 0 of an intermediate GL_TEXTURE_2D texture. | 1000 // Draw to level 0 of an intermediate GL_TEXTURE_2D texture. |
802 GLint dest_xoffset = xoffset; | 1001 GLint dest_xoffset = xoffset; |
803 GLint dest_yoffset = yoffset; | 1002 GLint dest_yoffset = yoffset; |
804 GLuint dest_texture = dest_id; | 1003 GLuint dest_texture = dest_id; |
805 GLint original_dest_level = dest_level; | 1004 GLint original_dest_level = dest_level; |
806 GLenum original_dest_target = dest_target; | 1005 GLenum original_dest_target = dest_target; |
807 GLuint intermediate_texture = 0; | 1006 GLuint intermediate_texture = 0; |
808 if (method == DRAW_AND_COPY) { | 1007 GLenum original_internal_format = dest_internal_format; |
| 1008 if (method == DRAW_AND_COPY || method == DRAW_AND_READBACK) { |
809 GLenum adjusted_internal_format = | 1009 GLenum adjusted_internal_format = |
810 getIntermediateFormat(dest_internal_format); | 1010 method == DRAW_AND_READBACK |
| 1011 ? GL_RGBA |
| 1012 : getIntermediateFormat(dest_internal_format); |
811 dest_target = GL_TEXTURE_2D; | 1013 dest_target = GL_TEXTURE_2D; |
812 glGenTextures(1, &intermediate_texture); | 1014 glGenTextures(1, &intermediate_texture); |
813 glBindTexture(dest_target, intermediate_texture); | 1015 glBindTexture(dest_target, intermediate_texture); |
814 GLenum format = TextureManager::ExtractFormatFromStorageFormat( | 1016 GLenum format = TextureManager::ExtractFormatFromStorageFormat( |
815 adjusted_internal_format); | 1017 adjusted_internal_format); |
816 GLenum type = | 1018 GLenum type = |
817 TextureManager::ExtractTypeFromStorageFormat(adjusted_internal_format); | 1019 TextureManager::ExtractTypeFromStorageFormat(adjusted_internal_format); |
818 | 1020 |
819 glTexImage2D(dest_target, 0, adjusted_internal_format, width, height, 0, | 1021 glTexImage2D(dest_target, 0, adjusted_internal_format, width, height, 0, |
820 format, type, nullptr); | 1022 format, type, nullptr); |
821 dest_texture = intermediate_texture; | 1023 dest_texture = intermediate_texture; |
822 dest_level = 0; | 1024 dest_level = 0; |
823 dest_internal_format = adjusted_internal_format; | 1025 dest_internal_format = adjusted_internal_format; |
824 dest_xoffset = 0; | 1026 dest_xoffset = 0; |
825 dest_yoffset = 0; | 1027 dest_yoffset = 0; |
826 dest_width = width; | 1028 dest_width = width; |
827 dest_height = height; | 1029 dest_height = height; |
828 } | 1030 } |
829 | 1031 |
830 DoCopySubTextureWithTransform( | 1032 DoCopySubTextureWithTransform( |
831 decoder, source_target, source_id, source_level, source_internal_format, | 1033 decoder, source_target, source_id, source_level, source_internal_format, |
832 dest_target, dest_texture, dest_level, dest_internal_format, dest_xoffset, | 1034 dest_target, dest_texture, dest_level, dest_internal_format, dest_xoffset, |
833 dest_yoffset, x, y, width, height, dest_width, dest_height, source_width, | 1035 dest_yoffset, x, y, width, height, dest_width, dest_height, source_width, |
834 source_height, flip_y, premultiply_alpha, unpremultiply_alpha, | 1036 source_height, flip_y, premultiply_alpha, unpremultiply_alpha, |
835 kIdentityMatrix); | 1037 kIdentityMatrix); |
836 | 1038 |
837 if (method == DRAW_AND_COPY) { | 1039 if (method == DRAW_AND_COPY || method == DRAW_AND_READBACK) { |
838 source_level = 0; | 1040 source_level = 0; |
839 DoCopyTexSubImage2D(decoder, dest_target, intermediate_texture, | 1041 if (method == DRAW_AND_COPY) { |
840 source_level, original_dest_target, dest_id, | 1042 DoCopyTexSubImage2D(decoder, dest_target, intermediate_texture, |
841 original_dest_level, xoffset, yoffset, 0, 0, width, | 1043 source_level, original_dest_target, dest_id, |
842 height, framebuffer_); | 1044 original_dest_level, xoffset, yoffset, 0, 0, width, |
| 1045 height, framebuffer_); |
| 1046 } else if (method == DRAW_AND_READBACK) { |
| 1047 DoReadbackAndTexImage(kTexSubImage, decoder, dest_target, |
| 1048 intermediate_texture, source_level, |
| 1049 original_dest_target, dest_id, original_dest_level, |
| 1050 original_internal_format, xoffset, yoffset, width, |
| 1051 height, framebuffer_); |
| 1052 } |
843 glDeleteTextures(1, &intermediate_texture); | 1053 glDeleteTextures(1, &intermediate_texture); |
844 } | 1054 } |
845 } | 1055 } |
846 | 1056 |
847 void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( | 1057 void CopyTextureCHROMIUMResourceManager::DoCopySubTextureWithTransform( |
848 const gles2::GLES2Decoder* decoder, | 1058 const gles2::GLES2Decoder* decoder, |
849 GLenum source_target, | 1059 GLenum source_target, |
850 GLuint source_id, | 1060 GLuint source_id, |
851 GLint source_level, | 1061 GLint source_level, |
852 GLenum source_internal_format, | 1062 GLenum source_internal_format, |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 decoder->RestoreTextureUnitBindings(0); | 1343 decoder->RestoreTextureUnitBindings(0); |
1134 decoder->RestoreActiveTexture(); | 1344 decoder->RestoreActiveTexture(); |
1135 decoder->RestoreProgramBindings(); | 1345 decoder->RestoreProgramBindings(); |
1136 decoder->RestoreBufferBindings(); | 1346 decoder->RestoreBufferBindings(); |
1137 decoder->RestoreFramebufferBindings(); | 1347 decoder->RestoreFramebufferBindings(); |
1138 decoder->RestoreGlobalState(); | 1348 decoder->RestoreGlobalState(); |
1139 } | 1349 } |
1140 | 1350 |
1141 } // namespace gles2 | 1351 } // namespace gles2 |
1142 } // namespace gpu | 1352 } // namespace gpu |
OLD | NEW |