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/gl2.h> | 9 #include <GLES2/gl2.h> |
10 #include <GLES2/gl2ext.h> | 10 #include <GLES2/gl2ext.h> |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 mapped_memory_->FreePendingToken(mem, helper_->InsertToken()); | 369 mapped_memory_->FreePendingToken(mem, helper_->InsertToken()); |
370 } | 370 } |
371 | 371 |
372 void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) { | 372 void GLES2Implementation::RunIfContextNotLost(const base::Closure& callback) { |
373 if (!lost_context_callback_run_) | 373 if (!lost_context_callback_run_) |
374 callback.Run(); | 374 callback.Run(); |
375 } | 375 } |
376 | 376 |
377 void GLES2Implementation::SignalSyncToken(const gpu::SyncToken& sync_token, | 377 void GLES2Implementation::SignalSyncToken(const gpu::SyncToken& sync_token, |
378 const base::Closure& callback) { | 378 const base::Closure& callback) { |
| 379 SyncToken verified_sync_token; |
379 if (sync_token.HasData() && | 380 if (sync_token.HasData() && |
380 (sync_token.verified_flush() || | 381 GetVerifiedSyncTokenForIPC(sync_token, &verified_sync_token)) { |
381 gpu_control_->CanWaitUnverifiedSyncToken(&sync_token))) { | 382 // We can only send verified sync tokens across IPC. |
382 | |
383 gpu::SyncToken intermediate_sync_token = sync_token; | |
384 | |
385 // Mark the intermediate sync token as verified if we can wait on | |
386 // unverified sync tokens. | |
387 intermediate_sync_token.SetVerifyFlush(); | |
388 | |
389 gpu_control_->SignalSyncToken( | 383 gpu_control_->SignalSyncToken( |
390 intermediate_sync_token, | 384 verified_sync_token, |
391 base::Bind(&GLES2Implementation::RunIfContextNotLost, | 385 base::Bind(&GLES2Implementation::RunIfContextNotLost, |
392 weak_ptr_factory_.GetWeakPtr(), | 386 weak_ptr_factory_.GetWeakPtr(), callback)); |
393 callback)); | |
394 } else { | 387 } else { |
395 // Invalid sync token, just call the callback immediately. | 388 // Invalid sync token, just call the callback immediately. |
396 callback.Run(); | 389 callback.Run(); |
397 } | 390 } |
398 } | 391 } |
399 | 392 |
400 // This may be called from any thread. It's safe to access gpu_control_ without | 393 // This may be called from any thread. It's safe to access gpu_control_ without |
401 // the lock because it is const. | 394 // the lock because it is const. |
402 bool GLES2Implementation::IsSyncTokenSignalled( | 395 bool GLES2Implementation::IsSyncTokenSignaled( |
403 const gpu::SyncToken& sync_token) { | 396 const gpu::SyncToken& sync_token) { |
404 // Check that the sync token belongs to this context. | 397 // Check that the sync token belongs to this context. |
405 DCHECK_EQ(gpu_control_->GetNamespaceID(), sync_token.namespace_id()); | 398 DCHECK_EQ(gpu_control_->GetNamespaceID(), sync_token.namespace_id()); |
406 DCHECK_EQ(gpu_control_->GetCommandBufferID(), sync_token.command_buffer_id()); | 399 DCHECK_EQ(gpu_control_->GetCommandBufferID(), sync_token.command_buffer_id()); |
407 return gpu_control_->IsFenceSyncReleased(sync_token.release_count()); | 400 return gpu_control_->IsFenceSyncReleased(sync_token.release_count()); |
408 } | 401 } |
409 | 402 |
410 void GLES2Implementation::SignalQuery(uint32_t query, | 403 void GLES2Implementation::SignalQuery(uint32_t query, |
411 const base::Closure& callback) { | 404 const base::Closure& callback) { |
412 // Flush previously entered commands to ensure ordering with any | 405 // Flush previously entered commands to ensure ordering with any |
(...skipping 5666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6079 SyncToken sync_token_data(gpu_control_->GetNamespaceID(), | 6072 SyncToken sync_token_data(gpu_control_->GetNamespaceID(), |
6080 gpu_control_->GetExtraCommandBufferData(), | 6073 gpu_control_->GetExtraCommandBufferData(), |
6081 gpu_control_->GetCommandBufferID(), fence_sync); | 6074 gpu_control_->GetCommandBufferID(), fence_sync); |
6082 sync_token_data.SetVerifyFlush(); | 6075 sync_token_data.SetVerifyFlush(); |
6083 memcpy(sync_token, &sync_token_data, sizeof(sync_token_data)); | 6076 memcpy(sync_token, &sync_token_data, sizeof(sync_token_data)); |
6084 } | 6077 } |
6085 | 6078 |
6086 void GLES2Implementation::GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, | 6079 void GLES2Implementation::GenUnverifiedSyncTokenCHROMIUM(GLuint64 fence_sync, |
6087 GLbyte* sync_token) { | 6080 GLbyte* sync_token) { |
6088 if (!sync_token) { | 6081 if (!sync_token) { |
6089 SetGLError(GL_INVALID_VALUE, "glGenNonFlushedSyncTokenCHROMIUM", | 6082 SetGLError(GL_INVALID_VALUE, "glGenUnverifiedSyncTokenCHROMIUM", |
6090 "empty sync_token"); | 6083 "empty sync_token"); |
6091 return; | 6084 return; |
6092 } else if (!gpu_control_->IsFenceSyncRelease(fence_sync)) { | 6085 } else if (!gpu_control_->IsFenceSyncRelease(fence_sync)) { |
6093 SetGLError(GL_INVALID_VALUE, "glGenNonFlushedSyncTokenCHROMIUM", | 6086 SetGLError(GL_INVALID_VALUE, "glGenUnverifiedSyncTokenCHROMIUM", |
6094 "invalid fence sync"); | 6087 "invalid fence sync"); |
6095 return; | 6088 return; |
6096 } else if (!gpu_control_->IsFenceSyncFlushed(fence_sync)) { | 6089 } else if (!gpu_control_->IsFenceSyncFlushed(fence_sync)) { |
6097 SetGLError(GL_INVALID_OPERATION, "glGenSyncTokenCHROMIUM", | 6090 SetGLError(GL_INVALID_OPERATION, "glGenUnverifiedSyncTokenCHROMIUM", |
6098 "fence sync must be flushed before generating sync token"); | 6091 "fence sync must be flushed before generating sync token"); |
6099 return; | 6092 return; |
6100 } | 6093 } |
6101 | 6094 |
6102 // Copy the data over after setting the data to ensure alignment. | 6095 // Copy the data over after setting the data to ensure alignment. |
6103 SyncToken sync_token_data(gpu_control_->GetNamespaceID(), | 6096 SyncToken sync_token_data(gpu_control_->GetNamespaceID(), |
6104 gpu_control_->GetExtraCommandBufferData(), | 6097 gpu_control_->GetExtraCommandBufferData(), |
6105 gpu_control_->GetCommandBufferID(), fence_sync); | 6098 gpu_control_->GetCommandBufferID(), fence_sync); |
6106 memcpy(sync_token, &sync_token_data, sizeof(sync_token_data)); | 6099 memcpy(sync_token, &sync_token_data, sizeof(sync_token_data)); |
6107 } | 6100 } |
6108 | 6101 |
6109 void GLES2Implementation::VerifySyncTokensCHROMIUM(GLbyte **sync_tokens, | 6102 void GLES2Implementation::VerifySyncTokensCHROMIUM(GLbyte **sync_tokens, |
6110 GLsizei count) { | 6103 GLsizei count) { |
6111 bool requires_synchronization = false; | 6104 bool requires_synchronization = false; |
6112 for (GLsizei i = 0; i < count; ++i) { | 6105 for (GLsizei i = 0; i < count; ++i) { |
6113 if (sync_tokens[i]) { | 6106 if (sync_tokens[i]) { |
6114 SyncToken sync_token; | 6107 SyncToken sync_token; |
6115 memcpy(&sync_token, sync_tokens[i], sizeof(sync_token)); | 6108 memcpy(&sync_token, sync_tokens[i], sizeof(sync_token)); |
6116 | 6109 |
6117 if (sync_token.HasData() && !sync_token.verified_flush()) { | 6110 if (sync_token.HasData() && !sync_token.verified_flush()) { |
6118 if (!gpu_control_->CanWaitUnverifiedSyncToken(&sync_token)) { | 6111 if (!GetVerifiedSyncTokenForIPC(sync_token, &sync_token)) { |
6119 SetGLError(GL_INVALID_VALUE, "glVerifySyncTokensCHROMIUM", | 6112 SetGLError(GL_INVALID_VALUE, "glVerifySyncTokensCHROMIUM", |
6120 "Cannot verify sync token using this context."); | 6113 "Cannot verify sync token using this context."); |
6121 return; | 6114 return; |
6122 } | 6115 } |
6123 requires_synchronization = true; | 6116 requires_synchronization = true; |
| 6117 DCHECK(sync_token.verified_flush()); |
| 6118 memcpy(sync_tokens[i], &sync_token, sizeof(sync_token)); |
6124 } | 6119 } |
6125 } | 6120 } |
6126 } | 6121 } |
6127 | 6122 |
6128 // This step must be done after all unverified tokens have finished processing | 6123 // This step must be done after all unverified tokens have finished processing |
6129 // CanWaitUnverifiedSyncToken(), command buffers use that to do any necessary | 6124 // CanWaitUnverifiedSyncToken(), command buffers use that to do any necessary |
6130 // flushes. | 6125 // flushes. |
6131 if (requires_synchronization) { | 6126 if (requires_synchronization) { |
6132 // Make sure we have no pending ordering barriers by flushing now. | 6127 // Make sure we have no pending ordering barriers by flushing now. |
6133 FlushHelper(); | 6128 FlushHelper(); |
6134 | |
6135 // Ensure all the fence syncs are visible on GPU service. | 6129 // Ensure all the fence syncs are visible on GPU service. |
6136 gpu_control_->EnsureWorkVisible(); | 6130 gpu_control_->EnsureWorkVisible(); |
6137 | |
6138 // We can automatically mark everything as verified now. | |
6139 for (GLsizei i = 0; i < count; ++i) { | |
6140 if (sync_tokens[i]) { | |
6141 SyncToken sync_token; | |
6142 memcpy(&sync_token, sync_tokens[i], sizeof(sync_token)); | |
6143 if (sync_token.HasData() && !sync_token.verified_flush()) { | |
6144 sync_token.SetVerifyFlush(); | |
6145 memcpy(sync_tokens[i], &sync_token, sizeof(sync_token)); | |
6146 } | |
6147 } | |
6148 } | |
6149 } | 6131 } |
6150 } | 6132 } |
6151 | 6133 |
6152 void GLES2Implementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token) { | 6134 void GLES2Implementation::WaitSyncTokenCHROMIUM(const GLbyte* sync_token_data) { |
6153 if (sync_token) { | 6135 if (!sync_token_data) |
6154 // Copy the data over before data access to ensure alignment. | 6136 return; |
6155 SyncToken sync_token_data; | |
6156 memcpy(&sync_token_data, sync_token, sizeof(SyncToken)); | |
6157 if (sync_token_data.HasData()) { | |
6158 if (!sync_token_data.verified_flush() && | |
6159 !gpu_control_->CanWaitUnverifiedSyncToken(&sync_token_data)) { | |
6160 SetGLError(GL_INVALID_VALUE, "glWaitSyncTokenCHROMIUM", | |
6161 "Cannot wait on sync_token which has not been verified"); | |
6162 return; | |
6163 } | |
6164 | 6137 |
6165 helper_->WaitSyncTokenCHROMIUM( | 6138 // Copy the data over before data access to ensure alignment. |
6166 static_cast<GLint>(sync_token_data.namespace_id()), | 6139 SyncToken sync_token, verified_sync_token; |
6167 sync_token_data.command_buffer_id().GetUnsafeValue(), | 6140 memcpy(&sync_token, sync_token_data, sizeof(SyncToken)); |
6168 sync_token_data.release_count()); | 6141 |
6169 } | 6142 if (!sync_token.HasData()) |
| 6143 return; |
| 6144 |
| 6145 if (!GetVerifiedSyncTokenForIPC(sync_token, &verified_sync_token)) { |
| 6146 SetGLError(GL_INVALID_VALUE, "glWaitSyncTokenCHROMIUM", |
| 6147 "Cannot wait on sync_token which has not been verified"); |
| 6148 return; |
6170 } | 6149 } |
| 6150 |
| 6151 helper_->WaitSyncTokenCHROMIUM( |
| 6152 static_cast<GLint>(sync_token.namespace_id()), |
| 6153 sync_token.command_buffer_id().GetUnsafeValue(), |
| 6154 sync_token.release_count()); |
| 6155 |
| 6156 // Enqueue sync token in flush after inserting command so that it's not |
| 6157 // included in an automatic flush. |
| 6158 gpu_control_->WaitSyncTokenHint(verified_sync_token); |
| 6159 } |
| 6160 |
| 6161 bool GLES2Implementation::GetVerifiedSyncTokenForIPC( |
| 6162 const SyncToken& sync_token, |
| 6163 SyncToken* verified_sync_token) { |
| 6164 DCHECK(sync_token.HasData()); |
| 6165 DCHECK(verified_sync_token); |
| 6166 |
| 6167 if (!sync_token.verified_flush() && |
| 6168 !gpu_control_->CanWaitUnverifiedSyncToken(sync_token)) |
| 6169 return false; |
| 6170 |
| 6171 *verified_sync_token = sync_token; |
| 6172 verified_sync_token->SetVerifyFlush(); |
| 6173 return true; |
6171 } | 6174 } |
6172 | 6175 |
6173 namespace { | 6176 namespace { |
6174 | 6177 |
6175 bool CreateImageValidInternalFormat(GLenum internalformat, | 6178 bool CreateImageValidInternalFormat(GLenum internalformat, |
6176 const Capabilities& capabilities) { | 6179 const Capabilities& capabilities) { |
6177 switch (internalformat) { | 6180 switch (internalformat) { |
6178 case GL_ATC_RGB_AMD: | 6181 case GL_ATC_RGB_AMD: |
6179 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: | 6182 case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD: |
6180 return capabilities.texture_format_atc; | 6183 return capabilities.texture_format_atc; |
(...skipping 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7023 CheckGLError(); | 7026 CheckGLError(); |
7024 } | 7027 } |
7025 | 7028 |
7026 // Include the auto-generated part of this file. We split this because it means | 7029 // Include the auto-generated part of this file. We split this because it means |
7027 // we can easily edit the non-auto generated parts right here in this file | 7030 // we can easily edit the non-auto generated parts right here in this file |
7028 // instead of having to edit some template or the code generator. | 7031 // instead of having to edit some template or the code generator. |
7029 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" | 7032 #include "gpu/command_buffer/client/gles2_implementation_impl_autogen.h" |
7030 | 7033 |
7031 } // namespace gles2 | 7034 } // namespace gles2 |
7032 } // namespace gpu | 7035 } // namespace gpu |
OLD | NEW |