Chromium Code Reviews| 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 <utility> | |
|
no sievers
2014/07/08 22:54:04
needed?
hj.r.chung
2014/07/09 05:26:46
Done.
| |
| 18 #include "base/bind.h" | 19 #include "base/bind.h" |
| 19 #include "gpu/command_buffer/client/buffer_tracker.h" | 20 #include "gpu/command_buffer/client/buffer_tracker.h" |
| 20 #include "gpu/command_buffer/client/gpu_control.h" | 21 #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/gpu_memory_buffer_tracker.h" |
| 22 #include "gpu/command_buffer/client/program_info_manager.h" | 23 #include "gpu/command_buffer/client/program_info_manager.h" |
| 23 #include "gpu/command_buffer/client/query_tracker.h" | 24 #include "gpu/command_buffer/client/query_tracker.h" |
| 24 #include "gpu/command_buffer/client/transfer_buffer.h" | 25 #include "gpu/command_buffer/client/transfer_buffer.h" |
| 25 #include "gpu/command_buffer/client/vertex_array_object_manager.h" | 26 #include "gpu/command_buffer/client/vertex_array_object_manager.h" |
| 26 #include "gpu/command_buffer/common/gles2_cmd_utils.h" | 27 #include "gpu/command_buffer/common/gles2_cmd_utils.h" |
| 27 #include "gpu/command_buffer/common/trace_event.h" | 28 #include "gpu/command_buffer/common/trace_event.h" |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 static_state_.int_state.num_shader_binary_formats); | 186 static_state_.int_state.num_shader_binary_formats); |
| 186 | 187 |
| 187 texture_units_.reset( | 188 texture_units_.reset( |
| 188 new TextureUnit[ | 189 new TextureUnit[ |
| 189 static_state_.int_state.max_combined_texture_image_units]); | 190 static_state_.int_state.max_combined_texture_image_units]); |
| 190 | 191 |
| 191 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); | 192 query_tracker_.reset(new QueryTracker(mapped_memory_.get())); |
| 192 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); | 193 buffer_tracker_.reset(new BufferTracker(mapped_memory_.get())); |
| 193 gpu_memory_buffer_tracker_.reset(new GpuMemoryBufferTracker(gpu_control_)); | 194 gpu_memory_buffer_tracker_.reset(new GpuMemoryBufferTracker(gpu_control_)); |
| 194 | 195 |
| 196 query_id_allocator_.reset(new IdAllocator()); | |
| 195 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) | 197 #if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS) |
| 196 GetIdHandler(id_namespaces::kBuffers)->MakeIds( | 198 GetIdHandler(id_namespaces::kBuffers)->MakeIds( |
| 197 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); | 199 this, kClientSideArrayId, arraysize(reserved_ids_), &reserved_ids_[0]); |
| 198 #endif | 200 #endif |
| 199 | 201 |
| 200 vertex_array_object_manager_.reset(new VertexArrayObjectManager( | 202 vertex_array_object_manager_.reset(new VertexArrayObjectManager( |
| 201 static_state_.int_state.max_vertex_attribs, | 203 static_state_.int_state.max_vertex_attribs, |
| 202 reserved_ids_[0], | 204 reserved_ids_[0], |
| 203 reserved_ids_[1])); | 205 reserved_ids_[1])); |
| 204 | 206 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 | 317 |
| 316 // Make sure the commands make it the service. | 318 // Make sure the commands make it the service. |
| 317 WaitForCmd(); | 319 WaitForCmd(); |
| 318 } | 320 } |
| 319 | 321 |
| 320 GLES2CmdHelper* GLES2Implementation::helper() const { | 322 GLES2CmdHelper* GLES2Implementation::helper() const { |
| 321 return helper_; | 323 return helper_; |
| 322 } | 324 } |
| 323 | 325 |
| 324 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { | 326 IdHandlerInterface* GLES2Implementation::GetIdHandler(int namespace_id) const { |
| 325 return share_group_->GetIdHandler(namespace_id); | 327 return share_group_->GetIdHandler(namespace_id); |
|
no sievers
2014/07/08 22:54:04
How about DCHECK(namespace_id != id_namespaces::kQ
hj.r.chung
2014/07/09 05:26:46
Done.
no sievers
2014/07/09 17:50:48
I don't see it :)
| |
| 326 } | 328 } |
| 327 | 329 |
| 330 IdAllocatorInterface* GLES2Implementation::GetIdAllocator( | |
| 331 int namespace_id) const { | |
| 332 if (namespace_id == id_namespaces::kQueries) | |
| 333 return query_id_allocator_.get(); | |
| 334 | |
| 335 return NULL; | |
|
no sievers
2014/07/08 22:54:04
NOTREACHED?
hj.r.chung
2014/07/09 05:26:46
Done.
| |
| 336 } | |
| 337 | |
| 328 void* GLES2Implementation::GetResultBuffer() { | 338 void* GLES2Implementation::GetResultBuffer() { |
| 329 return transfer_buffer_->GetResultBuffer(); | 339 return transfer_buffer_->GetResultBuffer(); |
| 330 } | 340 } |
| 331 | 341 |
| 332 int32 GLES2Implementation::GetResultShmId() { | 342 int32 GLES2Implementation::GetResultShmId() { |
| 333 return transfer_buffer_->GetShmId(); | 343 return transfer_buffer_->GetShmId(); |
| 334 } | 344 } |
| 335 | 345 |
| 336 uint32 GLES2Implementation::GetResultShmOffset() { | 346 uint32 GLES2Implementation::GetResultShmOffset() { |
| 337 return transfer_buffer_->GetResultOffset(); | 347 return transfer_buffer_->GetResultOffset(); |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 561 } | 571 } |
| 562 helper_->GetBucketData( | 572 helper_->GetBucketData( |
| 563 bucket_id, offset, buffer.size(), buffer.shm_id(), buffer.offset()); | 573 bucket_id, offset, buffer.size(), buffer.shm_id(), buffer.offset()); |
| 564 WaitForCmd(); | 574 WaitForCmd(); |
| 565 } | 575 } |
| 566 uint32 size_to_copy = std::min(size, buffer.size()); | 576 uint32 size_to_copy = std::min(size, buffer.size()); |
| 567 memcpy(&(*data)[offset], buffer.address(), size_to_copy); | 577 memcpy(&(*data)[offset], buffer.address(), size_to_copy); |
| 568 offset += size_to_copy; | 578 offset += size_to_copy; |
| 569 size -= size_to_copy; | 579 size -= size_to_copy; |
| 570 buffer.Release(); | 580 buffer.Release(); |
| 571 }; | 581 } |
| 572 // Free the bucket. This is not required but it does free up the memory. | 582 // Free the bucket. This is not required but it does free up the memory. |
| 573 // and we don't have to wait for the result so from the client's perspective | 583 // and we don't have to wait for the result so from the client's perspective |
| 574 // it's cheap. | 584 // it's cheap. |
| 575 helper_->SetBucketSize(bucket_id, 0); | 585 helper_->SetBucketSize(bucket_id, 0); |
| 576 } | 586 } |
| 577 return true; | 587 return true; |
| 578 } | 588 } |
| 579 | 589 |
| 580 void GLES2Implementation::SetBucketContents( | 590 void GLES2Implementation::SetBucketContents( |
| 581 uint32 bucket_id, const void* data, size_t size) { | 591 uint32 bucket_id, const void* data, size_t size) { |
| (...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1314 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" | 1324 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttribDivisorANGLE(" |
| 1315 << index << ", " | 1325 << index << ", " |
| 1316 << divisor << ") "); | 1326 << divisor << ") "); |
| 1317 // Record the info on the client side. | 1327 // Record the info on the client side. |
| 1318 vertex_array_object_manager_->SetAttribDivisor(index, divisor); | 1328 vertex_array_object_manager_->SetAttribDivisor(index, divisor); |
| 1319 helper_->VertexAttribDivisorANGLE(index, divisor); | 1329 helper_->VertexAttribDivisorANGLE(index, divisor); |
| 1320 CheckGLError(); | 1330 CheckGLError(); |
| 1321 } | 1331 } |
| 1322 | 1332 |
| 1323 void GLES2Implementation::ShaderSource( | 1333 void GLES2Implementation::ShaderSource( |
| 1324 GLuint shader, GLsizei count, const GLchar* const* source, const GLint* leng th) { | 1334 GLuint shader, |
| 1335 GLsizei count, | |
| 1336 const GLchar* const* source, | |
| 1337 const GLint* length) { | |
| 1325 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 1338 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 1326 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" | 1339 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glShaderSource(" |
| 1327 << shader << ", " << count << ", " | 1340 << shader << ", " << count << ", " |
| 1328 << static_cast<const void*>(source) << ", " | 1341 << static_cast<const void*>(source) << ", " |
| 1329 << static_cast<const void*>(length) << ")"); | 1342 << static_cast<const void*>(length) << ")"); |
| 1330 GPU_CLIENT_LOG_CODE_BLOCK({ | 1343 GPU_CLIENT_LOG_CODE_BLOCK({ |
| 1331 for (GLsizei ii = 0; ii < count; ++ii) { | 1344 for (GLsizei ii = 0; ii < count; ++ii) { |
| 1332 if (source[ii]) { | 1345 if (source[ii]) { |
| 1333 if (length && length[ii] >= 0) { | 1346 if (length && length[ii] >= 0) { |
| 1334 std::string str(source[ii], length[ii]); | 1347 std::string str(source[ii], length[ii]); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1574 if (!*buffer_id) { | 1587 if (!*buffer_id) { |
| 1575 SetGLError(GL_INVALID_OPERATION, function_name, "no buffer bound"); | 1588 SetGLError(GL_INVALID_OPERATION, function_name, "no buffer bound"); |
| 1576 } | 1589 } |
| 1577 return true; | 1590 return true; |
| 1578 } | 1591 } |
| 1579 | 1592 |
| 1580 BufferTracker::Buffer* | 1593 BufferTracker::Buffer* |
| 1581 GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid( | 1594 GLES2Implementation::GetBoundPixelUnpackTransferBufferIfValid( |
| 1582 GLuint buffer_id, | 1595 GLuint buffer_id, |
| 1583 const char* function_name, | 1596 const char* function_name, |
| 1584 GLuint offset, GLsizei size) | 1597 GLuint offset, GLsizei size) { |
| 1585 { | |
| 1586 DCHECK(buffer_id); | 1598 DCHECK(buffer_id); |
| 1587 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); | 1599 BufferTracker::Buffer* buffer = buffer_tracker_->GetBuffer(buffer_id); |
| 1588 if (!buffer) { | 1600 if (!buffer) { |
| 1589 SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer"); | 1601 SetGLError(GL_INVALID_OPERATION, function_name, "invalid buffer"); |
| 1590 return NULL; | 1602 return NULL; |
| 1591 } | 1603 } |
| 1592 if (buffer->mapped()) { | 1604 if (buffer->mapped()) { |
| 1593 SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped"); | 1605 SetGLError(GL_INVALID_OPERATION, function_name, "buffer mapped"); |
| 1594 return NULL; | 1606 return NULL; |
| 1595 } | 1607 } |
| (...skipping 1682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3278 SetGLError( | 3290 SetGLError( |
| 3279 GL_INVALID_VALUE, "glProgramInfoCHROMIUM", "bufsize less than 0."); | 3291 GL_INVALID_VALUE, "glProgramInfoCHROMIUM", "bufsize less than 0."); |
| 3280 return; | 3292 return; |
| 3281 } | 3293 } |
| 3282 if (size == NULL) { | 3294 if (size == NULL) { |
| 3283 SetGLError(GL_INVALID_VALUE, "glProgramInfoCHROMIUM", "size is null."); | 3295 SetGLError(GL_INVALID_VALUE, "glProgramInfoCHROMIUM", "size is null."); |
| 3284 return; | 3296 return; |
| 3285 } | 3297 } |
| 3286 // Make sure they've set size to 0 else the value will be undefined on | 3298 // Make sure they've set size to 0 else the value will be undefined on |
| 3287 // lost context. | 3299 // lost context. |
| 3288 DCHECK(*size == 0); | 3300 DCHECK_EQ(0, *size); |
| 3289 std::vector<int8> result; | 3301 std::vector<int8> result; |
| 3290 GetProgramInfoCHROMIUMHelper(program, &result); | 3302 GetProgramInfoCHROMIUMHelper(program, &result); |
| 3291 if (result.empty()) { | 3303 if (result.empty()) { |
| 3292 return; | 3304 return; |
| 3293 } | 3305 } |
| 3294 *size = result.size(); | 3306 *size = result.size(); |
| 3295 if (!info) { | 3307 if (!info) { |
| 3296 return; | 3308 return; |
| 3297 } | 3309 } |
| 3298 if (static_cast<size_t>(bufsize) < result.size()) { | 3310 if (static_cast<size_t>(bufsize) < result.size()) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 3325 helper_->PostSubBufferCHROMIUM(x, y, width, height); | 3337 helper_->PostSubBufferCHROMIUM(x, y, width, height); |
| 3326 helper_->CommandBufferHelper::Flush(); | 3338 helper_->CommandBufferHelper::Flush(); |
| 3327 if (swap_buffers_tokens_.size() > kMaxSwapBuffers + 1) { | 3339 if (swap_buffers_tokens_.size() > kMaxSwapBuffers + 1) { |
| 3328 helper_->WaitForToken(swap_buffers_tokens_.front()); | 3340 helper_->WaitForToken(swap_buffers_tokens_.front()); |
| 3329 swap_buffers_tokens_.pop(); | 3341 swap_buffers_tokens_.pop(); |
| 3330 } | 3342 } |
| 3331 } | 3343 } |
| 3332 | 3344 |
| 3333 void GLES2Implementation::DeleteQueriesEXTHelper( | 3345 void GLES2Implementation::DeleteQueriesEXTHelper( |
| 3334 GLsizei n, const GLuint* queries) { | 3346 GLsizei n, const GLuint* queries) { |
| 3335 // TODO(gman): Remove this as queries are not shared resources. | 3347 for (GLsizei ii = 0; ii < n; ++ii) { |
| 3336 if (!GetIdHandler(id_namespaces::kQueries)->FreeIds( | 3348 query_tracker_->RemoveQuery(queries[ii]); |
| 3337 this, n, queries, &GLES2Implementation::DeleteQueriesStub)) { | 3349 query_id_allocator_->FreeID(queries[ii]); |
|
no sievers
2014/07/08 22:54:04
You are removing the check for whether these IDs w
hj.r.chung
2014/07/09 05:26:46
For now IdHandlerInterface::FreeIds always returns
no sievers
2014/07/09 17:50:48
Ok, I missed that the old code always returned tru
| |
| 3338 SetGLError( | |
| 3339 GL_INVALID_VALUE, | |
| 3340 "glDeleteTextures", "id not created by this context."); | |
| 3341 return; | |
| 3342 } | 3350 } |
| 3343 | 3351 |
| 3344 for (GLsizei ii = 0; ii < n; ++ii) | |
| 3345 query_tracker_->RemoveQuery(queries[ii]); | |
| 3346 | |
| 3347 helper_->DeleteQueriesEXTImmediate(n, queries); | 3352 helper_->DeleteQueriesEXTImmediate(n, queries); |
| 3348 } | 3353 } |
| 3349 | 3354 |
| 3350 // TODO(gman): Remove this. Queries are not shared resources. | |
| 3351 void GLES2Implementation::DeleteQueriesStub( | |
| 3352 GLsizei /* n */, const GLuint* /* queries */) { | |
| 3353 } | |
| 3354 | |
| 3355 GLboolean GLES2Implementation::IsQueryEXT(GLuint id) { | 3355 GLboolean GLES2Implementation::IsQueryEXT(GLuint id) { |
| 3356 GPU_CLIENT_SINGLE_THREAD_CHECK(); | 3356 GPU_CLIENT_SINGLE_THREAD_CHECK(); |
| 3357 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] IsQueryEXT(" << id << ")"); | 3357 GPU_CLIENT_LOG("[" << GetLogPrefix() << "] IsQueryEXT(" << id << ")"); |
| 3358 | 3358 |
| 3359 // TODO(gman): To be spec compliant IDs from other contexts sharing | 3359 // TODO(gman): To be spec compliant IDs from other contexts sharing |
| 3360 // resources need to return true here even though you can't share | 3360 // resources need to return true here even though you can't share |
| 3361 // queries across contexts? | 3361 // queries across contexts? |
| 3362 return query_tracker_->GetQuery(id) != NULL; | 3362 return query_tracker_->GetQuery(id) != NULL; |
| 3363 } | 3363 } |
| 3364 | 3364 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 3375 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); | 3375 GL_INVALID_OPERATION, "glBeginQueryEXT", "query already in progress"); |
| 3376 return; | 3376 return; |
| 3377 } | 3377 } |
| 3378 | 3378 |
| 3379 // id = 0 INV_OP | 3379 // id = 0 INV_OP |
| 3380 if (id == 0) { | 3380 if (id == 0) { |
| 3381 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); | 3381 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "id is 0"); |
| 3382 return; | 3382 return; |
| 3383 } | 3383 } |
| 3384 | 3384 |
| 3385 // TODO(gman) if id not GENned INV_OPERATION | 3385 // if not GENned INV_OPERATION |
| 3386 if (!query_id_allocator_->InUse(id)) { | |
| 3387 SetGLError(GL_INVALID_OPERATION, "glBeginQueryEXT", "invalid id"); | |
| 3388 return; | |
| 3389 } | |
| 3386 | 3390 |
| 3387 // if id does not have an object | 3391 // if id does not have an object |
| 3388 QueryTracker::Query* query = query_tracker_->GetQuery(id); | 3392 QueryTracker::Query* query = query_tracker_->GetQuery(id); |
| 3389 if (!query) { | 3393 if (!query) { |
| 3390 query = query_tracker_->CreateQuery(id, target); | 3394 query = query_tracker_->CreateQuery(id, target); |
| 3391 if (!query) { | 3395 if (!query) { |
| 3392 SetGLError(GL_OUT_OF_MEMORY, | 3396 SetGLError(GL_OUT_OF_MEMORY, |
| 3393 "glBeginQueryEXT", | 3397 "glBeginQueryEXT", |
| 3394 "transfer buffer allocation failed"); | 3398 "transfer buffer allocation failed"); |
| 3395 return; | 3399 return; |
| (...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4167 return true; | 4171 return true; |
| 4168 } | 4172 } |
| 4169 | 4173 |
| 4170 // Include the auto-generated part of this file. We split this because it means | 4174 // Include the auto-generated part of this file. We split this because it means |
| 4171 // we can easily edit the non-auto generated parts right here in this file | 4175 // we can easily edit the non-auto generated parts right here in this file |
| 4172 // instead of having to edit some template or the code generator. | 4176 // instead of having to edit some template or the code generator. |
| 4173 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 4177 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
| 4174 | 4178 |
| 4175 } // namespace gles2 | 4179 } // namespace gles2 |
| 4176 } // namespace gpu | 4180 } // namespace gpu |
| OLD | NEW |