| 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 // A class to emulate GLES2 over command buffers. | 5 // A class to emulate GLES2 over command buffers. |
| 6 | 6 |
| 7 #include "gpu/command_buffer/client/gles2_implementation.h" | 7 #include "gpu/command_buffer/client/gles2_implementation.h" |
| 8 | 8 |
| 9 #include <GLES2/gl2ext.h> | 9 #include <GLES2/gl2ext.h> |
| 10 #include <GLES2/gl2extchromium.h> | 10 #include <GLES2/gl2extchromium.h> |
| 11 #include <algorithm> | 11 #include <algorithm> |
| 12 #include <limits> | 12 #include <limits> |
| 13 #include <map> | 13 #include <map> |
| 14 #include <queue> | 14 #include <queue> |
| 15 #include <set> | 15 #include <set> |
| 16 #include <sstream> | 16 #include <sstream> |
| 17 #include <string> | 17 #include <string> |
| 18 #include "base/bind.h" | 18 #include "base/bind.h" |
| 19 #include "gpu/command_buffer/client/buffer_tracker.h" | 19 #include "gpu/command_buffer/client/buffer_tracker.h" |
| 20 #include "gpu/command_buffer/client/gpu_control.h" | 20 #include "gpu/command_buffer/client/gpu_control.h" |
| 21 #include "gpu/command_buffer/client/gpu_memory_buffer_tracker.h" | |
| 22 #include "gpu/command_buffer/client/program_info_manager.h" | 21 #include "gpu/command_buffer/client/program_info_manager.h" |
| 23 #include "gpu/command_buffer/client/query_tracker.h" | 22 #include "gpu/command_buffer/client/query_tracker.h" |
| 24 #include "gpu/command_buffer/client/transfer_buffer.h" | 23 #include "gpu/command_buffer/client/transfer_buffer.h" |
| 25 #include "gpu/command_buffer/client/vertex_array_object_manager.h" | 24 #include "gpu/command_buffer/client/vertex_array_object_manager.h" |
| 26 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 25 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 27 #include "gpu/command_buffer/common/trace_event.h" | 26 #include "gpu/command_buffer/common/trace_event.h" |
| 28 #include "ui/gfx/gpu_memory_buffer.h" | |
| 29 | 27 |
| 30 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 28 #if defined(__native_client__) && !defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 31 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS | 29 #define GLES2_SUPPORT_CLIENT_SIDE_ARRAYS |
| 32 #endif | 30 #endif |
| 33 | 31 |
| 34 #if defined(GPU_CLIENT_DEBUG) | 32 #if defined(GPU_CLIENT_DEBUG) |
| 35 #include "base/command_line.h" | 33 #include "base/command_line.h" |
| 36 #include "gpu/command_buffer/client/gpu_switches.h" | 34 #include "gpu/command_buffer/client/gpu_switches.h" |
| 37 #endif | 35 #endif |
| 38 | 36 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 static_state_.int_state.num_compressed_texture_formats); | 182 static_state_.int_state.num_compressed_texture_formats); |
| 185 util_.set_num_shader_binary_formats( | 183 util_.set_num_shader_binary_formats( |
| 186 static_state_.int_state.num_shader_binary_formats); | 184 static_state_.int_state.num_shader_binary_formats); |
| 187 | 185 |
| 188 texture_units_.reset( | 186 texture_units_.reset( |
| 189 new TextureUnit[ | 187 new TextureUnit[ |
| 190 static_state_.int_state.max_combined_texture_image_units]); | 188 static_state_.int_state.max_combined_texture_image_units]); |
| 191 | 189 |
| 192 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 190 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
| 193 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); | 191 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); |
| 194 gpu_memory_buffer_tracker_.reset(new GpuMemoryBufferTracker(gpu_control_)); | |
| 195 | 192 |
| 196 query_id_allocator_.reset(new IdAllocator()); | 193 query_id_allocator_.reset(new IdAllocator()); |
| 197 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 194 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 198 GetIdHandler(id_namespaces::kBuffers)->MakeIds( | 195 GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
| 199 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); | 196 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); |
| 200 #endif | 197 #endif |
| 201 | 198 |
| 202 vertex_array_object_manager_.reset(new VertexArrayObjectManager( | 199 vertex_array_object_manager_.reset(new VertexArrayObjectManager( |
| 203 static_state_.int_state.max_vertex_attribs, | 200 static_state_.int_state.max_vertex_attribs, |
| 204 reserved_ids_[0], | 201 reserved_ids_[0], |
| (...skipping 3725 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3930 case GL_MAP_CHROMIUM: | 3927 case GL_MAP_CHROMIUM: |
| 3931 case GL_SCANOUT_CHROMIUM: | 3928 case GL_SCANOUT_CHROMIUM: |
| 3932 return true; | 3929 return true; |
| 3933 default: | 3930 default: |
| 3934 return false; | 3931 return false; |
| 3935 } | 3932 } |
| 3936 } | 3933 } |
| 3937 | 3934 |
| 3938 } // namespace | 3935 } // namespace |
| 3939 | 3936 |
| 3940 GLuint GLES2Implementation::CreateImageCHROMIUMHelper(GLsizei width, | 3937 GLuint GLES2Implementation::CreateImageCHROMIUMHelper(ClientBuffer buffer, |
| 3938 GLsizei width, |
| 3941 GLsizei height, | 3939 GLsizei height, |
| 3942 GLenum internalformat, | 3940 GLenum internalformat) { |
| 3943 GLenum usage) { | |
| 3944 if (width <= 0) { | 3941 if (width <= 0) { |
| 3945 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "width <= 0"); | 3942 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "width <= 0"); |
| 3946 return 0; | 3943 return 0; |
| 3947 } | 3944 } |
| 3948 | 3945 |
| 3949 if (height <= 0) { | 3946 if (height <= 0) { |
| 3950 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "height <= 0"); | 3947 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "height <= 0"); |
| 3951 return 0; | 3948 return 0; |
| 3952 } | 3949 } |
| 3950 |
| 3951 if (!ValidImageFormat(internalformat)) { |
| 3952 SetGLError(GL_INVALID_VALUE, "glCreateImageCHROMIUM", "invalid format"); |
| 3953 return 0; |
| 3954 } |
| 3955 |
| 3953 // Flush the command stream to ensure ordering in case the newly | 3956 // Flush the command stream to ensure ordering in case the newly |
| 3954 // returned image_id has recently been in use with a different buffer. | 3957 // returned image_id has recently been in use with a different buffer. |
| 3955 helper_->CommandBufferHelper::Flush(); | 3958 helper_->CommandBufferHelper::Flush(); |
| 3956 | 3959 int32_t image_id = |
| 3957 // Create new buffer. | 3960 gpu_control_->CreateImage(buffer, width, height, internalformat); |
| 3958 GLuint buffer_id = gpu_memory_buffer_tracker_->CreateBuffer( | 3961 if (image_id < 0) { |
| 3959 width, height, internalformat, usage); | 3962 SetGLError(GL_OUT_OF_MEMORY, "glCreateImageCHROMIUM", "image_id < 0"); |
| 3960 if (buffer_id == 0) { | |
| 3961 SetGLError(GL_OUT_OF_MEMORY, "glCreateImageCHROMIUM", "out of GPU memory."); | |
| 3962 return 0; | 3963 return 0; |
| 3963 } | 3964 } |
| 3964 return buffer_id; | 3965 return image_id; |
| 3965 } | 3966 } |
| 3966 | 3967 |
| 3967 GLuint GLES2Implementation::CreateImageCHROMIUM(GLsizei width, | 3968 GLuint GLES2Implementation::CreateImageCHROMIUM(ClientBuffer buffer, |
| 3969 GLsizei width, |
| 3968 GLsizei height, | 3970 GLsizei height, |
| 3969 GLenum internalformat, | 3971 GLenum internalformat) { |
| 3970 GLenum usage) { | |
| 3971 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3972 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3972 GPU_CLIENT_LOG( | 3973 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateImageCHROMIUM(" << width |
| 3973 "[" << GetLogPrefix() << "] glCreateImageCHROMIUM(" << width << ", " | 3974 << ", " << height << ", " |
| 3974 << height << ", " | 3975 << GLES2Util::GetStringImageInternalFormat(internalformat) |
| 3975 << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " | 3976 << ")"); |
| 3976 << GLES2Util::GetStringTextureInternalFormat(usage) << ")"); | |
| 3977 GLuint image_id = | 3977 GLuint image_id = |
| 3978 CreateImageCHROMIUMHelper(width, height, internalformat, usage); | 3978 CreateImageCHROMIUMHelper(buffer, width, height, internalformat); |
| 3979 CheckGLError(); | 3979 CheckGLError(); |
| 3980 return image_id; | 3980 return image_id; |
| 3981 } | 3981 } |
| 3982 | 3982 |
| 3983 void GLES2Implementation::DestroyImageCHROMIUMHelper(GLuint image_id) { | 3983 void GLES2Implementation::DestroyImageCHROMIUMHelper(GLuint image_id) { |
| 3984 gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( | |
| 3985 image_id); | |
| 3986 if (!gpu_buffer) { | |
| 3987 SetGLError(GL_INVALID_OPERATION, "glDestroyImageCHROMIUM", "invalid image"); | |
| 3988 return; | |
| 3989 } | |
| 3990 | |
| 3991 // Flush the command stream to make sure all pending commands | 3984 // Flush the command stream to make sure all pending commands |
| 3992 // that may refer to the image_id are executed on the service side. | 3985 // that may refer to the image_id are executed on the service side. |
| 3993 helper_->CommandBufferHelper::Flush(); | 3986 helper_->CommandBufferHelper::Flush(); |
| 3994 gpu_memory_buffer_tracker_->RemoveBuffer(image_id); | 3987 gpu_control_->DestroyImage(image_id); |
| 3995 } | 3988 } |
| 3996 | 3989 |
| 3997 void GLES2Implementation::DestroyImageCHROMIUM(GLuint image_id) { | 3990 void GLES2Implementation::DestroyImageCHROMIUM(GLuint image_id) { |
| 3998 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3991 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3999 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDestroyImageCHROMIUM(" | 3992 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDestroyImageCHROMIUM(" |
| 4000 << image_id << ")"); | 3993 << image_id << ")"); |
| 4001 DestroyImageCHROMIUMHelper(image_id); | 3994 DestroyImageCHROMIUMHelper(image_id); |
| 4002 CheckGLError(); | 3995 CheckGLError(); |
| 4003 } | 3996 } |
| 4004 | 3997 |
| 4005 void GLES2Implementation::UnmapImageCHROMIUMHelper(GLuint image_id) { | |
| 4006 gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( | |
| 4007 image_id); | |
| 4008 if (!gpu_buffer) { | |
| 4009 SetGLError(GL_INVALID_OPERATION, "glUnmapImageCHROMIUM", "invalid image"); | |
| 4010 return; | |
| 4011 } | |
| 4012 | |
| 4013 if (!gpu_buffer->IsMapped()) { | |
| 4014 SetGLError(GL_INVALID_OPERATION, "glUnmapImageCHROMIUM", "not mapped"); | |
| 4015 return; | |
| 4016 } | |
| 4017 gpu_buffer->Unmap(); | |
| 4018 } | |
| 4019 | |
| 4020 void GLES2Implementation::UnmapImageCHROMIUM(GLuint image_id) { | |
| 4021 GPU_CLIENT_SINGLE_THREAD_CHECK(); | |
| 4022 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUnmapImageCHROMIUM(" | |
| 4023 << image_id << ")"); | |
| 4024 | |
| 4025 UnmapImageCHROMIUMHelper(image_id); | |
| 4026 CheckGLError(); | |
| 4027 } | |
| 4028 | |
| 4029 void* GLES2Implementation::MapImageCHROMIUMHelper(GLuint image_id) { | |
| 4030 gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( | |
| 4031 image_id); | |
| 4032 if (!gpu_buffer) { | |
| 4033 SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "invalid image"); | |
| 4034 return NULL; | |
| 4035 } | |
| 4036 | |
| 4037 if (gpu_buffer->IsMapped()) { | |
| 4038 SetGLError(GL_INVALID_OPERATION, "glMapImageCHROMIUM", "already mapped"); | |
| 4039 return NULL; | |
| 4040 } | |
| 4041 | |
| 4042 return gpu_buffer->Map(); | |
| 4043 } | |
| 4044 | |
| 4045 void* GLES2Implementation::MapImageCHROMIUM(GLuint image_id) { | |
| 4046 GPU_CLIENT_SINGLE_THREAD_CHECK(); | |
| 4047 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glMapImageCHROMIUM(" << image_id | |
| 4048 << ")"); | |
| 4049 | |
| 4050 void* mapped = MapImageCHROMIUMHelper(image_id); | |
| 4051 CheckGLError(); | |
| 4052 return mapped; | |
| 4053 } | |
| 4054 | |
| 4055 void GLES2Implementation::GetImageParameterivCHROMIUMHelper( | |
| 4056 GLuint image_id, GLenum pname, GLint* params) { | |
| 4057 if (pname != GL_IMAGE_ROWBYTES_CHROMIUM) { | |
| 4058 SetGLError(GL_INVALID_ENUM, "glGetImageParameterivCHROMIUM", | |
| 4059 "invalid parameter"); | |
| 4060 return; | |
| 4061 } | |
| 4062 | |
| 4063 gfx::GpuMemoryBuffer* gpu_buffer = gpu_memory_buffer_tracker_->GetBuffer( | |
| 4064 image_id); | |
| 4065 if (!gpu_buffer) { | |
| 4066 SetGLError(GL_INVALID_OPERATION, "glGetImageParameterivCHROMIUM", | |
| 4067 "invalid image"); | |
| 4068 return; | |
| 4069 } | |
| 4070 | |
| 4071 if (!gpu_buffer->IsMapped()) { | |
| 4072 SetGLError( | |
| 4073 GL_INVALID_OPERATION, "glGetImageParameterivCHROMIUM", "not mapped"); | |
| 4074 return; | |
| 4075 } | |
| 4076 | |
| 4077 *params = gpu_buffer->GetStride(); | |
| 4078 } | |
| 4079 | |
| 4080 void GLES2Implementation::GetImageParameterivCHROMIUM( | |
| 4081 GLuint image_id, GLenum pname, GLint* params) { | |
| 4082 GPU_CLIENT_SINGLE_THREAD_CHECK(); | |
| 4083 GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params); | |
| 4084 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glImageParameterivCHROMIUM(" | |
| 4085 << image_id << ", " | |
| 4086 << GLES2Util::GetStringBufferParameter(pname) << ", " | |
| 4087 << static_cast<const void*>(params) << ")"); | |
| 4088 GetImageParameterivCHROMIUMHelper(image_id, pname, params); | |
| 4089 CheckGLError(); | |
| 4090 } | |
| 4091 | |
| 4092 GLuint GLES2Implementation::CreateGpuMemoryBufferImageCHROMIUMHelper( | 3998 GLuint GLES2Implementation::CreateGpuMemoryBufferImageCHROMIUMHelper( |
| 4093 GLsizei width, | 3999 GLsizei width, |
| 4094 GLsizei height, | 4000 GLsizei height, |
| 4095 GLenum internalformat, | 4001 GLenum internalformat, |
| 4096 GLenum usage) { | 4002 GLenum usage) { |
| 4097 if (width <= 0) { | 4003 if (width <= 0) { |
| 4098 SetGLError( | 4004 SetGLError( |
| 4099 GL_INVALID_VALUE, "glCreateGpuMemoryBufferImageCHROMIUM", "width <= 0"); | 4005 GL_INVALID_VALUE, "glCreateGpuMemoryBufferImageCHROMIUM", "width <= 0"); |
| 4100 return 0; | 4006 return 0; |
| 4101 } | 4007 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 4117 if (!ValidImageUsage(usage)) { | 4023 if (!ValidImageUsage(usage)) { |
| 4118 SetGLError(GL_INVALID_VALUE, | 4024 SetGLError(GL_INVALID_VALUE, |
| 4119 "glCreateGpuMemoryBufferImageCHROMIUM", | 4025 "glCreateGpuMemoryBufferImageCHROMIUM", |
| 4120 "invalid usage"); | 4026 "invalid usage"); |
| 4121 return 0; | 4027 return 0; |
| 4122 } | 4028 } |
| 4123 | 4029 |
| 4124 // Flush the command stream to ensure ordering in case the newly | 4030 // Flush the command stream to ensure ordering in case the newly |
| 4125 // returned image_id has recently been in use with a different buffer. | 4031 // returned image_id has recently been in use with a different buffer. |
| 4126 helper_->CommandBufferHelper::Flush(); | 4032 helper_->CommandBufferHelper::Flush(); |
| 4127 | 4033 int32_t image_id = gpu_control_->CreateGpuMemoryBufferImage( |
| 4128 // Create new buffer. | 4034 width, height, internalformat, usage); |
| 4129 GLuint buffer_id = gpu_memory_buffer_tracker_->CreateBuffer( | 4035 if (image_id < 0) { |
| 4130 width, | |
| 4131 height, | |
| 4132 internalformat == GL_RGBA ? GL_RGBA8_OES : GL_RGB8_OES, | |
| 4133 usage); | |
| 4134 if (buffer_id == 0) { | |
| 4135 SetGLError(GL_OUT_OF_MEMORY, | 4036 SetGLError(GL_OUT_OF_MEMORY, |
| 4136 "glCreateGpuMemoryBufferImageCHROMIUM", | 4037 "glCreateGpuMemoryBufferImageCHROMIUM", |
| 4137 "out of GPU memory"); | 4038 "image_id < 0"); |
| 4138 return 0; | 4039 return 0; |
| 4139 } | 4040 } |
| 4140 return buffer_id; | 4041 return image_id; |
| 4141 } | 4042 } |
| 4142 | 4043 |
| 4143 GLuint GLES2Implementation::CreateGpuMemoryBufferImageCHROMIUM( | 4044 GLuint GLES2Implementation::CreateGpuMemoryBufferImageCHROMIUM( |
| 4144 GLsizei width, | 4045 GLsizei width, |
| 4145 GLsizei height, | 4046 GLsizei height, |
| 4146 GLenum internalformat, | 4047 GLenum internalformat, |
| 4147 GLenum usage) { | 4048 GLenum usage) { |
| 4148 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 4049 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 4149 GPU_CLIENT_LOG("[" << GetLogPrefix() | 4050 GPU_CLIENT_LOG("[" << GetLogPrefix() |
| 4150 << "] glCreateGpuMemoryBufferImageCHROMIUM(" << width | 4051 << "] glCreateGpuMemoryBufferImageCHROMIUM(" << width |
| (...skipping 30 matching lines...) Expand all Loading... |
| 4181 return true; | 4082 return true; |
| 4182 } | 4083 } |
| 4183 | 4084 |
| 4184 // Include the auto-generated part of this file. We split this because it means | 4085 // Include the auto-generated part of this file. We split this because it means |
| 4185 // we can easily edit the non-auto generated parts right here in this file | 4086 // we can easily edit the non-auto generated parts right here in this file |
| 4186 // instead of having to edit some template or the code generator. | 4087 // instead of having to edit some template or the code generator. |
| 4187 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 4088 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
| 4188 | 4089 |
| 4189 } // namespace gles2 | 4090 } // namespace gles2 |
| 4190 } // namespace gpu | 4091 } // namespace gpu |
| OLD | NEW |