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 |