| 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_decoder.h" | 5 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" |
| 6 | 6 |
| 7 #include <stdio.h> | 7 #include <stdio.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <cmath> | 10 #include <cmath> |
| (...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 GLsizei width, | 1057 GLsizei width, |
| 1058 GLsizei height, | 1058 GLsizei height, |
| 1059 GLboolean unpack_flip_y, | 1059 GLboolean unpack_flip_y, |
| 1060 GLboolean unpack_premultiply_alpha, | 1060 GLboolean unpack_premultiply_alpha, |
| 1061 GLboolean unpack_unmultiply_alpha); | 1061 GLboolean unpack_unmultiply_alpha); |
| 1062 | 1062 |
| 1063 void DoCompressedCopyTextureCHROMIUM(GLenum target, | 1063 void DoCompressedCopyTextureCHROMIUM(GLenum target, |
| 1064 GLuint source_id, | 1064 GLuint source_id, |
| 1065 GLuint dest_id); | 1065 GLuint dest_id); |
| 1066 | 1066 |
| 1067 void DoCompressedCopySubTextureCHROMIUM(GLenum target, |
| 1068 GLuint source_id, |
| 1069 GLuint dest_id, |
| 1070 GLint xoffset, |
| 1071 GLint yoffset, |
| 1072 GLint x, |
| 1073 GLint y, |
| 1074 GLsizei width, |
| 1075 GLsizei height); |
| 1076 |
| 1067 // Wrapper for TexStorage2DEXT. | 1077 // Wrapper for TexStorage2DEXT. |
| 1068 void DoTexStorage2DEXT( | 1078 void DoTexStorage2DEXT( |
| 1069 GLenum target, | 1079 GLenum target, |
| 1070 GLint levels, | 1080 GLint levels, |
| 1071 GLenum internal_format, | 1081 GLenum internal_format, |
| 1072 GLsizei width, | 1082 GLsizei width, |
| 1073 GLsizei height); | 1083 GLsizei height); |
| 1074 | 1084 |
| 1075 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); | 1085 void DoProduceTextureCHROMIUM(GLenum target, const GLbyte* key); |
| 1076 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, | 1086 void DoProduceTextureDirectCHROMIUM(GLuint texture, GLenum target, |
| (...skipping 11571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12648 } else { | 12658 } else { |
| 12649 copy_texture_CHROMIUM_->DoCopyTexture( | 12659 copy_texture_CHROMIUM_->DoCopyTexture( |
| 12650 this, source_texture->target(), source_texture->service_id(), | 12660 this, source_texture->target(), source_texture->service_id(), |
| 12651 source_internal_format, dest_texture->service_id(), GL_RGBA, | 12661 source_internal_format, dest_texture->service_id(), GL_RGBA, |
| 12652 source_width, source_height, false, false, false); | 12662 source_width, source_height, false, false, false); |
| 12653 } | 12663 } |
| 12654 | 12664 |
| 12655 DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); | 12665 DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); |
| 12656 } | 12666 } |
| 12657 | 12667 |
| 12668 void GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM(GLenum target, |
| 12669 GLuint source_id, |
| 12670 GLuint dest_id, |
| 12671 GLint xoffset, |
| 12672 GLint yoffset, |
| 12673 GLint x, |
| 12674 GLint y, |
| 12675 GLsizei width, |
| 12676 GLsizei height) { |
| 12677 TRACE_EVENT0("gpu", "GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM"); |
| 12678 |
| 12679 TextureRef* source_texture_ref = GetTexture(source_id); |
| 12680 TextureRef* dest_texture_ref = GetTexture(dest_id); |
| 12681 Texture* source_texture = source_texture_ref->texture(); |
| 12682 Texture* dest_texture = dest_texture_ref->texture(); |
| 12683 int source_width = 0; |
| 12684 int source_height = 0; |
| 12685 gfx::GLImage* image = |
| 12686 source_texture->GetLevelImage(source_texture->target(), 0); |
| 12687 if (image) { |
| 12688 gfx::Size size = image->GetSize(); |
| 12689 source_width = size.width(); |
| 12690 source_height = size.height(); |
| 12691 if (source_width <= 0 || source_height <= 0) { |
| 12692 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12693 "invalid image size"); |
| 12694 return; |
| 12695 } |
| 12696 } else { |
| 12697 if (!source_texture->GetLevelSize(source_texture->target(), 0, |
| 12698 &source_width, &source_height, nullptr)) { |
| 12699 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12700 "source texture has no level 0"); |
| 12701 return; |
| 12702 } |
| 12703 |
| 12704 // Check that this type of texture is allowed. |
| 12705 if (!texture_manager()->ValidForTarget(source_texture->target(), 0, |
| 12706 source_width, source_height, 1)) { |
| 12707 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12708 "source texture bad dimensions"); |
| 12709 return; |
| 12710 } |
| 12711 } |
| 12712 |
| 12713 GLenum source_type = 0; |
| 12714 GLenum source_internal_format = 0; |
| 12715 source_texture->GetLevelType(source_texture->target(), 0, &source_type, |
| 12716 &source_internal_format); |
| 12717 if (!source_texture->ValidForTexture(source_texture->target(), 0, x, y, 0, |
| 12718 width, height, 1, source_type)) { |
| 12719 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12720 "source texture bad dimensions."); |
| 12721 return; |
| 12722 } |
| 12723 |
| 12724 GLenum dest_type = 0; |
| 12725 GLenum dest_internal_format = 0; |
| 12726 bool dest_level_defined = dest_texture->GetLevelType( |
| 12727 dest_texture->target(), 0, &dest_type, &dest_internal_format); |
| 12728 if (!dest_level_defined) { |
| 12729 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, |
| 12730 "glCompressedCopySubTextureCHROMIUM", |
| 12731 "destination texture is not defined"); |
| 12732 return; |
| 12733 } |
| 12734 if (!dest_texture->ValidForTexture(dest_texture->target(), 0, xoffset, |
| 12735 yoffset, 0, width, height, 1, dest_type)) { |
| 12736 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glCompressedCopySubTextureCHROMIUM", |
| 12737 "destination texture bad dimensions."); |
| 12738 return; |
| 12739 } |
| 12740 |
| 12741 if (!ValidateCompressedCopyTextureCHROMIUM( |
| 12742 "glCompressedCopySubTextureCHROMIUM", target, source_texture_ref, |
| 12743 dest_texture_ref)) { |
| 12744 return; |
| 12745 } |
| 12746 |
| 12747 if (!ValidateCompressedTexSubDimensions("glCompressedCopySubTextureCHROMIUM", |
| 12748 source_texture->target(), 0, x, y, 0, |
| 12749 width, height, 1, |
| 12750 source_internal_format, |
| 12751 source_texture) || |
| 12752 !ValidateCompressedTexSubDimensions("glCompressedCopySubTextureCHROMIUM", |
| 12753 dest_texture->target(), 0, |
| 12754 xoffset, yoffset, 0, width, height, 1, |
| 12755 dest_internal_format, |
| 12756 dest_texture)) { |
| 12757 return; |
| 12758 } |
| 12759 |
| 12760 // Defer initializing the CopyTextureCHROMIUMResourceManager until it is |
| 12761 // needed because it takes 10s of milliseconds to initialize. |
| 12762 if (!copy_texture_CHROMIUM_.get()) { |
| 12763 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopySubTextureCHROMIUM"); |
| 12764 copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); |
| 12765 copy_texture_CHROMIUM_->Initialize(this); |
| 12766 RestoreCurrentFramebufferBindings(); |
| 12767 if (LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM") != |
| 12768 GL_NO_ERROR) { |
| 12769 return; |
| 12770 } |
| 12771 } |
| 12772 |
| 12773 // Clear the source texture if necessary. |
| 12774 if (!texture_manager()->ClearTextureLevel(this, source_texture_ref, |
| 12775 source_texture->target(), 0)) { |
| 12776 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, "glCompressedCopySubTextureCHROMIUM", |
| 12777 "source texture dimensions too big"); |
| 12778 return; |
| 12779 } |
| 12780 |
| 12781 int dest_width = 0; |
| 12782 int dest_height = 0; |
| 12783 bool ok = dest_texture->GetLevelSize( |
| 12784 GL_TEXTURE_2D, 0, &dest_width, &dest_height, nullptr); |
| 12785 DCHECK(ok); |
| 12786 if (xoffset != 0 || yoffset != 0 || width != dest_width || |
| 12787 height != dest_height) { |
| 12788 gfx::Rect cleared_rect; |
| 12789 if (CombineAdjacentRects(dest_texture->GetLevelClearedRect(target, 0), |
| 12790 gfx::Rect(xoffset, yoffset, width, height), |
| 12791 &cleared_rect)) { |
| 12792 DCHECK_GE(cleared_rect.size().GetArea(), |
| 12793 dest_texture->GetLevelClearedRect(target, 0).size().GetArea()); |
| 12794 texture_manager()->SetLevelClearedRect(dest_texture_ref, target, 0, |
| 12795 cleared_rect); |
| 12796 } else { |
| 12797 // Otherwise clear part of texture level that is not already cleared. |
| 12798 if (!texture_manager()->ClearTextureLevel(this, dest_texture_ref, target, |
| 12799 0)) { |
| 12800 LOCAL_SET_GL_ERROR(GL_OUT_OF_MEMORY, |
| 12801 "glCompressedCopySubTextureCHROMIUM", |
| 12802 "destination texture dimensions too big"); |
| 12803 return; |
| 12804 } |
| 12805 } |
| 12806 } else { |
| 12807 texture_manager()->SetLevelCleared(dest_texture_ref, GL_TEXTURE_2D, 0, |
| 12808 true); |
| 12809 } |
| 12810 |
| 12811 ScopedTextureBinder binder( |
| 12812 &state_, dest_texture->service_id(), GL_TEXTURE_2D); |
| 12813 |
| 12814 ScopedModifyPixels modify(dest_texture_ref); |
| 12815 |
| 12816 // Try using GLImage::CopyTexSubImage when possible. |
| 12817 if (image) { |
| 12818 if (image->CopyTexSubImage(GL_TEXTURE_2D, gfx::Point(xoffset, yoffset), |
| 12819 gfx::Rect(x, y, width, height))) { |
| 12820 return; |
| 12821 } |
| 12822 } |
| 12823 |
| 12824 TRACE_EVENT0( |
| 12825 "gpu", |
| 12826 "GLES2DecoderImpl::DoCompressedCopySubTextureCHROMIUM, fallback"); |
| 12827 |
| 12828 DoWillUseTexImageIfNeeded(source_texture, source_texture->target()); |
| 12829 |
| 12830 // As a fallback, copy into a non-compressed GL_RGBA texture. |
| 12831 if (dest_internal_format != GL_RGBA) { |
| 12832 // To preserve the contents of the original destination texture we must |
| 12833 // first copy the original destination texture to a temporary storage, then |
| 12834 // copy it back to the original destination texture. |
| 12835 GLuint tmp_service_id; |
| 12836 glGenTextures(1, &tmp_service_id); |
| 12837 DCHECK_NE(0u, tmp_service_id); |
| 12838 |
| 12839 glBindTexture(GL_TEXTURE_2D, tmp_service_id); |
| 12840 |
| 12841 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM"); |
| 12842 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dest_width, dest_height, 0, GL_RGBA, |
| 12843 GL_UNSIGNED_BYTE, NULL); |
| 12844 GLenum error = LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM"); |
| 12845 if (error != GL_NO_ERROR) |
| 12846 return; |
| 12847 |
| 12848 copy_texture_CHROMIUM_->DoCopyTexture( |
| 12849 this, dest_texture->target(), dest_texture->service_id(), |
| 12850 dest_internal_format, tmp_service_id, GL_RGBA, |
| 12851 dest_width, dest_height, false, false, false); |
| 12852 |
| 12853 // Redefine destination texture to use RGBA. |
| 12854 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); |
| 12855 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCompressedCopyTextureCHROMIUM"); |
| 12856 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dest_width, dest_height, 0, GL_RGBA, |
| 12857 GL_UNSIGNED_BYTE, NULL); |
| 12858 error = LOCAL_PEEK_GL_ERROR("glCompressedCopySubTextureCHROMIUM"); |
| 12859 if (error != GL_NO_ERROR) |
| 12860 return; |
| 12861 |
| 12862 texture_manager()->SetLevelInfo( |
| 12863 dest_texture_ref, GL_TEXTURE_2D, 0, GL_RGBA, dest_width, dest_height, |
| 12864 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect(dest_width, dest_height)); |
| 12865 |
| 12866 copy_texture_CHROMIUM_->DoCopyTexture( |
| 12867 this, GL_TEXTURE_2D, tmp_service_id, GL_RGBA, |
| 12868 dest_texture->service_id(), GL_RGBA, |
| 12869 dest_width, dest_height, false, false, false); |
| 12870 |
| 12871 glDeleteTextures(1, &tmp_service_id); |
| 12872 } |
| 12873 |
| 12874 // TODO(hkuang): get the StreamTexture transform matrix in GPU process. |
| 12875 // crbug.com/226218. |
| 12876 copy_texture_CHROMIUM_->DoCopySubTexture( |
| 12877 this, source_texture->target(), source_texture->service_id(), |
| 12878 source_internal_format, dest_texture->service_id(), GL_RGBA, |
| 12879 xoffset, yoffset, x, y, width, height, dest_width, dest_height, |
| 12880 source_width, source_height, false, false, false); |
| 12881 |
| 12882 DoDidUseTexImageIfNeeded(source_texture, source_texture->target()); |
| 12883 } |
| 12884 |
| 12658 static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { | 12885 static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { |
| 12659 switch (internalformat) { | 12886 switch (internalformat) { |
| 12660 case GL_R8: | 12887 case GL_R8: |
| 12661 return GL_UNSIGNED_BYTE; | 12888 return GL_UNSIGNED_BYTE; |
| 12662 case GL_R8_SNORM: | 12889 case GL_R8_SNORM: |
| 12663 return GL_BYTE; | 12890 return GL_BYTE; |
| 12664 case GL_R16F: | 12891 case GL_R16F: |
| 12665 return GL_HALF_FLOAT; | 12892 return GL_HALF_FLOAT; |
| 12666 case GL_R32F: | 12893 case GL_R32F: |
| 12667 return GL_FLOAT; | 12894 return GL_FLOAT; |
| (...skipping 1737 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14405 return error::kNoError; | 14632 return error::kNoError; |
| 14406 } | 14633 } |
| 14407 | 14634 |
| 14408 // Include the auto-generated part of this file. We split this because it means | 14635 // Include the auto-generated part of this file. We split this because it means |
| 14409 // we can easily edit the non-auto generated parts right here in this file | 14636 // we can easily edit the non-auto generated parts right here in this file |
| 14410 // instead of having to edit some template or the code generator. | 14637 // instead of having to edit some template or the code generator. |
| 14411 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 14638 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 14412 | 14639 |
| 14413 } // namespace gles2 | 14640 } // namespace gles2 |
| 14414 } // namespace gpu | 14641 } // namespace gpu |
| OLD | NEW |