Chromium Code Reviews| 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 |