 Chromium Code Reviews
 Chromium Code Reviews Issue 12017032:
  Add calls to EnsureGPUMemoryAvailable into GLES2DecoderImpl  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src
    
  
    Issue 12017032:
  Add calls to EnsureGPUMemoryAvailable into GLES2DecoderImpl  (Closed) 
  Base URL: svn://svn.chromium.org/chrome/trunk/src| OLD | NEW | 
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 652 } | 652 } | 
| 653 | 653 | 
| 654 ImageManager* image_manager() { | 654 ImageManager* image_manager() { | 
| 655 return group_->image_manager(); | 655 return group_->image_manager(); | 
| 656 } | 656 } | 
| 657 | 657 | 
| 658 VertexArrayManager* vertex_array_manager() { | 658 VertexArrayManager* vertex_array_manager() { | 
| 659 return vertex_array_manager_.get(); | 659 return vertex_array_manager_.get(); | 
| 660 } | 660 } | 
| 661 | 661 | 
| 662 MemoryTracker* memory_tracker() { | |
| 663 return group_->memory_tracker(); | |
| 664 } | |
| 665 | |
| 662 bool IsOffscreenBufferMultisampled() const { | 666 bool IsOffscreenBufferMultisampled() const { | 
| 663 return offscreen_target_samples_ > 1; | 667 return offscreen_target_samples_ > 1; | 
| 664 } | 668 } | 
| 665 | 669 | 
| 666 // Creates a TextureInfo for the given texture. | 670 // Creates a TextureInfo for the given texture. | 
| 667 TextureManager::TextureInfo* CreateTextureInfo( | 671 TextureManager::TextureInfo* CreateTextureInfo( | 
| 668 GLuint client_id, GLuint service_id) { | 672 GLuint client_id, GLuint service_id) { | 
| 669 return texture_manager()->CreateTextureInfo(client_id, service_id); | 673 return texture_manager()->CreateTextureInfo(client_id, service_id); | 
| 670 } | 674 } | 
| 671 | 675 | 
| (...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1819 } | 1823 } | 
| 1820 | 1824 | 
| 1821 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { | 1825 ScopedTextureUploadTimer::~ScopedTextureUploadTimer() { | 
| 1822 decoder_->texture_upload_count_++; | 1826 decoder_->texture_upload_count_++; | 
| 1823 decoder_->total_texture_upload_time_ += | 1827 decoder_->total_texture_upload_time_ += | 
| 1824 base::TimeTicks::HighResNow() - begin_time_; | 1828 base::TimeTicks::HighResNow() - begin_time_; | 
| 1825 } | 1829 } | 
| 1826 | 1830 | 
| 1827 Texture::Texture(GLES2DecoderImpl* decoder) | 1831 Texture::Texture(GLES2DecoderImpl* decoder) | 
| 1828 : decoder_(decoder), | 1832 : decoder_(decoder), | 
| 1829 memory_tracker_(decoder->GetContextGroup()->memory_tracker(), | 1833 memory_tracker_(decoder->memory_tracker(), | 
| 1830 MemoryTracker::kUnmanaged), | 1834 MemoryTracker::kUnmanaged), | 
| 1831 bytes_allocated_(0), | 1835 bytes_allocated_(0), | 
| 1832 id_(0) { | 1836 id_(0) { | 
| 1833 } | 1837 } | 
| 1834 | 1838 | 
| 1835 Texture::~Texture() { | 1839 Texture::~Texture() { | 
| 1836 // This does not destroy the render texture because that would require that | 1840 // This does not destroy the render texture because that would require that | 
| 1837 // the associated GL context was current. Just check that it was explicitly | 1841 // the associated GL context was current. Just check that it was explicitly | 
| 1838 // destroyed. | 1842 // destroyed. | 
| 1839 DCHECK_EQ(id_, 0u); | 1843 DCHECK_EQ(id_, 0u); | 
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1921 memory_tracker_.TrackMemFree(bytes_allocated_); | 1925 memory_tracker_.TrackMemFree(bytes_allocated_); | 
| 1922 bytes_allocated_ = 0; | 1926 bytes_allocated_ = 0; | 
| 1923 } | 1927 } | 
| 1924 | 1928 | 
| 1925 void Texture::Invalidate() { | 1929 void Texture::Invalidate() { | 
| 1926 id_ = 0; | 1930 id_ = 0; | 
| 1927 } | 1931 } | 
| 1928 | 1932 | 
| 1929 RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder) | 1933 RenderBuffer::RenderBuffer(GLES2DecoderImpl* decoder) | 
| 1930 : decoder_(decoder), | 1934 : decoder_(decoder), | 
| 1931 memory_tracker_(decoder->GetContextGroup()->memory_tracker(), | 1935 memory_tracker_(decoder->memory_tracker(), | 
| 1932 MemoryTracker::kUnmanaged), | 1936 MemoryTracker::kUnmanaged), | 
| 1933 bytes_allocated_(0), | 1937 bytes_allocated_(0), | 
| 1934 id_(0) { | 1938 id_(0) { | 
| 1935 } | 1939 } | 
| 1936 | 1940 | 
| 1937 RenderBuffer::~RenderBuffer() { | 1941 RenderBuffer::~RenderBuffer() { | 
| 1938 // This does not destroy the render buffer because that would require that | 1942 // This does not destroy the render buffer because that would require that | 
| 1939 // the associated GL context was current. Just check that it was explicitly | 1943 // the associated GL context was current. Just check that it was explicitly | 
| 1940 // destroyed. | 1944 // destroyed. | 
| 1941 DCHECK_EQ(id_, 0u); | 1945 DCHECK_EQ(id_, 0u); | 
| (...skipping 2833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4775 if (!features().chromium_framebuffer_multisample) { | 4779 if (!features().chromium_framebuffer_multisample) { | 
| 4776 SetGLError(GL_INVALID_OPERATION, | 4780 SetGLError(GL_INVALID_OPERATION, | 
| 4777 "glRenderbufferStorageMultisampleEXT", "function not available"); | 4781 "glRenderbufferStorageMultisampleEXT", "function not available"); | 
| 4778 return; | 4782 return; | 
| 4779 } | 4783 } | 
| 4780 | 4784 | 
| 4781 RenderbufferManager::RenderbufferInfo* renderbuffer = | 4785 RenderbufferManager::RenderbufferInfo* renderbuffer = | 
| 4782 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); | 4786 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); | 
| 4783 if (!renderbuffer) { | 4787 if (!renderbuffer) { | 
| 4784 SetGLError(GL_INVALID_OPERATION, | 4788 SetGLError(GL_INVALID_OPERATION, | 
| 4785 "glGetRenderbufferStorageMultisample", "no renderbuffer bound"); | 4789 "glRenderbufferStorageMultisampleEXT", "no renderbuffer bound"); | 
| 4786 return; | 4790 return; | 
| 4787 } | 4791 } | 
| 4788 | 4792 | 
| 4789 if (samples > renderbuffer_manager()->max_samples()) { | 4793 if (samples > renderbuffer_manager()->max_samples()) { | 
| 4790 SetGLError(GL_INVALID_VALUE, | 4794 SetGLError(GL_INVALID_VALUE, | 
| 4791 "glGetRenderbufferStorageMultisample", "samples too large"); | 4795 "glRenderbufferStorageMultisampleEXT", "samples too large"); | 
| 4792 return; | 4796 return; | 
| 4793 } | 4797 } | 
| 4794 | 4798 | 
| 4795 if (width > renderbuffer_manager()->max_renderbuffer_size() || | 4799 if (width > renderbuffer_manager()->max_renderbuffer_size() || | 
| 4796 height > renderbuffer_manager()->max_renderbuffer_size()) { | 4800 height > renderbuffer_manager()->max_renderbuffer_size()) { | 
| 4797 SetGLError(GL_INVALID_VALUE, | 4801 SetGLError(GL_INVALID_VALUE, | 
| 4798 "glGetRenderbufferStorageMultisample", "size too large"); | 4802 "glRenderbufferStorageMultisample", "dimensions too large"); | 
| 4799 return; | 4803 return; | 
| 4800 } | 4804 } | 
| 4801 | 4805 | 
| 4802 GLenum impl_format = internalformat; | 4806 GLenum impl_format = internalformat; | 
| 4803 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { | 4807 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { | 
| 4804 switch (impl_format) { | 4808 switch (impl_format) { | 
| 4805 case GL_DEPTH_COMPONENT16: | 4809 case GL_DEPTH_COMPONENT16: | 
| 4806 impl_format = GL_DEPTH_COMPONENT; | 4810 impl_format = GL_DEPTH_COMPONENT; | 
| 4807 break; | 4811 break; | 
| 4808 case GL_RGBA4: | 4812 case GL_RGBA4: | 
| 4809 case GL_RGB5_A1: | 4813 case GL_RGB5_A1: | 
| 4810 impl_format = GL_RGBA; | 4814 impl_format = GL_RGBA; | 
| 4811 break; | 4815 break; | 
| 4812 case GL_RGB565: | 4816 case GL_RGB565: | 
| 4813 impl_format = GL_RGB; | 4817 impl_format = GL_RGB; | 
| 4814 break; | 4818 break; | 
| 4815 } | 4819 } | 
| 4816 } | 4820 } | 
| 4817 | 4821 | 
| 4822 uint32 estimated_size = 0; | |
| 4823 if (!GLES2Util::ComputeEstimatedRenderbufferSize( | |
| 4824 width, height, samples, impl_format, &estimated_size)) { | |
| 4825 SetGLError(GL_OUT_OF_MEMORY, | |
| 4826 "glRenderbufferStorageMultsampleEXT", "dimensions too large"); | |
| 4827 return; | |
| 4828 } | |
| 4829 | |
| 4830 if (!memory_tracker()->EnsureGPUMemoryAvailable(estimated_size)) { | |
| 4831 SetGLError(GL_OUT_OF_MEMORY, | |
| 4832 "glRenderbufferStorageMultsampleEXT", "out of memory"); | |
| 4833 return; | |
| 4834 } | |
| 4835 | |
| 4818 CopyRealGLErrorsToWrapper(); | 4836 CopyRealGLErrorsToWrapper(); | 
| 4819 if (IsAngle()) { | 4837 if (IsAngle()) { | 
| 4820 glRenderbufferStorageMultisampleANGLE( | 4838 glRenderbufferStorageMultisampleANGLE( | 
| 4821 target, samples, impl_format, width, height); | 4839 target, samples, impl_format, width, height); | 
| 4822 } else { | 4840 } else { | 
| 4823 glRenderbufferStorageMultisampleEXT( | 4841 glRenderbufferStorageMultisampleEXT( | 
| 4824 target, samples, impl_format, width, height); | 4842 target, samples, impl_format, width, height); | 
| 4825 } | 4843 } | 
| 4826 GLenum error = PeekGLError(); | 4844 GLenum error = PeekGLError(); | 
| 4827 if (error == GL_NO_ERROR) { | 4845 if (error == GL_NO_ERROR) { | 
| 4828 // TODO(gman): If renderbuffers tracked which framebuffers they were | 4846 // TODO(gman): If renderbuffers tracked which framebuffers they were | 
| 4829 // attached to we could just mark those framebuffers as not complete. | 4847 // attached to we could just mark those framebuffers as not complete. | 
| 4830 framebuffer_manager()->IncFramebufferStateChangeCount(); | 4848 framebuffer_manager()->IncFramebufferStateChangeCount(); | 
| 4831 renderbuffer_manager()->SetInfo( | 4849 renderbuffer_manager()->SetInfo( | 
| 4832 renderbuffer, samples, internalformat, width, height); | 4850 renderbuffer, samples, internalformat, width, height); | 
| 4833 } | 4851 } | 
| 4834 } | 4852 } | 
| 4835 | 4853 | 
| 4836 void GLES2DecoderImpl::DoRenderbufferStorage( | 4854 void GLES2DecoderImpl::DoRenderbufferStorage( | 
| 4837 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { | 4855 GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { | 
| 4838 RenderbufferManager::RenderbufferInfo* renderbuffer = | 4856 RenderbufferManager::RenderbufferInfo* renderbuffer = | 
| 4839 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); | 4857 GetRenderbufferInfoForTarget(GL_RENDERBUFFER); | 
| 4840 if (!renderbuffer) { | 4858 if (!renderbuffer) { | 
| 4841 SetGLError(GL_INVALID_OPERATION, | 4859 SetGLError(GL_INVALID_OPERATION, | 
| 4842 "glGetRenderbufferStorage", "no renderbuffer bound"); | 4860 "glRenderbufferStorage", "no renderbuffer bound"); | 
| 4843 return; | 4861 return; | 
| 4844 } | 4862 } | 
| 4845 | 4863 | 
| 4846 if (width > renderbuffer_manager()->max_renderbuffer_size() || | 4864 if (width > renderbuffer_manager()->max_renderbuffer_size() || | 
| 4847 height > renderbuffer_manager()->max_renderbuffer_size()) { | 4865 height > renderbuffer_manager()->max_renderbuffer_size()) { | 
| 4848 SetGLError(GL_INVALID_VALUE, | 4866 SetGLError(GL_INVALID_VALUE, | 
| 4849 "glGetRenderbufferStorage", "size too large"); | 4867 "glRenderbufferStorage", "dimensions too large"); | 
| 4850 return; | 4868 return; | 
| 4851 } | 4869 } | 
| 4852 | 4870 | 
| 4853 GLenum impl_format = internalformat; | 4871 GLenum impl_format = internalformat; | 
| 4854 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { | 4872 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { | 
| 4855 switch (impl_format) { | 4873 switch (impl_format) { | 
| 4856 case GL_DEPTH_COMPONENT16: | 4874 case GL_DEPTH_COMPONENT16: | 
| 4857 impl_format = GL_DEPTH_COMPONENT; | 4875 impl_format = GL_DEPTH_COMPONENT; | 
| 4858 break; | 4876 break; | 
| 4859 case GL_RGBA4: | 4877 case GL_RGBA4: | 
| 4860 case GL_RGB5_A1: | 4878 case GL_RGB5_A1: | 
| 4861 impl_format = GL_RGBA; | 4879 impl_format = GL_RGBA; | 
| 4862 break; | 4880 break; | 
| 4863 case GL_RGB565: | 4881 case GL_RGB565: | 
| 4864 impl_format = GL_RGB; | 4882 impl_format = GL_RGB; | 
| 4865 break; | 4883 break; | 
| 4866 } | 4884 } | 
| 4867 } | 4885 } | 
| 4868 | 4886 | 
| 4887 uint32 estimated_size = 0; | |
| 4888 if (!GLES2Util::ComputeEstimatedRenderbufferSize( | |
| 4889 width, height, 1, impl_format, &estimated_size)) { | |
| 4890 SetGLError(GL_OUT_OF_MEMORY, "glRenderbufferStorage", | |
| 4891 "dimensions too large"); | |
| 4892 return; | |
| 4893 } | |
| 4894 | |
| 4895 if (!memory_tracker()->EnsureGPUMemoryAvailable(estimated_size)) { | |
| 4896 SetGLError(GL_OUT_OF_MEMORY, "glRenderbufferStorage", "out of memory"); | |
| 4897 return; | |
| 4898 } | |
| 4899 | |
| 4869 CopyRealGLErrorsToWrapper(); | 4900 CopyRealGLErrorsToWrapper(); | 
| 4870 glRenderbufferStorageEXT(target, impl_format, width, height); | 4901 glRenderbufferStorageEXT(target, impl_format, width, height); | 
| 4871 GLenum error = PeekGLError(); | 4902 GLenum error = PeekGLError(); | 
| 4872 if (error == GL_NO_ERROR) { | 4903 if (error == GL_NO_ERROR) { | 
| 4873 // TODO(gman): If tetxures tracked which framebuffers they were attached to | 4904 // TODO(gman): If tetxures tracked which framebuffers they were attached to | 
| 4874 // we could just mark those framebuffers as not complete. | 4905 // we could just mark those framebuffers as not complete. | 
| 4875 framebuffer_manager()->IncFramebufferStateChangeCount(); | 4906 framebuffer_manager()->IncFramebufferStateChangeCount(); | 
| 4876 renderbuffer_manager()->SetInfo( | 4907 renderbuffer_manager()->SetInfo( | 
| 4877 renderbuffer, 0, internalformat, width, height); | 4908 renderbuffer, 0, internalformat, width, height); | 
| 4878 } | 4909 } | 
| (...skipping 2205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7084 } | 7115 } | 
| 7085 if (size < 0) { | 7116 if (size < 0) { | 
| 7086 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); | 7117 SetGLError(GL_INVALID_VALUE, "glBufferData", "size < 0"); | 
| 7087 return; | 7118 return; | 
| 7088 } | 7119 } | 
| 7089 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target); | 7120 BufferManager::BufferInfo* info = GetBufferInfoForTarget(target); | 
| 7090 if (!info) { | 7121 if (!info) { | 
| 7091 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); | 7122 SetGLError(GL_INVALID_VALUE, "glBufferData", "unknown buffer"); | 
| 7092 return; | 7123 return; | 
| 7093 } | 7124 } | 
| 7125 | |
| 7126 if (!memory_tracker()->EnsureGPUMemoryAvailable(size)) { | |
| 7127 SetGLError(GL_OUT_OF_MEMORY, "glBufferData", "out of memory"); | |
| 7128 return; | |
| 7129 } | |
| 7130 | |
| 7094 // Clear the buffer to 0 if no initial data was passed in. | 7131 // Clear the buffer to 0 if no initial data was passed in. | 
| 7095 scoped_array<int8> zero; | 7132 scoped_array<int8> zero; | 
| 7096 if (!data) { | 7133 if (!data) { | 
| 7097 zero.reset(new int8[size]); | 7134 zero.reset(new int8[size]); | 
| 7098 memset(zero.get(), 0, size); | 7135 memset(zero.get(), 0, size); | 
| 7099 data = zero.get(); | 7136 data = zero.get(); | 
| 7100 } | 7137 } | 
| 7101 | 7138 | 
| 7102 CopyRealGLErrorsToWrapper(); | 7139 CopyRealGLErrorsToWrapper(); | 
| 7103 glBufferData(target, size, data, usage); | 7140 glBufferData(target, size, data, usage); | 
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7435 return error::kNoError; | 7472 return error::kNoError; | 
| 7436 } | 7473 } | 
| 7437 | 7474 | 
| 7438 if (!ValidateCompressedTexDimensions( | 7475 if (!ValidateCompressedTexDimensions( | 
| 7439 "glCompressedTexImage2D", level, width, height, internal_format) || | 7476 "glCompressedTexImage2D", level, width, height, internal_format) || | 
| 7440 !ValidateCompressedTexFuncData( | 7477 !ValidateCompressedTexFuncData( | 
| 7441 "glCompressedTexImage2D", width, height, internal_format, image_size)) { | 7478 "glCompressedTexImage2D", width, height, internal_format, image_size)) { | 
| 7442 return error::kNoError; | 7479 return error::kNoError; | 
| 7443 } | 7480 } | 
| 7444 | 7481 | 
| 7482 if (!memory_tracker()->EnsureGPUMemoryAvailable(image_size)) { | |
| 7483 SetGLError(GL_OUT_OF_MEMORY, "glCompressedTexImage2D", "out of memory"); | |
| 7484 return error::kNoError; | |
| 7485 } | |
| 7486 | |
| 7445 if (info->IsAttachedToFramebuffer()) { | 7487 if (info->IsAttachedToFramebuffer()) { | 
| 7446 clear_state_dirty_ = true; | 7488 clear_state_dirty_ = true; | 
| 7447 // TODO(gman): If textures tracked which framebuffers they were attached to | 7489 // TODO(gman): If textures tracked which framebuffers they were attached to | 
| 7448 // we could just mark those framebuffers as not complete. | 7490 // we could just mark those framebuffers as not complete. | 
| 7449 framebuffer_manager()->IncFramebufferStateChangeCount(); | 7491 framebuffer_manager()->IncFramebufferStateChangeCount(); | 
| 7450 } | 7492 } | 
| 7451 | 7493 | 
| 7452 scoped_array<int8> zero; | 7494 scoped_array<int8> zero; | 
| 7453 if (!data) { | 7495 if (!data) { | 
| 7454 zero.reset(new int8[image_size]); | 7496 zero.reset(new int8[image_size]); | 
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7669 GLsizei height, | 7711 GLsizei height, | 
| 7670 GLint border, | 7712 GLint border, | 
| 7671 GLenum format, | 7713 GLenum format, | 
| 7672 GLenum type, | 7714 GLenum type, | 
| 7673 const void* pixels, | 7715 const void* pixels, | 
| 7674 uint32 pixels_size) { | 7716 uint32 pixels_size) { | 
| 7675 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format, | 7717 if (!ValidateTexImage2D("glTexImage2D", target, level, internal_format, | 
| 7676 width, height, border, format, type, pixels, pixels_size)) { | 7718 width, height, border, format, type, pixels, pixels_size)) { | 
| 7677 return; | 7719 return; | 
| 7678 } | 7720 } | 
| 7721 | |
| 7722 if (!memory_tracker()->EnsureGPUMemoryAvailable(pixels_size)) { | |
| 7723 SetGLError(GL_OUT_OF_MEMORY, "glTexImage2D", "out of memory"); | |
| 7724 return; | |
| 7725 } | |
| 7726 | |
| 7679 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 7727 TextureManager::TextureInfo* info = GetTextureInfoForTarget(target); | 
| 7680 GLsizei tex_width = 0; | 7728 GLsizei tex_width = 0; | 
| 7681 GLsizei tex_height = 0; | 7729 GLsizei tex_height = 0; | 
| 7682 GLenum tex_type = 0; | 7730 GLenum tex_type = 0; | 
| 7683 GLenum tex_format = 0; | 7731 GLenum tex_format = 0; | 
| 7684 bool level_is_same = | 7732 bool level_is_same = | 
| 7685 info->GetLevelSize(target, level, &tex_width, &tex_height) && | 7733 info->GetLevelSize(target, level, &tex_width, &tex_height) && | 
| 7686 info->GetLevelType(target, level, &tex_type, &tex_format) && | 7734 info->GetLevelType(target, level, &tex_type, &tex_format) && | 
| 7687 width == tex_width && height == tex_height && | 7735 width == tex_width && height == tex_height && | 
| 7688 type == tex_type && format == tex_format; | 7736 type == tex_type && format == tex_format; | 
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7895 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); | 7943 uint32 channels_needed = GLES2Util::GetChannelsForFormat(internal_format); | 
| 7896 | 7944 | 
| 7897 if ((channels_needed & channels_exist) != channels_needed) { | 7945 if ((channels_needed & channels_exist) != channels_needed) { | 
| 7898 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); | 7946 SetGLError(GL_INVALID_OPERATION, "glCopyTexImage2D", "incompatible format"); | 
| 7899 return; | 7947 return; | 
| 7900 } | 7948 } | 
| 7901 | 7949 | 
| 7902 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { | 7950 if ((channels_needed & (GLES2Util::kDepth | GLES2Util::kStencil)) != 0) { | 
| 7903 SetGLError( | 7951 SetGLError( | 
| 7904 GL_INVALID_OPERATION, | 7952 GL_INVALID_OPERATION, | 
| 7905 "glCopyImage2D", "can not be used with depth or stencil textures"); | 7953 "glCopyTexImage2D", "can not be used with depth or stencil textures"); | 
| 7906 return; | 7954 return; | 
| 7907 } | 7955 } | 
| 7908 | 7956 | 
| 7957 uint32 estimated_size = 0; | |
| 7958 if (!GLES2Util::ComputeImageDataSizes( | |
| 7959 width, height, internal_format, GL_UNSIGNED_BYTE, state_.unpack_alignment, | |
| 7960 &estimated_size, NULL, NULL)) { | |
| 7961 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "dimensions too large"); | |
| 7962 return; | |
| 7963 } | |
| 7964 | |
| 7965 if (!memory_tracker()->EnsureGPUMemoryAvailable(estimated_size)) { | |
| 
ccameron
2013/01/19 01:38:46
So that we can take into account the current usage
 | |
| 7966 SetGLError(GL_OUT_OF_MEMORY, "glCopyTexImage2D", "out of memory"); | |
| 7967 return; | |
| 7968 } | |
| 7969 | |
| 7909 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { | 7970 if (!CheckBoundFramebuffersValid("glCopyTexImage2D")) { | 
| 7910 return; | 7971 return; | 
| 7911 } | 7972 } | 
| 7912 | 7973 | 
| 7913 CopyRealGLErrorsToWrapper(); | 7974 CopyRealGLErrorsToWrapper(); | 
| 7914 ScopedResolvedFrameBufferBinder binder(this, false, true); | 7975 ScopedResolvedFrameBufferBinder binder(this, false, true); | 
| 7915 gfx::Size size = GetBoundReadFrameBufferSize(); | 7976 gfx::Size size = GetBoundReadFrameBufferSize(); | 
| 7916 | 7977 | 
| 7917 if (info->IsAttachedToFramebuffer()) { | 7978 if (info->IsAttachedToFramebuffer()) { | 
| 7918 clear_state_dirty_ = true; | 7979 clear_state_dirty_ = true; | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7951 copyWidth, copyHeight); | 8012 copyWidth, copyHeight); | 
| 7952 } | 8013 } | 
| 7953 } else { | 8014 } else { | 
| 7954 glCopyTexImage2D(target, level, internal_format, | 8015 glCopyTexImage2D(target, level, internal_format, | 
| 7955 copyX, copyY, copyWidth, copyHeight, border); | 8016 copyX, copyY, copyWidth, copyHeight, border); | 
| 7956 } | 8017 } | 
| 7957 GLenum error = PeekGLError(); | 8018 GLenum error = PeekGLError(); | 
| 7958 if (error == GL_NO_ERROR) { | 8019 if (error == GL_NO_ERROR) { | 
| 7959 texture_manager()->SetLevelInfo( | 8020 texture_manager()->SetLevelInfo( | 
| 7960 info, target, level, internal_format, width, height, 1, | 8021 info, target, level, internal_format, width, height, 1, | 
| 7961 border, internal_format, GL_UNSIGNED_BYTE, true); | 8022 border, internal_format, GL_UNSIGNED_BYTE, true); | 
| 
ccameron
2013/01/19 01:38:46
... we would cash in here (and otherwise in the pr
 | |
| 7962 } | 8023 } | 
| 7963 } | 8024 } | 
| 7964 | 8025 | 
| 7965 void GLES2DecoderImpl::DoCopyTexSubImage2D( | 8026 void GLES2DecoderImpl::DoCopyTexSubImage2D( | 
| 7966 GLenum target, | 8027 GLenum target, | 
| 7967 GLint level, | 8028 GLint level, | 
| 7968 GLint xoffset, | 8029 GLint xoffset, | 
| 7969 GLint yoffset, | 8030 GLint yoffset, | 
| 7970 GLint x, | 8031 GLint x, | 
| 7971 GLint y, | 8032 GLint y, | 
| (...skipping 1596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9568 return; | 9629 return; | 
| 9569 } | 9630 } | 
| 9570 if (info->IsAttachedToFramebuffer()) { | 9631 if (info->IsAttachedToFramebuffer()) { | 
| 9571 clear_state_dirty_ = true; | 9632 clear_state_dirty_ = true; | 
| 9572 } | 9633 } | 
| 9573 if (info->IsImmutable()) { | 9634 if (info->IsImmutable()) { | 
| 9574 SetGLError(GL_INVALID_OPERATION, | 9635 SetGLError(GL_INVALID_OPERATION, | 
| 9575 "glTexStorage2DEXT", "texture is immutable"); | 9636 "glTexStorage2DEXT", "texture is immutable"); | 
| 9576 return; | 9637 return; | 
| 9577 } | 9638 } | 
| 9639 | |
| 9640 GLenum format = ExtractFormatFromStorageFormat(internal_format); | |
| 9641 GLenum type = ExtractTypeFromStorageFormat(internal_format); | |
| 9642 | |
| 9643 { | |
| 9644 GLsizei level_width = width; | |
| 9645 GLsizei level_height = height; | |
| 9646 uint32 estimated_size = 0; | |
| 9647 for (int ii = 0; ii < levels; ++ii) { | |
| 9648 uint32 level_size = 0; | |
| 9649 if (!GLES2Util::ComputeImageDataSizes( | |
| 9650 level_width, level_height, format, type, state_.unpack_alignment, | |
| 9651 &estimated_size, NULL, NULL) || | |
| 9652 !SafeAddUint32(estimated_size, level_size, &estimated_size)) { | |
| 9653 SetGLError(GL_OUT_OF_MEMORY, | |
| 9654 "glTexStorage2DEXT", "dimensions too large"); | |
| 9655 return; | |
| 9656 } | |
| 9657 level_width = std::max(1, level_width >> 1); | |
| 9658 level_height = std::max(1, level_height >> 1); | |
| 9659 } | |
| 9660 if (!memory_tracker()->EnsureGPUMemoryAvailable(estimated_size)) { | |
| 9661 SetGLError(GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory"); | |
| 9662 return; | |
| 9663 } | |
| 9664 } | |
| 9665 | |
| 9578 CopyRealGLErrorsToWrapper(); | 9666 CopyRealGLErrorsToWrapper(); | 
| 9579 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format), | 9667 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format), | 
| 9580 width, height); | 9668 width, height); | 
| 9581 GLenum error = PeekGLError(); | 9669 GLenum error = PeekGLError(); | 
| 9582 if (error == GL_NO_ERROR) { | 9670 if (error == GL_NO_ERROR) { | 
| 9583 GLenum format = ExtractFormatFromStorageFormat(internal_format); | |
| 9584 GLenum type = ExtractTypeFromStorageFormat(internal_format); | |
| 9585 GLsizei level_width = width; | 9671 GLsizei level_width = width; | 
| 9586 GLsizei level_height = height; | 9672 GLsizei level_height = height; | 
| 9587 for (int ii = 0; ii < levels; ++ii) { | 9673 for (int ii = 0; ii < levels; ++ii) { | 
| 9588 texture_manager()->SetLevelInfo( | 9674 texture_manager()->SetLevelInfo( | 
| 9589 info, target, ii, format, level_width, level_height, 1, 0, format, | 9675 info, target, ii, format, level_width, level_height, 1, 0, format, | 
| 9590 type, false); | 9676 type, false); | 
| 9591 level_width = std::max(1, level_width >> 1); | 9677 level_width = std::max(1, level_width >> 1); | 
| 9592 level_height = std::max(1, level_height >> 1); | 9678 level_height = std::max(1, level_height >> 1); | 
| 9593 } | 9679 } | 
| 9594 info->SetImmutable(true); | 9680 info->SetImmutable(true); | 
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9876 "glAsyncTexImage2DCHROMIUM", info, target, level, pixels)) | 9962 "glAsyncTexImage2DCHROMIUM", info, target, level, pixels)) | 
| 9877 return error::kNoError; | 9963 return error::kNoError; | 
| 9878 | 9964 | 
| 9879 // Don't allow async redefinition of a textures. | 9965 // Don't allow async redefinition of a textures. | 
| 9880 if (info->IsDefined()) { | 9966 if (info->IsDefined()) { | 
| 9881 SetGLError(GL_INVALID_OPERATION, | 9967 SetGLError(GL_INVALID_OPERATION, | 
| 9882 "glAsyncTexImage2DCHROMIUM", "already defined"); | 9968 "glAsyncTexImage2DCHROMIUM", "already defined"); | 
| 9883 return error::kNoError; | 9969 return error::kNoError; | 
| 9884 } | 9970 } | 
| 9885 | 9971 | 
| 9972 if (!memory_tracker()->EnsureGPUMemoryAvailable(pixels_size)) { | |
| 9973 SetGLError(GL_OUT_OF_MEMORY, "glAsyncTexImage2DCHROMIUM", "out of memory"); | |
| 9974 return error::kNoError; | |
| 9975 } | |
| 9976 | |
| 9886 // We know the memory/size is safe, so get the real shared memory since | 9977 // We know the memory/size is safe, so get the real shared memory since | 
| 9887 // it might need to be duped to prevent use-after-free of the memory. | 9978 // it might need to be duped to prevent use-after-free of the memory. | 
| 9888 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id); | 9979 Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id); | 
| 9889 base::SharedMemory* shared_memory = buffer.shared_memory; | 9980 base::SharedMemory* shared_memory = buffer.shared_memory; | 
| 9890 uint32 shm_size = buffer.size; | 9981 uint32 shm_size = buffer.size; | 
| 9891 uint32 shm_data_offset = c.pixels_shm_offset; | 9982 uint32 shm_data_offset = c.pixels_shm_offset; | 
| 9892 uint32 shm_data_size = pixels_size; | 9983 uint32 shm_data_size = pixels_size; | 
| 9893 | 9984 | 
| 9894 // Set up the async state if needed, and make the texture | 9985 // Set up the async state if needed, and make the texture | 
| 9895 // immutable so the async state stays valid. The level info | 9986 // immutable so the async state stays valid. The level info | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9995 return error::kNoError; | 10086 return error::kNoError; | 
| 9996 } | 10087 } | 
| 9997 | 10088 | 
| 9998 // Include the auto-generated part of this file. We split this because it means | 10089 // Include the auto-generated part of this file. We split this because it means | 
| 9999 // we can easily edit the non-auto generated parts right here in this file | 10090 // we can easily edit the non-auto generated parts right here in this file | 
| 10000 // instead of having to edit some template or the code generator. | 10091 // instead of having to edit some template or the code generator. | 
| 10001 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 10092 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 
| 10002 | 10093 | 
| 10003 } // namespace gles2 | 10094 } // namespace gles2 | 
| 10004 } // namespace gpu | 10095 } // namespace gpu | 
| OLD | NEW |