| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/mailbox_synchronizer.h" | 5 #include "gpu/command_buffer/service/mailbox_synchronizer.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "gpu/command_buffer/service/mailbox_manager.h" | 8 #include "gpu/command_buffer/service/mailbox_manager.h" |
| 9 #include "gpu/command_buffer/service/texture_manager.h" | 9 #include "gpu/command_buffer/service/texture_manager.h" |
| 10 #include "ui/gl/gl_implementation.h" | 10 #include "ui/gl/gl_implementation.h" |
| 11 | 11 |
| 12 #if !defined(OS_MACOSX) |
| 13 #include "ui/gl/gl_fence_egl.h" |
| 14 #endif |
| 15 |
| 12 namespace gpu { | 16 namespace gpu { |
| 13 namespace gles2 { | 17 namespace gles2 { |
| 14 | 18 |
| 15 namespace { | 19 namespace { |
| 16 | 20 |
| 17 MailboxSynchronizer* g_instance = NULL; | 21 MailboxSynchronizer* g_instance = NULL; |
| 18 | 22 |
| 19 } // anonymous namespace | 23 } // anonymous namespace |
| 20 | 24 |
| 21 // static | 25 // static |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 void MailboxSynchronizer::TextureDeleted(Texture* texture) { | 133 void MailboxSynchronizer::TextureDeleted(Texture* texture) { |
| 130 base::AutoLock lock(lock_); | 134 base::AutoLock lock(lock_); |
| 131 TextureMap::iterator it = textures_.find(texture); | 135 TextureMap::iterator it = textures_.find(texture); |
| 132 if (it != textures_.end()) { | 136 if (it != textures_.end()) { |
| 133 // TODO: We could avoid the update if this was the last ref. | 137 // TODO: We could avoid the update if this was the last ref. |
| 134 UpdateTextureLocked(it->first, it->second); | 138 UpdateTextureLocked(it->first, it->second); |
| 135 textures_.erase(it); | 139 textures_.erase(it); |
| 136 } | 140 } |
| 137 } | 141 } |
| 138 | 142 |
| 139 void MailboxSynchronizer::PushTextureUpdates(MailboxManager* manager) { | 143 void MailboxSynchronizer::PushTextureUpdates(MailboxManager* manager, |
| 144 uint32 sync_point) { |
| 140 base::AutoLock lock(lock_); | 145 base::AutoLock lock(lock_); |
| 141 for (MailboxManager::MailboxToTextureMap::const_iterator texture_it = | 146 for (MailboxManager::MailboxToTextureMap::const_iterator texture_it = |
| 142 manager->mailbox_to_textures_.begin(); | 147 manager->mailbox_to_textures_.begin(); |
| 143 texture_it != manager->mailbox_to_textures_.end(); | 148 texture_it != manager->mailbox_to_textures_.end(); |
| 144 texture_it++) { | 149 texture_it++) { |
| 145 TargetName target_name(texture_it->first.target, texture_it->first.mailbox); | 150 TargetName target_name(texture_it->first.target, texture_it->first.mailbox); |
| 146 Texture* texture = texture_it->second->first; | 151 Texture* texture = texture_it->second->first; |
| 147 // TODO(sievers): crbug.com/352274 | 152 // TODO(sievers): crbug.com/352274 |
| 148 // Should probably only fail if it already *has* mipmaps, while allowing | 153 // Should probably only fail if it already *has* mipmaps, while allowing |
| 149 // incomplete textures here. Also reconsider how to fail otherwise. | 154 // incomplete textures here. Also reconsider how to fail otherwise. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 172 continue; | 177 continue; |
| 173 | 178 |
| 174 linked_ptr<TextureGroup> group = make_linked_ptr(new TextureGroup( | 179 linked_ptr<TextureGroup> group = make_linked_ptr(new TextureGroup( |
| 175 TextureDefinition(target_name.target, texture, 1, NULL))); | 180 TextureDefinition(target_name.target, texture, 1, NULL))); |
| 176 | 181 |
| 177 // Unlink other textures from this mailbox in case the name is not new. | 182 // Unlink other textures from this mailbox in case the name is not new. |
| 178 ReassociateMailboxLocked(target_name, group.get()); | 183 ReassociateMailboxLocked(target_name, group.get()); |
| 179 textures_.insert(std::make_pair(texture, TextureVersion(group))); | 184 textures_.insert(std::make_pair(texture, TextureVersion(group))); |
| 180 } | 185 } |
| 181 } | 186 } |
| 187 |
| 188 CreateFenceLocked(sync_point); |
| 189 } |
| 190 |
| 191 void MailboxSynchronizer::CreateFenceLocked(uint32 sync_point) { |
| 192 lock_.AssertAcquired(); |
| 193 if (gfx::GetGLImplementation() == gfx::kGLImplementationMockGL) |
| 194 return; |
| 195 |
| 196 if (sync_point) { |
| 197 while (!sync_points_.empty() && |
| 198 sync_points_.front()->second->HasCompleted()) { |
| 199 sync_point_to_fence_.erase(sync_points_.front()); |
| 200 sync_points_.pop(); |
| 201 } |
| 202 #if !defined(OS_MACOSX) |
| 203 // Need to use EGL fences since we are likely not in a single share group. |
| 204 linked_ptr<gfx::GLFence> fence(make_linked_ptr(new gfx::GLFenceEGL(true))); |
| 205 #endif |
| 206 if (fence.get()) { |
| 207 std::pair<SyncPointToFenceMap::iterator, bool> result = |
| 208 sync_point_to_fence_.insert(std::make_pair(sync_point, fence)); |
| 209 DCHECK(result.second); |
| 210 sync_points_.push(result.first); |
| 211 } |
| 212 DCHECK(sync_points_.size() == sync_point_to_fence_.size()); |
| 213 } |
| 182 } | 214 } |
| 183 | 215 |
| 184 void MailboxSynchronizer::UpdateTextureLocked(Texture* texture, | 216 void MailboxSynchronizer::UpdateTextureLocked(Texture* texture, |
| 185 TextureVersion& texture_version) { | 217 TextureVersion& texture_version) { |
| 186 lock_.AssertAcquired(); | 218 lock_.AssertAcquired(); |
| 187 gfx::GLImage* gl_image = texture->GetLevelImage(texture->target(), 0); | 219 gfx::GLImage* gl_image = texture->GetLevelImage(texture->target(), 0); |
| 188 TextureGroup* group = texture_version.group.get(); | 220 TextureGroup* group = texture_version.group.get(); |
| 189 scoped_refptr<NativeImageBuffer> image_buffer = group->definition.image(); | 221 scoped_refptr<NativeImageBuffer> image_buffer = group->definition.image(); |
| 190 | 222 |
| 191 // Make sure we don't clobber with an older version | 223 // Make sure we don't clobber with an older version |
| 192 if (!group->definition.IsOlderThan(texture_version.version)) | 224 if (!group->definition.IsOlderThan(texture_version.version)) |
| 193 return; | 225 return; |
| 194 | 226 |
| 195 // Also don't push redundant updates. Note that it would break the | 227 // Also don't push redundant updates. Note that it would break the |
| 196 // versioning. | 228 // versioning. |
| 197 if (group->definition.Matches(texture)) | 229 if (group->definition.Matches(texture)) |
| 198 return; | 230 return; |
| 199 | 231 |
| 200 if (gl_image && !image_buffer->IsClient(gl_image)) { | 232 if (gl_image && !image_buffer->IsClient(gl_image)) { |
| 201 LOG(ERROR) << "MailboxSync: Incompatible attachment"; | 233 LOG(ERROR) << "MailboxSync: Incompatible attachment"; |
| 202 return; | 234 return; |
| 203 } | 235 } |
| 204 | 236 |
| 205 group->definition = TextureDefinition(texture->target(), | 237 group->definition = TextureDefinition(texture->target(), |
| 206 texture, | 238 texture, |
| 207 ++texture_version.version, | 239 ++texture_version.version, |
| 208 gl_image ? image_buffer : NULL); | 240 gl_image ? image_buffer : NULL); |
| 209 } | 241 } |
| 210 | 242 |
| 211 void MailboxSynchronizer::PullTextureUpdates(MailboxManager* manager) { | 243 void MailboxSynchronizer::AcquireFenceLocked(uint32 sync_point) { |
| 244 lock_.AssertAcquired(); |
| 245 SyncPointToFenceMap::iterator fence_it = |
| 246 sync_point_to_fence_.find(sync_point); |
| 247 if (fence_it != sync_point_to_fence_.end()) { |
| 248 fence_it->second->ServerWait(); |
| 249 } |
| 250 } |
| 251 |
| 252 void MailboxSynchronizer::PullTextureUpdates(MailboxManager* manager, |
| 253 uint32 sync_point) { |
| 212 base::AutoLock lock(lock_); | 254 base::AutoLock lock(lock_); |
| 255 AcquireFenceLocked(sync_point); |
| 256 |
| 213 for (MailboxManager::MailboxToTextureMap::const_iterator texture_it = | 257 for (MailboxManager::MailboxToTextureMap::const_iterator texture_it = |
| 214 manager->mailbox_to_textures_.begin(); | 258 manager->mailbox_to_textures_.begin(); |
| 215 texture_it != manager->mailbox_to_textures_.end(); | 259 texture_it != manager->mailbox_to_textures_.end(); |
| 216 texture_it++) { | 260 texture_it++) { |
| 217 Texture* texture = texture_it->second->first; | 261 Texture* texture = texture_it->second->first; |
| 218 TextureMap::iterator it = textures_.find(texture); | 262 TextureMap::iterator it = textures_.find(texture); |
| 219 if (it != textures_.end()) { | 263 if (it != textures_.end()) { |
| 220 TextureDefinition& definition = it->second.group->definition; | 264 TextureDefinition& definition = it->second.group->definition; |
| 221 if (it->second.version == definition.version() || | 265 if (it->second.version == definition.version() || |
| 222 definition.IsOlderThan(it->second.version)) | 266 definition.IsOlderThan(it->second.version)) |
| 223 continue; | 267 continue; |
| 224 it->second.version = definition.version(); | 268 it->second.version = definition.version(); |
| 225 definition.UpdateTexture(texture); | 269 definition.UpdateTexture(texture); |
| 226 } | 270 } |
| 227 } | 271 } |
| 228 } | 272 } |
| 229 | 273 |
| 230 } // namespace gles2 | 274 } // namespace gles2 |
| 231 } // namespace gpu | 275 } // namespace gpu |
| OLD | NEW |