Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(157)

Side by Side Diff: ui/gl/async_pixel_transfer_delegate_idle.cc

Issue 12040049: gpu: Implement idle async pixel transfers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove texture_dirty_ state from AsyncPixelTransferDelegateIdle Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 "ui/gl/async_pixel_transfer_delegate_idle.h"
6
7 #include "base/bind.h"
8 #include "base/debug/trace_event.h"
9 #include "base/lazy_instance.h"
10 #include "base/message_loop.h"
11 #include "base/process_util.h"
12 #include "base/shared_memory.h"
13 #include "build/build_config.h"
14 #include "ui/gl/gl_bindings.h"
15 #include "ui/gl/gl_context.h"
16 #include "ui/gl/gl_surface.h"
17 #include "ui/gl/safe_shared_memory_pool.h"
18 #include "ui/gl/scoped_make_current.h"
19
20 using base::SharedMemory;
21 using base::SharedMemoryHandle;
22
23 namespace gfx {
24
25 namespace {
26
27 // Gets the address of the data from shared memory.
28 void* GetAddress(SharedMemory* shared_memory, uint32 shm_data_offset) {
29 // Memory bounds have already been validated, so there
30 // is just DCHECKS here.
31 DCHECK(shared_memory);
32 DCHECK(shared_memory->memory());
33 return static_cast<int8*>(shared_memory->memory()) + shm_data_offset;
34 }
35
36 base::LazyInstance<SafeSharedMemoryPool> g_safe_shared_memory_pool =
37 LAZY_INSTANCE_INITIALIZER;
38
39 SafeSharedMemoryPool* safe_shared_memory_pool() {
40 return g_safe_shared_memory_pool.Pointer();
41 }
42
43 static uint64 g_next_pixel_transfer_state_id = 1;
44
45 } // namespace
46
47 #if !defined(OS_ANDROID)
48 scoped_ptr<AsyncPixelTransferDelegate>
49 AsyncPixelTransferDelegate::Create(gfx::GLContext* context) {
50 return AsyncPixelTransferDelegateIdle::Create(context);
51 }
52 #endif
53
54 scoped_ptr<AsyncPixelTransferDelegate>
55 AsyncPixelTransferDelegateIdle::Create(gfx::GLContext* context) {
56 return make_scoped_ptr(
57 static_cast<AsyncPixelTransferDelegate*>(
58 new AsyncPixelTransferDelegateIdle()));
59 }
60
61 class AsyncPixelTransferStateIdle : public AsyncPixelTransferState {
62 public:
63 typedef base::Callback<void(GLuint)> TransferCallback;
64
65 explicit AsyncPixelTransferStateIdle(GLuint texture_id)
66 : id_(g_next_pixel_transfer_state_id++),
67 texture_id_(texture_id),
68 transfer_in_progress_(false) {
69 }
70 virtual ~AsyncPixelTransferStateIdle() {}
71
72 // Overridden from gfx::AsyncPixelTransferState:
73 virtual bool TransferIsInProgress() OVERRIDE {
74 return transfer_in_progress_;
75 }
76
77 uint64 id() const { return id_; }
78
79 void set_transfer_in_progress(bool transfer_in_progress) {
80 transfer_in_progress_ = transfer_in_progress;
81 }
82
83 void PerformTransfer(const TransferCallback& callback) {
84 DCHECK(texture_id_);
85 DCHECK(transfer_in_progress_);
86 callback.Run(texture_id_);
87 transfer_in_progress_ = false;
88 }
89
90 private:
91 uint64 id_;
92 GLuint texture_id_;
93 bool transfer_in_progress_;
94 };
95
96 AsyncPixelTransferDelegateIdle::Transfer::Transfer(
97 uint64 id, const base::Closure& task)
98 : id(id),
99 task(task) {
epenner 2013/03/14 18:23:24 id=id? Would we call it 'id_' by making it a class
reveman 2013/03/14 19:21:47 Yes, but I prefer using a struct for this simple c
epenner 2013/03/14 20:31:00 Touche! I thought it was a bug, but it's totally f
100 }
101
102 AsyncPixelTransferDelegateIdle::Transfer::~Transfer() {}
103
104 AsyncPixelTransferDelegateIdle::AsyncPixelTransferDelegateIdle()
105 : texture_upload_count_(0) {
106 }
107
108 AsyncPixelTransferDelegateIdle::~AsyncPixelTransferDelegateIdle() {
109 }
110
111 AsyncPixelTransferState*
112 AsyncPixelTransferDelegateIdle::CreateRawPixelTransferState(
113 GLuint texture_id,
114 const AsyncTexImage2DParams& define_params) {
115 return static_cast<AsyncPixelTransferState*>(
116 new AsyncPixelTransferStateIdle(texture_id));
117 }
118
119 bool AsyncPixelTransferDelegateIdle::BindCompletedAsyncTransfers() {
120 // Everything is already bound.
121 return false;
122 }
123
124 void AsyncPixelTransferDelegateIdle::AsyncNotifyCompletion(
125 const AsyncMemoryParams& mem_params,
126 const CompletionCallback& callback) {
127 if (transfers_.empty()) {
128 callback.Run(mem_params);
129 return;
130 }
131
132 transfers_.back().notifications.push(
133 base::Bind(
134 &AsyncPixelTransferDelegateIdle::PerformNotifyCompletion,
135 AsWeakPtr(),
136 mem_params,
137 base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
138 mem_params.shared_memory,
139 mem_params.shm_size)),
140 callback));
141 }
142
143 void AsyncPixelTransferDelegateIdle::AsyncTexImage2D(
144 AsyncPixelTransferState* transfer_state,
145 const AsyncTexImage2DParams& tex_params,
146 const AsyncMemoryParams& mem_params,
147 const base::Closure& bind_callback) {
148 AsyncPixelTransferStateIdle* state =
149 static_cast<AsyncPixelTransferStateIdle*>(transfer_state);
150 DCHECK(mem_params.shared_memory);
151 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
152 mem_params.shm_size);
153 DCHECK(state);
154
155 transfers_.push_back(
156 Transfer(
157 state->id(),
158 base::Bind(
159 &AsyncPixelTransferStateIdle::PerformTransfer,
160 base::AsWeakPtr(state),
161 base::Bind(
162 &AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D,
163 AsWeakPtr(),
164 tex_params,
165 mem_params,
166 bind_callback,
167 base::Owned(new ScopedSafeSharedMemory(
168 safe_shared_memory_pool(),
169 mem_params.shared_memory,
170 mem_params.shm_size))))));
171
172 state->set_transfer_in_progress(true);
173 }
174
175 void AsyncPixelTransferDelegateIdle::AsyncTexSubImage2D(
176 AsyncPixelTransferState* transfer_state,
177 const AsyncTexSubImage2DParams& tex_params,
178 const AsyncMemoryParams& mem_params) {
179 AsyncPixelTransferStateIdle* state =
180 static_cast<AsyncPixelTransferStateIdle*>(transfer_state);
181 DCHECK(mem_params.shared_memory);
182 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
183 mem_params.shm_size);
184 DCHECK(state);
185
186 transfers_.push_back(
187 Transfer(
188 state->id(),
189 base::Bind(
190 &AsyncPixelTransferStateIdle::PerformTransfer,
191 base::AsWeakPtr(state),
192 base::Bind(
193 &AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D,
194 AsWeakPtr(),
195 tex_params,
196 mem_params,
197 base::Owned(new ScopedSafeSharedMemory(
198 safe_shared_memory_pool(),
199 mem_params.shared_memory,
200 mem_params.shm_size))))));
201
202 state->set_transfer_in_progress(true);
203 }
204
205 void AsyncPixelTransferDelegateIdle::WaitForTransferCompletion(
206 AsyncPixelTransferState* transfer_state) {
207 AsyncPixelTransferStateIdle* state =
208 static_cast<AsyncPixelTransferStateIdle*>(transfer_state);
209 DCHECK(state);
210
211 for (std::list<Transfer>::iterator iter = transfers_.begin();
212 iter != transfers_.end(); ++iter) {
213 if (iter->id != state->id())
214 continue;
215
216 ProcessTransfer(*iter);
217 transfers_.erase(iter);
218 break;
219 }
220 }
221
222 uint32 AsyncPixelTransferDelegateIdle::GetTextureUploadCount() {
223 return texture_upload_count_;
224 }
225
226 base::TimeDelta AsyncPixelTransferDelegateIdle::GetTotalTextureUploadTime() {
227 return total_texture_upload_time_;
228 }
229
230 bool AsyncPixelTransferDelegateIdle::ProcessMorePendingTransfers() {
231 if (transfers_.empty())
232 return false;
233
234 ProcessTransfer(transfers_.front());
235 transfers_.pop_front();
236 return true;
237 }
238
239 bool AsyncPixelTransferDelegateIdle::NeedsProcessMorePendingTransfers() {
240 return !transfers_.empty();
241 }
242
243 void AsyncPixelTransferDelegateIdle::ProcessTransfer(Transfer& transfer) {
244 transfer.task.Run();
245 while (!transfer.notifications.empty()) {
246 transfer.notifications.front().Run();
247 transfer.notifications.pop();
248 }
249 }
250
251 void AsyncPixelTransferDelegateIdle::PerformNotifyCompletion(
252 AsyncMemoryParams mem_params,
253 ScopedSafeSharedMemory* safe_shared_memory,
254 const CompletionCallback& callback) {
255 TRACE_EVENT0("gpu", "PerformNotifyCompletion");
256 gfx::AsyncMemoryParams safe_mem_params = mem_params;
257 safe_mem_params.shared_memory = safe_shared_memory->shared_memory();
258 callback.Run(safe_mem_params);
259 }
260
261 void AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D(
262 AsyncTexImage2DParams tex_params,
263 AsyncMemoryParams mem_params,
264 const base::Closure& bind_callback,
265 ScopedSafeSharedMemory* safe_shared_memory,
266 GLuint texture_id) {
267 TRACE_EVENT2("gpu", "PerformAsyncTexImage2D",
268 "width", tex_params.width,
269 "height", tex_params.height);
270 DCHECK_EQ(0, tex_params.level);
271
272 void* data = GetAddress(safe_shared_memory->shared_memory(),
273 mem_params.shm_data_offset);
274
275 glActiveTexture(GL_TEXTURE0);
276 glBindTexture(GL_TEXTURE_2D, texture_id);
277
278 {
279 TRACE_EVENT0("gpu", "glTexImage2D");
280 glTexImage2D(
281 tex_params.target,
282 tex_params.level,
283 tex_params.internal_format,
284 tex_params.width,
285 tex_params.height,
286 tex_params.border,
287 tex_params.format,
288 tex_params.type,
289 data);
290 }
291
292 // The texture is already fully bound so just call it now.
293 bind_callback.Run();
294 }
295
296 void AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D(
297 AsyncTexSubImage2DParams tex_params,
298 AsyncMemoryParams mem_params,
299 ScopedSafeSharedMemory* safe_shared_memory,
300 GLuint texture_id) {
301 TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D",
302 "width", tex_params.width,
303 "height", tex_params.height);
304 DCHECK_EQ(0, tex_params.level);
305
306 void* data = GetAddress(safe_shared_memory->shared_memory(),
307 mem_params.shm_data_offset);
308
309 base::TimeTicks begin_time(base::TimeTicks::HighResNow());
310 glActiveTexture(GL_TEXTURE0);
311 glBindTexture(GL_TEXTURE_2D, texture_id);
312
313 {
314 TRACE_EVENT0("gpu", "glTexSubImage2D");
315 glTexSubImage2D(
316 GL_TEXTURE_2D,
317 tex_params.level,
318 tex_params.xoffset,
319 tex_params.yoffset,
320 tex_params.width,
321 tex_params.height,
322 tex_params.format,
323 tex_params.type,
324 data);
325 }
326
327 texture_upload_count_++;
328 total_texture_upload_time_ += base::TimeTicks::HighResNow() - begin_time;
329 }
330
331 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698