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