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 893 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
904 | 904 |
905 // overridden from GLES2Decoder | 905 // overridden from GLES2Decoder |
906 virtual bool ClearLevel( | 906 virtual bool ClearLevel( |
907 unsigned service_id, | 907 unsigned service_id, |
908 unsigned bind_target, | 908 unsigned bind_target, |
909 unsigned target, | 909 unsigned target, |
910 int level, | 910 int level, |
911 unsigned format, | 911 unsigned format, |
912 unsigned type, | 912 unsigned type, |
913 int width, | 913 int width, |
914 int height, | 914 int height); |
915 bool is_texture_immutable); | |
916 | 915 |
917 // Restore all GL state that affects clearing. | 916 // Restore all GL state that affects clearing. |
918 void RestoreClearState(); | 917 void RestoreClearState(); |
919 | 918 |
920 // Remembers the state of some capabilities. | 919 // Remembers the state of some capabilities. |
921 // Returns: true if glEnable/glDisable should actually be called. | 920 // Returns: true if glEnable/glDisable should actually be called. |
922 bool SetCapabilityState(GLenum cap, bool enabled); | 921 bool SetCapabilityState(GLenum cap, bool enabled); |
923 | 922 |
924 // Check that the currently bound framebuffers are valid. | 923 // Check that the currently bound framebuffers are valid. |
925 // Generates GL error if not. | 924 // Generates GL error if not. |
(...skipping 2306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3232 glEnableVertexAttribArray(index); | 3231 glEnableVertexAttribArray(index); |
3233 } else { | 3232 } else { |
3234 SetGLError(GL_INVALID_VALUE, | 3233 SetGLError(GL_INVALID_VALUE, |
3235 "glEnableVertexAttribArray: index out of range"); | 3234 "glEnableVertexAttribArray: index out of range"); |
3236 } | 3235 } |
3237 } | 3236 } |
3238 | 3237 |
3239 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { | 3238 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { |
3240 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 3239 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
3241 if (!info || | 3240 if (!info || |
3242 !texture_manager()->MarkMipmapsGenerated(feature_info_, info)) { | 3241 !texture_manager()->MarkMipmapsGenerated(feature_info_, info, true)) { |
3243 SetGLError(GL_INVALID_OPERATION, | 3242 SetGLError(GL_INVALID_OPERATION, |
3244 "glGenerateMipmaps: Can not generate mips for npot textures"); | 3243 "glGenerateMipmaps: Can not generate mips for npot textures"); |
3245 return; | 3244 return; |
3246 } | 3245 } |
3247 // Workaround for Mac driver bug. In the large scheme of things setting | 3246 // Workaround for Mac driver bug. In the large scheme of things setting |
3248 // glTexParamter twice for glGenerateMipmap is probably not a lage performance | 3247 // glTexParamter twice for glGenerateMipmap is probably not a lage performance |
3249 // hit so there's probably no need to make this conditional. The bug appears | 3248 // hit so there's probably no need to make this conditional. The bug appears |
3250 // to be that if the filtering mode is set to something that doesn't require | 3249 // to be that if the filtering mode is set to something that doesn't require |
3251 // mipmaps for rendering, or is never set to something other than the default, | 3250 // mipmaps for rendering, or is never set to something other than the default, |
3252 // then glGenerateMipmap misbehaves. | 3251 // then glGenerateMipmap misbehaves. |
(...skipping 2884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6137 } | 6136 } |
6138 | 6137 |
6139 bool GLES2DecoderImpl::ClearLevel( | 6138 bool GLES2DecoderImpl::ClearLevel( |
6140 unsigned service_id, | 6139 unsigned service_id, |
6141 unsigned bind_target, | 6140 unsigned bind_target, |
6142 unsigned target, | 6141 unsigned target, |
6143 int level, | 6142 int level, |
6144 unsigned format, | 6143 unsigned format, |
6145 unsigned type, | 6144 unsigned type, |
6146 int width, | 6145 int width, |
6147 int height, | 6146 int height) { |
6148 bool is_texture_immutable) { | |
6149 // Assumes the size has already been checked. | 6147 // Assumes the size has already been checked. |
6150 uint32 pixels_size = 0; | 6148 uint32 pixels_size = 0; |
6151 if (!GLES2Util::ComputeImageDataSize( | 6149 if (!GLES2Util::ComputeImageDataSize( |
6152 width, height, format, type, unpack_alignment_, &pixels_size)) { | 6150 width, height, format, type, unpack_alignment_, &pixels_size)) { |
6153 return false; | 6151 return false; |
6154 } | 6152 } |
6155 scoped_array<char> zero(new char[pixels_size]); | 6153 scoped_array<char> zero(new char[pixels_size]); |
6156 memset(zero.get(), 0, pixels_size); | 6154 memset(zero.get(), 0, pixels_size); |
6157 glBindTexture(bind_target, service_id); | 6155 glBindTexture(bind_target, service_id); |
6158 if (is_texture_immutable) { | 6156 WrappedTexImage2D( |
6159 glTexSubImage2D( | 6157 target, level, format, width, height, 0, format, type, zero.get()); |
6160 target, level, 0, 0, width, height, format, type, zero.get()); | |
6161 } else { | |
6162 WrappedTexImage2D( | |
6163 target, level, format, width, height, 0, format, type, zero.get()); | |
6164 } | |
6165 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target); | 6158 TextureManager::TextureInfo* info = GetTextureInfoForTarget(bind_target); |
6166 glBindTexture(bind_target, info ? info->service_id() : 0); | 6159 glBindTexture(bind_target, info ? info->service_id() : 0); |
6167 return true; | 6160 return true; |
6168 } | 6161 } |
6169 | 6162 |
6170 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( | 6163 error::Error GLES2DecoderImpl::DoCompressedTexImage2D( |
6171 GLenum target, | 6164 GLenum target, |
6172 GLint level, | 6165 GLint level, |
6173 GLenum internal_format, | 6166 GLenum internal_format, |
6174 GLsizei width, | 6167 GLsizei width, |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6499 if (!info) { | 6492 if (!info) { |
6500 SetGLError(GL_INVALID_OPERATION, | 6493 SetGLError(GL_INVALID_OPERATION, |
6501 "glCompressedTexSubImage2D: unknown texture for target"); | 6494 "glCompressedTexSubImage2D: unknown texture for target"); |
6502 return; | 6495 return; |
6503 } | 6496 } |
6504 GLenum type = 0; | 6497 GLenum type = 0; |
6505 GLenum internal_format = 0; | 6498 GLenum internal_format = 0; |
6506 if (!info->GetLevelType(target, level, &type, &internal_format)) { | 6499 if (!info->GetLevelType(target, level, &type, &internal_format)) { |
6507 SetGLError( | 6500 SetGLError( |
6508 GL_INVALID_OPERATION, | 6501 GL_INVALID_OPERATION, |
6509 "glCompressedTexSubImage2D: level does not exist."); | 6502 "glCompressdTexSubImage2D: level does not exist."); |
6510 return; | 6503 return; |
6511 } | 6504 } |
6512 if (internal_format != format) { | 6505 if (internal_format != format) { |
6513 SetGLError( | 6506 SetGLError( |
6514 GL_INVALID_OPERATION, | 6507 GL_INVALID_OPERATION, |
6515 "glCompressedTexSubImage2D: format does not match internal format."); | 6508 "glCompressdTexSubImage2D: format does not match internal format."); |
6516 return; | 6509 return; |
6517 } | 6510 } |
6518 if (!info->ValidForTexture( | 6511 if (!info->ValidForTexture( |
6519 target, level, xoffset, yoffset, width, height, format, type)) { | 6512 target, level, xoffset, yoffset, width, height, format, type)) { |
6520 SetGLError(GL_INVALID_VALUE, | 6513 SetGLError(GL_INVALID_VALUE, |
6521 "glCompressedTexSubImage2D: bad dimensions."); | 6514 "glCompressdTexSubImage2D: bad dimensions."); |
6522 return; | 6515 return; |
6523 } | 6516 } |
6524 // Note: There is no need to deal with texture cleared tracking here | 6517 // Note: There is no need to deal with texture cleared tracking here |
6525 // because the validation above means you can only get here if the level | 6518 // because the validation above means you can only get here if the level |
6526 // is already a matching compressed format and in that case | 6519 // is already a matching compressed format and in that case |
6527 // CompressedTexImage2D already cleared the texture. | 6520 // CompressedTexImage2D already cleared the texture. |
6528 glCompressedTexSubImage2D( | 6521 glCompressedTexSubImage2D( |
6529 target, level, xoffset, yoffset, width, height, format, image_size, data); | 6522 target, level, xoffset, yoffset, width, height, format, image_size, data); |
6530 } | 6523 } |
6531 | 6524 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6602 Clip(x, width, size.width(), ©X, ©Width); | 6595 Clip(x, width, size.width(), ©X, ©Width); |
6603 Clip(y, height, size.height(), ©Y, ©Height); | 6596 Clip(y, height, size.height(), ©Y, ©Height); |
6604 | 6597 |
6605 if (copyX != x || | 6598 if (copyX != x || |
6606 copyY != y || | 6599 copyY != y || |
6607 copyWidth != width || | 6600 copyWidth != width || |
6608 copyHeight != height) { | 6601 copyHeight != height) { |
6609 // some part was clipped so clear the texture. | 6602 // some part was clipped so clear the texture. |
6610 if (!ClearLevel( | 6603 if (!ClearLevel( |
6611 info->service_id(), info->target(), | 6604 info->service_id(), info->target(), |
6612 target, level, internal_format, GL_UNSIGNED_BYTE, width, height, | 6605 target, level, internal_format, GL_UNSIGNED_BYTE, width, height)) { |
6613 info->IsImmutable())) { | |
6614 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D: dimensions too big"); | 6606 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D: dimensions too big"); |
6615 return; | 6607 return; |
6616 } | 6608 } |
6617 if (copyHeight > 0 && copyWidth > 0) { | 6609 if (copyHeight > 0 && copyWidth > 0) { |
6618 GLint dx = copyX - x; | 6610 GLint dx = copyX - x; |
6619 GLint dy = copyY - y; | 6611 GLint dy = copyY - y; |
6620 GLint destX = dx; | 6612 GLint destX = dx; |
6621 GLint destY = dy; | 6613 GLint destY = dy; |
6622 glCopyTexSubImage2D(target, level, | 6614 glCopyTexSubImage2D(target, level, |
6623 destX, destY, copyX, copyY, | 6615 destX, destY, copyX, copyY, |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6753 return; | 6745 return; |
6754 } | 6746 } |
6755 | 6747 |
6756 if (!info->ValidForTexture( | 6748 if (!info->ValidForTexture( |
6757 target, level, xoffset, yoffset, width, height, format, type)) { | 6749 target, level, xoffset, yoffset, width, height, format, type)) { |
6758 SetGLError(GL_INVALID_VALUE, | 6750 SetGLError(GL_INVALID_VALUE, |
6759 "glTexSubImage2D: bad dimensions."); | 6751 "glTexSubImage2D: bad dimensions."); |
6760 return; | 6752 return; |
6761 } | 6753 } |
6762 | 6754 |
6763 GLsizei tex_width = 0; | 6755 // See if we can call glTexImage2D instead since it appears to be faster. |
6764 GLsizei tex_height = 0; | 6756 if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0 && |
6765 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); | 6757 !info->IsImmutable()) { |
6766 DCHECK(ok); | 6758 GLsizei tex_width = 0; |
6767 if (xoffset != 0 || yoffset != 0 || | 6759 GLsizei tex_height = 0; |
6768 width != tex_width || height != tex_height) { | 6760 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); |
6769 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { | 6761 DCHECK(ok); |
6770 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big"); | 6762 if (width == tex_width && height == tex_height) { |
| 6763 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the |
| 6764 // same as internal_foramt. If that changes we'll need to look them up. |
| 6765 WrappedTexImage2D( |
| 6766 target, level, format, width, height, 0, format, type, data); |
| 6767 texture_manager()->SetLevelCleared(info, target, level); |
6771 return; | 6768 return; |
6772 } | 6769 } |
6773 glTexSubImage2D( | 6770 } |
6774 target, level, xoffset, yoffset, width, height, format, type, data); | 6771 if (!texture_manager()->ClearTextureLevel(this, info, target, level)) { |
| 6772 SetGLError(GL_OUT_OF_MEMORY, "glTexSubImage2D: dimensions too big"); |
6775 return; | 6773 return; |
6776 } | 6774 } |
6777 | 6775 glTexSubImage2D( |
6778 if (teximage2d_faster_than_texsubimage2d_ && !info->IsImmutable()) { | 6776 target, level, xoffset, yoffset, width, height, format, type, data); |
6779 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the | |
6780 // same as internal_foramt. If that changes we'll need to look them up. | |
6781 WrappedTexImage2D( | |
6782 target, level, format, width, height, 0, format, type, data); | |
6783 } else { | |
6784 glTexSubImage2D( | |
6785 target, level, xoffset, yoffset, width, height, format, type, data); | |
6786 } | |
6787 texture_manager()->SetLevelCleared(info, target, level); | |
6788 } | 6777 } |
6789 | 6778 |
6790 error::Error GLES2DecoderImpl::HandleTexSubImage2D( | 6779 error::Error GLES2DecoderImpl::HandleTexSubImage2D( |
6791 uint32 immediate_data_size, const gles2::TexSubImage2D& c) { | 6780 uint32 immediate_data_size, const gles2::TexSubImage2D& c) { |
6792 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D"); | 6781 TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleTexSubImage2D"); |
6793 GLboolean internal = static_cast<GLboolean>(c.internal); | 6782 GLboolean internal = static_cast<GLboolean>(c.internal); |
6794 if (internal == GL_TRUE && tex_image_2d_failed_) | 6783 if (internal == GL_TRUE && tex_image_2d_failed_) |
6795 return error::kNoError; | 6784 return error::kNoError; |
6796 | 6785 |
6797 GLenum target = static_cast<GLenum>(c.target); | 6786 GLenum target = static_cast<GLenum>(c.target); |
(...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7835 SetGLError(GL_INVALID_OPERATION, | 7824 SetGLError(GL_INVALID_OPERATION, |
7836 "glTexStorage2DEXT: texture is immutable"); | 7825 "glTexStorage2DEXT: texture is immutable"); |
7837 return; | 7826 return; |
7838 } | 7827 } |
7839 CopyRealGLErrorsToWrapper(); | 7828 CopyRealGLErrorsToWrapper(); |
7840 glTexStorage2DEXT(target, levels, internal_format, width, height); | 7829 glTexStorage2DEXT(target, levels, internal_format, width, height); |
7841 GLenum error = PeekGLError(); | 7830 GLenum error = PeekGLError(); |
7842 if (error == GL_NO_ERROR) { | 7831 if (error == GL_NO_ERROR) { |
7843 GLenum format = ExtractFormatFromStorageFormat(internal_format); | 7832 GLenum format = ExtractFormatFromStorageFormat(internal_format); |
7844 GLenum type = ExtractTypeFromStorageFormat(internal_format); | 7833 GLenum type = ExtractTypeFromStorageFormat(internal_format); |
7845 GLsizei level_width = width; | 7834 texture_manager()->SetLevelInfo( |
7846 GLsizei level_height = height; | 7835 feature_info_, info, |
7847 for (int ii = 0; ii < levels; ++ii) { | 7836 target, 0, format, width, height, 1, 0, format, type, |
7848 texture_manager()->SetLevelInfo( | 7837 false); |
7849 feature_info_, info, | 7838 texture_manager()->MarkMipmapsGenerated(feature_info_, info, false); |
7850 target, 0, format, level_width, level_height, 1, 0, format, type, | |
7851 false); | |
7852 level_width = std::max(1, level_width >> 1); | |
7853 level_height = std::max(1, level_height >> 1); | |
7854 } | |
7855 info->SetImmutable(true); | 7839 info->SetImmutable(true); |
7856 } | 7840 } |
7857 | 7841 |
7858 } | 7842 } |
7859 | 7843 |
7860 // Include the auto-generated part of this file. We split this because it means | 7844 // Include the auto-generated part of this file. We split this because it means |
7861 // we can easily edit the non-auto generated parts right here in this file | 7845 // we can easily edit the non-auto generated parts right here in this file |
7862 // instead of having to edit some template or the code generator. | 7846 // instead of having to edit some template or the code generator. |
7863 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 7847 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
7864 | 7848 |
7865 } // namespace gles2 | 7849 } // namespace gles2 |
7866 } // namespace gpu | 7850 } // namespace gpu |
OLD | NEW |