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) { |
| 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 |