OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "base/callback.h" | 5 #include "base/callback.h" |
6 #include "base/compiler_specific.h" | 6 #include "base/compiler_specific.h" |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "app/gfx/gl/gl_context.h" | 8 #include "app/gfx/gl/gl_context.h" |
9 #include "gpu/command_buffer/service/gpu_processor.h" | 9 #include "gpu/command_buffer/service/gpu_processor.h" |
10 | 10 |
11 using ::base::SharedMemory; | 11 using ::base::SharedMemory; |
12 | 12 |
13 namespace gpu { | 13 namespace gpu { |
14 | 14 |
15 GPUProcessor::GPUProcessor(CommandBuffer* command_buffer, | 15 GPUProcessor::GPUProcessor(CommandBuffer* command_buffer, |
16 gles2::ContextGroup* group) | 16 gles2::ContextGroup* group) |
17 : command_buffer_(command_buffer), | 17 : command_buffer_(command_buffer), |
18 commands_per_update_(100), | 18 commands_per_update_(100), |
| 19 #if defined(OS_MACOSX) |
| 20 swap_buffers_count_(0), |
| 21 acknowledged_swap_buffers_count_(0), |
| 22 #endif |
19 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 23 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
20 DCHECK(command_buffer); | 24 DCHECK(command_buffer); |
21 decoder_.reset(gles2::GLES2Decoder::Create(group)); | 25 decoder_.reset(gles2::GLES2Decoder::Create(group)); |
22 decoder_->set_engine(this); | 26 decoder_->set_engine(this); |
23 } | 27 } |
24 | 28 |
25 GPUProcessor::GPUProcessor(CommandBuffer* command_buffer, | 29 GPUProcessor::GPUProcessor(CommandBuffer* command_buffer, |
26 gles2::GLES2Decoder* decoder, | 30 gles2::GLES2Decoder* decoder, |
27 CommandParser* parser, | 31 CommandParser* parser, |
28 int commands_per_update) | 32 int commands_per_update) |
29 : command_buffer_(command_buffer), | 33 : command_buffer_(command_buffer), |
30 commands_per_update_(commands_per_update), | 34 commands_per_update_(commands_per_update), |
| 35 #if defined(OS_MACOSX) |
| 36 swap_buffers_count_(0), |
| 37 acknowledged_swap_buffers_count_(0), |
| 38 #endif |
31 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 39 method_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
32 DCHECK(command_buffer); | 40 DCHECK(command_buffer); |
33 decoder_.reset(decoder); | 41 decoder_.reset(decoder); |
34 parser_.reset(parser); | 42 parser_.reset(parser); |
35 } | 43 } |
36 | 44 |
37 GPUProcessor::~GPUProcessor() { | 45 GPUProcessor::~GPUProcessor() { |
38 Destroy(); | 46 Destroy(); |
39 } | 47 } |
40 | 48 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 bool have_context = false; | 88 bool have_context = false; |
81 if (decoder_.get()) { | 89 if (decoder_.get()) { |
82 have_context = decoder_->MakeCurrent(); | 90 have_context = decoder_->MakeCurrent(); |
83 decoder_->Destroy(); | 91 decoder_->Destroy(); |
84 decoder_.reset(); | 92 decoder_.reset(); |
85 } | 93 } |
86 | 94 |
87 parser_.reset(); | 95 parser_.reset(); |
88 } | 96 } |
89 | 97 |
| 98 #if defined(OS_MACOSX) |
| 99 namespace { |
| 100 const unsigned int kMaxOutstandingSwapBuffersCallsPerOnscreenContext = 1; |
| 101 } |
| 102 #endif |
| 103 |
90 void GPUProcessor::ProcessCommands() { | 104 void GPUProcessor::ProcessCommands() { |
91 CommandBuffer::State state = command_buffer_->GetState(); | 105 CommandBuffer::State state = command_buffer_->GetState(); |
92 if (state.error != error::kNoError) | 106 if (state.error != error::kNoError) |
93 return; | 107 return; |
94 | 108 |
95 if (decoder_.get()) { | 109 if (decoder_.get()) { |
96 if (!decoder_->MakeCurrent()) { | 110 if (!decoder_->MakeCurrent()) { |
97 LOG(ERROR) << "Context lost because MakeCurrent failed."; | 111 LOG(ERROR) << "Context lost because MakeCurrent failed."; |
98 command_buffer_->SetParseError(error::kLostContext); | 112 command_buffer_->SetParseError(error::kLostContext); |
99 return; | 113 return; |
100 } | 114 } |
101 } | 115 } |
102 | 116 |
103 parser_->set_put(state.put_offset); | 117 parser_->set_put(state.put_offset); |
104 | 118 |
| 119 #if defined(OS_MACOSX) |
| 120 bool do_rate_limiting = surface_.get() != NULL; |
| 121 // Don't swamp the browser process with SwapBuffers calls it can't handle. |
| 122 if (do_rate_limiting && |
| 123 swap_buffers_count_ - acknowledged_swap_buffers_count_ >= |
| 124 kMaxOutstandingSwapBuffersCallsPerOnscreenContext) { |
| 125 // Stop doing work on this command buffer. In the GPU process, |
| 126 // receipt of the GpuMsg_AcceleratedSurfaceBuffersSwappedACK |
| 127 // message causes ProcessCommands to be scheduled again. |
| 128 return; |
| 129 } |
| 130 #endif |
| 131 |
105 int commands_processed = 0; | 132 int commands_processed = 0; |
106 while (commands_processed < commands_per_update_ && !parser_->IsEmpty()) { | 133 while (commands_processed < commands_per_update_ && !parser_->IsEmpty()) { |
107 error::Error error = parser_->ProcessCommand(); | 134 error::Error error = parser_->ProcessCommand(); |
108 if (error != error::kNoError) { | 135 if (error != error::kNoError) { |
109 command_buffer_->SetParseError(error); | 136 command_buffer_->SetParseError(error); |
110 return; | 137 return; |
111 } | 138 } |
112 ++commands_processed; | 139 ++commands_processed; |
113 } | 140 } |
114 | 141 |
115 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); | 142 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); |
116 | 143 |
117 if (!parser_->IsEmpty()) { | 144 if (!parser_->IsEmpty()) { |
118 MessageLoop::current()->PostTask( | 145 ScheduleProcessCommands(); |
119 FROM_HERE, | |
120 method_factory_.NewRunnableMethod(&GPUProcessor::ProcessCommands)); | |
121 } | 146 } |
122 } | 147 } |
123 | 148 |
| 149 void GPUProcessor::ScheduleProcessCommands() { |
| 150 MessageLoop::current()->PostTask( |
| 151 FROM_HERE, |
| 152 method_factory_.NewRunnableMethod(&GPUProcessor::ProcessCommands)); |
| 153 } |
| 154 |
124 Buffer GPUProcessor::GetSharedMemoryBuffer(int32 shm_id) { | 155 Buffer GPUProcessor::GetSharedMemoryBuffer(int32 shm_id) { |
125 return command_buffer_->GetTransferBuffer(shm_id); | 156 return command_buffer_->GetTransferBuffer(shm_id); |
126 } | 157 } |
127 | 158 |
128 void GPUProcessor::set_token(int32 token) { | 159 void GPUProcessor::set_token(int32 token) { |
129 command_buffer_->SetToken(token); | 160 command_buffer_->SetToken(token); |
130 } | 161 } |
131 | 162 |
132 bool GPUProcessor::SetGetOffset(int32 offset) { | 163 bool GPUProcessor::SetGetOffset(int32 offset) { |
133 if (parser_->set_get(offset)) { | 164 if (parser_->set_get(offset)) { |
(...skipping 13 matching lines...) Expand all Loading... |
147 | 178 |
148 void GPUProcessor::SetSwapBuffersCallback( | 179 void GPUProcessor::SetSwapBuffersCallback( |
149 Callback0::Type* callback) { | 180 Callback0::Type* callback) { |
150 wrapped_swap_buffers_callback_.reset(callback); | 181 wrapped_swap_buffers_callback_.reset(callback); |
151 decoder_->SetSwapBuffersCallback( | 182 decoder_->SetSwapBuffersCallback( |
152 NewCallback(this, | 183 NewCallback(this, |
153 &GPUProcessor::WillSwapBuffers)); | 184 &GPUProcessor::WillSwapBuffers)); |
154 } | 185 } |
155 | 186 |
156 } // namespace gpu | 187 } // namespace gpu |
OLD | NEW |