| 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 |