Chromium Code Reviews| 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 |