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 |