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 #if defined(ENABLE_GPU) | 5 #if defined(ENABLE_GPU) |
| 6 | 6 |
| 7 #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" | 7 #include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" |
| 8 | 8 |
| 9 #include <GLES2/gl2.h> | 9 #include <GLES2/gl2.h> |
| 10 #ifndef GL_GLEXT_PROTOTYPES | 10 #ifndef GL_GLEXT_PROTOTYPES |
| 11 #define GL_GLEXT_PROTOTYPES 1 | 11 #define GL_GLEXT_PROTOTYPES 1 |
| 12 #endif | 12 #endif |
| 13 #include <GLES2/gl2ext.h> | 13 #include <GLES2/gl2ext.h> |
| 14 | 14 |
| 15 #include <algorithm> | 15 #include <algorithm> |
| 16 #include <set> | |
| 16 | 17 |
| 17 #include "base/string_tokenizer.h" | 18 #include "base/string_tokenizer.h" |
| 18 #include "base/command_line.h" | 19 #include "base/command_line.h" |
| 19 #include "base/lazy_instance.h" | 20 #include "base/lazy_instance.h" |
| 20 #include "base/logging.h" | 21 #include "base/logging.h" |
| 21 #include "base/message_loop.h" | 22 #include "base/message_loop.h" |
| 22 #include "base/memory/singleton.h" | 23 #include "base/memory/singleton.h" |
| 23 #include "base/metrics/histogram.h" | 24 #include "base/metrics/histogram.h" |
| 24 #include "gpu/command_buffer/client/gles2_lib.h" | 25 #include "gpu/command_buffer/client/gles2_lib.h" |
| 25 #include "gpu/command_buffer/client/gles2_implementation.h" | 26 #include "gpu/command_buffer/client/gles2_implementation.h" |
| 26 #include "gpu/command_buffer/common/constants.h" | 27 #include "gpu/command_buffer/common/constants.h" |
| 28 #include "gpu/command_buffer/service/context_group.h" | |
| 27 #include "gpu/command_buffer/service/gpu_scheduler.h" | 29 #include "gpu/command_buffer/service/gpu_scheduler.h" |
| 28 #include "gpu/command_buffer/service/command_buffer_service.h" | 30 #include "gpu/command_buffer/service/command_buffer_service.h" |
| 29 #include "gpu/GLES2/gles2_command_buffer.h" | 31 #include "gpu/GLES2/gles2_command_buffer.h" |
| 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" |
| 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | 34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" |
| 33 #include "ui/gfx/gl/gl_share_group.h" | 35 #include "ui/gfx/gl/gl_share_group.h" |
| 34 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h" | 36 #include "webkit/glue/gl_bindings_skia_cmd_buffer.h" |
| 35 | 37 |
| 36 using gpu::Buffer; | 38 using gpu::Buffer; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 // accelerated compositor's output. On this platform, we actually pass | 91 // accelerated compositor's output. On this platform, we actually pass |
| 90 // a gfx::PluginWindowHandle in place of the gfx::NativeViewId, | 92 // a gfx::PluginWindowHandle in place of the gfx::NativeViewId, |
| 91 // because the facility to allocate a fake PluginWindowHandle is | 93 // because the facility to allocate a fake PluginWindowHandle is |
| 92 // already in place. We could add more entry points and messages to | 94 // already in place. We could add more entry points and messages to |
| 93 // allocate both fake PluginWindowHandles and NativeViewIds and map | 95 // allocate both fake PluginWindowHandles and NativeViewIds and map |
| 94 // from fake NativeViewIds to PluginWindowHandles, but this seems like | 96 // from fake NativeViewIds to PluginWindowHandles, but this seems like |
| 95 // unnecessary complexity at the moment. | 97 // unnecessary complexity at the moment. |
| 96 // | 98 // |
| 97 static GLInProcessContext* CreateViewContext( | 99 static GLInProcessContext* CreateViewContext( |
| 98 gfx::PluginWindowHandle render_surface, | 100 gfx::PluginWindowHandle render_surface, |
| 101 GLInProcessContext* context_group, | |
| 99 const char* allowed_extensions, | 102 const char* allowed_extensions, |
| 100 const int32* attrib_list, | 103 const int32* attrib_list, |
| 101 const GURL& active_arl); | 104 const GURL& active_arl); |
| 102 | 105 |
| 103 #if defined(OS_MACOSX) | 106 #if defined(OS_MACOSX) |
| 104 // On Mac OS X only, view GLInProcessContexts actually behave like offscreen | 107 // On Mac OS X only, view GLInProcessContexts actually behave like offscreen |
| 105 // GLInProcessContexts, and require an explicit resize operation which is | 108 // GLInProcessContexts, and require an explicit resize operation which is |
| 106 // slightly different from that of offscreen GLInProcessContexts. | 109 // slightly different from that of offscreen GLInProcessContexts. |
| 107 void ResizeOnscreen(const gfx::Size& size); | 110 void ResizeOnscreen(const gfx::Size& size); |
| 108 #endif | 111 #endif |
| 109 | 112 |
| 110 // Create a GLInProcessContext that renders to an offscreen frame buffer. If | 113 // Create a GLInProcessContext that renders to an offscreen frame buffer. If |
| 111 // parent is not NULL, that GLInProcessContext can access a copy of the | 114 // parent is not NULL, that GLInProcessContext can access a copy of the |
| 112 // created GLInProcessContext's frame buffer that is updated every time | 115 // created GLInProcessContext's frame buffer that is updated every time |
| 113 // SwapBuffers is called. It is not as general as shared GLInProcessContexts | 116 // SwapBuffers is called. It is not as general as shared GLInProcessContexts |
| 114 // in other implementations of OpenGL. If parent is not NULL, it must be used | 117 // in other implementations of OpenGL. If parent is not NULL, it must be used |
| 115 // on the same thread as the parent. A child GLInProcessContext may not | 118 // on the same thread as the parent. A child GLInProcessContext may not |
| 116 // outlive its parent. attrib_list must be NULL or a NONE-terminated list of | 119 // outlive its parent. attrib_list must be NULL or a NONE-terminated list of |
| 117 // attribute/value pairs. | 120 // attribute/value pairs. |
| 118 static GLInProcessContext* CreateOffscreenContext( | 121 static GLInProcessContext* CreateOffscreenContext( |
| 119 GLInProcessContext* parent, | 122 GLInProcessContext* parent, |
| 120 const gfx::Size& size, | 123 const gfx::Size& size, |
| 124 GLInProcessContext* context_group, | |
| 121 const char* allowed_extensions, | 125 const char* allowed_extensions, |
| 122 const int32* attrib_list, | 126 const int32* attrib_list, |
| 123 const GURL& active_url); | 127 const GURL& active_url); |
| 124 | 128 |
| 125 // Resize an offscreen frame buffer. The resize occurs on the next call to | 129 // Resize an offscreen frame buffer. The resize occurs on the next call to |
| 126 // SwapBuffers. This is to avoid waiting until all pending GL calls have been | 130 // SwapBuffers. This is to avoid waiting until all pending GL calls have been |
| 127 // executed by the GPU process. Everything rendered up to the call to | 131 // executed by the GPU process. Everything rendered up to the call to |
| 128 // SwapBuffers will be lost. A lost GLInProcessContext will be reported if the | 132 // SwapBuffers will be lost. A lost GLInProcessContext will be reported if the |
| 129 // resize fails. | 133 // resize fails. |
| 130 void ResizeOffscreen(const gfx::Size& size); | 134 void ResizeOffscreen(const gfx::Size& size); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 bool IsCommandBufferContextLost(); | 175 bool IsCommandBufferContextLost(); |
| 172 | 176 |
| 173 CommandBufferService* GetCommandBufferService(); | 177 CommandBufferService* GetCommandBufferService(); |
| 174 | 178 |
| 175 private: | 179 private: |
| 176 GLInProcessContext(GLInProcessContext* parent); | 180 GLInProcessContext(GLInProcessContext* parent); |
| 177 | 181 |
| 178 bool Initialize(bool onscreen, | 182 bool Initialize(bool onscreen, |
| 179 gfx::PluginWindowHandle render_surface, | 183 gfx::PluginWindowHandle render_surface, |
| 180 const gfx::Size& size, | 184 const gfx::Size& size, |
| 185 GLInProcessContext* context_group, | |
| 181 const char* allowed_extensions, | 186 const char* allowed_extensions, |
| 182 const int32* attrib_list, | 187 const int32* attrib_list, |
| 183 const GURL& active_url); | 188 const GURL& active_url); |
| 184 void Destroy(); | 189 void Destroy(); |
| 185 | 190 |
| 186 void OnSwapBuffers(); | 191 void OnSwapBuffers(); |
| 187 void OnContextLost(); | 192 void OnContextLost(); |
| 188 | 193 |
| 189 base::WeakPtr<GLInProcessContext> parent_; | 194 base::WeakPtr<GLInProcessContext> parent_; |
| 190 scoped_ptr<Callback0::Type> swap_buffers_callback_; | 195 scoped_ptr<Callback0::Type> swap_buffers_callback_; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 201 DISALLOW_COPY_AND_ASSIGN(GLInProcessContext); | 206 DISALLOW_COPY_AND_ASSIGN(GLInProcessContext); |
| 202 }; | 207 }; |
| 203 | 208 |
| 204 namespace { | 209 namespace { |
| 205 | 210 |
| 206 const int32 kCommandBufferSize = 1024 * 1024; | 211 const int32 kCommandBufferSize = 1024 * 1024; |
| 207 // TODO(kbr): make the transfer buffer size configurable via context | 212 // TODO(kbr): make the transfer buffer size configurable via context |
| 208 // creation attributes. | 213 // creation attributes. |
| 209 const int32 kTransferBufferSize = 1024 * 1024; | 214 const int32 kTransferBufferSize = 1024 * 1024; |
| 210 | 215 |
| 216 static base::LazyInstance< | |
| 217 std::set<WebGraphicsContext3DInProcessCommandBufferImpl*> > g_all_contexts( | |
| 218 base::LINKER_INITIALIZED); | |
| 219 | |
| 211 // Singleton used to initialize and terminate the gles2 library. | 220 // Singleton used to initialize and terminate the gles2 library. |
| 212 class GLES2Initializer { | 221 class GLES2Initializer { |
| 213 public: | 222 public: |
| 214 GLES2Initializer() { | 223 GLES2Initializer() { |
| 215 gles2::Initialize(); | 224 gles2::Initialize(); |
| 216 } | 225 } |
| 217 | 226 |
| 218 ~GLES2Initializer() { | 227 ~GLES2Initializer() { |
| 219 gles2::Terminate(); | 228 gles2::Terminate(); |
| 220 } | 229 } |
| 221 | 230 |
| 222 private: | 231 private: |
| 223 DISALLOW_COPY_AND_ASSIGN(GLES2Initializer); | 232 DISALLOW_COPY_AND_ASSIGN(GLES2Initializer); |
| 224 }; | 233 }; |
| 225 | 234 |
| 226 //////////////////////////////////////////////////////////////////////////////// | 235 //////////////////////////////////////////////////////////////////////////////// |
| 227 | 236 |
| 228 static base::LazyInstance<GLES2Initializer> g_gles2_initializer( | 237 static base::LazyInstance<GLES2Initializer> g_gles2_initializer( |
| 229 base::LINKER_INITIALIZED); | 238 base::LINKER_INITIALIZED); |
| 230 | 239 |
| 231 } // namespace anonymous | 240 } // namespace anonymous |
| 232 | 241 |
| 233 GLInProcessContext::~GLInProcessContext() { | 242 GLInProcessContext::~GLInProcessContext() { |
| 234 Destroy(); | 243 Destroy(); |
| 235 } | 244 } |
| 236 | 245 |
| 237 GLInProcessContext* GLInProcessContext::CreateViewContext( | 246 GLInProcessContext* GLInProcessContext::CreateViewContext( |
| 238 gfx::PluginWindowHandle render_surface, | 247 gfx::PluginWindowHandle render_surface, |
| 248 GLInProcessContext* context_group, | |
| 239 const char* allowed_extensions, | 249 const char* allowed_extensions, |
| 240 const int32* attrib_list, | 250 const int32* attrib_list, |
| 241 const GURL& active_url) { | 251 const GURL& active_url) { |
| 242 #if defined(ENABLE_GPU) | 252 #if defined(ENABLE_GPU) |
| 243 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(NULL)); | 253 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(NULL)); |
| 244 if (!context->Initialize( | 254 if (!context->Initialize( |
| 245 true, | 255 true, |
| 246 render_surface, | 256 render_surface, |
| 247 gfx::Size(), | 257 gfx::Size(), |
| 258 context_group, | |
| 248 allowed_extensions, | 259 allowed_extensions, |
| 249 attrib_list, | 260 attrib_list, |
| 250 active_url)) | 261 active_url)) |
| 251 return NULL; | 262 return NULL; |
| 252 | 263 |
| 253 return context.release(); | 264 return context.release(); |
| 254 #else | 265 #else |
| 255 return NULL; | 266 return NULL; |
| 256 #endif | 267 #endif |
| 257 } | 268 } |
| 258 | 269 |
| 259 #if defined(OS_MACOSX) | 270 #if defined(OS_MACOSX) |
| 260 void GLInProcessContext::ResizeOnscreen(const gfx::Size& size) { | 271 void GLInProcessContext::ResizeOnscreen(const gfx::Size& size) { |
| 261 DCHECK(size.width() > 0 && size.height() > 0); | 272 DCHECK(size.width() > 0 && size.height() > 0); |
| 262 size_ = size; | 273 size_ = size; |
| 263 } | 274 } |
| 264 #endif | 275 #endif |
| 265 | 276 |
| 266 GLInProcessContext* GLInProcessContext::CreateOffscreenContext( | 277 GLInProcessContext* GLInProcessContext::CreateOffscreenContext( |
| 267 GLInProcessContext* parent, | 278 GLInProcessContext* parent, |
| 268 const gfx::Size& size, | 279 const gfx::Size& size, |
| 280 GLInProcessContext* context_group, | |
| 269 const char* allowed_extensions, | 281 const char* allowed_extensions, |
| 270 const int32* attrib_list, | 282 const int32* attrib_list, |
| 271 const GURL& active_url) { | 283 const GURL& active_url) { |
| 272 #if defined(ENABLE_GPU) | 284 #if defined(ENABLE_GPU) |
| 273 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent)); | 285 scoped_ptr<GLInProcessContext> context(new GLInProcessContext(parent)); |
| 274 if (!context->Initialize( | 286 if (!context->Initialize( |
| 275 false, | 287 false, |
| 276 gfx::kNullPluginWindow, | 288 gfx::kNullPluginWindow, |
| 277 size, | 289 size, |
| 290 context_group, | |
| 278 allowed_extensions, | 291 allowed_extensions, |
| 279 attrib_list, | 292 attrib_list, |
| 280 active_url)) | 293 active_url)) |
| 281 return NULL; | 294 return NULL; |
| 282 | 295 |
| 283 return context.release(); | 296 return context.release(); |
| 284 #else | 297 #else |
| 285 return NULL; | 298 return NULL; |
| 286 #endif | 299 #endif |
| 287 } | 300 } |
| 288 | 301 |
| 289 void GLInProcessContext::ResizeOffscreen(const gfx::Size& size) { | 302 void GLInProcessContext::ResizeOffscreen(const gfx::Size& size) { |
| 290 DCHECK(size.width() > 0 && size.height() > 0); | 303 DCHECK(size.width() > 0 && size.height() > 0); |
| 291 if (size_ != size) { | 304 if (size_ != size) { |
| 292 gpu_scheduler_->ResizeOffscreenFrameBuffer(size); | 305 gpu_scheduler_->ResizeOffscreenFrameBuffer(size); |
| 293 // TODO(gman): See if the next line is needed. | 306 // TODO(gman): See if the next line is needed. |
| 294 gles2_implementation_->ResizeCHROMIUM(size.width(), size.height()); | 307 gles2_implementation_->ResizeCHROMIUM(size.width(), size.height()); |
| 295 size_ = size; | 308 size_ = size; |
| 296 } | 309 } |
| 297 } | 310 } |
| 298 | 311 |
| 299 void GLInProcessContext::PumpCommands() { | 312 void GLInProcessContext::PumpCommands() { |
| 300 ::gpu::CommandBuffer::State state; | 313 ::gpu::CommandBuffer::State state; |
| 301 do { | 314 do { |
| 302 gpu_scheduler_->PutChanged(); | 315 gpu_scheduler_->PutChanged(); |
| 303 MessageLoop::current()->RunAllPending(); | 316 MessageLoop::current()->RunAllPending(); |
| 304 state = command_buffer_->GetState(); | 317 state = command_buffer_->GetState(); |
| 318 CHECK(state.error == ::gpu::error::kNoError); | |
|
jamesr
2011/08/03 21:51:20
On second thought, can you get rid of the RunAllPe
| |
| 305 } while (state.get_offset != state.put_offset); | 319 } while (state.get_offset != state.put_offset); |
| 306 } | 320 } |
| 307 | 321 |
| 308 uint32 GLInProcessContext::GetParentTextureId() { | 322 uint32 GLInProcessContext::GetParentTextureId() { |
| 309 return parent_texture_id_; | 323 return parent_texture_id_; |
| 310 } | 324 } |
| 311 | 325 |
| 312 uint32 GLInProcessContext::CreateParentTexture(const gfx::Size& size) { | 326 uint32 GLInProcessContext::CreateParentTexture(const gfx::Size& size) { |
| 313 // Allocate a texture ID with respect to the parent. | 327 uint32 texture = 0; |
| 314 if (parent_.get()) { | 328 gles2_implementation_->GenTextures(1, &texture); |
| 315 if (!MakeCurrent(parent_.get())) | 329 gles2_implementation_->Flush(); |
| 316 return 0; | 330 return texture; |
| 317 uint32 texture_id = parent_->gles2_implementation_->MakeTextureId(); | |
| 318 parent_->gles2_implementation_->BindTexture(GL_TEXTURE_2D, texture_id); | |
| 319 parent_->gles2_implementation_->TexParameteri( | |
| 320 GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |
| 321 parent_->gles2_implementation_->TexParameteri( | |
| 322 GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |
| 323 parent_->gles2_implementation_->TexParameteri( | |
| 324 GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 325 parent_->gles2_implementation_->TexParameteri( | |
| 326 GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 327 | |
| 328 parent_->gles2_implementation_->TexImage2D(GL_TEXTURE_2D, | |
| 329 0, // mip level | |
| 330 GL_RGBA, | |
| 331 size.width(), | |
| 332 size.height(), | |
| 333 0, // border | |
| 334 GL_RGBA, | |
| 335 GL_UNSIGNED_BYTE, | |
| 336 NULL); | |
| 337 // Make sure that the parent texture's storage is allocated before we let | |
| 338 // the caller attempt to use it. | |
| 339 int32 token = parent_->gles2_helper_->InsertToken(); | |
| 340 parent_->gles2_helper_->WaitForToken(token); | |
| 341 return texture_id; | |
| 342 } | |
| 343 return 0; | |
| 344 } | 331 } |
| 345 | 332 |
| 346 void GLInProcessContext::DeleteParentTexture(uint32 texture) { | 333 void GLInProcessContext::DeleteParentTexture(uint32 texture) { |
| 347 if (parent_.get()) { | 334 gles2_implementation_->DeleteTextures(1, &texture); |
| 348 if (!MakeCurrent(parent_.get())) | |
| 349 return; | |
| 350 parent_->gles2_implementation_->DeleteTextures(1, &texture); | |
| 351 } | |
| 352 } | 335 } |
| 353 | 336 |
| 354 void GLInProcessContext::SetSwapBuffersCallback(Callback0::Type* callback) { | 337 void GLInProcessContext::SetSwapBuffersCallback(Callback0::Type* callback) { |
| 355 swap_buffers_callback_.reset(callback); | 338 swap_buffers_callback_.reset(callback); |
| 356 } | 339 } |
| 357 | 340 |
| 358 void GLInProcessContext::SetContextLostCallback(Callback0::Type* callback) { | 341 void GLInProcessContext::SetContextLostCallback(Callback0::Type* callback) { |
| 359 context_lost_callback_.reset(callback); | 342 context_lost_callback_.reset(callback); |
| 360 } | 343 } |
| 361 | 344 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 427 gpu_scheduler_(NULL), | 410 gpu_scheduler_(NULL), |
| 428 gles2_helper_(NULL), | 411 gles2_helper_(NULL), |
| 429 transfer_buffer_id_(-1), | 412 transfer_buffer_id_(-1), |
| 430 gles2_implementation_(NULL), | 413 gles2_implementation_(NULL), |
| 431 last_error_(SUCCESS) { | 414 last_error_(SUCCESS) { |
| 432 } | 415 } |
| 433 | 416 |
| 434 bool GLInProcessContext::Initialize(bool onscreen, | 417 bool GLInProcessContext::Initialize(bool onscreen, |
| 435 gfx::PluginWindowHandle render_surface, | 418 gfx::PluginWindowHandle render_surface, |
| 436 const gfx::Size& size, | 419 const gfx::Size& size, |
| 420 GLInProcessContext* context_group, | |
| 437 const char* allowed_extensions, | 421 const char* allowed_extensions, |
| 438 const int32* attrib_list, | 422 const int32* attrib_list, |
| 439 const GURL& active_url) { | 423 const GURL& active_url) { |
| 440 // Use one share group for all contexts. | 424 // Use one share group for all contexts. |
| 441 static scoped_refptr<gfx::GLShareGroup> share_group(new gfx::GLShareGroup); | 425 static scoped_refptr<gfx::GLShareGroup> share_group(new gfx::GLShareGroup); |
| 442 | 426 |
| 443 DCHECK(size.width() >= 0 && size.height() >= 0); | 427 DCHECK(size.width() >= 0 && size.height() >= 0); |
| 444 | 428 |
| 445 // Ensure the gles2 library is initialized first in a thread safe way. | 429 // Ensure the gles2 library is initialized first in a thread safe way. |
| 446 g_gles2_initializer.Get(); | 430 g_gles2_initializer.Get(); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 479 attribs.push_back(NONE); | 463 attribs.push_back(NONE); |
| 480 attrib_list = NULL; | 464 attrib_list = NULL; |
| 481 break; | 465 break; |
| 482 } | 466 } |
| 483 } | 467 } |
| 484 | 468 |
| 485 command_buffer_.reset(new CommandBufferService); | 469 command_buffer_.reset(new CommandBufferService); |
| 486 if (!command_buffer_->Initialize(kCommandBufferSize)) | 470 if (!command_buffer_->Initialize(kCommandBufferSize)) |
| 487 return false; | 471 return false; |
| 488 | 472 |
| 489 gpu_scheduler_ = GpuScheduler::Create(command_buffer_.get(), | 473 gpu_scheduler_ = GpuScheduler::Create( |
| 490 NULL, | 474 command_buffer_.get(), |
| 491 NULL); | 475 NULL, |
| 476 context_group ? | |
| 477 context_group->gpu_scheduler_->decoder()->GetContextGroup() : NULL); | |
| 492 | 478 |
| 493 if (onscreen) { | 479 if (onscreen) { |
| 494 if (render_surface == gfx::kNullPluginWindow) { | 480 if (render_surface == gfx::kNullPluginWindow) { |
| 495 LOG(ERROR) << "Invalid surface handle for onscreen context."; | 481 LOG(ERROR) << "Invalid surface handle for onscreen context."; |
| 496 command_buffer_.reset(); | 482 command_buffer_.reset(); |
| 497 } else { | 483 } else { |
| 498 if (!gpu_scheduler_->Initialize(render_surface, | 484 if (!gpu_scheduler_->Initialize(render_surface, |
| 499 gfx::Size(), | 485 gfx::Size(), |
| 500 false, | 486 false, |
| 501 ::gpu::gles2::DisallowedExtensions(), | 487 ::gpu::gles2::DisallowedExtensions(), |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 Destroy(); | 541 Destroy(); |
| 556 return false; | 542 return false; |
| 557 } | 543 } |
| 558 | 544 |
| 559 // Create the object exposing the OpenGL API. | 545 // Create the object exposing the OpenGL API. |
| 560 gles2_implementation_ = new GLES2Implementation( | 546 gles2_implementation_ = new GLES2Implementation( |
| 561 gles2_helper_, | 547 gles2_helper_, |
| 562 transfer_buffer.size, | 548 transfer_buffer.size, |
| 563 transfer_buffer.ptr, | 549 transfer_buffer.ptr, |
| 564 transfer_buffer_id_, | 550 transfer_buffer_id_, |
| 565 false); | 551 true); |
| 566 | 552 |
| 567 size_ = size; | 553 size_ = size; |
| 568 | 554 |
| 569 return true; | 555 return true; |
| 570 } | 556 } |
| 571 | 557 |
| 572 void GLInProcessContext::Destroy() { | 558 void GLInProcessContext::Destroy() { |
| 573 if (parent_.get() && parent_texture_id_ != 0) { | 559 if (parent_.get() && parent_texture_id_ != 0) { |
| 574 parent_->gles2_implementation_->FreeTextureId(parent_texture_id_); | 560 parent_->gles2_implementation_->FreeTextureId(parent_texture_id_); |
| 575 parent_texture_id_ = 0; | 561 parent_texture_id_ = 0; |
| 576 } | 562 } |
| 577 | 563 |
| 578 delete gles2_implementation_; | 564 if (gles2_implementation_) { |
| 579 gles2_implementation_ = NULL; | 565 // First flush the context to ensure that any pending frees of resources |
| 566 // are completed. Otherwise, if this context is part of a share group, | |
| 567 // those resources might leak. Also, any remaining side effects of commands | |
| 568 // issued on this context might not be visible to other contexts in the | |
| 569 // share group. | |
| 570 gles2_implementation_->Flush(); | |
| 571 | |
| 572 delete gles2_implementation_; | |
| 573 gles2_implementation_ = NULL; | |
| 574 } | |
| 580 | 575 |
| 581 if (command_buffer_.get() && transfer_buffer_id_ != -1) { | 576 if (command_buffer_.get() && transfer_buffer_id_ != -1) { |
| 582 command_buffer_->DestroyTransferBuffer(transfer_buffer_id_); | 577 command_buffer_->DestroyTransferBuffer(transfer_buffer_id_); |
| 583 transfer_buffer_id_ = -1; | 578 transfer_buffer_id_ = -1; |
| 584 } | 579 } |
| 585 | 580 |
| 586 delete gles2_helper_; | 581 delete gles2_helper_; |
| 587 gles2_helper_ = NULL; | 582 gles2_helper_ = NULL; |
| 588 | 583 |
| 589 command_buffer_.reset(); | 584 command_buffer_.reset(); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 609 #endif // defined(OS_MACOSX) | 604 #endif // defined(OS_MACOSX) |
| 610 context_lost_callback_(0), | 605 context_lost_callback_(0), |
| 611 context_lost_reason_(GL_NO_ERROR), | 606 context_lost_reason_(GL_NO_ERROR), |
| 612 cached_width_(0), | 607 cached_width_(0), |
| 613 cached_height_(0), | 608 cached_height_(0), |
| 614 bound_fbo_(0) { | 609 bound_fbo_(0) { |
| 615 } | 610 } |
| 616 | 611 |
| 617 WebGraphicsContext3DInProcessCommandBufferImpl:: | 612 WebGraphicsContext3DInProcessCommandBufferImpl:: |
| 618 ~WebGraphicsContext3DInProcessCommandBufferImpl() { | 613 ~WebGraphicsContext3DInProcessCommandBufferImpl() { |
| 614 g_all_contexts.Pointer()->erase(this); | |
| 619 } | 615 } |
| 620 | 616 |
| 621 // This string should only be passed for WebGL contexts. Nothing ELSE!!! | 617 // This string should only be passed for WebGL contexts. Nothing ELSE!!! |
| 622 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of | 618 // Compositor contexts, Canvas2D contexts, Pepper Contexts, nor any other use of |
| 623 // a context should not pass this string. | 619 // a context should not pass this string. |
| 624 static const char* kWebGLPreferredGLExtensions = | 620 static const char* kWebGLPreferredGLExtensions = |
| 625 "GL_OES_packed_depth_stencil " | 621 "GL_OES_packed_depth_stencil " |
| 626 "GL_OES_depth24 " | 622 "GL_OES_depth24 " |
| 627 "GL_CHROMIUM_webglsl"; | 623 "GL_CHROMIUM_webglsl"; |
| 628 | 624 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 660 WebKit::WebGraphicsContext3D* view_context = | 656 WebKit::WebGraphicsContext3D* view_context = |
| 661 web_view->graphicsContext3D(); | 657 web_view->graphicsContext3D(); |
| 662 if (view_context) { | 658 if (view_context) { |
| 663 WebGraphicsContext3DInProcessCommandBufferImpl* context_impl = | 659 WebGraphicsContext3DInProcessCommandBufferImpl* context_impl = |
| 664 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>( | 660 static_cast<WebGraphicsContext3DInProcessCommandBufferImpl*>( |
| 665 view_context); | 661 view_context); |
| 666 parent_context = context_impl->context_; | 662 parent_context = context_impl->context_; |
| 667 } | 663 } |
| 668 } | 664 } |
| 669 | 665 |
| 666 // HACK: Assume this is a WebGL context by looking for the noExtensions | |
| 667 // attribute. WebGL contexts must not go in the share group because they | |
| 668 // rely on destruction of the context to clean up owned resources. Putting | |
| 669 // them in a share group would prevent this from happening. | |
| 670 WebGraphicsContext3DInProcessCommandBufferImpl* context_group = NULL; | |
| 671 if (!attributes.noExtensions) | |
| 672 context_group = g_all_contexts.Pointer()->empty() ? | |
| 673 NULL : *g_all_contexts.Pointer()->begin(); | |
| 674 | |
| 670 context_ = GLInProcessContext::CreateOffscreenContext( | 675 context_ = GLInProcessContext::CreateOffscreenContext( |
| 671 parent_context, | 676 parent_context, |
| 672 gfx::Size(1, 1), | 677 gfx::Size(1, 1), |
| 678 context_group ? context_group->context_ : NULL, | |
| 673 preferred_extensions, | 679 preferred_extensions, |
| 674 attribs, | 680 attribs, |
| 675 active_url); | 681 active_url); |
| 676 web_view_ = NULL; | 682 web_view_ = NULL; |
| 677 | 683 |
| 678 if (!context_) | 684 if (!context_) |
| 679 return false; | 685 return false; |
| 680 | 686 |
| 681 gl_ = context_->GetImplementation(); | 687 gl_ = context_->GetImplementation(); |
| 682 context_->SetContextLostCallback( | 688 context_->SetContextLostCallback( |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 695 attributes_.depth = depth_bits > 0; | 701 attributes_.depth = depth_bits > 0; |
| 696 GLint stencil_bits = 0; | 702 GLint stencil_bits = 0; |
| 697 getIntegerv(GL_STENCIL_BITS, &stencil_bits); | 703 getIntegerv(GL_STENCIL_BITS, &stencil_bits); |
| 698 attributes_.stencil = stencil_bits > 0; | 704 attributes_.stencil = stencil_bits > 0; |
| 699 GLint samples = 0; | 705 GLint samples = 0; |
| 700 getIntegerv(GL_SAMPLES, &samples); | 706 getIntegerv(GL_SAMPLES, &samples); |
| 701 attributes_.antialias = samples > 0; | 707 attributes_.antialias = samples > 0; |
| 702 } | 708 } |
| 703 makeContextCurrent(); | 709 makeContextCurrent(); |
| 704 | 710 |
| 711 if (!attributes.noExtensions) | |
| 712 g_all_contexts.Pointer()->insert(this); | |
| 713 | |
| 705 return true; | 714 return true; |
| 706 } | 715 } |
| 707 | 716 |
| 708 bool WebGraphicsContext3DInProcessCommandBufferImpl::makeContextCurrent() { | 717 bool WebGraphicsContext3DInProcessCommandBufferImpl::makeContextCurrent() { |
| 709 return GLInProcessContext::MakeCurrent(context_); | 718 return GLInProcessContext::MakeCurrent(context_); |
| 710 } | 719 } |
| 711 | 720 |
| 712 void WebGraphicsContext3DInProcessCommandBufferImpl::ClearContext() { | 721 void WebGraphicsContext3DInProcessCommandBufferImpl::ClearContext() { |
| 713 // NOTE: Comment in the line below to check for code that is not calling | 722 // NOTE: Comment in the line below to check for code that is not calling |
| 714 // eglMakeCurrent where appropriate. The issue is code using | 723 // eglMakeCurrent where appropriate. The issue is code using |
| (...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1621 if (context_lost_callback_) { | 1630 if (context_lost_callback_) { |
| 1622 context_lost_callback_->onContextLost(); | 1631 context_lost_callback_->onContextLost(); |
| 1623 } | 1632 } |
| 1624 } | 1633 } |
| 1625 | 1634 |
| 1626 } // namespace gpu | 1635 } // namespace gpu |
| 1627 } // namespace webkit | 1636 } // namespace webkit |
| 1628 | 1637 |
| 1629 #endif // defined(ENABLE_GPU) | 1638 #endif // defined(ENABLE_GPU) |
| 1630 | 1639 |
| OLD | NEW |