OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/renderer/gpu/renderer_gl_context.h" | 5 #include "content/renderer/gpu/renderer_gl_context.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
76 | 76 |
77 } // namespace anonymous | 77 } // namespace anonymous |
78 | 78 |
79 RendererGLContext::~RendererGLContext() { | 79 RendererGLContext::~RendererGLContext() { |
80 Destroy(); | 80 Destroy(); |
81 } | 81 } |
82 | 82 |
83 RendererGLContext* RendererGLContext::CreateViewContext( | 83 RendererGLContext* RendererGLContext::CreateViewContext( |
84 GpuChannelHost* channel, | 84 GpuChannelHost* channel, |
85 int render_view_id, | 85 int render_view_id, |
86 RendererGLContext* share_group, | |
86 const char* allowed_extensions, | 87 const char* allowed_extensions, |
87 const int32* attrib_list, | 88 const int32* attrib_list, |
88 const GURL& active_url) { | 89 const GURL& active_url) { |
89 #if defined(ENABLE_GPU) | 90 #if defined(ENABLE_GPU) |
90 scoped_ptr<RendererGLContext> context(new RendererGLContext(channel)); | 91 scoped_ptr<RendererGLContext> context(new RendererGLContext(channel)); |
91 if (!context->Initialize( | 92 if (!context->Initialize( |
92 true, | 93 true, |
93 render_view_id, | 94 render_view_id, |
94 gfx::Size(), | 95 gfx::Size(), |
96 share_group, | |
95 allowed_extensions, | 97 allowed_extensions, |
96 attrib_list, | 98 attrib_list, |
97 active_url)) | 99 active_url)) |
98 return NULL; | 100 return NULL; |
99 | 101 |
100 return context.release(); | 102 return context.release(); |
101 #else | 103 #else |
102 return NULL; | 104 return NULL; |
103 #endif | 105 #endif |
104 } | 106 } |
105 | 107 |
106 #if defined(OS_MACOSX) | 108 #if defined(OS_MACOSX) |
107 void RendererGLContext::ResizeOnscreen(const gfx::Size& size) { | 109 void RendererGLContext::ResizeOnscreen(const gfx::Size& size) { |
108 DCHECK(size.width() > 0 && size.height() > 0); | 110 DCHECK(size.width() > 0 && size.height() > 0); |
109 size_ = size; | 111 size_ = size; |
110 command_buffer_->SetWindowSize(size); | 112 command_buffer_->SetWindowSize(size); |
111 } | 113 } |
112 #endif | 114 #endif |
113 | 115 |
114 RendererGLContext* RendererGLContext::CreateOffscreenContext( | 116 RendererGLContext* RendererGLContext::CreateOffscreenContext( |
115 GpuChannelHost* channel, | 117 GpuChannelHost* channel, |
116 const gfx::Size& size, | 118 const gfx::Size& size, |
119 RendererGLContext* share_group, | |
117 const char* allowed_extensions, | 120 const char* allowed_extensions, |
118 const int32* attrib_list, | 121 const int32* attrib_list, |
119 const GURL& active_url) { | 122 const GURL& active_url) { |
120 #if defined(ENABLE_GPU) | 123 #if defined(ENABLE_GPU) |
121 scoped_ptr<RendererGLContext> context(new RendererGLContext(channel)); | 124 scoped_ptr<RendererGLContext> context(new RendererGLContext(channel)); |
122 if (!context->Initialize( | 125 if (!context->Initialize( |
123 false, | 126 false, |
124 0, | 127 0, |
125 size, | 128 size, |
129 share_group, | |
126 allowed_extensions, | 130 allowed_extensions, |
127 attrib_list, | 131 attrib_list, |
128 active_url)) | 132 active_url)) |
129 return NULL; | 133 return NULL; |
130 | 134 |
131 return context.release(); | 135 return context.release(); |
132 #else | 136 #else |
133 return NULL; | 137 return NULL; |
134 #endif | 138 #endif |
135 } | 139 } |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 command_buffer_->ResizeOffscreenFrameBuffer(size); | 192 command_buffer_->ResizeOffscreenFrameBuffer(size); |
189 size_ = size; | 193 size_ = size; |
190 } | 194 } |
191 } | 195 } |
192 | 196 |
193 uint32 RendererGLContext::GetParentTextureId() { | 197 uint32 RendererGLContext::GetParentTextureId() { |
194 return parent_texture_id_; | 198 return parent_texture_id_; |
195 } | 199 } |
196 | 200 |
197 uint32 RendererGLContext::CreateParentTexture(const gfx::Size& size) { | 201 uint32 RendererGLContext::CreateParentTexture(const gfx::Size& size) { |
198 // Allocate a texture ID with respect to the parent. | 202 uint32 texture_id = 0; |
199 if (parent_.get()) { | 203 gles2_implementation_->GenTextures(1, &texture_id); |
200 if (!MakeCurrent(parent_.get())) | 204 parent_->gles2_implementation_->Flush(); |
jamesr
2011/08/03 21:51:20
why is this doing a flush on the parent? shouldn't
| |
201 return 0; | 205 return texture_id; |
202 uint32 texture_id = parent_->gles2_implementation_->MakeTextureId(); | |
203 parent_->gles2_implementation_->BindTexture(GL_TEXTURE_2D, texture_id); | |
204 parent_->gles2_implementation_->TexParameteri( | |
205 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
206 parent_->gles2_implementation_->TexParameteri( | |
207 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
208 parent_->gles2_implementation_->TexParameteri( | |
209 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
210 parent_->gles2_implementation_->TexParameteri( | |
211 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
212 | |
213 parent_->gles2_implementation_->TexImage2D(GL_TEXTURE_2D, | |
214 0, // mip level | |
215 GL_RGBA, | |
216 size.width(), | |
217 size.height(), | |
218 0, // border | |
219 GL_RGBA, | |
220 GL_UNSIGNED_BYTE, | |
221 NULL); | |
222 // Make sure that the parent texture's storage is allocated before we let | |
223 // the caller attempt to use it. | |
224 int32 token = parent_->gles2_helper_->InsertToken(); | |
225 parent_->gles2_helper_->WaitForToken(token); | |
226 return texture_id; | |
227 } | |
228 return 0; | |
229 } | 206 } |
230 | 207 |
231 void RendererGLContext::DeleteParentTexture(uint32 texture) { | 208 void RendererGLContext::DeleteParentTexture(uint32 texture) { |
232 if (parent_.get()) { | 209 gles2_implementation_->DeleteTextures(1, &texture); |
233 if (!MakeCurrent(parent_.get())) | |
234 return; | |
235 parent_->gles2_implementation_->DeleteTextures(1, &texture); | |
236 } | |
237 } | 210 } |
238 | 211 |
239 void RendererGLContext::SetSwapBuffersCallback(Callback0::Type* callback) { | 212 void RendererGLContext::SetSwapBuffersCallback(Callback0::Type* callback) { |
240 swap_buffers_callback_.reset(callback); | 213 swap_buffers_callback_.reset(callback); |
241 } | 214 } |
242 | 215 |
243 void RendererGLContext::SetContextLostCallback( | 216 void RendererGLContext::SetContextLostCallback( |
244 Callback1<ContextLostReason>::Type* callback) { | 217 Callback1<ContextLostReason>::Type* callback) { |
245 context_lost_callback_.reset(callback); | 218 context_lost_callback_.reset(callback); |
246 } | 219 } |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
323 transfer_buffer_id_(-1), | 296 transfer_buffer_id_(-1), |
324 gles2_implementation_(NULL), | 297 gles2_implementation_(NULL), |
325 last_error_(SUCCESS), | 298 last_error_(SUCCESS), |
326 frame_number_(0) { | 299 frame_number_(0) { |
327 DCHECK(channel); | 300 DCHECK(channel); |
328 } | 301 } |
329 | 302 |
330 bool RendererGLContext::Initialize(bool onscreen, | 303 bool RendererGLContext::Initialize(bool onscreen, |
331 int render_view_id, | 304 int render_view_id, |
332 const gfx::Size& size, | 305 const gfx::Size& size, |
306 RendererGLContext* share_group, | |
333 const char* allowed_extensions, | 307 const char* allowed_extensions, |
334 const int32* attrib_list, | 308 const int32* attrib_list, |
335 const GURL& active_url) { | 309 const GURL& active_url) { |
336 DCHECK(size.width() >= 0 && size.height() >= 0); | 310 DCHECK(size.width() >= 0 && size.height() >= 0); |
337 TRACE_EVENT2("gpu", "RendererGLContext::Initialize", | 311 TRACE_EVENT2("gpu", "RendererGLContext::Initialize", |
338 "on_screen", onscreen, "num_pixels", size.GetArea()); | 312 "on_screen", onscreen, "num_pixels", size.GetArea()); |
339 | 313 |
340 if (channel_->state() != GpuChannelHost::kConnected) | 314 if (channel_->state() != GpuChannelHost::kConnected) |
341 return false; | 315 return false; |
342 | 316 |
(...skipping 27 matching lines...) Expand all Loading... | |
370 break; | 344 break; |
371 } | 345 } |
372 } | 346 } |
373 | 347 |
374 // Create a proxy to a command buffer in the GPU process. | 348 // Create a proxy to a command buffer in the GPU process. |
375 if (onscreen) { | 349 if (onscreen) { |
376 TRACE_EVENT0("gpu", | 350 TRACE_EVENT0("gpu", |
377 "RendererGLContext::Initialize::CreateViewCommandBuffer"); | 351 "RendererGLContext::Initialize::CreateViewCommandBuffer"); |
378 command_buffer_ = channel_->CreateViewCommandBuffer( | 352 command_buffer_ = channel_->CreateViewCommandBuffer( |
379 render_view_id, | 353 render_view_id, |
354 share_group ? share_group->command_buffer_ : NULL, | |
380 allowed_extensions, | 355 allowed_extensions, |
381 attribs, | 356 attribs, |
382 active_url); | 357 active_url); |
383 } else { | 358 } else { |
384 command_buffer_ = channel_->CreateOffscreenCommandBuffer( | 359 command_buffer_ = channel_->CreateOffscreenCommandBuffer( |
385 size, | 360 size, |
361 share_group ? share_group->command_buffer_ : NULL, | |
386 allowed_extensions, | 362 allowed_extensions, |
387 attribs, | 363 attribs, |
388 active_url); | 364 active_url); |
389 } | 365 } |
390 if (!command_buffer_) { | 366 if (!command_buffer_) { |
391 Destroy(); | 367 Destroy(); |
392 return false; | 368 return false; |
393 } | 369 } |
394 | 370 |
395 { | 371 { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
434 Destroy(); | 410 Destroy(); |
435 return false; | 411 return false; |
436 } | 412 } |
437 | 413 |
438 // Create the object exposing the OpenGL API. | 414 // Create the object exposing the OpenGL API. |
439 gles2_implementation_ = new gpu::gles2::GLES2Implementation( | 415 gles2_implementation_ = new gpu::gles2::GLES2Implementation( |
440 gles2_helper_, | 416 gles2_helper_, |
441 transfer_buffer.size, | 417 transfer_buffer.size, |
442 transfer_buffer.ptr, | 418 transfer_buffer.ptr, |
443 transfer_buffer_id_, | 419 transfer_buffer_id_, |
444 false); | 420 true); |
445 | 421 |
446 size_ = size; | 422 size_ = size; |
447 | 423 |
448 return true; | 424 return true; |
449 } | 425 } |
450 | 426 |
451 void RendererGLContext::Destroy() { | 427 void RendererGLContext::Destroy() { |
452 TRACE_EVENT0("gpu", "RendererGLContext::Destroy"); | 428 TRACE_EVENT0("gpu", "RendererGLContext::Destroy"); |
453 SetParent(NULL); | 429 SetParent(NULL); |
454 | 430 |
455 delete gles2_implementation_; | 431 if (gles2_implementation_) { |
456 gles2_implementation_ = NULL; | 432 // First flush the context to ensure that any pending frees of resources |
433 // are completed. Otherwise, if this context is part of a share group, | |
434 // those resources might leak. Also, any remaining side effects of commands | |
435 // issued on this context might not be visible to other contexts in the | |
436 // share group. | |
437 gles2_implementation_->Flush(); | |
438 | |
439 delete gles2_implementation_; | |
440 gles2_implementation_ = NULL; | |
441 } | |
457 | 442 |
458 // Do not destroy this transfer buffer here, because commands are still | 443 // Do not destroy this transfer buffer here, because commands are still |
459 // in flight on the GPU process that may access them. When the command buffer | 444 // in flight on the GPU process that may access them. When the command buffer |
460 // is destroyed, the associated shared memory will be cleaned up. | 445 // is destroyed, the associated shared memory will be cleaned up. |
461 transfer_buffer_id_ = -1; | 446 transfer_buffer_id_ = -1; |
462 | 447 |
463 delete gles2_helper_; | 448 delete gles2_helper_; |
464 gles2_helper_ = NULL; | 449 gles2_helper_ = NULL; |
465 | 450 |
466 if (channel_ && command_buffer_) { | 451 if (channel_ && command_buffer_) { |
(...skipping 12 matching lines...) Expand all Loading... | |
479 void RendererGLContext::OnContextLost() { | 464 void RendererGLContext::OnContextLost() { |
480 if (context_lost_callback_.get()) { | 465 if (context_lost_callback_.get()) { |
481 RendererGLContext::ContextLostReason reason = kUnknown; | 466 RendererGLContext::ContextLostReason reason = kUnknown; |
482 if (command_buffer_) { | 467 if (command_buffer_) { |
483 reason = ConvertReason( | 468 reason = ConvertReason( |
484 command_buffer_->GetLastState().context_lost_reason); | 469 command_buffer_->GetLastState().context_lost_reason); |
485 } | 470 } |
486 context_lost_callback_->Run(reason); | 471 context_lost_callback_->Run(reason); |
487 } | 472 } |
488 } | 473 } |
OLD | NEW |