- add sources.
[platform/framework/web/crosswalk.git] / src / gpu / command_buffer / service / command_buffer_service.cc
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
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
33 CommandBufferService::~CommandBufferService() {
34 }
35
36 bool CommandBufferService::Initialize() {
37   return true;
38 }
39
40 CommandBufferService::State CommandBufferService::GetState() {
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
53 CommandBufferService::State CommandBufferService::GetLastState() {
54   return GetState();
55 }
56
57 int32 CommandBufferService::GetLastToken() {
58   return GetState().token;
59 }
60
61 void CommandBufferService::UpdateState() {
62   if (shared_state_) {
63     CommandBufferService::State state = GetState();
64     shared_state_->Write(state);
65   }
66 }
67
68 CommandBufferService::State CommandBufferService::FlushSync(
69     int32 put_offset, int32 last_known_get) {
70   if (put_offset < 0 || put_offset > num_entries_) {
71     error_ = gpu::error::kOutOfBounds;
72     return GetState();
73   }
74
75   put_offset_ = put_offset;
76
77   if (!put_offset_change_callback_.is_null())
78     put_offset_change_callback_.Run();
79
80   return GetState();
81 }
82
83 void CommandBufferService::Flush(int32 put_offset) {
84   if (put_offset < 0 || put_offset > num_entries_) {
85     error_ = gpu::error::kOutOfBounds;
86     return;
87   }
88
89   put_offset_ = put_offset;
90
91   if (!put_offset_change_callback_.is_null())
92     put_offset_change_callback_.Run();
93 }
94
95 void CommandBufferService::SetGetBuffer(int32 transfer_buffer_id) {
96   DCHECK_EQ(-1, ring_buffer_id_);
97   DCHECK_EQ(put_offset_, get_offset_);  // Only if it's empty.
98   ring_buffer_ = GetTransferBuffer(transfer_buffer_id);
99   DCHECK(ring_buffer_.ptr);
100   ring_buffer_id_ = transfer_buffer_id;
101   num_entries_ = ring_buffer_.size / sizeof(CommandBufferEntry);
102   put_offset_ = 0;
103   SetGetOffset(0);
104   if (!get_buffer_change_callback_.is_null()) {
105     get_buffer_change_callback_.Run(ring_buffer_id_);
106   }
107
108   UpdateState();
109 }
110
111 bool CommandBufferService::SetSharedStateBuffer(
112     scoped_ptr<base::SharedMemory> shared_state_shm) {
113   shared_state_shm_.reset(shared_state_shm.release());
114   if (!shared_state_shm_->Map(sizeof(*shared_state_)))
115     return false;
116
117   shared_state_ =
118       static_cast<CommandBufferSharedState*>(shared_state_shm_->memory());
119
120   UpdateState();
121   return true;
122 }
123
124 void CommandBufferService::SetGetOffset(int32 get_offset) {
125   DCHECK(get_offset >= 0 && get_offset < num_entries_);
126   get_offset_ = get_offset;
127 }
128
129 Buffer CommandBufferService::CreateTransferBuffer(size_t size,
130                                                   int32* id) {
131   *id = -1;
132
133   SharedMemory buffer;
134   if (!buffer.CreateAnonymous(size))
135     return Buffer();
136
137   static int32 next_id = 1;
138   *id = next_id++;
139
140   if (!RegisterTransferBuffer(*id, &buffer, size)) {
141     *id = -1;
142     return Buffer();
143   }
144
145   return GetTransferBuffer(*id);
146 }
147
148 void CommandBufferService::DestroyTransferBuffer(int32 id) {
149   transfer_buffer_manager_->DestroyTransferBuffer(id);
150   if (id == ring_buffer_id_) {
151     ring_buffer_id_ = -1;
152     ring_buffer_ = Buffer();
153     num_entries_ = 0;
154     get_offset_ = 0;
155     put_offset_ = 0;
156   }
157 }
158
159 Buffer CommandBufferService::GetTransferBuffer(int32 id) {
160   return transfer_buffer_manager_->GetTransferBuffer(id);
161 }
162
163 bool CommandBufferService::RegisterTransferBuffer(
164     int32 id,
165     base::SharedMemory* shared_memory,
166     size_t size) {
167   return transfer_buffer_manager_->RegisterTransferBuffer(id,
168                                                           shared_memory,
169                                                           size);
170 }
171
172 void CommandBufferService::SetToken(int32 token) {
173   token_ = token;
174   UpdateState();
175 }
176
177 void CommandBufferService::SetParseError(error::Error error) {
178   if (error_ == error::kNoError) {
179     error_ = error;
180     if (!parse_error_callback_.is_null())
181       parse_error_callback_.Run();
182   }
183 }
184
185 void CommandBufferService::SetContextLostReason(
186     error::ContextLostReason reason) {
187   context_lost_reason_ = reason;
188 }
189
190 void CommandBufferService::SetPutOffsetChangeCallback(
191     const base::Closure& callback) {
192   put_offset_change_callback_ = callback;
193 }
194
195 void CommandBufferService::SetGetBufferChangeCallback(
196     const GetBufferChangedCallback& callback) {
197   get_buffer_change_callback_ = callback;
198 }
199
200 void CommandBufferService::SetParseErrorCallback(
201     const base::Closure& callback) {
202   parse_error_callback_ = callback;
203 }
204
205 }  // namespace gpu