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 |