OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
epenner
2013/03/08 21:44:57
I've found it useful to have this 'no-op' stub aro
reveman
2013/03/12 00:31:42
How about _delegate_sync.cc and _delegate_idle.cc?
| |
5 #include "ui/gl/async_pixel_transfer_delegate_stub.h" | 5 #include "ui/gl/async_pixel_transfer_delegate_stub.h" |
6 | 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" | |
7 #include "base/shared_memory.h" | 12 #include "base/shared_memory.h" |
8 #include "build/build_config.h" | 13 #include "build/build_config.h" |
9 #include "ui/gl/gl_bindings.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" | |
10 | 19 |
11 using base::SharedMemory; | 20 using base::SharedMemory; |
12 using base::SharedMemoryHandle; | 21 using base::SharedMemoryHandle; |
13 | 22 |
23 namespace gfx { | |
24 | |
14 namespace { | 25 namespace { |
26 | |
15 // Gets the address of the data from shared memory. | 27 // Gets the address of the data from shared memory. |
16 void* GetAddress(SharedMemory* shared_memory, | 28 void* GetAddress(SharedMemory* shared_memory, uint32 shm_data_offset) { |
17 uint32 shm_size, | |
18 uint32 shm_data_offset, | |
19 uint32 shm_data_size) { | |
20 // Memory bounds have already been validated, so there | 29 // Memory bounds have already been validated, so there |
21 // is just DCHECKS here. | 30 // is just DCHECKS here. |
22 DCHECK(shared_memory); | 31 DCHECK(shared_memory); |
23 DCHECK(shared_memory->memory()); | 32 DCHECK(shared_memory->memory()); |
24 DCHECK_LE(shm_data_offset + shm_data_size, shm_size); | |
25 return static_cast<int8*>(shared_memory->memory()) + shm_data_offset; | 33 return static_cast<int8*>(shared_memory->memory()) + shm_data_offset; |
26 } | 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 | |
27 } // namespace | 43 } // namespace |
28 | 44 |
29 namespace gfx { | |
30 | |
31 #if !defined(OS_ANDROID) | 45 #if !defined(OS_ANDROID) |
32 scoped_ptr<AsyncPixelTransferDelegate> | 46 scoped_ptr<AsyncPixelTransferDelegate> |
33 AsyncPixelTransferDelegate::Create(gfx::GLContext* context) { | 47 AsyncPixelTransferDelegate::Create(gfx::GLContext* context) { |
34 return AsyncPixelTransferDelegateStub::Create(context); | 48 return AsyncPixelTransferDelegateStub::Create(context); |
35 } | 49 } |
36 #endif | 50 #endif |
37 | 51 |
38 scoped_ptr<AsyncPixelTransferDelegate> | 52 scoped_ptr<AsyncPixelTransferDelegate> |
39 AsyncPixelTransferDelegateStub::Create(gfx::GLContext* context) { | 53 AsyncPixelTransferDelegateStub::Create(gfx::GLContext* context) { |
40 return make_scoped_ptr( | 54 return make_scoped_ptr( |
41 static_cast<AsyncPixelTransferDelegate*>( | 55 static_cast<AsyncPixelTransferDelegate*>( |
42 new AsyncPixelTransferDelegateStub())); | 56 new AsyncPixelTransferDelegateStub())); |
43 } | 57 } |
44 | 58 |
45 AsyncTransferStateStub::AsyncTransferStateStub(GLuint texture_id) { | 59 // Class which holds async pixel transfers state. |
46 static const AsyncTexImage2DParams zero_params = {0, 0, 0, 0, 0, 0, 0, 0}; | 60 class TransferStateInternalStub |
47 late_bind_define_params_ = zero_params; | 61 : public base::RefCounted<TransferStateInternalStub> { |
48 needs_late_bind_ = false; | 62 public: |
63 explicit TransferStateInternalStub(GLuint texture_id) | |
64 : texture_id_(texture_id), | |
65 needs_late_bind_(false), | |
66 transfer_in_progress_(false) { | |
67 static const AsyncTexImage2DParams zero_params = {0, 0, 0, 0, 0, 0, 0, 0}; | |
greggman
2013/03/08 21:06:21
just fyi, you only need one 0, C++ will zero the r
| |
68 late_bind_define_params_ = zero_params; | |
69 } | |
70 | |
71 // Implement AsyncPixelTransferState: | |
72 bool TransferIsInProgress() { | |
73 return transfer_in_progress_; | |
74 } | |
75 | |
76 void BindTransfer(AsyncTexImage2DParams* bound_params) { | |
77 DCHECK(bound_params); | |
78 DCHECK(needs_late_bind_); | |
79 *bound_params = late_bind_define_params_; | |
80 needs_late_bind_ = false; | |
81 } | |
82 | |
83 protected: | |
84 friend class base::RefCounted<TransferStateInternalStub>; | |
85 friend class AsyncPixelTransferDelegateStub; | |
86 | |
87 virtual ~TransferStateInternalStub() {} | |
88 | |
89 GLuint texture_id_; | |
90 | |
91 // Just for book keeping. | |
92 bool needs_late_bind_; | |
93 | |
94 // Definition params for texture that needs binding. | |
95 AsyncTexImage2DParams late_bind_define_params_; | |
96 | |
97 // Indicates that an async transfer is in progress. | |
98 bool transfer_in_progress_; | |
99 }; | |
100 | |
101 // This just wraps an internal ref-counted state object. | |
102 class AsyncTransferStateStub : public AsyncPixelTransferState { | |
103 public: | |
104 explicit AsyncTransferStateStub(GLuint texture_id) | |
105 : internal_(new TransferStateInternalStub(texture_id)) { | |
106 } | |
107 virtual ~AsyncTransferStateStub() {} | |
108 virtual bool TransferIsInProgress() { | |
109 return internal_->TransferIsInProgress(); | |
110 } | |
111 virtual void BindTransfer(AsyncTexImage2DParams* bound_params) { | |
112 internal_->BindTransfer(bound_params); | |
113 } | |
114 scoped_refptr<TransferStateInternalStub> internal_; | |
115 }; | |
116 | |
117 AsyncPixelTransferDelegateStub::Transfer::Transfer( | |
118 TransferStateInternalStub* state, | |
119 const base::Closure& task) | |
120 : state(state), | |
121 task(task) { | |
49 } | 122 } |
50 | 123 |
51 AsyncTransferStateStub::~AsyncTransferStateStub() { | 124 AsyncPixelTransferDelegateStub::Transfer::~Transfer() {} |
52 } | |
53 | |
54 bool AsyncTransferStateStub::TransferIsInProgress() { | |
55 return false; | |
56 } | |
57 | |
58 void AsyncTransferStateStub::BindTransfer(AsyncTexImage2DParams* out_params) { | |
59 DCHECK(out_params); | |
60 DCHECK(needs_late_bind_); | |
61 *out_params = late_bind_define_params_; | |
62 needs_late_bind_ = false; | |
63 } | |
64 | 125 |
65 AsyncPixelTransferDelegateStub::AsyncPixelTransferDelegateStub() | 126 AsyncPixelTransferDelegateStub::AsyncPixelTransferDelegateStub() |
66 : texture_upload_count_(0) { | 127 : texture_upload_count_(0) { |
67 } | 128 } |
68 | 129 |
69 AsyncPixelTransferDelegateStub::~AsyncPixelTransferDelegateStub() { | 130 AsyncPixelTransferDelegateStub::~AsyncPixelTransferDelegateStub() { |
70 } | 131 } |
71 | 132 |
72 AsyncPixelTransferState* | 133 AsyncPixelTransferState* |
73 AsyncPixelTransferDelegateStub::CreateRawPixelTransferState( | 134 AsyncPixelTransferDelegateStub::CreateRawPixelTransferState( |
74 GLuint texture_id) { | 135 GLuint texture_id) { |
75 return static_cast<AsyncPixelTransferState*>( | 136 return static_cast<AsyncPixelTransferState*>( |
76 new AsyncTransferStateStub(texture_id)); | 137 new AsyncTransferStateStub(texture_id)); |
77 } | 138 } |
78 | 139 |
79 void AsyncPixelTransferDelegateStub::AsyncNotifyCompletion( | 140 void AsyncPixelTransferDelegateStub::AsyncNotifyCompletion( |
80 const AsyncMemoryParams& mem_params, | 141 const AsyncMemoryParams& mem_params, |
81 const CompletionCallback& callback) { | 142 const CompletionCallback& callback) { |
82 callback.Run(mem_params); | 143 if (transfers_.empty()) { |
144 callback.Run(mem_params); | |
145 return; | |
146 } | |
147 | |
148 transfers_.back().notifications.push( | |
149 base::Bind( | |
150 &AsyncPixelTransferDelegateStub::PerformNotifyCompletion, | |
151 AsWeakPtr(), | |
152 mem_params, | |
153 base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(), | |
154 mem_params.shared_memory, | |
155 mem_params.shm_size)), | |
156 callback)); | |
83 } | 157 } |
84 | 158 |
85 void AsyncPixelTransferDelegateStub::AsyncTexImage2D( | 159 void AsyncPixelTransferDelegateStub::AsyncTexImage2D( |
86 AsyncPixelTransferState* transfer_state, | 160 AsyncPixelTransferState* transfer_state, |
87 const AsyncTexImage2DParams& tex_params, | 161 const AsyncTexImage2DParams& tex_params, |
88 const AsyncMemoryParams& mem_params) { | 162 const AsyncMemoryParams& mem_params) { |
89 // Save the define params to return later during deferred | 163 scoped_refptr<TransferStateInternalStub> state = |
90 // binding of the transfer texture. | 164 static_cast<AsyncTransferStateStub*>(transfer_state)->internal_.get(); |
91 DCHECK(transfer_state); | 165 DCHECK(mem_params.shared_memory); |
92 AsyncTransferStateStub* state = | 166 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size, |
93 static_cast<AsyncTransferStateStub*>(transfer_state); | 167 mem_params.shm_size); |
94 // We don't actually need a late bind since this stub does | 168 DCHECK(state); |
95 // everything synchronously, but this tries to be similar | 169 DCHECK(state->texture_id_); |
96 // as an async implementation. | 170 DCHECK(!state->needs_late_bind_); |
171 | |
172 transfers_.push_back( | |
173 Transfer( | |
174 state.get(), | |
175 base::Bind( | |
176 &AsyncPixelTransferDelegateStub::PerformAsyncTexImage2D, | |
177 AsWeakPtr(), | |
178 state, | |
179 tex_params, | |
180 mem_params, | |
181 base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(), | |
182 mem_params.shared_memory, | |
183 mem_params.shm_size))))); | |
184 | |
97 state->needs_late_bind_ = true; | 185 state->needs_late_bind_ = true; |
98 state->late_bind_define_params_ = tex_params; | 186 state->late_bind_define_params_ = tex_params; |
99 void* data = GetAddress(mem_params.shared_memory, | 187 state->transfer_in_progress_ = true; |
100 mem_params.shm_size, | |
101 mem_params.shm_data_offset, | |
102 mem_params.shm_data_size); | |
103 glTexImage2D( | |
104 tex_params.target, | |
105 tex_params.level, | |
106 tex_params.internal_format, | |
107 tex_params.width, | |
108 tex_params.height, | |
109 tex_params.border, | |
110 tex_params.format, | |
111 tex_params.type, | |
112 data); | |
113 } | 188 } |
114 | 189 |
115 void AsyncPixelTransferDelegateStub::AsyncTexSubImage2D( | 190 void AsyncPixelTransferDelegateStub::AsyncTexSubImage2D( |
116 AsyncPixelTransferState* transfer_state, | 191 AsyncPixelTransferState* transfer_state, |
117 const AsyncTexSubImage2DParams& tex_params, | 192 const AsyncTexSubImage2DParams& tex_params, |
118 const AsyncMemoryParams& mem_params) { | 193 const AsyncMemoryParams& mem_params) { |
119 void* data = GetAddress(mem_params.shared_memory, | 194 scoped_refptr<TransferStateInternalStub> state = |
120 mem_params.shm_size, | 195 static_cast<AsyncTransferStateStub*>(transfer_state)->internal_.get(); |
121 mem_params.shm_data_offset, | 196 DCHECK(mem_params.shared_memory); |
122 mem_params.shm_data_size); | 197 DCHECK_LE(mem_params.shm_data_offset + mem_params.shm_data_size, |
123 DCHECK(transfer_state); | 198 mem_params.shm_size); |
124 AsyncTransferStateStub* state = | 199 DCHECK(state); |
125 static_cast<AsyncTransferStateStub*>(transfer_state); | 200 DCHECK(state->texture_id_); |
126 DCHECK(!state->needs_late_bind_); | 201 DCHECK(!state->needs_late_bind_); |
127 base::TimeTicks begin_time(base::TimeTicks::HighResNow()); | 202 |
128 glTexSubImage2D( | 203 transfers_.push_back( |
129 tex_params.target, | 204 Transfer( |
130 tex_params.level, | 205 state.get(), |
131 tex_params.xoffset, | 206 base::Bind( |
132 tex_params.yoffset, | 207 &AsyncPixelTransferDelegateStub::PerformAsyncTexSubImage2D, |
133 tex_params.width, | 208 AsWeakPtr(), |
134 tex_params.height, | 209 state, |
135 tex_params.format, | 210 tex_params, |
136 tex_params.type, | 211 mem_params, |
137 data); | 212 base::Owned(new ScopedSafeSharedMemory(safe_shared_memory_pool(), |
138 texture_upload_count_++; | 213 mem_params.shared_memory, |
139 total_texture_upload_time_ += base::TimeTicks::HighResNow() - begin_time; | 214 mem_params.shm_size))))); |
215 | |
216 state->transfer_in_progress_ = true; | |
140 } | 217 } |
141 | 218 |
142 void AsyncPixelTransferDelegateStub::WaitForTransferCompletion( | 219 void AsyncPixelTransferDelegateStub::WaitForTransferCompletion( |
143 AsyncPixelTransferState* state) { | 220 AsyncPixelTransferState* transfer_state) { |
144 // Already done. | 221 scoped_refptr<TransferStateInternalStub> state = |
222 static_cast<AsyncTransferStateStub*>(transfer_state)->internal_.get(); | |
223 | |
224 for (std::list<Transfer>::iterator iter = transfers_.begin(); | |
225 iter != transfers_.end(); ++iter) { | |
226 if (iter->state.get() != state) | |
227 continue; | |
228 | |
229 ProcessTransfer(*iter); | |
230 transfers_.erase(iter); | |
231 break; | |
232 } | |
145 } | 233 } |
146 | 234 |
147 uint32 AsyncPixelTransferDelegateStub::GetTextureUploadCount() { | 235 uint32 AsyncPixelTransferDelegateStub::GetTextureUploadCount() { |
148 return texture_upload_count_; | 236 return texture_upload_count_; |
149 } | 237 } |
150 | 238 |
151 base::TimeDelta AsyncPixelTransferDelegateStub::GetTotalTextureUploadTime() { | 239 base::TimeDelta AsyncPixelTransferDelegateStub::GetTotalTextureUploadTime() { |
152 return total_texture_upload_time_; | 240 return total_texture_upload_time_; |
153 } | 241 } |
154 | 242 |
243 void AsyncPixelTransferDelegateStub::ProcessPendingTransfers() { | |
244 if (transfers_.empty()) | |
245 return; | |
246 | |
247 ProcessTransfer(transfers_.front()); | |
248 transfers_.pop_front(); | |
249 } | |
250 | |
251 bool AsyncPixelTransferDelegateStub::CanProcessPendingTransfers() { | |
252 return !transfers_.empty(); | |
253 } | |
254 | |
255 void AsyncPixelTransferDelegateStub::ProcessTransfer(Transfer& transfer) { | |
256 transfer.task.Run(); | |
257 while (!transfer.notifications.empty()) { | |
258 transfer.notifications.front().Run(); | |
259 transfer.notifications.pop(); | |
260 } | |
261 } | |
262 | |
263 void AsyncPixelTransferDelegateStub::PerformNotifyCompletion( | |
264 AsyncMemoryParams mem_params, | |
265 ScopedSafeSharedMemory* safe_shared_memory, | |
266 const CompletionCallback& callback) { | |
267 TRACE_EVENT0("gpu", "PerformNotifyCompletion"); | |
268 gfx::AsyncMemoryParams safe_mem_params = mem_params; | |
269 safe_mem_params.shared_memory = safe_shared_memory->shared_memory(); | |
270 callback.Run(safe_mem_params); | |
271 } | |
272 | |
273 void AsyncPixelTransferDelegateStub::PerformAsyncTexImage2D( | |
274 scoped_refptr<TransferStateInternalStub> state, | |
275 AsyncTexImage2DParams tex_params, | |
276 AsyncMemoryParams mem_params, | |
277 ScopedSafeSharedMemory* safe_shared_memory) { | |
278 TRACE_EVENT2("gpu", "PerformAsyncTexImage2D", | |
279 "width", tex_params.width, | |
280 "height", tex_params.height); | |
281 DCHECK_EQ(0, tex_params.level); | |
282 | |
283 void* data = GetAddress(safe_shared_memory->shared_memory(), | |
284 mem_params.shm_data_offset); | |
285 | |
286 glActiveTexture(GL_TEXTURE0); | |
287 glBindTexture(GL_TEXTURE_2D, state->texture_id_); | |
288 | |
289 { | |
290 TRACE_EVENT0("gpu", "glTexImage2D"); | |
291 glTexImage2D( | |
292 tex_params.target, | |
293 tex_params.level, | |
294 tex_params.internal_format, | |
295 tex_params.width, | |
296 tex_params.height, | |
297 tex_params.border, | |
298 tex_params.format, | |
299 tex_params.type, | |
300 data); | |
301 } | |
302 | |
303 state->transfer_in_progress_ = false; | |
304 } | |
305 | |
306 void AsyncPixelTransferDelegateStub::PerformAsyncTexSubImage2D( | |
307 scoped_refptr<TransferStateInternalStub> state, | |
308 AsyncTexSubImage2DParams tex_params, | |
309 AsyncMemoryParams mem_params, | |
310 ScopedSafeSharedMemory* safe_shared_memory) { | |
311 TRACE_EVENT2("gpu", "PerformAsyncTexSubImage2D", | |
312 "width", tex_params.width, | |
313 "height", tex_params.height); | |
314 DCHECK_EQ(0, tex_params.level); | |
315 | |
316 void* data = GetAddress(safe_shared_memory->shared_memory(), | |
317 mem_params.shm_data_offset); | |
318 | |
319 base::TimeTicks begin_time(base::TimeTicks::HighResNow()); | |
320 glActiveTexture(GL_TEXTURE0); | |
321 glBindTexture(GL_TEXTURE_2D, state->texture_id_); | |
322 | |
323 { | |
324 TRACE_EVENT0("gpu", "glTexSubImage2D"); | |
325 glTexSubImage2D( | |
326 GL_TEXTURE_2D, | |
327 tex_params.level, | |
328 tex_params.xoffset, | |
329 tex_params.yoffset, | |
330 tex_params.width, | |
331 tex_params.height, | |
332 tex_params.format, | |
333 tex_params.type, | |
334 data); | |
335 } | |
336 | |
337 texture_upload_count_++; | |
338 total_texture_upload_time_ += base::TimeTicks::HighResNow() - begin_time; | |
339 | |
340 state->transfer_in_progress_ = false; | |
341 } | |
342 | |
155 } // namespace gfx | 343 } // namespace gfx |
156 | 344 |
OLD | NEW |