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 <limits.h> | 7 #include <limits.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <stdio.h> | 10 #include <stdio.h> |
(...skipping 6228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6239 framebuffer->AttachRenderbuffer(attachment, renderbuffer); | 6239 framebuffer->AttachRenderbuffer(attachment, renderbuffer); |
6240 } | 6240 } |
6241 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { | 6241 if (framebuffer == framebuffer_state_.bound_draw_framebuffer.get()) { |
6242 framebuffer_state_.clear_state_dirty = true; | 6242 framebuffer_state_.clear_state_dirty = true; |
6243 } | 6243 } |
6244 OnFboChanged(); | 6244 OnFboChanged(); |
6245 } | 6245 } |
6246 | 6246 |
6247 void GLES2DecoderImpl::DoDisable(GLenum cap) { | 6247 void GLES2DecoderImpl::DoDisable(GLenum cap) { |
6248 if (SetCapabilityState(cap, false)) { | 6248 if (SetCapabilityState(cap, false)) { |
| 6249 if (cap == GL_PRIMITIVE_RESTART_FIXED_INDEX && |
| 6250 feature_info_->feature_flags().emulate_primitive_restart_fixed_index) { |
| 6251 // Enable and Disable PRIMITIVE_RESTART only before and after |
| 6252 // DrawElements* for old desktop GL. |
| 6253 return; |
| 6254 } |
6249 glDisable(cap); | 6255 glDisable(cap); |
6250 } | 6256 } |
6251 } | 6257 } |
6252 | 6258 |
6253 void GLES2DecoderImpl::DoEnable(GLenum cap) { | 6259 void GLES2DecoderImpl::DoEnable(GLenum cap) { |
6254 if (SetCapabilityState(cap, true)) { | 6260 if (SetCapabilityState(cap, true)) { |
| 6261 if (cap == GL_PRIMITIVE_RESTART_FIXED_INDEX && |
| 6262 feature_info_->feature_flags().emulate_primitive_restart_fixed_index) { |
| 6263 // Enable and Disable PRIMITIVE_RESTART only before and after |
| 6264 // DrawElements* for old desktop GL. |
| 6265 return; |
| 6266 } |
6255 glEnable(cap); | 6267 glEnable(cap); |
6256 } | 6268 } |
6257 } | 6269 } |
6258 | 6270 |
6259 void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) { | 6271 void GLES2DecoderImpl::DoDepthRangef(GLclampf znear, GLclampf zfar) { |
6260 state_.z_near = std::min(1.0f, std::max(0.0f, znear)); | 6272 state_.z_near = std::min(1.0f, std::max(0.0f, znear)); |
6261 state_.z_far = std::min(1.0f, std::max(0.0f, zfar)); | 6273 state_.z_far = std::min(1.0f, std::max(0.0f, zfar)); |
6262 glDepthRange(znear, zfar); | 6274 glDepthRange(znear, zfar); |
6263 } | 6275 } |
6264 | 6276 |
(...skipping 2003 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8268 // it in each draw call, and attrib 0 generic data queries use cached | 8280 // it in each draw call, and attrib 0 generic data queries use cached |
8269 // values instead of passing down to the underlying driver. | 8281 // values instead of passing down to the underlying driver. |
8270 RestoreStateForAttrib(0, false); | 8282 RestoreStateForAttrib(0, false); |
8271 } | 8283 } |
8272 } | 8284 } |
8273 return error::kNoError; | 8285 return error::kNoError; |
8274 } | 8286 } |
8275 | 8287 |
8276 error::Error GLES2DecoderImpl::HandleDrawArrays(uint32_t immediate_data_size, | 8288 error::Error GLES2DecoderImpl::HandleDrawArrays(uint32_t immediate_data_size, |
8277 const void* cmd_data) { | 8289 const void* cmd_data) { |
8278 // TODO(zmo): crbug.com/481184 | |
8279 // On Desktop GL with versions lower than 4.3, we need to emulate | |
8280 // GL_PRIMITIVE_RESTART_FIXED_INDEX using glPrimitiveRestartIndex(). | |
8281 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data); | 8290 const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data); |
8282 return DoDrawArrays("glDrawArrays", | 8291 return DoDrawArrays("glDrawArrays", |
8283 false, | 8292 false, |
8284 static_cast<GLenum>(c.mode), | 8293 static_cast<GLenum>(c.mode), |
8285 static_cast<GLint>(c.first), | 8294 static_cast<GLint>(c.first), |
8286 static_cast<GLsizei>(c.count), | 8295 static_cast<GLsizei>(c.count), |
8287 1); | 8296 1); |
8288 } | 8297 } |
8289 | 8298 |
8290 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE( | 8299 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8346 | 8355 |
8347 if (count == 0 || primcount == 0) { | 8356 if (count == 0 || primcount == 0) { |
8348 return error::kNoError; | 8357 return error::kNoError; |
8349 } | 8358 } |
8350 | 8359 |
8351 GLuint max_vertex_accessed; | 8360 GLuint max_vertex_accessed; |
8352 Buffer* element_array_buffer = | 8361 Buffer* element_array_buffer = |
8353 state_.vertex_attrib_manager->element_array_buffer(); | 8362 state_.vertex_attrib_manager->element_array_buffer(); |
8354 | 8363 |
8355 if (!element_array_buffer->GetMaxValueForRange( | 8364 if (!element_array_buffer->GetMaxValueForRange( |
8356 offset, count, type, &max_vertex_accessed)) { | 8365 offset, count, type, |
| 8366 state_.enable_flags.primitive_restart_fixed_index, |
| 8367 &max_vertex_accessed)) { |
8357 LOCAL_SET_GL_ERROR( | 8368 LOCAL_SET_GL_ERROR( |
8358 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer"); | 8369 GL_INVALID_OPERATION, function_name, "range out of bounds for buffer"); |
8359 return error::kNoError; | 8370 return error::kNoError; |
8360 } | 8371 } |
8361 | 8372 |
8362 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) { | 8373 if (IsDrawValid(function_name, max_vertex_accessed, instanced, primcount)) { |
8363 if (!ClearUnclearedTextures()) { | 8374 if (!ClearUnclearedTextures()) { |
8364 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory"); | 8375 LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, function_name, "out of memory"); |
8365 return error::kNoError; | 8376 return error::kNoError; |
8366 } | 8377 } |
(...skipping 11 matching lines...) Expand all Loading... |
8378 // TODO(gman): Refactor to hide these details in BufferManager or | 8389 // TODO(gman): Refactor to hide these details in BufferManager or |
8379 // VertexAttribManager. | 8390 // VertexAttribManager. |
8380 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); | 8391 const GLvoid* indices = reinterpret_cast<const GLvoid*>(offset); |
8381 bool used_client_side_array = false; | 8392 bool used_client_side_array = false; |
8382 if (element_array_buffer->IsClientSideArray()) { | 8393 if (element_array_buffer->IsClientSideArray()) { |
8383 used_client_side_array = true; | 8394 used_client_side_array = true; |
8384 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | 8395 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); |
8385 indices = element_array_buffer->GetRange(offset, 0); | 8396 indices = element_array_buffer->GetRange(offset, 0); |
8386 } | 8397 } |
8387 | 8398 |
| 8399 if (state_.enable_flags.primitive_restart_fixed_index && |
| 8400 feature_info_->feature_flags(). |
| 8401 emulate_primitive_restart_fixed_index) { |
| 8402 glEnable(GL_PRIMITIVE_RESTART); |
| 8403 buffer_manager()->SetPrimitiveRestartFixedIndexIfNecessary(type); |
| 8404 } |
| 8405 |
8388 if (!instanced) { | 8406 if (!instanced) { |
8389 glDrawElements(mode, count, type, indices); | 8407 glDrawElements(mode, count, type, indices); |
8390 } else { | 8408 } else { |
8391 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); | 8409 glDrawElementsInstancedANGLE(mode, count, type, indices, primcount); |
8392 } | 8410 } |
8393 | 8411 |
| 8412 if (state_.enable_flags.primitive_restart_fixed_index && |
| 8413 feature_info_->feature_flags(). |
| 8414 emulate_primitive_restart_fixed_index) { |
| 8415 glDisable(GL_PRIMITIVE_RESTART); |
| 8416 } |
| 8417 |
8394 if (used_client_side_array) { | 8418 if (used_client_side_array) { |
8395 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, | 8419 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, |
8396 element_array_buffer->service_id()); | 8420 element_array_buffer->service_id()); |
8397 } | 8421 } |
8398 | 8422 |
8399 if (textures_set) { | 8423 if (textures_set) { |
8400 RestoreStateForTextures(); | 8424 RestoreStateForTextures(); |
8401 } | 8425 } |
8402 if (simulated_fixed_attribs) { | 8426 if (simulated_fixed_attribs) { |
8403 RestoreStateForSimulatedFixedAttribs(); | 8427 RestoreStateForSimulatedFixedAttribs(); |
8404 } | 8428 } |
8405 } | 8429 } |
8406 if (simulated_attrib_0) { | 8430 if (simulated_attrib_0) { |
8407 // We don't have to restore attrib 0 generic data at the end of this | 8431 // We don't have to restore attrib 0 generic data at the end of this |
8408 // function even if it is simulated. This is because we will simulate | 8432 // function even if it is simulated. This is because we will simulate |
8409 // it in each draw call, and attrib 0 generic data queries use cached | 8433 // it in each draw call, and attrib 0 generic data queries use cached |
8410 // values instead of passing down to the underlying driver. | 8434 // values instead of passing down to the underlying driver. |
8411 RestoreStateForAttrib(0, false); | 8435 RestoreStateForAttrib(0, false); |
8412 } | 8436 } |
8413 } | 8437 } |
8414 return error::kNoError; | 8438 return error::kNoError; |
8415 } | 8439 } |
8416 | 8440 |
8417 error::Error GLES2DecoderImpl::HandleDrawElements(uint32_t immediate_data_size, | 8441 error::Error GLES2DecoderImpl::HandleDrawElements(uint32_t immediate_data_size, |
8418 const void* cmd_data) { | 8442 const void* cmd_data) { |
8419 // TODO(zmo): crbug.com/481184 | |
8420 // On Desktop GL with versions lower than 4.3, we need to emulate | |
8421 // GL_PRIMITIVE_RESTART_FIXED_INDEX using glPrimitiveRestartIndex(). | |
8422 const gles2::cmds::DrawElements& c = | 8443 const gles2::cmds::DrawElements& c = |
8423 *static_cast<const gles2::cmds::DrawElements*>(cmd_data); | 8444 *static_cast<const gles2::cmds::DrawElements*>(cmd_data); |
8424 return DoDrawElements("glDrawElements", false, static_cast<GLenum>(c.mode), | 8445 return DoDrawElements("glDrawElements", false, static_cast<GLenum>(c.mode), |
8425 static_cast<GLsizei>(c.count), | 8446 static_cast<GLsizei>(c.count), |
8426 static_cast<GLenum>(c.type), | 8447 static_cast<GLenum>(c.type), |
8427 static_cast<int32_t>(c.index_offset), 1); | 8448 static_cast<int32_t>(c.index_offset), 1); |
8428 } | 8449 } |
8429 | 8450 |
8430 error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE( | 8451 error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE( |
8431 uint32_t immediate_data_size, | 8452 uint32_t immediate_data_size, |
(...skipping 11 matching lines...) Expand all Loading... |
8443 | 8464 |
8444 GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM( | 8465 GLuint GLES2DecoderImpl::DoGetMaxValueInBufferCHROMIUM( |
8445 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) { | 8466 GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) { |
8446 GLuint max_vertex_accessed = 0; | 8467 GLuint max_vertex_accessed = 0; |
8447 Buffer* buffer = GetBuffer(buffer_id); | 8468 Buffer* buffer = GetBuffer(buffer_id); |
8448 if (!buffer) { | 8469 if (!buffer) { |
8449 // TODO(gman): Should this be a GL error or a command buffer error? | 8470 // TODO(gman): Should this be a GL error or a command buffer error? |
8450 LOCAL_SET_GL_ERROR( | 8471 LOCAL_SET_GL_ERROR( |
8451 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer"); | 8472 GL_INVALID_VALUE, "GetMaxValueInBufferCHROMIUM", "unknown buffer"); |
8452 } else { | 8473 } else { |
| 8474 // The max value is used here to emulate client-side vertex |
| 8475 // arrays, by uploading enough vertices into buffer objects to |
| 8476 // cover the DrawElements call. Baking the primitive restart bit |
| 8477 // into this result isn't strictly correct in all cases; the |
| 8478 // client side code should pass down the bit and decide how to use |
| 8479 // the result. However, the only caller makes the draw call |
| 8480 // immediately afterward, so the state won't change between this |
| 8481 // query and the draw call. |
8453 if (!buffer->GetMaxValueForRange( | 8482 if (!buffer->GetMaxValueForRange( |
8454 offset, count, type, &max_vertex_accessed)) { | 8483 offset, count, type, |
| 8484 state_.enable_flags.primitive_restart_fixed_index, |
| 8485 &max_vertex_accessed)) { |
8455 // TODO(gman): Should this be a GL error or a command buffer error? | 8486 // TODO(gman): Should this be a GL error or a command buffer error? |
8456 LOCAL_SET_GL_ERROR( | 8487 LOCAL_SET_GL_ERROR( |
8457 GL_INVALID_OPERATION, | 8488 GL_INVALID_OPERATION, |
8458 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer"); | 8489 "GetMaxValueInBufferCHROMIUM", "range out of bounds for buffer"); |
8459 } | 8490 } |
8460 } | 8491 } |
8461 return max_vertex_accessed; | 8492 return max_vertex_accessed; |
8462 } | 8493 } |
8463 | 8494 |
8464 void GLES2DecoderImpl::DoShaderSource( | 8495 void GLES2DecoderImpl::DoShaderSource( |
(...skipping 7880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16345 } | 16376 } |
16346 | 16377 |
16347 // Include the auto-generated part of this file. We split this because it means | 16378 // Include the auto-generated part of this file. We split this because it means |
16348 // we can easily edit the non-auto generated parts right here in this file | 16379 // we can easily edit the non-auto generated parts right here in this file |
16349 // instead of having to edit some template or the code generator. | 16380 // instead of having to edit some template or the code generator. |
16350 #include "base/macros.h" | 16381 #include "base/macros.h" |
16351 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" | 16382 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" |
16352 | 16383 |
16353 } // namespace gles2 | 16384 } // namespace gles2 |
16354 } // namespace gpu | 16385 } // namespace gpu |
OLD | NEW |