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

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: Add DCHECKs to ensure idle async uploads are only used with GL_TEXTURE_2D target 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 // are 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) {
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 new AsyncPixelTransferStateIdle(texture_id);
116 }
117
118 bool AsyncPixelTransferDelegateIdle::BindCompletedAsyncTransfers() {
119 // Everything is already bound.
120 return false;
121 }
122
123 void AsyncPixelTransferDelegateIdle::AsyncNotifyCompletion(
124 const AsyncMemoryParams& mem_params,
125 const CompletionCallback& callback) {
126 if (transfers_.empty()) {
127 callback.Run(mem_params);
128 return;
129 }
130
131 transfers_.back().notifications.push(
132 base::Bind(
133 &AsyncPixelTransferDelegateIdle::PerformNotifyCompletion,
134 AsWeakPtr(),
135 mem_params,
136 base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(),
137 mem_params.shared_memory,
138 mem_params.shm_size)),
139 callback));
140 }
141
142 void AsyncPixelTransferDelegateIdle::AsyncTexImage2D(
143 AsyncPixelTransferState* transfer_state,
144 const AsyncTexImage2DParams& tex_params,
145 const AsyncMemoryParams& mem_params,
146 const base::Closure& bind_callback) {
147 AsyncPixelTransferStateIdle* state =
148 static_cast<AsyncPixelTransferStateIdle*>(transfer_state);
149 DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
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_EQ(static_cast<GLenum>(GL_TEXTURE_2D), tex_params.target);
182 DCHECK(mem_params.shared_memory);
183 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size,
184 mem_params.shm_size);
185 DCHECK(state);
186
187 transfers_.push_back(
188 Transfer(
189 state->id(),
190 base::Bind(
191 &AsyncPixelTransferStateIdle::PerformTransfer,
192 base::AsWeakPtr(state),
193 base::Bind(
194 &AsyncPixelTransferDelegateIdle::PerformAsyncTexSubImage2D,
195 AsWeakPtr(),
196 tex_params,
197 mem_params,
198 base::Owned(new ScopedSafeSharedMemory(
199 safe_shared_memory_pool(),
200 mem_params.shared_memory,
201 mem_params.shm_size))))));
202
203 state->set_transfer_in_progress(true);
204 }
205
206 void AsyncPixelTransferDelegateIdle::WaitForTransferCompletion(
207 AsyncPixelTransferState* transfer_state) {
208 AsyncPixelTransferStateIdle* state =
209 static_cast<AsyncPixelTransferStateIdle*>(transfer_state);
210 DCHECK(state);
211
212 for (std::list<Transfer>::iterator iter = transfers_.begin();
213 iter != transfers_.end(); ++iter) {
214 if (iter->id != state->id())
215 continue;
216
217 ProcessTransfer(*iter);
218 transfers_.erase(iter);
219 break;
220 }
221 }
222
223 uint32 AsyncPixelTransferDelegateIdle::GetTextureUploadCount() {
224 return texture_upload_count_;
225 }
226
227 base::TimeDelta AsyncPixelTransferDelegateIdle::GetTotalTextureUploadTime() {
228 return total_texture_upload_time_;
229 }
230
231 bool AsyncPixelTransferDelegateIdle::ProcessMorePendingTransfers() {
232 if (transfers_.empty())
233 return false;
234
235 ProcessTransfer(transfers_.front());
236 transfers_.pop_front();
237 return true;
238 }
239
240 bool AsyncPixelTransferDelegateIdle::NeedsProcessMorePendingTransfers() {
241 return !transfers_.empty();
242 }
243
244 void AsyncPixelTransferDelegateIdle::ProcessTransfer(Transfer& transfer) {
245 transfer.task.Run();
246 while (!transfer.notifications.empty()) {
247 transfer.notifications.front().Run();
248 transfer.notifications.pop();
249 }
250 }
251
252 void AsyncPixelTransferDelegateIdle::PerformNotifyCompletion(
253 AsyncMemoryParams mem_params,
254 ScopedSafeSharedMemory* safe_shared_memory,
255 const CompletionCallback& callback) {
256 TRACE_EVENT0("gpu", "PerformNotifyCompletion");
257 gfx::AsyncMemoryParams safe_mem_params = mem_params;
258 safe_mem_params.shared_memory = safe_shared_memory->shared_memory();
259 callback.Run(safe_mem_params);
260 }
261
262 void AsyncPixelTransferDelegateIdle::PerformAsyncTexImage2D(
263 AsyncTexImage2DParams tex_params,
264 AsyncMemoryParams mem_params,
265 const base::Closure& bind_callback,
266 ScopedSafeSharedMemory* safe_shared_memory,
267 GLuint texture_id) {
268 TRACE_EVENT2("gpu", "PerformAsyncTexImage2D",
269 "width", tex_params.width,
270 "height", tex_params.height);
271
272 void* data = GetAddress(safe_shared_memory->shared_memory(),
273 mem_params.shm_data_offset);
274
275 glBindTexture(tex_params.target, texture_id);
276
277 {
278 TRACE_EVENT0("gpu", "glTexImage2D");
279 glTexImage2D(
280 tex_params.target,
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
304 void* data = GetAddress(safe_shared_memory->shared_memory(),
305 mem_params.shm_data_offset);
306
307 base::TimeTicks begin_time(base::TimeTicks::HighResNow());
308 glBindTexture(tex_params.target, texture_id);
309
310 {
311 TRACE_EVENT0("gpu", "glTexSubImage2D");
312 glTexSubImage2D(
313 tex_params.target,
314 tex_params.level,
315 tex_params.xoffset,
316 tex_params.yoffset,
317 tex_params.width,
318 tex_params.height,
319 tex_params.format,
320 tex_params.type,
321 data);
322 }
323
324 texture_upload_count_++;
325 total_texture_upload_time_ += base::TimeTicks::HighResNow() - begin_time;
326 }
327
328 } // 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