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 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
744 const void * data); | 744 const void * data); |
745 | 745 |
746 // Wrapper for TexImageIOSurface2DCHROMIUM. | 746 // Wrapper for TexImageIOSurface2DCHROMIUM. |
747 void DoTexImageIOSurface2DCHROMIUM( | 747 void DoTexImageIOSurface2DCHROMIUM( |
748 GLenum target, | 748 GLenum target, |
749 GLsizei width, | 749 GLsizei width, |
750 GLsizei height, | 750 GLsizei height, |
751 GLuint io_surface_id, | 751 GLuint io_surface_id, |
752 GLuint plane); | 752 GLuint plane); |
753 | 753 |
754 // Wrapper for TexStorage2DEXT. | |
755 void DoTexStorage2DEXT( | |
756 GLenum target, | |
757 GLint levels, | |
758 GLenum internal_format, | |
759 GLsizei width, | |
760 GLsizei height); | |
761 | |
754 // Creates a ProgramInfo for the given program. | 762 // Creates a ProgramInfo for the given program. |
755 ProgramManager::ProgramInfo* CreateProgramInfo( | 763 ProgramManager::ProgramInfo* CreateProgramInfo( |
756 GLuint client_id, GLuint service_id) { | 764 GLuint client_id, GLuint service_id) { |
757 return program_manager()->CreateProgramInfo(client_id, service_id); | 765 return program_manager()->CreateProgramInfo(client_id, service_id); |
758 } | 766 } |
759 | 767 |
760 // Gets the program info for the given program. Returns NULL if none exists. | 768 // Gets the program info for the given program. Returns NULL if none exists. |
761 ProgramManager::ProgramInfo* GetProgramInfo(GLuint client_id) { | 769 ProgramManager::ProgramInfo* GetProgramInfo(GLuint client_id) { |
762 return program_manager()->GetProgramInfo(client_id); | 770 return program_manager()->GetProgramInfo(client_id); |
763 } | 771 } |
(...skipping 2458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3222 if (vertex_attrib_manager_.Enable(index, true)) { | 3230 if (vertex_attrib_manager_.Enable(index, true)) { |
3223 glEnableVertexAttribArray(index); | 3231 glEnableVertexAttribArray(index); |
3224 } else { | 3232 } else { |
3225 SetGLError(GL_INVALID_VALUE, | 3233 SetGLError(GL_INVALID_VALUE, |
3226 "glEnableVertexAttribArray: index out of range"); | 3234 "glEnableVertexAttribArray: index out of range"); |
3227 } | 3235 } |
3228 } | 3236 } |
3229 | 3237 |
3230 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { | 3238 void GLES2DecoderImpl::DoGenerateMipmap(GLenum target) { |
3231 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 3239 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
3232 if (!info || !texture_manager()->MarkMipmapsGenerated(feature_info_, info)) { | 3240 if (!info || |
3241 !texture_manager()->MarkMipmapsGenerated(feature_info_, info, true)) { | |
3233 SetGLError(GL_INVALID_OPERATION, | 3242 SetGLError(GL_INVALID_OPERATION, |
3234 "glGenerateMipmaps: Can not generate mips for npot textures"); | 3243 "glGenerateMipmaps: Can not generate mips for npot textures"); |
3235 return; | 3244 return; |
3236 } | 3245 } |
3237 // 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 |
3238 // glTexParamter twice for glGenerateMipmap is probably not a lage performance | 3247 // glTexParamter twice for glGenerateMipmap is probably not a lage performance |
3239 // 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 |
3240 // 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 |
3241 // 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, |
3242 // then glGenerateMipmap misbehaves. | 3251 // then glGenerateMipmap misbehaves. |
(...skipping 2935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6178 SetGLError(GL_INVALID_VALUE, | 6187 SetGLError(GL_INVALID_VALUE, |
6179 "glCompressedTexImage2D: dimensions out of range"); | 6188 "glCompressedTexImage2D: dimensions out of range"); |
6180 return error::kNoError; | 6189 return error::kNoError; |
6181 } | 6190 } |
6182 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 6191 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
6183 if (!info) { | 6192 if (!info) { |
6184 SetGLError(GL_INVALID_VALUE, | 6193 SetGLError(GL_INVALID_VALUE, |
6185 "glCompressedTexImage2D: unknown texture target"); | 6194 "glCompressedTexImage2D: unknown texture target"); |
6186 return error::kNoError; | 6195 return error::kNoError; |
6187 } | 6196 } |
6197 if (info->IsImmutable()) { | |
6198 SetGLError(GL_INVALID_OPERATION, | |
6199 "glCompressedTexImage2D: texture is immutable"); | |
6200 return error::kNoError; | |
6201 } | |
6188 scoped_array<int8> zero; | 6202 scoped_array<int8> zero; |
6189 if (!data) { | 6203 if (!data) { |
6190 zero.reset(new int8[image_size]); | 6204 zero.reset(new int8[image_size]); |
6191 memset(zero.get(), 0, image_size); | 6205 memset(zero.get(), 0, image_size); |
6192 data = zero.get(); | 6206 data = zero.get(); |
6193 } | 6207 } |
6194 CopyRealGLErrorsToWrapper(); | 6208 CopyRealGLErrorsToWrapper(); |
6195 glCompressedTexImage2D( | 6209 glCompressedTexImage2D( |
6196 target, level, internal_format, width, height, border, image_size, data); | 6210 target, level, internal_format, width, height, border, image_size, data); |
6197 GLenum error = PeekGLError(); | 6211 GLenum error = PeekGLError(); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6353 SetGLError(GL_INVALID_VALUE, "glTexImage2D: dimensions out of range"); | 6367 SetGLError(GL_INVALID_VALUE, "glTexImage2D: dimensions out of range"); |
6354 return error::kNoError; | 6368 return error::kNoError; |
6355 } | 6369 } |
6356 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 6370 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
6357 if (!info) { | 6371 if (!info) { |
6358 SetGLError(GL_INVALID_OPERATION, | 6372 SetGLError(GL_INVALID_OPERATION, |
6359 "glTexImage2D: unknown texture for target"); | 6373 "glTexImage2D: unknown texture for target"); |
6360 return error::kNoError; | 6374 return error::kNoError; |
6361 } | 6375 } |
6362 | 6376 |
6377 if (info->IsImmutable()) { | |
6378 SetGLError(GL_INVALID_OPERATION, | |
6379 "glTexImage2D: texture is immutable"); | |
6380 return error::kNoError; | |
6381 } | |
6382 | |
6363 GLsizei tex_width = 0; | 6383 GLsizei tex_width = 0; |
6364 GLsizei tex_height = 0; | 6384 GLsizei tex_height = 0; |
6365 GLenum tex_type = 0; | 6385 GLenum tex_type = 0; |
6366 GLenum tex_format = 0; | 6386 GLenum tex_format = 0; |
6367 bool level_is_same = | 6387 bool level_is_same = |
6368 info->GetLevelSize(target, level, &tex_width, &tex_height) && | 6388 info->GetLevelSize(target, level, &tex_width, &tex_height) && |
6369 info->GetLevelType(target, level, &tex_type, &tex_format) && | 6389 info->GetLevelType(target, level, &tex_type, &tex_format) && |
6370 width == tex_width && height == tex_height && | 6390 width == tex_width && height == tex_height && |
6371 type == tex_type && format == tex_format; | 6391 type == tex_type && format == tex_format; |
6372 | 6392 |
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6527 GLint y, | 6547 GLint y, |
6528 GLsizei width, | 6548 GLsizei width, |
6529 GLsizei height, | 6549 GLsizei height, |
6530 GLint border) { | 6550 GLint border) { |
6531 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 6551 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); |
6532 if (!info) { | 6552 if (!info) { |
6533 SetGLError(GL_INVALID_OPERATION, | 6553 SetGLError(GL_INVALID_OPERATION, |
6534 "glCopyTexImage2D: unknown texture for target"); | 6554 "glCopyTexImage2D: unknown texture for target"); |
6535 return; | 6555 return; |
6536 } | 6556 } |
6557 if (info->IsImmutable()) { | |
6558 SetGLError(GL_INVALID_OPERATION, | |
6559 "glCopyTexImage2D: texture is immutable"); | |
6560 } | |
6537 if (!texture_manager()->ValidForTarget( | 6561 if (!texture_manager()->ValidForTarget( |
6538 feature_info_, target, level, width, height, 1) || | 6562 feature_info_, target, level, width, height, 1) || |
6539 border != 0) { | 6563 border != 0) { |
6540 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D: dimensions out of range"); | 6564 SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D: dimensions out of range"); |
6541 return; | 6565 return; |
6542 } | 6566 } |
6543 | 6567 |
6544 // Check we have compatible formats. | 6568 // Check we have compatible formats. |
6545 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); | 6569 GLenum read_format = GetBoundReadFrameBufferInternalFormat(); |
6546 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); | 6570 uint32 channels_exist = GLES2Util::GetChannelsForFormat(read_format); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6722 } | 6746 } |
6723 | 6747 |
6724 if (!info->ValidForTexture( | 6748 if (!info->ValidForTexture( |
6725 target, level, xoffset, yoffset, width, height, format, type)) { | 6749 target, level, xoffset, yoffset, width, height, format, type)) { |
6726 SetGLError(GL_INVALID_VALUE, | 6750 SetGLError(GL_INVALID_VALUE, |
6727 "glTexSubImage2D: bad dimensions."); | 6751 "glTexSubImage2D: bad dimensions."); |
6728 return; | 6752 return; |
6729 } | 6753 } |
6730 | 6754 |
6731 // See if we can call glTexImage2D instead since it appears to be faster. | 6755 // See if we can call glTexImage2D instead since it appears to be faster. |
6732 if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0) { | 6756 if (teximage2d_faster_than_texsubimage2d_ && xoffset == 0 && yoffset == 0 && |
6757 !info->IsImmutable()) { | |
6733 GLsizei tex_width = 0; | 6758 GLsizei tex_width = 0; |
6734 GLsizei tex_height = 0; | 6759 GLsizei tex_height = 0; |
6735 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); | 6760 bool ok = info->GetLevelSize(target, level, &tex_width, &tex_height); |
6736 DCHECK(ok); | 6761 DCHECK(ok); |
6737 if (width == tex_width && height == tex_height) { | 6762 if (width == tex_width && height == tex_height) { |
6738 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the | 6763 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the |
6739 // same as internal_foramt. If that changes we'll need to look them up. | 6764 // same as internal_foramt. If that changes we'll need to look them up. |
6740 WrappedTexImage2D( | 6765 WrappedTexImage2D( |
6741 target, level, format, width, height, 0, format, type, data); | 6766 target, level, format, width, height, 0, format, type, data); |
6742 texture_manager()->SetLevelCleared(info, target, level); | 6767 texture_manager()->SetLevelCleared(info, target, level); |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7677 feature_info_, info, | 7702 feature_info_, info, |
7678 target, 0, GL_RGBA, width, height, 1, 0, | 7703 target, 0, GL_RGBA, width, height, 1, 0, |
7679 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true); | 7704 GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, true); |
7680 | 7705 |
7681 #else | 7706 #else |
7682 SetGLError(GL_INVALID_OPERATION, | 7707 SetGLError(GL_INVALID_OPERATION, |
7683 "glTexImageIOSurface2DCHROMIUM: not supported."); | 7708 "glTexImageIOSurface2DCHROMIUM: not supported."); |
7684 #endif | 7709 #endif |
7685 } | 7710 } |
7686 | 7711 |
7712 static GLenum ExtractFormatFromStorageFormat(GLenum internalformat) { | |
7713 switch (internalformat) { | |
greggman
2011/12/03 01:41:01
this function and the next have too many spaces. d
| |
7714 case GL_RGB565: | |
7715 return GL_RGB; | |
7716 case GL_RGBA4: | |
7717 return GL_RGBA; | |
7718 case GL_RGB5_A1: | |
7719 return GL_RGBA; | |
7720 case GL_RGB8_OES: | |
7721 return GL_RGB; | |
7722 case GL_RGBA8_OES: | |
7723 return GL_RGBA; | |
7724 case GL_LUMINANCE8_ALPHA8_EXT: | |
7725 return GL_LUMINANCE_ALPHA; | |
7726 case GL_LUMINANCE8_EXT: | |
7727 return GL_LUMINANCE; | |
7728 case GL_ALPHA8_EXT: | |
7729 return GL_ALPHA; | |
7730 case GL_RGBA32F_EXT: | |
7731 return GL_RGBA; | |
7732 case GL_RGB32F_EXT: | |
7733 return GL_RGB; | |
7734 case GL_ALPHA32F_EXT: | |
7735 return GL_ALPHA; | |
7736 case GL_LUMINANCE32F_EXT: | |
7737 return GL_LUMINANCE; | |
7738 case GL_LUMINANCE_ALPHA32F_EXT: | |
7739 return GL_LUMINANCE_ALPHA; | |
7740 case GL_RGBA16F_EXT: | |
7741 return GL_RGBA; | |
7742 case GL_RGB16F_EXT: | |
7743 return GL_RGB; | |
7744 case GL_ALPHA16F_EXT: | |
7745 return GL_ALPHA; | |
7746 case GL_LUMINANCE16F_EXT: | |
7747 return GL_LUMINANCE; | |
7748 case GL_LUMINANCE_ALPHA16F_EXT: | |
7749 return GL_LUMINANCE_ALPHA; | |
7750 case GL_BGRA8_EXT: | |
7751 return GL_BGRA_EXT; | |
7752 default: | |
7753 return GL_NONE; | |
7754 } | |
7755 } | |
7756 | |
7757 static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { | |
7758 switch (internalformat) { | |
7759 case GL_RGB565: | |
7760 return GL_UNSIGNED_SHORT_5_6_5; | |
7761 case GL_RGBA4: | |
7762 return GL_UNSIGNED_SHORT_4_4_4_4; | |
7763 case GL_RGB5_A1: | |
7764 return GL_UNSIGNED_SHORT_5_5_5_1; | |
7765 case GL_RGB8_OES: | |
7766 return GL_UNSIGNED_BYTE; | |
7767 case GL_RGBA8_OES: | |
7768 return GL_UNSIGNED_BYTE; | |
7769 case GL_LUMINANCE8_ALPHA8_EXT: | |
7770 return GL_UNSIGNED_BYTE; | |
7771 case GL_LUMINANCE8_EXT: | |
7772 return GL_UNSIGNED_BYTE; | |
7773 case GL_ALPHA8_EXT: | |
7774 return GL_UNSIGNED_BYTE; | |
7775 case GL_RGBA32F_EXT: | |
7776 return GL_FLOAT; | |
7777 case GL_RGB32F_EXT: | |
7778 return GL_FLOAT; | |
7779 case GL_ALPHA32F_EXT: | |
7780 return GL_FLOAT; | |
7781 case GL_LUMINANCE32F_EXT: | |
7782 return GL_FLOAT; | |
7783 case GL_LUMINANCE_ALPHA32F_EXT: | |
7784 return GL_FLOAT; | |
7785 case GL_RGBA16F_EXT: | |
7786 return GL_HALF_FLOAT_OES; | |
7787 case GL_RGB16F_EXT: | |
7788 return GL_HALF_FLOAT_OES; | |
7789 case GL_ALPHA16F_EXT: | |
7790 return GL_HALF_FLOAT_OES; | |
7791 case GL_LUMINANCE16F_EXT: | |
7792 return GL_HALF_FLOAT_OES; | |
7793 case GL_LUMINANCE_ALPHA16F_EXT: | |
7794 return GL_HALF_FLOAT_OES; | |
7795 case GL_BGRA8_EXT: | |
7796 return GL_UNSIGNED_BYTE; | |
7797 default: | |
7798 return GL_NONE; | |
7799 } | |
7800 } | |
7801 | |
7802 void GLES2DecoderImpl::DoTexStorage2DEXT( | |
7803 GLenum target, | |
7804 GLint levels, | |
7805 GLenum internal_format, | |
7806 GLsizei width, | |
7807 GLsizei height) { | |
7808 if (!texture_manager()->ValidForTarget( | |
7809 feature_info_, target, 0, width, height, 1) || | |
7810 TextureManager::ComputeMipMapCount(width, height, 1) < levels) { | |
7811 SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT: dimensions out of range"); | |
7812 return; | |
7813 } | |
7814 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | |
7815 if (!info) { | |
7816 SetGLError(GL_INVALID_OPERATION, | |
7817 "glTexStorage2DEXT: unknown texture for target"); | |
7818 return; | |
7819 } | |
7820 if (info->IsAttachedToFramebuffer()) { | |
7821 state_dirty_ = true; | |
7822 } | |
7823 if (info->IsImmutable()) { | |
7824 SetGLError(GL_INVALID_OPERATION, | |
7825 "glTexStorage2DEXT: texture is immutable"); | |
7826 return; | |
7827 } | |
7828 CopyRealGLErrorsToWrapper(); | |
7829 glTexStorage2DEXT(target, levels, internal_format, width, height); | |
7830 GLenum error = PeekGLError(); | |
7831 if (error == GL_NO_ERROR) { | |
7832 GLenum format = ExtractFormatFromStorageFormat(internal_format); | |
7833 GLenum type = ExtractTypeFromStorageFormat(internal_format); | |
7834 texture_manager()->SetLevelInfo( | |
7835 feature_info_, info, | |
7836 target, 0, format, width, height, 1, 0, format, type, | |
7837 false); | |
7838 texture_manager()->MarkMipmapsGenerated(feature_info_, info, false); | |
7839 info->SetImmutable(true); | |
7840 } | |
7841 | |
7842 } | |
7687 | 7843 |
7688 // 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 |
7689 // 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 |
7690 // instead of having to edit some template or the code generator. | 7846 // instead of having to edit some template or the code generator. |
7691 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 7847 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
7692 | 7848 |
7693 } // namespace gles2 | 7849 } // namespace gles2 |
7694 } // namespace gpu | 7850 } // namespace gpu |
OLD | NEW |