| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <list> | 10 #include <list> |
| (...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 | 905 |
| 906 // overridden from GLES2Decoder | 906 // overridden from GLES2Decoder |
| 907 virtual bool ClearLevel( | 907 virtual bool ClearLevel( |
| 908 unsigned service_id, | 908 unsigned service_id, |
| 909 unsigned bind_target, | 909 unsigned bind_target, |
| 910 unsigned target, | 910 unsigned target, |
| 911 int level, | 911 int level, |
| 912 unsigned format, | 912 unsigned format, |
| 913 unsigned type, | 913 unsigned type, |
| 914 int width, | 914 int width, |
| 915 int height); | 915 int height, |
| 916 bool is_texture_immutable); |
| 916 | 917 |
| 917 // Restore all GL state that affects clearing. | 918 // Restore all GL state that affects clearing. |
| 918 void RestoreClearState(); | 919 void RestoreClearState(); |
| 919 | 920 |
| 920 // Remembers the state of some capabilities. | 921 // Remembers the state of some capabilities. |
| 921 // Returns: true if glEnable/glDisable should actually be called. | 922 // Returns: true if glEnable/glDisable should actually be called. |
| 922 bool SetCapabilityState(GLenum cap, bool enabled); | 923 bool SetCapabilityState(GLenum cap, bool enabled); |
| 923 | 924 |
| 924 // Check that the currently bound framebuffers are valid. | 925 // Check that the currently bound framebuffers are valid. |
| 925 // Generates GL error if not. | 926 // Generates GL error if not. |
| (...skipping 2311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3237 glEnableVertexAttribArray(index); | 3238 glEnableVertexAttribArray(index); |
| 3238 } else { | 3239 } else { |
| 3239 SetGLError(GL_INVALID_VALUE, | 3240 SetGLError(GL_INVALID_VALUE, |
| 3240 "glEnableVertexAttribArray: index out of range"); | 3241 "glEnableVertexAttribArray: index out of range"); |
| 3241 } | 3242 } |
| 3242 } | 3243 } |
| 3243 | 3244 |
| 3244 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { | 3245 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { |
| 3245 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 3246 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
| 3246 if (!info || | 3247 if (!info || |
| 3247 !texture_manager()->MarkMipmapsGenerated(feature_info_, info, true)) { | 3248 !texture_manager()->MarkMipmapsGenerated(feature_info_, info)) { |
| 3248 SetGLError(GL_INVALID_OPERATION, | 3249 SetGLError(GL_INVALID_OPERATION, |
| 3249 "glGenerateMipmaps: Can not generate mips for npot textures"); | 3250 "glGenerateMipmaps: Can not generate mips for npot textures"); |
| 3250 return; | 3251 return; |
| 3251 } | 3252 } |
| 3252 // Workaround for Mac driver bug. In the large scheme of things setting | 3253 // Workaround for Mac driver bug. In the large scheme of things setting |
| 3253 // glTexParamter twice for glGenerateMipmap is probably not a lage performance | 3254 // glTexParamter twice for glGenerateMipmap is probably not a lage performance |
| 3254 // hit so there's probably no need to make this conditional. The bug appears | 3255 // hit so there's probably no need to make this conditional. The bug appears |
| 3255 // to be that if the filtering mode is set to something that doesn't require | 3256 // to be that if the filtering mode is set to something that doesn't require |
| 3256 // mipmaps for rendering, or is never set to something other than the default, | 3257 // mipmaps for rendering, or is never set to something other than the default, |
| 3257 // then glGenerateMipmap misbehaves. | 3258 // then glGenerateMipmap misbehaves. |
| (...skipping 2890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6148 } | 6149 } |
| 6149 | 6150 |
| 6150 bool GLES2DecoderImpl::ClearLevel( | 6151 bool GLES2DecoderImpl::ClearLevel( |
| 6151 unsigned service_id, | 6152 unsigned service_id, |
| 6152 unsigned bind_target, | 6153 unsigned bind_target, |
| 6153 unsigned target, | 6154 unsigned target, |
| 6154 int level, | 6155 int level, |
| 6155 unsigned format, | 6156 unsigned format, |
| 6156 unsigned type, | 6157 unsigned type, |
| 6157 int width, | 6158 int width, |
| 6158 int height) { | 6159 int height, |
| 6160 bool is_texture_immutable) { |
| 6159 // Assumes the size has already been checked. | 6161 // Assumes the size has already been checked. |
| 6160 uint32 pixels_size = 0; | 6162 uint32 pixels_size = 0; |
| 6161 if (!GLES2Util::ComputeImageDataSize( | 6163 if (!GLES2Util::ComputeImageDataSize( |
| 6162 width, height, format, type, unpack_alignment_, &pixels_size)) { | 6164 width, height, format, type, unpack_alignment_, &pixels_size)) { |
| 6163 return false; | 6165 return false; |
| 6164 } | 6166 } |
| 6165 scoped_array<char> zero(new char[pixels_size]); | 6167 scoped_array<char> zero(new char[pixels_size]); |
| 6166 memset(zero.get(), 0, pixels_size); | 6168 memset(zero.get(), 0, pixels_size); |
| 6167 glBindTexture(bind_target, service_id); | 6169 glBindTexture(bind_target, service_id); |
| 6168 WrappedTexImage2D( | 6170 if (is_texture_immutable) { |
| 6169 target, level, format, width, height, 0, format, type, zero.get()); | 6171 glTexSubImage2D( |
| 6172 target, level, 0, 0, width, height, format, type, zero.get()); |
| 6173 } else { |
| 6174 WrappedTexImage2D( |
| 6175 target, level, format, width, height, 0, format, type, zero.get()); |
| 6176 } |
| 6170 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target); | 6177 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target); |
| 6171 glBindTexture(bind_target, info ? info->service_id() : 0); | 6178 glBindTexture(bind_target, info ? info->service_id() : 0); |
| 6172 return true; | 6179 return true; |
| 6173 } | 6180 } |
| 6174 | 6181 |
| 6175 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( | 6182 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( |
| 6176 GLenum target, | 6183 GLenum target, |
| 6177 GLint level, | 6184 GLint level, |
| 6178 GLenum internal_format, | 6185 GLenum internal_format, |
| 6179 GLsizei width, | 6186 GLsizei width, |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6504 if (!info) { | 6511 if (!info) { |
| 6505 SetGLError(GL_INVALID_OPERATION, | 6512 SetGLError(GL_INVALID_OPERATION, |
| 6506 "glCompressedTexSubImage2D: unknown texture for target"); | 6513 "glCompressedTexSubImage2D: unknown texture for target"); |
| 6507 return; | 6514 return; |
| 6508 } | 6515 } |
| 6509 GLenum type = 0; | 6516 GLenum type = 0; |
| 6510 GLenum internal_format = 0; | 6517 GLenum internal_format = 0; |
| 6511 if (!info->GetLevelType(target, level, &type, &internal_format)) { | 6518 if (!info->GetLevelType(target, level, &type, &internal_format)) { |
| 6512 SetGLError( | 6519 SetGLError( |
| 6513 GL_INVALID_OPERATION, | 6520 GL_INVALID_OPERATION, |
| 6514 "glCompressdTexSubImage2D: level does not exist."); | 6521 "glCompressedTexSubImage2D: level does not exist."); |
| 6515 return; | 6522 return; |
| 6516 } | 6523 } |
| 6517 if (internal_format != format) { | 6524 if (internal_format != format) { |
| 6518 SetGLError( | 6525 SetGLError( |
| 6519 GL_INVALID_OPERATION, | 6526 GL_INVALID_OPERATION, |
| 6520 "glCompressdTexSubImage2D: format does not match internal format."); | 6527 "glCompressedTexSubImage2D: format does not match internal format."); |
| 6521 return; | 6528 return; |
| 6522 } | 6529 } |
| 6523 if (!info->ValidForTexture( | 6530 if (!info->ValidForTexture( |
| 6524 target, level, xoffset, yoffset, width, height, format, type)) { | 6531 target, level, xoffset, yoffset, width, height, format, type)) { |
| 6525 SetGLError(GL_INVALID_VALUE, | 6532 SetGLError(GL_INVALID_VALUE, |
| 6526 "glCompressdTexSubImage2D: bad dimensions."); | 6533 "glCompressedTexSubImage2D: bad dimensions."); |
| 6527 return; | 6534 return; |
| 6528 } | 6535 } |
| 6529 // Note: There is no need to deal with texture cleared tracking here | 6536 // Note: There is no need to deal with texture cleared tracking here |
| 6530 // because the validation above means you can only get here if the level | 6537 // because the validation above means you can only get here if the level |
| 6531 // is already a matching compressed format and in that case | 6538 // is already a matching compressed format and in that case |
| 6532 // CompressedTexImage2D already cleared the texture. | 6539 // CompressedTexImage2D already cleared the texture. |
| 6533 glCompressedTexSubImage2D( | 6540 glCompressedTexSubImage2D( |
| 6534 target, level, xoffset, yoffset, width, height, format, image_size, data); | 6541 target, level, xoffset, yoffset, width, height, format, image_size, data); |
| 6535 } | 6542 } |
| 6536 | 6543 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6607 Clip(x, width, size.width(), ©X, ©Width); | 6614 Clip(x, width, size.width(), ©X, ©Width); |
| 6608 Clip(y, height, size.height(), ©Y, ©Height); | 6615 Clip(y, height, size.height(), ©Y, ©Height); |
| 6609 | 6616 |
| 6610 if (copyX != x || | 6617 if (copyX != x || |
| 6611 copyY != y || | 6618 copyY != y || |
| 6612 copyWidth != width || | 6619 copyWidth != width || |
| 6613 copyHeight != height) { | 6620 copyHeight != height) { |
| 6614 // some part was clipped so clear the texture. | 6621 // some part was clipped so clear the texture. |
| 6615 if (!ClearLevel( | 6622 if (!ClearLevel( |
| 6616 info->service_id(), info->target(), | 6623 info->service_id(), info->target(), |
| 6617 target, level, internal_format, GL_UNSIGNED_BYTE, width, height)) { | 6624 target, level, internal_format, GL_UNSIGNED_BYTE, width, height, |
| 6625 info->IsImmutable())) { |
| 6618 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D: dimensions too big"); | 6626 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D: dimensions too big"); |
| 6619 return; | 6627 return; |
| 6620 } | 6628 } |
| 6621 if (copyHeight > 0 && copyWidth > 0) { | 6629 if (copyHeight > 0 && copyWidth > 0) { |
| 6622 GLint dx = copyX - x; | 6630 GLint dx = copyX - x; |
| 6623 GLint dy = copyY - y; | 6631 GLint dy = copyY - y; |
| 6624 GLint destX = dx; | 6632 GLint destX = dx; |
| 6625 GLint destY = dy; | 6633 GLint destY = dy; |
| 6626 glCopyTexSubImage2D(target, level, | 6634 glCopyTexSubImage2D(target, level, |
| 6627 destX, destY, copyX, copyY, | 6635 destX, destY, copyX, copyY, |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6757 return; | 6765 return; |
| 6758 } | 6766 } |
| 6759 | 6767 |
| 6760 if (!info->ValidForTexture( | 6768 if (!info->ValidForTexture( |
| 6761 target, level, xoffset, yoffset, width, height, format, type)) { | 6769 target, level, xoffset, yoffset, width, height, format, type)) { |
| 6762 SetGLError(GL_INVALID_VALUE, | 6770 SetGLError(GL_INVALID_VALUE, |
| 6763 "glTexSubImage2D: bad dimensions."); | 6771 "glTexSubImage2D: bad dimensions."); |
| 6764 return; | 6772 return; |
| 6765 } | 6773 } |
| 6766 | 6774 |
| 6767 // See if we can call glTexImage2D instead since it appears to be faster. | 6775 GLsizei tex_width = 0; |
| 6768 if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0 && | 6776 GLsizei tex_height = 0; |
| 6769 !info->IsImmutable()) { | 6777 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); |
| 6770 GLsizei tex_width = 0; | 6778 DCHECK(ok); |
| 6771 GLsizei tex_height = 0; | 6779 if (xoffset != 0 || yoffset != 0 || |
| 6772 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); | 6780 width != tex_width || height != tex_height) { |
| 6773 DCHECK(ok); | 6781 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { |
| 6774 if (width == tex_width && height == tex_height) { | 6782 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big"); |
| 6775 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the | |
| 6776 // same as internal_foramt. If that changes we'll need to look them up. | |
| 6777 WrappedTexImage2D( | |
| 6778 target, level, format, width, height, 0, format, type, data); | |
| 6779 texture_manager()->SetLevelCleared(info, target, level); | |
| 6780 return; | 6783 return; |
| 6781 } | 6784 } |
| 6782 } | 6785 glTexSubImage2D( |
| 6783 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { | 6786 target, level, xoffset, yoffset, width, height, format, type, data); |
| 6784 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big"); | |
| 6785 return; | 6787 return; |
| 6786 } | 6788 } |
| 6787 glTexSubImage2D( | 6789 |
| 6788 target, level, xoffset, yoffset, width, height, format, type, data); | 6790 if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) { |
| 6791 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the |
| 6792 // same as internal_foramt. If that changes we'll need to look them up. |
| 6793 WrappedTexImage2D( |
| 6794 target, level, format, width, height, 0, format, type, data); |
| 6795 } else { |
| 6796 glTexSubImage2D( |
| 6797 target, level, xoffset, yoffset, width, height, format, type, data); |
| 6798 } |
| 6799 texture_manager()->SetLevelCleared(info, target, level); |
| 6789 } | 6800 } |
| 6790 | 6801 |
| 6791 error::Error GLES2DecoderImpl::HandleTexSubImage2D( | 6802 error::Error GLES2DecoderImpl::HandleTexSubImage2D( |
| 6792 uint32 immediate_data_size, const gles2::TexSubImage2D& c) { | 6803 uint32 immediate_data_size, const gles2::TexSubImage2D& c) { |
| 6793 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D"); | 6804 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D"); |
| 6794 GLboolean internal = static_cast<GLboolean>(c.internal); | 6805 GLboolean internal = static_cast<GLboolean>(c.internal); |
| 6795 if (internal == GL_TRUE && tex_image_2d_failed_) | 6806 if (internal == GL_TRUE && tex_image_2d_failed_) |
| 6796 return error::kNoError; | 6807 return error::kNoError; |
| 6797 | 6808 |
| 6798 GLenum target = static_cast<GLenum>(c.target); | 6809 GLenum target = static_cast<GLenum>(c.target); |
| (...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7836 SetGLError(GL_INVALID_OPERATION, | 7847 SetGLError(GL_INVALID_OPERATION, |
| 7837 "glTexStorage2DEXT: texture is immutable"); | 7848 "glTexStorage2DEXT: texture is immutable"); |
| 7838 return; | 7849 return; |
| 7839 } | 7850 } |
| 7840 CopyRealGLErrorsToWrapper(); | 7851 CopyRealGLErrorsToWrapper(); |
| 7841 glTexStorage2DEXT(target, levels, internal_format, width, height); | 7852 glTexStorage2DEXT(target, levels, internal_format, width, height); |
| 7842 GLenum error = PeekGLError(); | 7853 GLenum error = PeekGLError(); |
| 7843 if (error == GL_NO_ERROR) { | 7854 if (error == GL_NO_ERROR) { |
| 7844 GLenum format = ExtractFormatFromStorageFormat(internal_format); | 7855 GLenum format = ExtractFormatFromStorageFormat(internal_format); |
| 7845 GLenum type = ExtractTypeFromStorageFormat(internal_format); | 7856 GLenum type = ExtractTypeFromStorageFormat(internal_format); |
| 7846 texture_manager()->SetLevelInfo( | 7857 GLsizei level_width = width; |
| 7847 feature_info_, info, | 7858 GLsizei level_height = height; |
| 7848 target, 0, format, width, height, 1, 0, format, type, | 7859 for (int ii = 0; ii < levels; ++ii) { |
| 7849 false); | 7860 texture_manager()->SetLevelInfo( |
| 7850 texture_manager()->MarkMipmapsGenerated(feature_info_, info, false); | 7861 feature_info_, info, |
| 7862 target, 0, format, level_width, level_height, 1, 0, format, type, |
| 7863 false); |
| 7864 level_width = std::max(1, level_width >> 1); |
| 7865 level_height = std::max(1, level_height >> 1); |
| 7866 } |
| 7851 info->SetImmutable(true); | 7867 info->SetImmutable(true); |
| 7852 } | 7868 } |
| 7853 | 7869 |
| 7854 } | 7870 } |
| 7855 | 7871 |
| 7856 // Include the auto-generated part of this file. We split this because it means | 7872 // Include the auto-generated part of this file. We split this because it means |
| 7857 // we can easily edit the non-auto generated parts right here in this file | 7873 // we can easily edit the non-auto generated parts right here in this file |
| 7858 // instead of having to edit some template or the code generator. | 7874 // instead of having to edit some template or the code generator. |
| 7859 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 7875 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 7860 | 7876 |
| 7861 } // namespace gles2 | 7877 } // namespace gles2 |
| 7862 } // namespace gpu | 7878 } // namespace gpu |
| OLD | NEW |