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