• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #include "gpu/command_buffer/service/command_buffer_service.h"
6 
7 #include <limits>
8 
9 #include "base/logging.h"
10 #include "base/debug/trace_event.h"
11 #include "gpu/command_buffer/common/cmd_buffer_common.h"
12 #include "gpu/command_buffer/common/command_buffer_shared.h"
13 #include "gpu/command_buffer/service/transfer_buffer_manager.h"
14 
15 using ::base::SharedMemory;
16 
17 namespace gpu {
18 
CommandBufferService(TransferBufferManagerInterface * transfer_buffer_manager)19 CommandBufferService::CommandBufferService(
20     TransferBufferManagerInterface* transfer_buffer_manager)
21     : ring_buffer_id_(-1),
22       shared_state_(NULL),
23       num_entries_(0),
24       get_offset_(0),
25       put_offset_(0),
26       transfer_buffer_manager_(transfer_buffer_manager),
27       token_(0),
28       generation_(0),
29       error_(error::kNoError),
30       context_lost_reason_(error::kUnknown) {
31 }
32 
~CommandBufferService()33 CommandBufferService::~CommandBufferService() {
34 }
35 
Initialize()36 bool CommandBufferService::Initialize() {
37   return true;
38 }
39 
GetLastState()40 CommandBufferService::State CommandBufferService::GetLastState() {
41   State state;
42   state.num_entries = num_entries_;
43   state.get_offset = get_offset_;
44   state.put_offset = put_offset_;
45   state.token = token_;
46   state.error = error_;
47   state.context_lost_reason = context_lost_reason_;
48   state.generation = ++generation_;
49 
50   return state;
51 }
52 
GetLastToken()53 int32 CommandBufferService::GetLastToken() {
54   return GetLastState().token;
55 }
56 
UpdateState()57 void CommandBufferService::UpdateState() {
58   if (shared_state_) {
59     CommandBufferService::State state = GetLastState();
60     shared_state_->Write(state);
61   }
62 }
63 
WaitForTokenInRange(int32 start,int32 end)64 void CommandBufferService::WaitForTokenInRange(int32 start, int32 end) {
65   DCHECK(error_ != error::kNoError || InRange(start, end, token_));
66 }
67 
WaitForGetOffsetInRange(int32 start,int32 end)68 void CommandBufferService::WaitForGetOffsetInRange(int32 start, int32 end) {
69   DCHECK(error_ != error::kNoError || InRange(start, end, get_offset_));
70 }
71 
Flush(int32 put_offset)72 void CommandBufferService::Flush(int32 put_offset) {
73   if (put_offset < 0 || put_offset > num_entries_) {
74     error_ = gpu::error::kOutOfBounds;
75     return;
76   }
77 
78   put_offset_ = put_offset;
79 
80   if (!put_offset_change_callback_.is_null())
81     put_offset_change_callback_.Run();
82 }
83 
SetGetBuffer(int32 transfer_buffer_id)84 void CommandBufferService::SetGetBuffer(int32 transfer_buffer_id) {
85   DCHECK_EQ(-1, ring_buffer_id_);
86   DCHECK_EQ(put_offset_, get_offset_);  // Only if it's empty.
87   // If the buffer is invalid we handle it gracefully.
88   // This means ring_buffer_ can be NULL.
89   ring_buffer_ = GetTransferBuffer(transfer_buffer_id);
90   ring_buffer_id_ = transfer_buffer_id;
91   int32 size = ring_buffer_.get() ? ring_buffer_->size() : 0;
92   num_entries_ = size / sizeof(CommandBufferEntry);
93   put_offset_ = 0;
94   SetGetOffset(0);
95   if (!get_buffer_change_callback_.is_null()) {
96     get_buffer_change_callback_.Run(ring_buffer_id_);
97   }
98 
99   UpdateState();
100 }
101 
SetSharedStateBuffer(scoped_ptr<BufferBacking> shared_state_buffer)102 void CommandBufferService::SetSharedStateBuffer(
103     scoped_ptr<BufferBacking> shared_state_buffer) {
104   shared_state_buffer_ = shared_state_buffer.Pass();
105   DCHECK(shared_state_buffer_->GetSize() >= sizeof(*shared_state_));
106 
107   shared_state_ =
108       static_cast<CommandBufferSharedState*>(shared_state_buffer_->GetMemory());
109 
110   UpdateState();
111 }
112 
SetGetOffset(int32 get_offset)113 void CommandBufferService::SetGetOffset(int32 get_offset) {
114   DCHECK(get_offset >= 0 && get_offset < num_entries_);
115   get_offset_ = get_offset;
116 }
117 
CreateTransferBuffer(size_t size,int32 * id)118 scoped_refptr<Buffer> CommandBufferService::CreateTransferBuffer(size_t size,
119                                                                  int32* id) {
120   *id = -1;
121 
122   scoped_ptr<SharedMemory> shared_memory(new SharedMemory());
123   if (!shared_memory->CreateAndMapAnonymous(size))
124     return NULL;
125 
126   static int32 next_id = 1;
127   *id = next_id++;
128 
129   if (!RegisterTransferBuffer(
130           *id, MakeBackingFromSharedMemory(shared_memory.Pass(), size))) {
131     *id = -1;
132     return NULL;
133   }
134 
135   return GetTransferBuffer(*id);
136 }
137 
DestroyTransferBuffer(int32 id)138 void CommandBufferService::DestroyTransferBuffer(int32 id) {
139   transfer_buffer_manager_->DestroyTransferBuffer(id);
140   if (id == ring_buffer_id_) {
141     ring_buffer_id_ = -1;
142     ring_buffer_ = NULL;
143     num_entries_ = 0;
144     get_offset_ = 0;
145     put_offset_ = 0;
146   }
147 }
148 
GetTransferBuffer(int32 id)149 scoped_refptr<Buffer> CommandBufferService::GetTransferBuffer(int32 id) {
150   return transfer_buffer_manager_->GetTransferBuffer(id);
151 }
152 
RegisterTransferBuffer(int32 id,scoped_ptr<BufferBacking> buffer)153 bool CommandBufferService::RegisterTransferBuffer(
154     int32 id,
155     scoped_ptr<BufferBacking> buffer) {
156   return transfer_buffer_manager_->RegisterTransferBuffer(id, buffer.Pass());
157 }
158 
SetToken(int32 token)159 void CommandBufferService::SetToken(int32 token) {
160   token_ = token;
161   UpdateState();
162 }
163 
SetParseError(error::Error error)164 void CommandBufferService::SetParseError(error::Error error) {
165   if (error_ == error::kNoError) {
166     error_ = error;
167     if (!parse_error_callback_.is_null())
168       parse_error_callback_.Run();
169   }
170 }
171 
SetContextLostReason(error::ContextLostReason reason)172 void CommandBufferService::SetContextLostReason(
173     error::ContextLostReason reason) {
174   context_lost_reason_ = reason;
175 }
176 
SetPutOffsetChangeCallback(const base::Closure & callback)177 void CommandBufferService::SetPutOffsetChangeCallback(
178     const base::Closure& callback) {
179   put_offset_change_callback_ = callback;
180 }
181 
SetGetBufferChangeCallback(const GetBufferChangedCallback & callback)182 void CommandBufferService::SetGetBufferChangeCallback(
183     const GetBufferChangedCallback& callback) {
184   get_buffer_change_callback_ = callback;
185 }
186 
SetParseErrorCallback(const base::Closure & callback)187 void CommandBufferService::SetParseErrorCallback(
188     const base::Closure& callback) {
189   parse_error_callback_ = callback;
190 }
191 
192 }  // namespace gpu
193