| 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 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 | 237 |
| 238 static bool StringIsValidForGLES(const char* str) { | 238 static bool StringIsValidForGLES(const char* str) { |
| 239 for (; *str; ++str) { | 239 for (; *str; ++str) { |
| 240 if (!CharacterIsValidForGLES(*str)) { | 240 if (!CharacterIsValidForGLES(*str)) { |
| 241 return false; | 241 return false; |
| 242 } | 242 } |
| 243 } | 243 } |
| 244 return true; | 244 return true; |
| 245 } | 245 } |
| 246 | 246 |
| 247 static inline GLenum GetTexInternalFormat(GLenum internal_format) { | |
| 248 if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) { | |
| 249 if (internal_format == GL_BGRA_EXT || internal_format == GL_BGRA8_EXT) | |
| 250 return GL_RGBA8; | |
| 251 } | |
| 252 return internal_format; | |
| 253 } | |
| 254 | |
| 255 // TODO(epenner): Could the above function be merged into this and removed? | |
| 256 static inline GLenum GetTexInternalFormat(GLenum internal_format, | |
| 257 GLenum format, | |
| 258 GLenum type) { | |
| 259 GLenum gl_internal_format = GetTexInternalFormat(internal_format); | |
| 260 | |
| 261 if (gfx::GetGLImplementation() == gfx::kGLImplementationEGLGLES2) | |
| 262 return gl_internal_format; | |
| 263 | |
| 264 if (type == GL_FLOAT) { | |
| 265 switch (format) { | |
| 266 case GL_RGBA: | |
| 267 gl_internal_format = GL_RGBA32F_ARB; | |
| 268 break; | |
| 269 case GL_RGB: | |
| 270 gl_internal_format = GL_RGB32F_ARB; | |
| 271 break; | |
| 272 case GL_LUMINANCE_ALPHA: | |
| 273 gl_internal_format = GL_LUMINANCE_ALPHA32F_ARB; | |
| 274 break; | |
| 275 case GL_LUMINANCE: | |
| 276 gl_internal_format = GL_LUMINANCE32F_ARB; | |
| 277 break; | |
| 278 case GL_ALPHA: | |
| 279 gl_internal_format = GL_ALPHA32F_ARB; | |
| 280 break; | |
| 281 default: | |
| 282 NOTREACHED(); | |
| 283 break; | |
| 284 } | |
| 285 } else if (type == GL_HALF_FLOAT_OES) { | |
| 286 switch (format) { | |
| 287 case GL_RGBA: | |
| 288 gl_internal_format = GL_RGBA16F_ARB; | |
| 289 break; | |
| 290 case GL_RGB: | |
| 291 gl_internal_format = GL_RGB16F_ARB; | |
| 292 break; | |
| 293 case GL_LUMINANCE_ALPHA: | |
| 294 gl_internal_format = GL_LUMINANCE_ALPHA16F_ARB; | |
| 295 break; | |
| 296 case GL_LUMINANCE: | |
| 297 gl_internal_format = GL_LUMINANCE16F_ARB; | |
| 298 break; | |
| 299 case GL_ALPHA: | |
| 300 gl_internal_format = GL_ALPHA16F_ARB; | |
| 301 break; | |
| 302 default: | |
| 303 NOTREACHED(); | |
| 304 break; | |
| 305 } | |
| 306 } | |
| 307 return gl_internal_format; | |
| 308 } | |
| 309 | |
| 310 static void WrappedTexImage2D( | |
| 311 GLenum target, | |
| 312 GLint level, | |
| 313 GLenum internal_format, | |
| 314 GLsizei width, | |
| 315 GLsizei height, | |
| 316 GLint border, | |
| 317 GLenum format, | |
| 318 GLenum type, | |
| 319 const void* pixels) { | |
| 320 glTexImage2D( | |
| 321 target, level, GetTexInternalFormat(internal_format, format, type), | |
| 322 width, height, border, format, type, pixels); | |
| 323 } | |
| 324 | |
| 325 // Wrapper for glEnable/glDisable that doesn't suck. | 247 // Wrapper for glEnable/glDisable that doesn't suck. |
| 326 static void EnableDisable(GLenum pname, bool enable) { | 248 static void EnableDisable(GLenum pname, bool enable) { |
| 327 if (enable) { | 249 if (enable) { |
| 328 glEnable(pname); | 250 glEnable(pname); |
| 329 } else { | 251 } else { |
| 330 glDisable(pname); | 252 glDisable(pname); |
| 331 } | 253 } |
| 332 } | 254 } |
| 333 | 255 |
| 334 // This class prevents any GL errors that occur when it is in scope from | 256 // This class prevents any GL errors that occur when it is in scope from |
| (...skipping 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1963 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) { | 1885 if (!memory_tracker_.EnsureGPUMemoryAvailable(image_size)) { |
| 1964 return false; | 1886 return false; |
| 1965 } | 1887 } |
| 1966 | 1888 |
| 1967 scoped_ptr<char[]> zero_data; | 1889 scoped_ptr<char[]> zero_data; |
| 1968 if (zero) { | 1890 if (zero) { |
| 1969 zero_data.reset(new char[image_size]); | 1891 zero_data.reset(new char[image_size]); |
| 1970 memset(zero_data.get(), 0, image_size); | 1892 memset(zero_data.get(), 0, image_size); |
| 1971 } | 1893 } |
| 1972 | 1894 |
| 1973 WrappedTexImage2D(GL_TEXTURE_2D, | 1895 glTexImage2D(GL_TEXTURE_2D, |
| 1974 0, // mip level | 1896 0, // mip level |
| 1975 format, | 1897 format, |
| 1976 size.width(), | 1898 size.width(), |
| 1977 size.height(), | 1899 size.height(), |
| 1978 0, // border | 1900 0, // border |
| 1979 format, | 1901 format, |
| 1980 GL_UNSIGNED_BYTE, | 1902 GL_UNSIGNED_BYTE, |
| 1981 zero_data.get()); | 1903 zero_data.get()); |
| 1982 | 1904 |
| 1983 size_ = size; | 1905 size_ = size; |
| 1984 | 1906 |
| 1985 bool success = glGetError() == GL_NO_ERROR; | 1907 bool success = glGetError() == GL_NO_ERROR; |
| 1986 if (success) { | 1908 if (success) { |
| 1987 memory_tracker_.TrackMemFree(bytes_allocated_); | 1909 memory_tracker_.TrackMemFree(bytes_allocated_); |
| 1988 bytes_allocated_ = image_size; | 1910 bytes_allocated_ = image_size; |
| 1989 memory_tracker_.TrackMemAlloc(bytes_allocated_); | 1911 memory_tracker_.TrackMemAlloc(bytes_allocated_); |
| 1990 } | 1912 } |
| 1991 return success; | 1913 return success; |
| (...skipping 5402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7394 scoped_ptr<char[]> zero(new char[size]); | 7316 scoped_ptr<char[]> zero(new char[size]); |
| 7395 memset(zero.get(), 0, size); | 7317 memset(zero.get(), 0, size); |
| 7396 glBindTexture(bind_target, service_id); | 7318 glBindTexture(bind_target, service_id); |
| 7397 | 7319 |
| 7398 GLint y = 0; | 7320 GLint y = 0; |
| 7399 while (y < height) { | 7321 while (y < height) { |
| 7400 GLint h = y + tile_height > height ? height - y : tile_height; | 7322 GLint h = y + tile_height > height ? height - y : tile_height; |
| 7401 if (is_texture_immutable || h != height) { | 7323 if (is_texture_immutable || h != height) { |
| 7402 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get()); | 7324 glTexSubImage2D(target, level, 0, y, width, h, format, type, zero.get()); |
| 7403 } else { | 7325 } else { |
| 7404 WrappedTexImage2D( | 7326 glTexImage2D( |
| 7405 target, level, format, width, h, 0, format, type, zero.get()); | 7327 target, level, format, width, h, 0, format, type, zero.get()); |
| 7406 } | 7328 } |
| 7407 y += tile_height; | 7329 y += tile_height; |
| 7408 } | 7330 } |
| 7409 Texture* texture = GetTextureInfoForTarget(bind_target); | 7331 Texture* texture = GetTextureInfoForTarget(bind_target); |
| 7410 glBindTexture(bind_target, texture ? texture->service_id() : 0); | 7332 glBindTexture(bind_target, texture ? texture->service_id() : 0); |
| 7411 return true; | 7333 return true; |
| 7412 } | 7334 } |
| 7413 | 7335 |
| 7414 namespace { | 7336 namespace { |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7885 } | 7807 } |
| 7886 | 7808 |
| 7887 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) { | 7809 if (!teximage2d_faster_than_texsubimage2d_ && level_is_same && pixels) { |
| 7888 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); | 7810 glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); |
| 7889 texture_manager()->SetLevelCleared(texture, target, level, true); | 7811 texture_manager()->SetLevelCleared(texture, target, level, true); |
| 7890 tex_image_2d_failed_ = false; | 7812 tex_image_2d_failed_ = false; |
| 7891 return; | 7813 return; |
| 7892 } | 7814 } |
| 7893 | 7815 |
| 7894 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexImage2D"); | 7816 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexImage2D"); |
| 7895 WrappedTexImage2D( | 7817 glTexImage2D( |
| 7896 target, level, internal_format, width, height, border, format, type, | 7818 target, level, internal_format, width, height, border, format, type, |
| 7897 pixels); | 7819 pixels); |
| 7898 GLenum error = LOCAL_PEEK_GL_ERROR("glTexImage2D"); | 7820 GLenum error = LOCAL_PEEK_GL_ERROR("glTexImage2D"); |
| 7899 if (error == GL_NO_ERROR) { | 7821 if (error == GL_NO_ERROR) { |
| 7900 texture_manager()->SetLevelInfo( | 7822 texture_manager()->SetLevelInfo( |
| 7901 texture, | 7823 texture, |
| 7902 target, level, internal_format, width, height, 1, border, format, type, | 7824 target, level, internal_format, width, height, 1, border, format, type, |
| 7903 pixels != NULL); | 7825 pixels != NULL); |
| 7904 tex_image_2d_failed_ = false; | 7826 tex_image_2d_failed_ = false; |
| 7905 } | 7827 } |
| (...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8377 ScopedTextureUploadTimer timer(this); | 8299 ScopedTextureUploadTimer timer(this); |
| 8378 glTexSubImage2D( | 8300 glTexSubImage2D( |
| 8379 target, level, xoffset, yoffset, width, height, format, type, data); | 8301 target, level, xoffset, yoffset, width, height, format, type, data); |
| 8380 return error::kNoError; | 8302 return error::kNoError; |
| 8381 } | 8303 } |
| 8382 | 8304 |
| 8383 if (teximage2d_faster_than_texsubimage2d_ && !texture->IsImmutable()) { | 8305 if (teximage2d_faster_than_texsubimage2d_ && !texture->IsImmutable()) { |
| 8384 ScopedTextureUploadTimer timer(this); | 8306 ScopedTextureUploadTimer timer(this); |
| 8385 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the | 8307 // NOTE: In OpenGL ES 2.0 border is always zero and format is always the |
| 8386 // same as internal_foramt. If that changes we'll need to look them up. | 8308 // same as internal_foramt. If that changes we'll need to look them up. |
| 8387 WrappedTexImage2D( | 8309 glTexImage2D( |
| 8388 target, level, format, width, height, 0, format, type, data); | 8310 target, level, format, width, height, 0, format, type, data); |
| 8389 } else { | 8311 } else { |
| 8390 ScopedTextureUploadTimer timer(this); | 8312 ScopedTextureUploadTimer timer(this); |
| 8391 glTexSubImage2D( | 8313 glTexSubImage2D( |
| 8392 target, level, xoffset, yoffset, width, height, format, type, data); | 8314 target, level, xoffset, yoffset, width, height, format, type, data); |
| 8393 } | 8315 } |
| 8394 texture_manager()->SetLevelCleared(texture, target, level, true); | 8316 texture_manager()->SetLevelCleared(texture, target, level, true); |
| 8395 return error::kNoError; | 8317 return error::kNoError; |
| 8396 } | 8318 } |
| 8397 | 8319 |
| (...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9711 } | 9633 } |
| 9712 | 9634 |
| 9713 // Resize the destination texture to the dimensions of the source texture. | 9635 // Resize the destination texture to the dimensions of the source texture. |
| 9714 if (!dest_level_defined || dest_width != source_width || | 9636 if (!dest_level_defined || dest_width != source_width || |
| 9715 dest_height != source_height || | 9637 dest_height != source_height || |
| 9716 dest_internal_format != internal_format || | 9638 dest_internal_format != internal_format || |
| 9717 dest_type_previous != dest_type) { | 9639 dest_type_previous != dest_type) { |
| 9718 // Ensure that the glTexImage2D succeeds. | 9640 // Ensure that the glTexImage2D succeeds. |
| 9719 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); | 9641 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glCopyTextureCHROMIUM"); |
| 9720 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); | 9642 glBindTexture(GL_TEXTURE_2D, dest_texture->service_id()); |
| 9721 WrappedTexImage2D( | 9643 glTexImage2D( |
| 9722 GL_TEXTURE_2D, level, internal_format, source_width, source_height, | 9644 GL_TEXTURE_2D, level, internal_format, source_width, source_height, |
| 9723 0, internal_format, dest_type, NULL); | 9645 0, internal_format, dest_type, NULL); |
| 9724 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); | 9646 GLenum error = LOCAL_PEEK_GL_ERROR("glCopyTextureCHROMIUM"); |
| 9725 if (error != GL_NO_ERROR) { | 9647 if (error != GL_NO_ERROR) { |
| 9726 RestoreCurrentTexture2DBindings(); | 9648 RestoreCurrentTexture2DBindings(); |
| 9727 return; | 9649 return; |
| 9728 } | 9650 } |
| 9729 | 9651 |
| 9730 texture_manager()->SetLevelInfo( | 9652 texture_manager()->SetLevelInfo( |
| 9731 dest_texture, GL_TEXTURE_2D, level, internal_format, source_width, | 9653 dest_texture, GL_TEXTURE_2D, level, internal_format, source_width, |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9865 level_height = std::max(1, level_height >> 1); | 9787 level_height = std::max(1, level_height >> 1); |
| 9866 } | 9788 } |
| 9867 if (!EnsureGPUMemoryAvailable(estimated_size)) { | 9789 if (!EnsureGPUMemoryAvailable(estimated_size)) { |
| 9868 LOCAL_SET_GL_ERROR( | 9790 LOCAL_SET_GL_ERROR( |
| 9869 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory"); | 9791 GL_OUT_OF_MEMORY, "glTexStorage2DEXT", "out of memory"); |
| 9870 return; | 9792 return; |
| 9871 } | 9793 } |
| 9872 } | 9794 } |
| 9873 | 9795 |
| 9874 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT"); | 9796 LOCAL_COPY_REAL_GL_ERRORS_TO_WRAPPER("glTexStorage2DEXT"); |
| 9875 glTexStorage2DEXT(target, levels, GetTexInternalFormat(internal_format), | 9797 glTexStorage2DEXT(target, levels, internal_format, width, height); |
| 9876 width, height); | |
| 9877 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT"); | 9798 GLenum error = LOCAL_PEEK_GL_ERROR("glTexStorage2DEXT"); |
| 9878 if (error == GL_NO_ERROR) { | 9799 if (error == GL_NO_ERROR) { |
| 9879 GLsizei level_width = width; | 9800 GLsizei level_width = width; |
| 9880 GLsizei level_height = height; | 9801 GLsizei level_height = height; |
| 9881 for (int ii = 0; ii < levels; ++ii) { | 9802 for (int ii = 0; ii < levels; ++ii) { |
| 9882 texture_manager()->SetLevelInfo( | 9803 texture_manager()->SetLevelInfo( |
| 9883 texture, target, ii, format, level_width, level_height, 1, 0, format, | 9804 texture, target, ii, format, level_width, level_height, 1, 0, format, |
| 9884 type, false); | 9805 type, false); |
| 9885 level_width = std::max(1, level_width >> 1); | 9806 level_width = std::max(1, level_width >> 1); |
| 9886 level_height = std::max(1, level_height >> 1); | 9807 level_height = std::max(1, level_height >> 1); |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10261 | 10182 |
| 10262 // We know the memory/size is safe, so get the real shared memory since | 10183 // We know the memory/size is safe, so get the real shared memory since |
| 10263 // it might need to be duped to prevent use-after-free of the memory. | 10184 // it might need to be duped to prevent use-after-free of the memory. |
| 10264 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id); | 10185 gpu::Buffer buffer = GetSharedMemoryBuffer(c.pixels_shm_id); |
| 10265 base::SharedMemory* shared_memory = buffer.shared_memory; | 10186 base::SharedMemory* shared_memory = buffer.shared_memory; |
| 10266 uint32 shm_size = buffer.size; | 10187 uint32 shm_size = buffer.size; |
| 10267 uint32 shm_data_offset = c.pixels_shm_offset; | 10188 uint32 shm_data_offset = c.pixels_shm_offset; |
| 10268 uint32 shm_data_size = pixels_size; | 10189 uint32 shm_data_size = pixels_size; |
| 10269 | 10190 |
| 10270 // Setup the parameters. | 10191 // Setup the parameters. |
| 10271 GLenum gl_internal_format = | 10192 gfx::AsyncTexImage2DParams tex_params = {target, level, internal_format, |
| 10272 GetTexInternalFormat(internal_format, format, type); | |
| 10273 gfx::AsyncTexImage2DParams tex_params = {target, level, gl_internal_format, | |
| 10274 width, height, border, format, type}; | 10193 width, height, border, format, type}; |
| 10275 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size, | 10194 gfx::AsyncMemoryParams mem_params = {shared_memory, shm_size, |
| 10276 shm_data_offset, shm_data_size}; | 10195 shm_data_offset, shm_data_size}; |
| 10277 | 10196 |
| 10278 // Set up the async state if needed, and make the texture | 10197 // Set up the async state if needed, and make the texture |
| 10279 // immutable so the async state stays valid. The level info | 10198 // immutable so the async state stays valid. The level info |
| 10280 // is set up lazily when the transfer completes. | 10199 // is set up lazily when the transfer completes. |
| 10281 DCHECK(!texture->GetAsyncTransferState()); | 10200 DCHECK(!texture->GetAsyncTransferState()); |
| 10282 texture->SetAsyncTransferState( | 10201 texture->SetAsyncTransferState( |
| 10283 make_scoped_ptr( | 10202 make_scoped_ptr( |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10412 return error::kNoError; | 10331 return error::kNoError; |
| 10413 } | 10332 } |
| 10414 | 10333 |
| 10415 // Include the auto-generated part of this file. We split this because it means | 10334 // Include the auto-generated part of this file. We split this because it means |
| 10416 // we can easily edit the non-auto generated parts right here in this file | 10335 // we can easily edit the non-auto generated parts right here in this file |
| 10417 // instead of having to edit some template or the code generator. | 10336 // instead of having to edit some template or the code generator. |
| 10418 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 10337 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
| 10419 | 10338 |
| 10420 } // namespace gles2 | 10339 } // namespace gles2 |
| 10421 } // namespace gpu | 10340 } // namespace gpu |
| OLD | NEW |