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