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 2456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2467 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 2467 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
2468 switches::kEnableGPUDebugging)) { | 2468 switches::kEnableGPUDebugging)) { |
2469 set_debug(true); | 2469 set_debug(true); |
2470 } | 2470 } |
2471 | 2471 |
2472 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 2472 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
2473 switches::kEnableGPUCommandLogging)) { | 2473 switches::kEnableGPUCommandLogging)) { |
2474 set_log_commands(true); | 2474 set_log_commands(true); |
2475 } | 2475 } |
2476 | 2476 |
2477 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | |
2478 switches::kEnableUnsafeES3APIs) && | |
2479 attrib_parser.es3_context_required) { | |
2480 // TODO(zmo): We need to implement capabilities check to ensure we can | |
2481 // actually create ES3 contexts. | |
2482 set_unsafe_es3_apis_enabled(true); | |
2483 } | |
2484 | |
2485 compile_shader_always_succeeds_ = | 2477 compile_shader_always_succeeds_ = |
2486 base::CommandLine::ForCurrentProcess()->HasSwitch( | 2478 base::CommandLine::ForCurrentProcess()->HasSwitch( |
2487 switches::kCompileShaderAlwaysSucceeds); | 2479 switches::kCompileShaderAlwaysSucceeds); |
2488 | 2480 |
2489 // Take ownership of the context and surface. The surface can be replaced with | 2481 // Take ownership of the context and surface. The surface can be replaced with |
2490 // SetSurface. | 2482 // SetSurface. |
2491 context_ = context; | 2483 context_ = context; |
2492 surface_ = surface; | 2484 surface_ = surface; |
2493 | 2485 |
2494 // Create GPU Tracer for timing values. | 2486 // Create GPU Tracer for timing values. |
(...skipping 14 matching lines...) Expand all Loading... |
2509 | 2501 |
2510 if (!group_->Initialize(this, disallowed_features)) { | 2502 if (!group_->Initialize(this, disallowed_features)) { |
2511 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group " | 2503 LOG(ERROR) << "GpuScheduler::InitializeCommon failed because group " |
2512 << "failed to initialize."; | 2504 << "failed to initialize."; |
2513 group_ = NULL; // Must not destroy ContextGroup if it is not initialized. | 2505 group_ = NULL; // Must not destroy ContextGroup if it is not initialized. |
2514 Destroy(true); | 2506 Destroy(true); |
2515 return false; | 2507 return false; |
2516 } | 2508 } |
2517 CHECK_GL_ERROR(); | 2509 CHECK_GL_ERROR(); |
2518 | 2510 |
| 2511 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 2512 switches::kEnableUnsafeES3APIs) && |
| 2513 attrib_parser.es3_context_required && |
| 2514 feature_info_->IsES3Capable()) { |
| 2515 feature_info_->EnableES3Validators(); |
| 2516 set_unsafe_es3_apis_enabled(true); |
| 2517 } |
| 2518 |
2519 disallowed_features_ = disallowed_features; | 2519 disallowed_features_ = disallowed_features; |
2520 | 2520 |
2521 state_.attrib_values.resize(group_->max_vertex_attribs()); | 2521 state_.attrib_values.resize(group_->max_vertex_attribs()); |
2522 vertex_array_manager_.reset(new VertexArrayManager()); | 2522 vertex_array_manager_.reset(new VertexArrayManager()); |
2523 | 2523 |
2524 GLuint default_vertex_attrib_service_id = 0; | 2524 GLuint default_vertex_attrib_service_id = 0; |
2525 if (features().native_vertex_array_object) { | 2525 if (features().native_vertex_array_object) { |
2526 glGenVertexArraysOES(1, &default_vertex_attrib_service_id); | 2526 glGenVertexArraysOES(1, &default_vertex_attrib_service_id); |
2527 glBindVertexArrayOES(default_vertex_attrib_service_id); | 2527 glBindVertexArrayOES(default_vertex_attrib_service_id); |
2528 } | 2528 } |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3106 CreateTexture(client_ids[ii], service_ids[ii]); | 3106 CreateTexture(client_ids[ii], service_ids[ii]); |
3107 } | 3107 } |
3108 return true; | 3108 return true; |
3109 } | 3109 } |
3110 | 3110 |
3111 void GLES2DecoderImpl::DeleteBuffersHelper( | 3111 void GLES2DecoderImpl::DeleteBuffersHelper( |
3112 GLsizei n, const GLuint* client_ids) { | 3112 GLsizei n, const GLuint* client_ids) { |
3113 for (GLsizei ii = 0; ii < n; ++ii) { | 3113 for (GLsizei ii = 0; ii < n; ++ii) { |
3114 Buffer* buffer = GetBuffer(client_ids[ii]); | 3114 Buffer* buffer = GetBuffer(client_ids[ii]); |
3115 if (buffer && !buffer->IsDeleted()) { | 3115 if (buffer && !buffer->IsDeleted()) { |
| 3116 buffer->RemoveMappedRange(); |
3116 state_.vertex_attrib_manager->Unbind(buffer); | 3117 state_.vertex_attrib_manager->Unbind(buffer); |
3117 if (state_.bound_array_buffer.get() == buffer) { | 3118 if (state_.bound_array_buffer.get() == buffer) { |
3118 state_.bound_array_buffer = NULL; | 3119 state_.bound_array_buffer = NULL; |
3119 } | 3120 } |
3120 RemoveBuffer(client_ids[ii]); | 3121 RemoveBuffer(client_ids[ii]); |
3121 } | 3122 } |
3122 } | 3123 } |
3123 } | 3124 } |
3124 | 3125 |
3125 void GLES2DecoderImpl::DeleteFramebuffersHelper( | 3126 void GLES2DecoderImpl::DeleteFramebuffersHelper( |
(...skipping 9155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12281 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1); | 12282 GLuint64 timeout = GLES2Util::MapTwoUint32ToUint64(c.timeout_0, c.timeout_1); |
12282 GLsync service_sync = 0; | 12283 GLsync service_sync = 0; |
12283 if (!group_->GetSyncServiceId(sync, &service_sync)) { | 12284 if (!group_->GetSyncServiceId(sync, &service_sync)) { |
12284 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "WaitSync", "invalid sync"); | 12285 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "WaitSync", "invalid sync"); |
12285 return error::kNoError; | 12286 return error::kNoError; |
12286 } | 12287 } |
12287 glWaitSync(service_sync, flags, timeout); | 12288 glWaitSync(service_sync, flags, timeout); |
12288 return error::kNoError; | 12289 return error::kNoError; |
12289 } | 12290 } |
12290 | 12291 |
| 12292 error::Error GLES2DecoderImpl::HandleMapBufferRange( |
| 12293 uint32_t immediate_data_size, const void* cmd_data) { |
| 12294 if (!unsafe_es3_apis_enabled()) { |
| 12295 return error::kUnknownCommand; |
| 12296 } |
| 12297 const gles2::cmds::MapBufferRange& c = |
| 12298 *static_cast<const gles2::cmds::MapBufferRange*>(cmd_data); |
| 12299 GLenum target = static_cast<GLenum>(c.target); |
| 12300 GLbitfield access = static_cast<GLbitfield>(c.access); |
| 12301 GLintptr offset = static_cast<GLintptr>(c.offset); |
| 12302 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); |
| 12303 |
| 12304 typedef cmds::MapBufferRange::Result Result; |
| 12305 Result* result = GetSharedMemoryAs<Result*>( |
| 12306 c.result_shm_id, c.result_shm_offset, sizeof(*result)); |
| 12307 if (!result) { |
| 12308 return error::kOutOfBounds; |
| 12309 } |
| 12310 if (*result != 0) { |
| 12311 *result = 0; |
| 12312 return error::kInvalidArguments; |
| 12313 } |
| 12314 int8_t* mem = |
| 12315 GetSharedMemoryAs<int8_t*>(c.data_shm_id, c.data_shm_offset, size); |
| 12316 if (!mem) { |
| 12317 return error::kOutOfBounds; |
| 12318 } |
| 12319 |
| 12320 GLbitfield mask = GL_MAP_INVALIDATE_BUFFER_BIT; |
| 12321 if ((access & mask) == mask) { |
| 12322 // TODO(zmo): To be on the safe side, always map |
| 12323 // GL_MAP_INVALIDATE_BUFFER_BIT to GL_MAP_INVALIDATE_RANGE_BIT. |
| 12324 access = (access & ~GL_MAP_INVALIDATE_BUFFER_BIT); |
| 12325 access = (access | GL_MAP_INVALIDATE_RANGE_BIT); |
| 12326 } |
| 12327 // TODO(zmo): Always filter out GL_MAP_UNSYNCHRONIZED_BIT to get rid of |
| 12328 // undefined behaviors. |
| 12329 mask = GL_MAP_READ_BIT | GL_MAP_UNSYNCHRONIZED_BIT; |
| 12330 if ((access & mask) == mask) { |
| 12331 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "MapBufferRange", |
| 12332 "incompatible access bits"); |
| 12333 return error::kNoError; |
| 12334 } |
| 12335 access = (access & ~GL_MAP_UNSYNCHRONIZED_BIT); |
| 12336 if ((access & GL_MAP_WRITE_BIT) == GL_MAP_WRITE_BIT && |
| 12337 (access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { |
| 12338 access = (access | GL_MAP_READ_BIT); |
| 12339 } |
| 12340 void* ptr = glMapBufferRange(target, offset, size, access); |
| 12341 if (ptr == nullptr) { |
| 12342 return error::kNoError; |
| 12343 } |
| 12344 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); |
| 12345 DCHECK(buffer); |
| 12346 buffer->SetMappedRange(offset, size, access, ptr, |
| 12347 GetSharedMemoryBuffer(c.data_shm_id)); |
| 12348 if ((access & GL_MAP_INVALIDATE_RANGE_BIT) == 0) { |
| 12349 memcpy(mem, ptr, size); |
| 12350 } |
| 12351 *result = 1; |
| 12352 return error::kNoError; |
| 12353 } |
| 12354 |
| 12355 error::Error GLES2DecoderImpl::HandleUnmapBuffer( |
| 12356 uint32_t immediate_data_size, const void* cmd_data) { |
| 12357 if (!unsafe_es3_apis_enabled()) { |
| 12358 return error::kUnknownCommand; |
| 12359 } |
| 12360 const gles2::cmds::UnmapBuffer& c = |
| 12361 *static_cast<const gles2::cmds::UnmapBuffer*>(cmd_data); |
| 12362 GLenum target = static_cast<GLenum>(c.target); |
| 12363 |
| 12364 Buffer* buffer = buffer_manager()->GetBufferInfoForTarget(&state_, target); |
| 12365 if (!buffer) { |
| 12366 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", "no buffer bound"); |
| 12367 return error::kNoError; |
| 12368 } |
| 12369 const Buffer::MappedRange* mapped_range = buffer->GetMappedRange(); |
| 12370 if (!mapped_range) { |
| 12371 LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "UnmapBuffer", |
| 12372 "buffer is unmapped"); |
| 12373 return error::kNoError; |
| 12374 } |
| 12375 if ((mapped_range->access & GL_MAP_WRITE_BIT) == 0 || |
| 12376 (mapped_range->access & GL_MAP_FLUSH_EXPLICIT_BIT) == |
| 12377 GL_MAP_FLUSH_EXPLICIT_BIT) { |
| 12378 // If we don't need to write back, or explict flush is required, no copying |
| 12379 // back is needed. |
| 12380 } else { |
| 12381 void* mem = mapped_range->GetShmPointer(); |
| 12382 if (!mem) { |
| 12383 return error::kOutOfBounds; |
| 12384 } |
| 12385 DCHECK(mapped_range->pointer); |
| 12386 memcpy(mapped_range->pointer, mem, mapped_range->size); |
| 12387 } |
| 12388 buffer->RemoveMappedRange(); |
| 12389 GLboolean rt = glUnmapBuffer(target); |
| 12390 if (rt == GL_FALSE) { |
| 12391 // At this point, we have already done the necessary validation, so |
| 12392 // GL_FALSE indicates data corruption. |
| 12393 // TODO(zmo): We could redo the map / copy data / unmap to recover, but |
| 12394 // the second unmap could still return GL_FALSE. For now, we simply lose |
| 12395 // the contexts in the share group. |
| 12396 LOG(ERROR) << "glUnmapBuffer unexpectedly returned GL_FALSE"; |
| 12397 group_->LoseContexts(GL_INNOCENT_CONTEXT_RESET_ARB); |
| 12398 reset_status_ = GL_GUILTY_CONTEXT_RESET_ARB; |
| 12399 return error::kLostContext; |
| 12400 } |
| 12401 return error::kNoError; |
| 12402 } |
| 12403 |
12291 void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( | 12404 void GLES2DecoderImpl::OnTextureRefDetachedFromFramebuffer( |
12292 TextureRef* texture_ref) { | 12405 TextureRef* texture_ref) { |
12293 Texture* texture = texture_ref->texture(); | 12406 Texture* texture = texture_ref->texture(); |
12294 DoDidUseTexImageIfNeeded(texture, texture->target()); | 12407 DoDidUseTexImageIfNeeded(texture, texture->target()); |
12295 } | 12408 } |
12296 | 12409 |
12297 void GLES2DecoderImpl::OnContextLostError() { | 12410 void GLES2DecoderImpl::OnContextLostError() { |
12298 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB); | 12411 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB); |
12299 } | 12412 } |
12300 | 12413 |
12301 void GLES2DecoderImpl::OnOutOfMemoryError() { | 12414 void GLES2DecoderImpl::OnOutOfMemoryError() { |
12302 if (lose_context_when_out_of_memory_) { | 12415 if (lose_context_when_out_of_memory_) { |
12303 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB); | 12416 group_->LoseContexts(GL_UNKNOWN_CONTEXT_RESET_ARB); |
12304 } | 12417 } |
12305 } | 12418 } |
12306 | 12419 |
12307 // Include the auto-generated part of this file. We split this because it means | 12420 // Include the auto-generated part of this file. We split this because it means |
12308 // we can easily edit the non-auto generated parts right here in this file | 12421 // we can easily edit the non-auto generated parts right here in this file |
12309 // instead of having to edit some template or the code generator. | 12422 // instead of having to edit some template or the code generator. |
12310 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 12423 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
12311 | 12424 |
12312 } // namespace gles2 | 12425 } // namespace gles2 |
12313 } // namespace gpu | 12426 } // namespace gpu |
OLD | NEW |