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 "content/common/gpu/texture_image_transport_surface.h" | 5 #include "content/common/gpu/texture_image_transport_surface.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "content/common/gpu/gl_scoped_binders.h" | 11 #include "content/common/gpu/gl_scoped_binders.h" |
12 #include "content/common/gpu/gpu_channel.h" | 12 #include "content/common/gpu/gpu_channel.h" |
13 #include "content/common/gpu/gpu_channel_manager.h" | 13 #include "content/common/gpu/gpu_channel_manager.h" |
14 #include "content/common/gpu/gpu_messages.h" | 14 #include "content/common/gpu/gpu_messages.h" |
15 #include "content/common/gpu/sync_point_manager.h" | 15 #include "content/common/gpu/sync_point_manager.h" |
16 #include "content/public/common/content_switches.h" | 16 #include "content/public/common/content_switches.h" |
17 #include "gpu/command_buffer/service/context_group.h" | 17 #include "gpu/command_buffer/service/context_group.h" |
18 #include "gpu/command_buffer/service/gpu_scheduler.h" | 18 #include "gpu/command_buffer/service/gpu_scheduler.h" |
19 #include "gpu/command_buffer/service/texture_manager.h" | 19 #include "gpu/command_buffer/service/texture_definition.h" |
20 | 20 |
21 using gpu::gles2::ContextGroup; | 21 using gpu::gles2::ContextGroup; |
22 using gpu::gles2::MailboxManager; | |
23 using gpu::gles2::TextureDefinition; | |
22 using gpu::gles2::TextureManager; | 24 using gpu::gles2::TextureManager; |
23 typedef TextureManager::TextureInfo TextureInfo; | |
24 | 25 |
25 TextureImageTransportSurface::Texture::Texture() | 26 TextureImageTransportSurface::Texture::Texture() |
26 : client_id(0), | 27 : identifier(0), |
27 sent_to_client(false) { | 28 sent_to_client(false) { |
28 } | 29 } |
29 | 30 |
30 TextureImageTransportSurface::Texture::~Texture() { | 31 TextureImageTransportSurface::Texture::~Texture() { |
31 } | 32 } |
32 | 33 |
33 TextureImageTransportSurface::TextureImageTransportSurface( | 34 TextureImageTransportSurface::TextureImageTransportSurface( |
34 GpuChannelManager* manager, | 35 GpuChannelManager* manager, |
35 GpuCommandBufferStub* stub, | 36 GpuCommandBufferStub* stub, |
36 const gfx::GLSurfaceHandle& handle) | 37 const gfx::GLSurfaceHandle& handle) |
37 : fbo_id_(0), | 38 : fbo_id_(0), |
38 front_(0), | 39 front_(0), |
39 stub_destroyed_(false), | 40 stub_destroyed_(false), |
40 backbuffer_suggested_allocation_(true), | 41 backbuffer_suggested_allocation_(true), |
41 frontbuffer_suggested_allocation_(true), | 42 frontbuffer_suggested_allocation_(true), |
42 frontbuffer_is_protected_(true), | 43 frontbuffer_is_protected_(true), |
43 protection_state_id_(0), | 44 protection_state_id_(0), |
44 handle_(handle), | 45 handle_(handle), |
45 parent_stub_(NULL), | |
46 is_swap_buffers_pending_(false), | 46 is_swap_buffers_pending_(false), |
47 did_unschedule_(false) { | 47 did_unschedule_(false) { |
48 helper_.reset(new ImageTransportHelper(this, | 48 helper_.reset(new ImageTransportHelper(this, |
49 manager, | 49 manager, |
50 stub, | 50 stub, |
51 gfx::kNullPluginWindow)); | 51 gfx::kNullPluginWindow)); |
52 } | 52 } |
53 | 53 |
54 TextureImageTransportSurface::~TextureImageTransportSurface() { | 54 TextureImageTransportSurface::~TextureImageTransportSurface() { |
55 DCHECK(stub_destroyed_); | 55 DCHECK(stub_destroyed_); |
56 Destroy(); | 56 Destroy(); |
57 } | 57 } |
58 | 58 |
59 uint32 TextureImageTransportSurface::GenerateId() { | |
60 static int nextId = 0; | |
61 return ++nextId; | |
62 } | |
63 | |
59 bool TextureImageTransportSurface::Initialize() { | 64 bool TextureImageTransportSurface::Initialize() { |
60 GpuChannelManager* manager = helper_->manager(); | |
61 GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id); | |
62 if (!parent_channel) | |
63 return false; | |
64 | |
65 parent_stub_ = parent_channel->LookupCommandBuffer(handle_.parent_context_id); | |
66 if (!parent_stub_) | |
67 return false; | |
68 | |
69 parent_stub_->AddDestructionObserver(this); | |
70 TextureManager* texture_manager = | |
71 parent_stub_->decoder()->GetContextGroup()->texture_manager(); | |
72 DCHECK(texture_manager); | |
73 | |
74 for (int i = 0; i < 2; ++i) { | 65 for (int i = 0; i < 2; ++i) { |
75 Texture& texture = textures_[i]; | 66 Texture& texture = textures_[i]; |
76 texture.client_id = handle_.parent_texture_id[i]; | 67 texture.identifier = GenerateId(); |
piman
2012/10/17 23:47:20
They don't need to be globally unique, you can jus
| |
77 texture.info = texture_manager->GetTextureInfo(texture.client_id); | |
78 if (!texture.info) | |
79 return false; | |
80 | |
81 if (!texture.info->target()) | |
82 texture_manager->SetInfoTarget(texture.info, GL_TEXTURE_2D); | |
83 texture_manager->SetParameter( | |
84 texture.info, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
85 texture_manager->SetParameter( | |
86 texture.info, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
87 texture_manager->SetParameter( | |
88 texture.info, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
89 texture_manager->SetParameter( | |
90 texture.info, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
91 } | 68 } |
92 | 69 |
70 GpuChannelManager* manager = helper_->manager(); | |
93 surface_ = manager->GetDefaultOffscreenSurface(); | 71 surface_ = manager->GetDefaultOffscreenSurface(); |
94 if (!surface_.get()) | 72 if (!surface_.get()) |
95 return false; | 73 return false; |
96 | 74 |
97 if (!helper_->Initialize()) | 75 if (!helper_->Initialize()) |
98 return false; | 76 return false; |
99 | 77 |
100 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 78 // TODO: Can this go somewhere else? I guess somebody should still react to |
101 if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess)) | 79 // the UI context being recreated and update the preempt counter to the new |
102 helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount()); | 80 // channel. |
piman
2012/10/17 23:47:20
The way I imagine this, is to move it the channel
| |
81 GpuChannel* parent_channel = manager->LookupChannel(handle_.parent_client_id); | |
82 if (parent_channel) { | |
83 const CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
84 if (command_line->HasSwitch(switches::kUIPrioritizeInGpuProcess)) | |
85 helper_->SetPreemptByCounter(parent_channel->MessagesPendingCount()); | |
86 } | |
103 | 87 |
104 return true; | 88 return true; |
105 } | 89 } |
106 | 90 |
107 void TextureImageTransportSurface::Destroy() { | 91 void TextureImageTransportSurface::Destroy() { |
108 if (parent_stub_) { | 92 for (int i = 0; i < 2; ++i) { |
109 parent_stub_->decoder()->MakeCurrent(); | 93 Texture& texture = textures_[i]; |
110 ReleaseParentStub(); | 94 if (!texture.sent_to_client) |
95 continue; | |
96 GpuHostMsg_AcceleratedSurfaceRelease_Params params; | |
97 params.identifier = texture.identifier; | |
98 texture.identifier = 0; | |
99 helper_->SendAcceleratedSurfaceRelease(params); | |
111 } | 100 } |
112 | 101 |
113 if (surface_.get()) | 102 if (surface_.get()) |
114 surface_ = NULL; | 103 surface_ = NULL; |
115 | 104 |
116 helper_->Destroy(); | 105 helper_->Destroy(); |
117 } | 106 } |
118 | 107 |
119 bool TextureImageTransportSurface::DeferDraws() { | 108 bool TextureImageTransportSurface::DeferDraws() { |
120 // The command buffer hit a draw/clear command that could clobber the | 109 // The command buffer hit a draw/clear command that could clobber the |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
173 | 162 |
174 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { | 163 void TextureImageTransportSurface::SetBackbufferAllocation(bool allocation) { |
175 if (backbuffer_suggested_allocation_ == allocation) | 164 if (backbuffer_suggested_allocation_ == allocation) |
176 return; | 165 return; |
177 backbuffer_suggested_allocation_ = allocation; | 166 backbuffer_suggested_allocation_ = allocation; |
178 | 167 |
179 if (!helper_->MakeCurrent()) | 168 if (!helper_->MakeCurrent()) |
180 return; | 169 return; |
181 | 170 |
182 if (backbuffer_suggested_allocation_) { | 171 if (backbuffer_suggested_allocation_) { |
183 DCHECK(!textures_[back()].info->service_id() || | 172 DCHECK(!textures_[back()].service_id || |
184 !textures_[back()].sent_to_client); | 173 !textures_[back()].sent_to_client); |
185 CreateBackTexture(textures_[back()].size); | 174 CreateBackTexture(textures_[back()].size); |
186 } else { | 175 } else { |
187 ReleaseTexture(back()); | 176 ReleaseTexture(back()); |
188 } | 177 } |
189 } | 178 } |
190 | 179 |
191 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { | 180 void TextureImageTransportSurface::SetFrontbufferAllocation(bool allocation) { |
192 if (frontbuffer_suggested_allocation_ == allocation) | 181 if (frontbuffer_suggested_allocation_ == allocation) |
193 return; | 182 return; |
194 frontbuffer_suggested_allocation_ = allocation; | 183 frontbuffer_suggested_allocation_ = allocation; |
195 AdjustFrontBufferAllocation(); | 184 AdjustFrontBufferAllocation(); |
196 } | 185 } |
197 | 186 |
198 void TextureImageTransportSurface::AdjustFrontBufferAllocation() { | 187 void TextureImageTransportSurface::AdjustFrontBufferAllocation() { |
199 if (!helper_->MakeCurrent()) | 188 if (!helper_->MakeCurrent()) |
200 return; | 189 return; |
201 | 190 |
202 if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ && | 191 if (!frontbuffer_suggested_allocation_ && !frontbuffer_is_protected_ && |
203 textures_[front()].info->service_id()) { | 192 textures_[front()].service_id) { |
204 ReleaseTexture(front()); | 193 ReleaseTexture(front()); |
205 if (textures_[front()].sent_to_client) { | 194 if (textures_[front()].sent_to_client) { |
206 GpuHostMsg_AcceleratedSurfaceRelease_Params params; | 195 GpuHostMsg_AcceleratedSurfaceRelease_Params params; |
207 params.identifier = textures_[front()].client_id; | 196 params.identifier = textures_[front()].identifier; |
197 textures_[front()].identifier = 0; | |
208 helper_->SendAcceleratedSurfaceRelease(params); | 198 helper_->SendAcceleratedSurfaceRelease(params); |
209 textures_[front()].sent_to_client = false; | 199 textures_[front()].sent_to_client = false; |
210 } | 200 } |
211 } | 201 } |
212 } | 202 } |
213 | 203 |
214 void* TextureImageTransportSurface::GetShareHandle() { | 204 void* TextureImageTransportSurface::GetShareHandle() { |
215 return GetHandle(); | 205 return GetHandle(); |
216 } | 206 } |
217 | 207 |
218 void* TextureImageTransportSurface::GetDisplay() { | 208 void* TextureImageTransportSurface::GetDisplay() { |
219 return surface_.get() ? surface_->GetDisplay() : NULL; | 209 return surface_.get() ? surface_->GetDisplay() : NULL; |
220 } | 210 } |
221 | 211 |
222 void* TextureImageTransportSurface::GetConfig() { | 212 void* TextureImageTransportSurface::GetConfig() { |
223 return surface_.get() ? surface_->GetConfig() : NULL; | 213 return surface_.get() ? surface_->GetConfig() : NULL; |
224 } | 214 } |
225 | 215 |
226 void TextureImageTransportSurface::OnResize(gfx::Size size) { | 216 void TextureImageTransportSurface::OnResize(gfx::Size size) { |
227 CreateBackTexture(size); | 217 CreateBackTexture(size); |
228 } | 218 } |
229 | 219 |
230 void TextureImageTransportSurface::OnWillDestroyStub( | 220 void TextureImageTransportSurface::OnWillDestroyStub( |
231 GpuCommandBufferStub* stub) { | 221 GpuCommandBufferStub* stub) { |
232 if (stub == parent_stub_) { | 222 // TODO |
223 /*if (stub == parent_stub_) { | |
233 ReleaseParentStub(); | 224 ReleaseParentStub(); |
234 helper_->SetPreemptByCounter(NULL); | 225 helper_->SetPreemptByCounter(NULL); |
235 } else { | 226 }*/ |
236 DCHECK(stub == helper_->stub()); | 227 DCHECK(stub == helper_->stub()); |
237 stub->RemoveDestructionObserver(this); | 228 stub->RemoveDestructionObserver(this); |
238 | 229 |
239 // We are losing the stub owning us, this is our last chance to clean up the | 230 // We are losing the stub owning us, this is our last chance to clean up the |
240 // resources we allocated in the stub's context. | 231 // resources we allocated in the stub's context. |
241 if (fbo_id_) { | 232 if (fbo_id_) { |
242 glDeleteFramebuffersEXT(1, &fbo_id_); | 233 glDeleteFramebuffersEXT(1, &fbo_id_); |
243 CHECK_GL_ERROR(); | 234 CHECK_GL_ERROR(); |
244 fbo_id_ = 0; | 235 fbo_id_ = 0; |
245 } | 236 } |
246 | 237 |
247 stub_destroyed_ = true; | 238 stub_destroyed_ = true; |
248 } | |
249 } | 239 } |
250 | 240 |
251 bool TextureImageTransportSurface::SwapBuffers() { | 241 bool TextureImageTransportSurface::SwapBuffers() { |
252 DCHECK(backbuffer_suggested_allocation_); | 242 DCHECK(backbuffer_suggested_allocation_); |
253 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) | 243 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
254 return true; | 244 return true; |
255 if (!parent_stub_) { | |
256 LOG(ERROR) << "SwapBuffers failed because no parent stub."; | |
257 return false; | |
258 } | |
259 | 245 |
260 glFlush(); | 246 glFlush(); |
261 front_ = back(); | 247 front_ = back(); |
262 previous_damage_rect_ = gfx::Rect(textures_[front()].size); | 248 previous_damage_rect_ = gfx::Rect(textures_[front()].size); |
249 ProduceTexture(textures_[front()]); | |
263 | 250 |
264 DCHECK(textures_[front()].client_id != 0); | 251 DCHECK(textures_[front()].identifier != 0); |
265 | 252 |
266 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | 253 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
267 params.surface_handle = textures_[front()].client_id; | 254 params.surface_handle = textures_[front()].identifier; |
268 params.protection_state_id = protection_state_id_; | 255 params.protection_state_id = protection_state_id_; |
269 params.skip_ack = false; | 256 params.skip_ack = false; |
270 helper_->SendAcceleratedSurfaceBuffersSwapped(params); | 257 helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
271 | 258 |
272 DCHECK(!is_swap_buffers_pending_); | 259 DCHECK(!is_swap_buffers_pending_); |
273 is_swap_buffers_pending_ = true; | 260 is_swap_buffers_pending_ = true; |
274 return true; | 261 return true; |
275 } | 262 } |
276 | 263 |
277 bool TextureImageTransportSurface::PostSubBuffer( | 264 bool TextureImageTransportSurface::PostSubBuffer( |
278 int x, int y, int width, int height) { | 265 int x, int y, int width, int height) { |
279 DCHECK(backbuffer_suggested_allocation_); | 266 DCHECK(backbuffer_suggested_allocation_); |
280 DCHECK(textures_[back()].info->service_id()); | 267 DCHECK(textures_[back()].service_id); |
281 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) | 268 if (!frontbuffer_suggested_allocation_ || !frontbuffer_is_protected_) |
282 return true; | 269 return true; |
283 // If we are recreating the frontbuffer with this swap, make sure we are | 270 // If we are recreating the frontbuffer with this swap, make sure we are |
284 // drawing a full frame. | 271 // drawing a full frame. |
285 DCHECK(textures_[front()].info->service_id() || | 272 DCHECK(textures_[front()].service_id || |
286 (!x && !y && gfx::Size(width, height) == textures_[back()].size)); | 273 (!x && !y && gfx::Size(width, height) == textures_[back()].size)); |
287 if (!parent_stub_) { | |
288 LOG(ERROR) << "PostSubBuffer failed because no parent stub."; | |
289 return false; | |
290 } | |
291 | 274 |
292 const gfx::Rect new_damage_rect(x, y, width, height); | 275 const gfx::Rect new_damage_rect(x, y, width, height); |
293 | 276 |
294 // An empty damage rect is a successful no-op. | 277 // An empty damage rect is a successful no-op. |
295 if (new_damage_rect.IsEmpty()) | 278 if (new_damage_rect.IsEmpty()) |
296 return true; | 279 return true; |
297 | 280 |
298 int back_texture_service_id = textures_[back()].info->service_id(); | 281 int back_texture_service_id = textures_[back()].service_id; |
299 int front_texture_service_id = textures_[front()].info->service_id(); | 282 int front_texture_service_id = textures_[front()].service_id; |
300 | 283 |
301 gfx::Size expected_size = textures_[back()].size; | 284 gfx::Size expected_size = textures_[back()].size; |
302 bool surfaces_same_size = textures_[front()].size == expected_size; | 285 bool surfaces_same_size = textures_[front()].size == expected_size; |
303 | 286 |
304 if (surfaces_same_size) { | 287 if (surfaces_same_size) { |
305 std::vector<gfx::Rect> regions_to_copy; | 288 std::vector<gfx::Rect> regions_to_copy; |
306 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, ®ions_to_copy); | 289 GetRegionsToCopy(previous_damage_rect_, new_damage_rect, ®ions_to_copy); |
307 | 290 |
308 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); | 291 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); |
309 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, | 292 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
(...skipping 11 matching lines...) Expand all Loading... | |
321 region_to_copy.width(), region_to_copy.height()); | 304 region_to_copy.width(), region_to_copy.height()); |
322 } | 305 } |
323 } | 306 } |
324 } else { | 307 } else { |
325 DCHECK(new_damage_rect == gfx::Rect(expected_size)); | 308 DCHECK(new_damage_rect == gfx::Rect(expected_size)); |
326 } | 309 } |
327 | 310 |
328 glFlush(); | 311 glFlush(); |
329 front_ = back(); | 312 front_ = back(); |
330 previous_damage_rect_ = new_damage_rect; | 313 previous_damage_rect_ = new_damage_rect; |
314 ProduceTexture(textures_[front()]); | |
331 | 315 |
332 DCHECK(textures_[front()].client_id); | 316 DCHECK(textures_[front()].identifier); |
333 | 317 |
334 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; | 318 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params params; |
335 params.surface_handle = textures_[front()].client_id; | 319 params.surface_handle = textures_[front()].identifier; |
336 params.x = x; | 320 params.x = x; |
337 params.y = y; | 321 params.y = y; |
338 params.width = width; | 322 params.width = width; |
339 params.height = height; | 323 params.height = height; |
340 params.protection_state_id = protection_state_id_; | 324 params.protection_state_id = protection_state_id_; |
341 helper_->SendAcceleratedSurfacePostSubBuffer(params); | 325 helper_->SendAcceleratedSurfacePostSubBuffer(params); |
342 | 326 |
343 DCHECK(!is_swap_buffers_pending_); | 327 DCHECK(!is_swap_buffers_pending_); |
344 is_swap_buffers_pending_ = true; | 328 is_swap_buffers_pending_ = true; |
345 return true; | 329 return true; |
(...skipping 26 matching lines...) Expand all Loading... | |
372 void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected( | 356 void TextureImageTransportSurface::OnSetFrontSurfaceIsProtected( |
373 bool is_protected, uint32 protection_state_id) { | 357 bool is_protected, uint32 protection_state_id) { |
374 protection_state_id_ = protection_state_id; | 358 protection_state_id_ = protection_state_id; |
375 if (frontbuffer_is_protected_ == is_protected) | 359 if (frontbuffer_is_protected_ == is_protected) |
376 return; | 360 return; |
377 frontbuffer_is_protected_ = is_protected; | 361 frontbuffer_is_protected_ = is_protected; |
378 AdjustFrontBufferAllocation(); | 362 AdjustFrontBufferAllocation(); |
379 | 363 |
380 // If surface is set to protected, and we haven't actually released it yet, | 364 // If surface is set to protected, and we haven't actually released it yet, |
381 // we can set the ui surface handle now just by sending a swap message. | 365 // we can set the ui surface handle now just by sending a swap message. |
382 if (is_protected && textures_[front()].info->service_id() && | 366 if (is_protected && textures_[front()].service_id && |
383 textures_[front()].sent_to_client) { | 367 textures_[front()].sent_to_client) { |
384 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | 368 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
385 params.surface_handle = textures_[front()].client_id; | 369 params.surface_handle = textures_[front()].identifier; |
386 params.protection_state_id = protection_state_id_; | 370 params.protection_state_id = protection_state_id_; |
387 params.skip_ack = true; | 371 params.skip_ack = true; |
388 helper_->SendAcceleratedSurfaceBuffersSwapped(params); | 372 helper_->SendAcceleratedSurfaceBuffersSwapped(params); |
389 } | 373 } |
390 } | 374 } |
391 | 375 |
392 void TextureImageTransportSurface::OnBufferPresented(uint32 sync_point) { | 376 void TextureImageTransportSurface::OnBufferPresented(uint32 sync_point) { |
393 if (sync_point == 0) { | 377 if (sync_point == 0) { |
394 BufferPresentedImpl(); | 378 BufferPresentedImpl(); |
395 } else { | 379 } else { |
396 helper_->manager()->sync_point_manager()->AddSyncPointCallback( | 380 helper_->manager()->sync_point_manager()->AddSyncPointCallback( |
397 sync_point, | 381 sync_point, |
398 base::Bind(&TextureImageTransportSurface::BufferPresentedImpl, | 382 base::Bind(&TextureImageTransportSurface::BufferPresentedImpl, |
399 this->AsWeakPtr())); | 383 this->AsWeakPtr())); |
400 } | 384 } |
401 } | 385 } |
402 | 386 |
403 void TextureImageTransportSurface::BufferPresentedImpl() { | 387 void TextureImageTransportSurface::BufferPresentedImpl() { |
404 DCHECK(is_swap_buffers_pending_); | 388 DCHECK(is_swap_buffers_pending_); |
405 is_swap_buffers_pending_ = false; | 389 is_swap_buffers_pending_ = false; |
406 | 390 |
407 // We're relying on the fact that the parent context is | 391 // We're relying on the fact that the parent context is |
408 // finished with it's context when it inserts the sync point that | 392 // finished with it's context when it inserts the sync point that |
409 // triggers this callback. | 393 // triggers this callback. |
410 if (helper_->MakeCurrent()) { | 394 if (helper_->MakeCurrent()) { |
395 // TODO: Is this the right check to see if it was ever created and produced? | |
396 if (!textures_[back()].service_id && textures_[back()].sent_to_client) | |
397 ConsumeTexture(textures_[back()]); | |
411 if (textures_[front()].size != textures_[back()].size || | 398 if (textures_[front()].size != textures_[back()].size || |
412 !textures_[back()].info->service_id() || | 399 !textures_[back()].service_id || |
413 !textures_[back()].sent_to_client) { | 400 !textures_[back()].sent_to_client) { |
414 // We may get an ACK from a stale swap just to reschedule. In that case, | 401 // We may get an ACK from a stale swap just to reschedule. In that case, |
415 // we may not have a backbuffer suggestion and should not recreate one. | 402 // we may not have a backbuffer suggestion and should not recreate one. |
416 if (backbuffer_suggested_allocation_) | 403 if (backbuffer_suggested_allocation_) |
417 CreateBackTexture(textures_[front()].size); | 404 CreateBackTexture(textures_[front()].size); |
418 } else { | 405 } else { |
419 AttachBackTextureToFBO(); | 406 AttachBackTextureToFBO(); |
420 } | 407 } |
421 } | 408 } |
422 | 409 |
423 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context | 410 // Even if MakeCurrent fails, schedule anyway, to trigger the lost context |
424 // logic. | 411 // logic. |
425 if (did_unschedule_) { | 412 if (did_unschedule_) { |
426 did_unschedule_ = false; | 413 did_unschedule_ = false; |
427 helper_->SetScheduled(true); | 414 helper_->SetScheduled(true); |
428 } | 415 } |
429 } | 416 } |
430 | 417 |
431 void TextureImageTransportSurface::OnResizeViewACK() { | 418 void TextureImageTransportSurface::OnResizeViewACK() { |
432 NOTREACHED(); | 419 NOTREACHED(); |
433 } | 420 } |
434 | 421 |
435 void TextureImageTransportSurface::ReleaseTexture(int id) { | 422 void TextureImageTransportSurface::ReleaseTexture(int id) { |
436 if (!parent_stub_) | 423 if (!textures_[id].service_id) |
437 return; | 424 return; |
438 Texture& texture = textures_[id]; | 425 textures_[id].service_id = 0; |
439 TextureInfo* info = texture.info; | |
440 DCHECK(info); | |
441 | |
442 GLuint service_id = info->service_id(); | |
443 if (!service_id) | |
444 return; | |
445 info->SetServiceId(0); | |
446 | 426 |
447 { | 427 { |
448 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); | 428 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); |
449 glDeleteTextures(1, &service_id); | 429 glDeleteTextures(1, &textures_[id].service_id); |
450 } | 430 } |
451 glFlush(); | 431 glFlush(); |
452 CHECK_GL_ERROR(); | 432 CHECK_GL_ERROR(); |
453 } | 433 } |
454 | 434 |
455 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { | 435 void TextureImageTransportSurface::CreateBackTexture(const gfx::Size& size) { |
456 if (!parent_stub_) | |
457 return; | |
458 Texture& texture = textures_[back()]; | 436 Texture& texture = textures_[back()]; |
459 TextureInfo* info = texture.info; | |
460 DCHECK(info); | |
461 | 437 |
462 GLuint service_id = info->service_id(); | 438 if (texture.service_id && texture.size == size && texture.sent_to_client) |
463 | |
464 if (service_id && texture.size == size && texture.sent_to_client) | |
465 return; | 439 return; |
466 | 440 |
467 if (!service_id) { | 441 if (!texture.service_id) { |
468 glGenTextures(1, &service_id); | 442 glGenTextures(1, &texture.service_id); |
469 info->SetServiceId(service_id); | |
470 } | 443 } |
471 | 444 |
472 if (size != texture.size) { | 445 if (size != texture.size) { |
473 texture.size = size; | 446 texture.size = size; |
474 TextureManager* texture_manager = | |
475 parent_stub_->decoder()->GetContextGroup()->texture_manager(); | |
476 texture_manager->SetLevelInfo( | |
477 info, | |
478 GL_TEXTURE_2D, | |
479 0, | |
480 GL_RGBA, | |
481 size.width(), | |
482 size.height(), | |
483 1, | |
484 0, | |
485 GL_RGBA, | |
486 GL_UNSIGNED_BYTE, | |
487 true); | |
488 } | 447 } |
489 | 448 |
490 { | 449 { |
491 content::ScopedTextureBinder texture_binder(service_id); | 450 content::ScopedTextureBinder texture_binder(texture.service_id); |
492 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 451 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
493 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 452 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
494 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 453 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
495 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 454 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
496 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | 455 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
497 size.width(), size.height(), 0, | 456 size.width(), size.height(), 0, |
498 GL_RGBA, GL_UNSIGNED_BYTE, NULL); | 457 GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
499 CHECK_GL_ERROR(); | 458 CHECK_GL_ERROR(); |
500 } | 459 } |
501 | 460 |
502 AttachBackTextureToFBO(); | 461 AttachBackTextureToFBO(); |
503 | 462 |
463 if (!texture.identifier) | |
464 texture.identifier = GenerateId(); | |
465 | |
504 GpuHostMsg_AcceleratedSurfaceNew_Params params; | 466 GpuHostMsg_AcceleratedSurfaceNew_Params params; |
505 params.width = size.width(); | 467 params.width = size.width(); |
506 params.height = size.height(); | 468 params.height = size.height(); |
507 params.surface_handle = texture.client_id; | 469 MailboxManager* manager = helper_->stub()->decoder()->GetContextGroup()-> |
470 mailbox_manager(); | |
471 gpu::gles2::MailboxName& name = texture.mailbox_name; | |
472 manager->GenerateMailboxName(&name); | |
473 params.mailbox_name.append((char*)name.key, sizeof(name.key)); | |
474 params.mailbox_name.append((char*)name.signature, sizeof(name.signature)); | |
475 params.surface_handle = texture.identifier; | |
508 helper_->SendAcceleratedSurfaceNew(params); | 476 helper_->SendAcceleratedSurfaceNew(params); |
509 texture.sent_to_client = true; | 477 texture.sent_to_client = true; |
510 } | 478 } |
511 | 479 |
512 void TextureImageTransportSurface::AttachBackTextureToFBO() { | 480 void TextureImageTransportSurface::AttachBackTextureToFBO() { |
513 if (!parent_stub_) | |
514 return; | |
515 TextureInfo* info = textures_[back()].info; | |
516 DCHECK(info); | |
517 | |
518 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); | 481 content::ScopedFrameBufferBinder fbo_binder(fbo_id_); |
519 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, | 482 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, |
520 GL_COLOR_ATTACHMENT0, | 483 GL_COLOR_ATTACHMENT0, |
521 GL_TEXTURE_2D, | 484 GL_TEXTURE_2D, |
522 info->service_id(), | 485 textures_[back()].service_id, |
523 0); | 486 0); |
524 glFlush(); | 487 glFlush(); |
525 CHECK_GL_ERROR(); | 488 CHECK_GL_ERROR(); |
526 | 489 |
527 #ifndef NDEBUG | 490 #ifndef NDEBUG |
528 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); | 491 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); |
529 if (status != GL_FRAMEBUFFER_COMPLETE) { | 492 if (status != GL_FRAMEBUFFER_COMPLETE) { |
530 DLOG(ERROR) << "Framebuffer incomplete."; | 493 DLOG(ERROR) << "Framebuffer incomplete: " << status; |
494 DCHECK(false); | |
531 } | 495 } |
532 #endif | 496 #endif |
533 } | 497 } |
534 | 498 |
535 void TextureImageTransportSurface::ReleaseParentStub() { | 499 void TextureImageTransportSurface::ConsumeTexture(Texture& texture) { |
536 DCHECK(parent_stub_); | 500 MailboxManager* manager = helper_->stub()->decoder()->GetContextGroup()-> |
537 parent_stub_->RemoveDestructionObserver(this); | 501 mailbox_manager(); |
538 for (int i = 0; i < 2; ++i) { | 502 scoped_ptr<TextureDefinition> definition(manager->ConsumeTexture( |
539 Texture& texture = textures_[i]; | 503 GL_TEXTURE_2D, texture.mailbox_name)); |
540 texture.info = NULL; | 504 if (definition.get()) |
541 if (!texture.sent_to_client) | 505 texture.service_id = definition->ReleaseServiceId(); |
542 continue; | 506 |
543 GpuHostMsg_AcceleratedSurfaceRelease_Params params; | 507 // TODO: This can happen if the other side did not put the texture back |
544 params.identifier = texture.client_id; | 508 // before the sync point, or that other context was lost. |
545 helper_->SendAcceleratedSurfaceRelease(params); | 509 DCHECK(definition.get()); |
546 } | |
547 parent_stub_ = NULL; | |
548 } | 510 } |
511 | |
512 void TextureImageTransportSurface::ProduceTexture(Texture& texture) { | |
513 TextureManager* texture_manager = | |
514 helper_->stub()->decoder()->GetContextGroup()->texture_manager(); | |
515 MailboxManager* mailbox_manager = | |
516 helper_->stub()->decoder()->GetContextGroup()->mailbox_manager(); | |
517 DCHECK(texture.size.width() > 0 && texture.size.height() > 0); | |
518 TextureDefinition::LevelInfo info( | |
519 GL_TEXTURE_2D, GL_RGBA, texture.size.width(), texture.size.height(), 1, | |
520 0, GL_RGBA, GL_UNSIGNED_BYTE, true); | |
521 | |
522 TextureDefinition::LevelInfos level_infos; | |
523 level_infos.resize(1); | |
524 level_infos[0].resize(texture_manager->MaxLevelsForTarget(GL_TEXTURE_2D)); | |
525 level_infos[0][0] = info; | |
526 scoped_ptr<TextureDefinition> definition(new TextureDefinition( | |
527 GL_TEXTURE_2D, | |
528 texture.service_id, | |
529 true, | |
530 level_infos)); | |
531 mailbox_manager->ProduceTexture( | |
532 GL_TEXTURE_2D, | |
533 texture.mailbox_name, | |
534 definition.release(), | |
535 helper_->stub()->decoder()->GetContextGroup()->texture_manager()); | |
536 texture.service_id = 0; | |
537 } | |
OLD | NEW |