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

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: Restore use of kHandleMoreWorkPeriodBusyMs and address review feedback 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
« no previous file with comments | « ui/gl/async_pixel_transfer_delegate_idle.h ('k') | ui/gl/async_pixel_transfer_delegate_stub.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
apatrick_chromium 2013/03/14 23:30:39 is -> are
reveman 2013/03/15 01:34:03 Done. Also fixed _android.cc and _stub.cc where th
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) {
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*>(
apatrick_chromium 2013/03/14 23:30:39 static_cast is redundant?
reveman 2013/03/15 01:34:03 Yes. Fixed _android.cc/_stub.cc too.
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 glBindTexture(GL_TEXTURE_2D, texture_id);
apatrick_chromium 2013/03/14 23:30:39 GL_TEXTURE_2D shouldn't be tex_params.target? Or i
reveman 2013/03/15 01:34:03 Good call. Fixed. _android.cc is limited to TEXTU
276
277 {
278 TRACE_EVENT0("gpu", "glTexImage2D");
279 glTexImage2D(
280 tex_params.target,
apatrick_chromium 2013/03/14 23:30:39 ... in which case this should be GL_TEXTURE_2D and
reveman 2013/03/15 01:34:03 Done.
281 tex_params.level,
282 tex_params.internal_format,
283 tex_params.width,
284 tex_params.height,
285 tex_params.border,
286 tex_params.format,
287 tex_params.type,
288 data);
289 }
290
291 // The texture is already fully bound so just call it now.
292 bind_callback.Run();
293 }
294
295 void AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D(
296 AsyncTexSubImage2DParams tex_params,
297 AsyncMemoryParams mem_params,
298 ScopedSafeSharedMemory* safe_shared_memory,
299 GLuint texture_id) {
300 TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D",
301 "width", tex_params.width,
302 "height", tex_params.height);
303 DCHECK_EQ(0, tex_params.level);
apatrick_chromium 2013/03/14 23:30:39 Same here.
reveman 2013/03/15 01:34:03 Done. No reason this should be limited to level=0.
304
305 void* data = GetAddress(safe_shared_memory->shared_memory(),
306 mem_params.shm_data_offset);
307
308 base::TimeTicks begin_time(base::TimeTicks::HighResNow());
309 glBindTexture(GL_TEXTURE_2D, texture_id);
310
311 {
312 TRACE_EVENT0("gpu", "glTexSubImage2D");
313 glTexSubImage2D(
314 GL_TEXTURE_2D,
315 tex_params.level,
316 tex_params.xoffset,
317 tex_params.yoffset,
318 tex_params.width,
319 tex_params.height,
320 tex_params.format,
321 tex_params.type,
322 data);
323 }
324
325 texture_upload_count_++;
326 total_texture_upload_time_ += base::TimeTicks::HighResNow() - begin_time;
327 }
328
329 } // namespace gfx
OLDNEW
« no previous file with comments | « ui/gl/async_pixel_transfer_delegate_idle.h ('k') | ui/gl/async_pixel_transfer_delegate_stub.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698