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 "gpu/command_buffer/client/gl_in_process_context.h" | 5 #include "gpu/command_buffer/client/gl_in_process_context.h" |
6 | 6 |
7 #include <deque> | |
7 #include <utility> | 8 #include <utility> |
8 #include <vector> | 9 #include <vector> |
9 | 10 |
10 #include <GLES2/gl2.h> | 11 #include <GLES2/gl2.h> |
11 #ifndef GL_GLEXT_PROTOTYPES | 12 #ifndef GL_GLEXT_PROTOTYPES |
12 #define GL_GLEXT_PROTOTYPES 1 | 13 #define GL_GLEXT_PROTOTYPES 1 |
13 #endif | 14 #endif |
14 #include <GLES2/gl2ext.h> | 15 #include <GLES2/gl2ext.h> |
15 #include <GLES2/gl2extchromium.h> | 16 #include <GLES2/gl2extchromium.h> |
16 | 17 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
116 gles2::GLES2Decoder* GetDecoder(); | 117 gles2::GLES2Decoder* GetDecoder(); |
117 bool GetBufferChanged(int32 transfer_buffer_id); | 118 bool GetBufferChanged(int32 transfer_buffer_id); |
118 void PumpCommands(); | 119 void PumpCommands(); |
119 void OnResizeView(gfx::Size size, float scale_factor); | 120 void OnResizeView(gfx::Size size, float scale_factor); |
120 void OnContextLost(); | 121 void OnContextLost(); |
121 | 122 |
122 private: | 123 private: |
123 void Destroy(); | 124 void Destroy(); |
124 bool IsCommandBufferContextLost(); | 125 bool IsCommandBufferContextLost(); |
125 void PollQueryCallbacks(); | 126 void PollQueryCallbacks(); |
126 void CallQueryCallback(size_t index); | |
127 | 127 |
128 gles2::ImageManager* GetImageManager(); | 128 gles2::ImageManager* GetImageManager(); |
129 | 129 |
130 base::Closure context_lost_callback_; | 130 base::Closure context_lost_callback_; |
131 scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; | 131 scoped_ptr<TransferBufferManagerInterface> transfer_buffer_manager_; |
132 scoped_ptr<CommandBuffer> command_buffer_; | 132 scoped_ptr<CommandBuffer> command_buffer_; |
133 scoped_ptr<GpuScheduler> gpu_scheduler_; | 133 scoped_ptr<GpuScheduler> gpu_scheduler_; |
134 scoped_ptr<gles2::GLES2Decoder> decoder_; | 134 scoped_ptr<gles2::GLES2Decoder> decoder_; |
135 scoped_refptr<gfx::GLContext> context_; | 135 scoped_refptr<gfx::GLContext> context_; |
136 scoped_refptr<gfx::GLSurface> surface_; | 136 scoped_refptr<gfx::GLSurface> surface_; |
137 scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_; | 137 scoped_ptr<gles2::GLES2CmdHelper> gles2_helper_; |
138 scoped_ptr<TransferBuffer> transfer_buffer_; | 138 scoped_ptr<TransferBuffer> transfer_buffer_; |
139 scoped_ptr<gles2::GLES2Implementation> gles2_implementation_; | 139 scoped_ptr<gles2::GLES2Implementation> gles2_implementation_; |
140 scoped_refptr<ImageFactoryInProcess> image_factory_; | 140 scoped_refptr<ImageFactoryInProcess> image_factory_; |
141 base::Closure signal_sync_point_callback_; | 141 base::Closure signal_sync_point_callback_; |
142 bool share_resources_; | 142 bool share_resources_; |
143 bool context_lost_; | 143 bool context_lost_; |
144 | 144 |
145 typedef std::pair<unsigned, base::Closure> QueryCallback; | 145 typedef std::pair<unsigned, base::Closure> QueryCallback; |
146 std::vector<QueryCallback> query_callbacks_; | 146 std::deque<QueryCallback> query_callbacks_; |
147 | 147 |
148 DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl); | 148 DISALLOW_COPY_AND_ASSIGN(GLInProcessContextImpl); |
149 }; | 149 }; |
150 | 150 |
151 AutoLockAndDecoderDetachThread::AutoLockAndDecoderDetachThread( | 151 AutoLockAndDecoderDetachThread::AutoLockAndDecoderDetachThread( |
152 base::Lock& lock, | 152 base::Lock& lock, |
153 const std::set<GLInProcessContextImpl*>& contexts) | 153 const std::set<GLInProcessContextImpl*>& contexts) |
154 : auto_lock_(lock), | 154 : auto_lock_(lock), |
155 contexts_(contexts) { | 155 contexts_(contexts) { |
156 } | 156 } |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
497 g_all_shared_contexts.Get()); | 497 g_all_shared_contexts.Get()); |
498 g_all_shared_contexts.Pointer()->insert(this); | 498 g_all_shared_contexts.Pointer()->insert(this); |
499 } | 499 } |
500 | 500 |
501 context_lost_callback_ = context_lost_callback; | 501 context_lost_callback_ = context_lost_callback; |
502 return true; | 502 return true; |
503 } | 503 } |
504 | 504 |
505 void GLInProcessContextImpl::Destroy() { | 505 void GLInProcessContextImpl::Destroy() { |
506 while (!query_callbacks_.empty()) { | 506 while (!query_callbacks_.empty()) { |
507 CallQueryCallback(0); | 507 base::Closure query_callback = query_callbacks_.back().second; |
508 query_callbacks_.pop_back(); | |
509 query_callback.Run(); | |
508 } | 510 } |
509 | 511 |
512 | |
510 bool context_lost = IsCommandBufferContextLost(); | 513 bool context_lost = IsCommandBufferContextLost(); |
511 | 514 |
512 if (gles2_implementation_) { | 515 if (gles2_implementation_) { |
513 // First flush the context to ensure that any pending frees of resources | 516 // First flush the context to ensure that any pending frees of resources |
514 // are completed. Otherwise, if this context is part of a share group, | 517 // are completed. Otherwise, if this context is part of a share group, |
515 // those resources might leak. Also, any remaining side effects of commands | 518 // those resources might leak. Also, any remaining side effects of commands |
516 // issued on this context might not be visible to other contexts in the | 519 // issued on this context might not be visible to other contexts in the |
517 // share group. | 520 // share group. |
518 gles2_implementation_->Flush(); | 521 gles2_implementation_->Flush(); |
519 | 522 |
(...skipping 20 matching lines...) Expand all Loading... | |
540 context_lost_ = true; | 543 context_lost_ = true; |
541 if (share_resources_) { | 544 if (share_resources_) { |
542 for (std::set<GLInProcessContextImpl*>::iterator it = | 545 for (std::set<GLInProcessContextImpl*>::iterator it = |
543 g_all_shared_contexts.Get().begin(); | 546 g_all_shared_contexts.Get().begin(); |
544 it != g_all_shared_contexts.Get().end(); | 547 it != g_all_shared_contexts.Get().end(); |
545 ++it) | 548 ++it) |
546 (*it)->context_lost_ = true; | 549 (*it)->context_lost_ = true; |
547 } | 550 } |
548 } | 551 } |
549 | 552 |
550 void GLInProcessContextImpl::CallQueryCallback(size_t index) { | |
551 DCHECK_LT(index, query_callbacks_.size()); | |
552 QueryCallback query_callback = query_callbacks_[index]; | |
553 query_callbacks_[index] = query_callbacks_.back(); | |
554 query_callbacks_.pop_back(); | |
555 query_callback.second.Run(); | |
556 } | |
557 | |
558 void GLInProcessContextImpl::PollQueryCallbacks() { | 553 void GLInProcessContextImpl::PollQueryCallbacks() { |
559 for (size_t i = 0; i < query_callbacks_.size();) { | 554 // Queries are put on to to the query_callback_ deque from the FRONT. |
555 // This means that if there are several queries of the same type in | |
556 // the queue, and we find that one of them has finished, the rest | |
557 // of them should be finished too. We want to make sure that | |
piman
2013/06/28 23:35:46
That's not true though.
An async texture upload do
hubbe
2013/06/29 00:13:56
Async readpixels (and maybe other queries) *do* fi
| |
558 // a) Query callbacks are called in the right order | |
559 // b) query_callbacks_ is in a good state when we call the callbacks | |
560 // To do that we pul out the queries that have completed and put them | |
561 // in a separate container in reversed order, then we compress | |
562 // query_callbacks_ and before invoking the callbacks. | |
563 std::deque<QueryCallback> to_call; | |
564 size_t queries_left = 0; | |
565 for (size_t i = 0; i < query_callbacks_.size(); i++) { | |
560 unsigned query = query_callbacks_[i].first; | 566 unsigned query = query_callbacks_[i].first; |
561 GLuint param = 0; | 567 GLuint param = 0; |
562 gles2::GLES2Implementation* gl = GetImplementation(); | 568 gles2::GLES2Implementation* gl = GetImplementation(); |
563 if (gl->IsQueryEXT(query)) { | 569 if (gl->IsQueryEXT(query)) { |
564 gl->GetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, ¶m); | 570 gl->GetQueryObjectuivEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT, ¶m); |
565 } else { | 571 } else { |
566 param = 1; | 572 param = 1; |
567 } | 573 } |
568 if (param) { | 574 if (param) { |
569 CallQueryCallback(i); | 575 to_call.push_front(query_callbacks_[i]); |
570 } else { | 576 } else { |
571 i++; | 577 query_callbacks_[queries_left++] = query_callbacks_[i]; |
572 } | 578 } |
573 } | 579 } |
580 query_callbacks_.resize(queries_left); | |
581 for (size_t i = 0; i < to_call.size(); i++) { | |
582 to_call[i].second.Run(); | |
583 } | |
584 | |
574 if (!query_callbacks_.empty()) { | 585 if (!query_callbacks_.empty()) { |
575 base::MessageLoop::current()->PostDelayedTask( | 586 base::MessageLoop::current()->PostDelayedTask( |
576 FROM_HERE, | 587 FROM_HERE, |
577 base::Bind(&GLInProcessContextImpl::PollQueryCallbacks, | 588 base::Bind(&GLInProcessContextImpl::PollQueryCallbacks, |
578 this->AsWeakPtr()), | 589 this->AsWeakPtr()), |
579 base::TimeDelta::FromMilliseconds(5)); | 590 base::TimeDelta::FromMilliseconds(5)); |
580 } | 591 } |
581 } | 592 } |
582 | 593 |
583 void GLInProcessContextImpl::SignalQuery( | 594 void GLInProcessContextImpl::SignalQuery( |
584 unsigned query, | 595 unsigned query, |
585 const base::Closure& callback) { | 596 const base::Closure& callback) { |
586 query_callbacks_.push_back(std::make_pair(query, callback)); | 597 query_callbacks_.push_front(std::make_pair(query, callback)); |
587 // If size > 1, there is already a poll callback pending. | 598 // If size > 1, there is already a poll callback pending. |
588 if (query_callbacks_.size() == 1) { | 599 if (query_callbacks_.size() == 1) { |
589 PollQueryCallbacks(); | 600 PollQueryCallbacks(); |
590 } | 601 } |
591 } | 602 } |
592 | 603 |
593 } // anonymous namespace | 604 } // anonymous namespace |
594 | 605 |
595 // static | 606 // static |
596 GLInProcessContext* GLInProcessContext::CreateContext( | 607 GLInProcessContext* GLInProcessContext::CreateContext( |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
629 { | 640 { |
630 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), | 641 AutoLockAndDecoderDetachThread lock(g_decoder_lock.Get(), |
631 g_all_shared_contexts.Get()); | 642 g_all_shared_contexts.Get()); |
632 DCHECK(g_all_shared_contexts.Get().empty()); | 643 DCHECK(g_all_shared_contexts.Get().empty()); |
633 } | 644 } |
634 #endif // !defined(NDEBUG) | 645 #endif // !defined(NDEBUG) |
635 g_use_virtualized_gl_context = true; | 646 g_use_virtualized_gl_context = true; |
636 } | 647 } |
637 | 648 |
638 } // namespace gpu | 649 } // namespace gpu |
OLD | NEW |