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: content/common/gpu/client/gl_helper.cc

Issue 12892005: Implement client side PBOs for glReadPixel (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: make GLHelper constructor explicit Created 7 years, 8 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 | « content/common/gpu/client/gl_helper.h ('k') | gpu/GLES2/gl2extchromium.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
5 #include "content/common/gpu/client/gl_helper.h" 5 #include "content/common/gpu/client/gl_helper.h"
6 6
7 #include <queue> 7 #include <queue>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/trace_event.h"
10 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/message_loop.h" 13 #include "base/message_loop.h"
14 #include "base/synchronization/lock.h" 14 #include "base/time.h"
15 #include "base/synchronization/waitable_event.h"
16 #include "base/threading/thread.h"
17 #include "base/threading/thread_restrictions.h"
18 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h" 15 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
19 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" 16 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
20 #include "third_party/skia/include/core/SkRegion.h" 17 #include "third_party/skia/include/core/SkRegion.h"
21 #include "ui/gfx/rect.h" 18 #include "ui/gfx/rect.h"
22 #include "ui/gfx/size.h" 19 #include "ui/gfx/size.h"
23 #include "ui/gl/gl_bindings.h" 20 #include "ui/gl/gl_bindings.h"
24 21
25 using WebKit::WebGLId; 22 using WebKit::WebGLId;
26 using WebKit::WebGraphicsContext3D; 23 using WebKit::WebGraphicsContext3D;
27 24
28 namespace { 25 namespace {
29 26
30 const char kGLHelperThreadName[] = "GLHelperThread";
31
32 class GLHelperThread : public base::Thread {
33 public:
34 GLHelperThread() : base::Thread(kGLHelperThreadName) {
35 Start();
36 }
37 virtual ~GLHelperThread() {
38 Stop();
39 }
40
41 private:
42 DISALLOW_COPY_AND_ASSIGN(GLHelperThread);
43 };
44
45 base::LazyInstance<GLHelperThread> g_gl_helper_thread =
46 LAZY_INSTANCE_INITIALIZER;
47
48 class ScopedWebGLId { 27 class ScopedWebGLId {
49 public: 28 public:
50 typedef void (WebGraphicsContext3D::*DeleteFunc)(WebGLId); 29 typedef void (WebGraphicsContext3D::*DeleteFunc)(WebGLId);
51 ScopedWebGLId(WebGraphicsContext3D* context, 30 ScopedWebGLId(WebGraphicsContext3D* context,
52 WebGLId id, 31 WebGLId id,
53 DeleteFunc delete_func) 32 DeleteFunc delete_func)
54 : context_(context), 33 : context_(context),
55 id_(id), 34 id_(id),
56 delete_func_(delete_func) { 35 delete_func_(delete_func) {
57 } 36 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 71
93 class ScopedFramebuffer : public ScopedWebGLId { 72 class ScopedFramebuffer : public ScopedWebGLId {
94 public: 73 public:
95 ScopedFramebuffer(WebGraphicsContext3D* context, 74 ScopedFramebuffer(WebGraphicsContext3D* context,
96 WebGLId id) 75 WebGLId id)
97 : ScopedWebGLId(context, 76 : ScopedWebGLId(context,
98 id, 77 id,
99 &WebGraphicsContext3D::deleteFramebuffer) {} 78 &WebGraphicsContext3D::deleteFramebuffer) {}
100 }; 79 };
101 80
102 class ScopedRenderbuffer : public ScopedWebGLId {
103 public:
104 ScopedRenderbuffer(WebGraphicsContext3D* context,
105 WebGLId id)
106 : ScopedWebGLId(context,
107 id,
108 &WebGraphicsContext3D::deleteRenderbuffer) {}
109 };
110
111 class ScopedProgram : public ScopedWebGLId { 81 class ScopedProgram : public ScopedWebGLId {
112 public: 82 public:
113 ScopedProgram(WebGraphicsContext3D* context, 83 ScopedProgram(WebGraphicsContext3D* context,
114 WebGLId id) 84 WebGLId id)
115 : ScopedWebGLId(context, 85 : ScopedWebGLId(context,
116 id, 86 id,
117 &WebGraphicsContext3D::deleteProgram) {} 87 &WebGraphicsContext3D::deleteProgram) {}
118 }; 88 };
119 89
120 class ScopedShader : public ScopedWebGLId { 90 class ScopedShader : public ScopedWebGLId {
(...skipping 16 matching lines...) Expand all
137 107
138 template <WebKit::WGC3Denum target> 108 template <WebKit::WGC3Denum target>
139 class ScopedBinder { 109 class ScopedBinder {
140 public: 110 public:
141 typedef void (WebGraphicsContext3D::*BindFunc)(WebKit::WGC3Denum, 111 typedef void (WebGraphicsContext3D::*BindFunc)(WebKit::WGC3Denum,
142 WebGLId); 112 WebGLId);
143 ScopedBinder(WebGraphicsContext3D* context, 113 ScopedBinder(WebGraphicsContext3D* context,
144 WebGLId id, 114 WebGLId id,
145 BindFunc bind_func) 115 BindFunc bind_func)
146 : context_(context), 116 : context_(context),
147 id_(id),
148 bind_func_(bind_func) { 117 bind_func_(bind_func) {
149 (context_->*bind_func_)(target, id_); 118 (context_->*bind_func_)(target, id);
150 } 119 }
151 120
152 virtual ~ScopedBinder() { 121 virtual ~ScopedBinder() {
153 if (id_ != 0) 122 (context_->*bind_func_)(target, 0);
154 (context_->*bind_func_)(target, 0);
155 } 123 }
156 124
157 private: 125 private:
158 WebGraphicsContext3D* context_; 126 WebGraphicsContext3D* context_;
159 WebGLId id_;
160 BindFunc bind_func_; 127 BindFunc bind_func_;
161 128
162 DISALLOW_COPY_AND_ASSIGN(ScopedBinder); 129 DISALLOW_COPY_AND_ASSIGN(ScopedBinder);
163 }; 130 };
164 131
165 template <WebKit::WGC3Denum target> 132 template <WebKit::WGC3Denum target>
166 class ScopedBufferBinder : ScopedBinder<target> { 133 class ScopedBufferBinder : ScopedBinder<target> {
167 public: 134 public:
168 ScopedBufferBinder(WebGraphicsContext3D* context, 135 ScopedBufferBinder(WebGraphicsContext3D* context,
169 WebGLId id) 136 WebGLId id)
170 : ScopedBinder<target>( 137 : ScopedBinder<target>(
171 context, 138 context,
172 id, 139 id,
173 &WebGraphicsContext3D::bindBuffer) {} 140 &WebGraphicsContext3D::bindBuffer) {}
174 }; 141 };
175 142
176 template <WebKit::WGC3Denum target> 143 template <WebKit::WGC3Denum target>
177 class ScopedFramebufferBinder : ScopedBinder<target> { 144 class ScopedFramebufferBinder : ScopedBinder<target> {
178 public: 145 public:
179 ScopedFramebufferBinder(WebGraphicsContext3D* context, 146 ScopedFramebufferBinder(WebGraphicsContext3D* context,
180 WebGLId id) 147 WebGLId id)
181 : ScopedBinder<target>( 148 : ScopedBinder<target>(
182 context, 149 context,
183 id, 150 id,
184 &WebGraphicsContext3D::bindFramebuffer) {} 151 &WebGraphicsContext3D::bindFramebuffer) {}
185 }; 152 };
186 153
187 template <WebKit::WGC3Denum target> 154 template <WebKit::WGC3Denum target>
188 class ScopedRenderbufferBinder : ScopedBinder<target> {
189 public:
190 ScopedRenderbufferBinder(WebGraphicsContext3D* context,
191 WebGLId id)
192 : ScopedBinder<target>(
193 context,
194 id,
195 &WebGraphicsContext3D::bindRenderbuffer) {}
196 };
197
198 template <WebKit::WGC3Denum target>
199 class ScopedTextureBinder : ScopedBinder<target> { 155 class ScopedTextureBinder : ScopedBinder<target> {
200 public: 156 public:
201 ScopedTextureBinder(WebGraphicsContext3D* context, 157 ScopedTextureBinder(WebGraphicsContext3D* context,
202 WebGLId id) 158 WebGLId id)
203 : ScopedBinder<target>( 159 : ScopedBinder<target>(
204 context, 160 context,
205 id, 161 id,
206 &WebGraphicsContext3D::bindTexture) {} 162 &WebGraphicsContext3D::bindTexture) {}
207 }; 163 };
208 164
209 class ScopedFlush { 165 class ScopedFlush {
210 public: 166 public:
211 explicit ScopedFlush(WebGraphicsContext3D* context) 167 explicit ScopedFlush(WebGraphicsContext3D* context)
212 : context_(context) { 168 : context_(context) {
213 } 169 }
214 170
215 virtual ~ScopedFlush() { 171 virtual ~ScopedFlush() {
216 context_->flush(); 172 context_->flush();
217 } 173 }
218 174
219 private: 175 private:
220 WebGraphicsContext3D* context_; 176 WebGraphicsContext3D* context_;
221 177
222 DISALLOW_COPY_AND_ASSIGN(ScopedFlush); 178 DISALLOW_COPY_AND_ASSIGN(ScopedFlush);
223 }; 179 };
224 180
225 void DeleteContext(WebGraphicsContext3D* context) {
226 delete context;
227 }
228
229 void SignalWaitableEvent(base::WaitableEvent* event) {
230 event->Signal();
231 }
232
233 } // namespace 181 } // namespace
234 182
235 namespace content { 183 namespace content {
236 184
237 // Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates the 185 // Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates the
238 // data needed for it. 186 // data needed for it.
239 class GLHelper::CopyTextureToImpl { 187 class GLHelper::CopyTextureToImpl :
188 public base::SupportsWeakPtr<GLHelper::CopyTextureToImpl> {
240 public: 189 public:
241 CopyTextureToImpl(WebGraphicsContext3D* context, 190 CopyTextureToImpl(WebGraphicsContext3DCommandBufferImpl* context,
242 WebGraphicsContext3D* context_for_thread,
243 GLHelper* helper) 191 GLHelper* helper)
244 : context_(context), 192 : context_(context),
245 context_for_thread_(context_for_thread),
246 helper_(helper), 193 helper_(helper),
247 flush_(context), 194 flush_(context),
248 program_(context, context->createProgram()), 195 program_(context, context->createProgram()),
249 vertex_attributes_buffer_(context_, context_->createBuffer()), 196 vertex_attributes_buffer_(context_, context_->createBuffer()),
250 flipped_vertex_attributes_buffer_(context_, context_->createBuffer()) { 197 flipped_vertex_attributes_buffer_(context_, context_->createBuffer()) {
251 InitBuffer(); 198 InitBuffer();
252 InitProgram(); 199 InitProgram();
253 } 200 }
254 ~CopyTextureToImpl() { 201 ~CopyTextureToImpl() {
255 CancelRequests(); 202 CancelRequests();
256 DeleteContextForThread();
257 } 203 }
258 204
259 void InitBuffer(); 205 void InitBuffer();
260 void InitProgram(); 206 void InitProgram();
261 207
262 void CropScaleReadbackAndCleanTexture( 208 void CropScaleReadbackAndCleanTexture(
263 WebGLId src_texture, 209 WebGLId src_texture,
264 const gfx::Size& src_size, 210 const gfx::Size& src_size,
265 const gfx::Rect& src_subrect, 211 const gfx::Rect& src_subrect,
266 const gfx::Size& dst_size, 212 const gfx::Size& dst_size,
267 unsigned char* out, 213 unsigned char* out,
268 const base::Callback<void(bool)>& callback); 214 const base::Callback<void(bool)>& callback);
269 215
270 void ReadbackTextureSync(WebGLId texture, 216 void ReadbackTextureSync(WebGLId texture,
271 const gfx::Rect& src_rect, 217 const gfx::Rect& src_rect,
272 unsigned char* out); 218 unsigned char* out);
273 219
274 WebKit::WebGLId CopyAndScaleTexture(WebGLId texture, 220 WebKit::WebGLId CopyAndScaleTexture(WebGLId texture,
275 const gfx::Size& src_size, 221 const gfx::Size& src_size,
276 const gfx::Size& dst_size, 222 const gfx::Size& dst_size,
277 bool vertically_flip_texture); 223 bool vertically_flip_texture);
278 224
279 private: 225 private:
280 // A single request to CropScaleReadbackAndCleanTexture. 226 // A single request to CropScaleReadbackAndCleanTexture.
281 // Thread-safety notes: the main thread creates instances of this class. The 227 // The main thread can cancel the request, before it's handled by the helper
282 // main thread can cancel the request, before it's handled by the helper
283 // thread, by resetting the texture and pixels fields. Alternatively, the 228 // thread, by resetting the texture and pixels fields. Alternatively, the
284 // thread marks that it handles the request by resetting the pixels field 229 // thread marks that it handles the request by resetting the pixels field
285 // (meaning it guarantees that the callback with be called). 230 // (meaning it guarantees that the callback with be called).
286 // In either case, the callback must be called exactly once, and the texture 231 // In either case, the callback must be called exactly once, and the texture
287 // must be deleted by the main thread context. 232 // must be deleted by the main thread context.
288 struct Request : public base::RefCountedThreadSafe<Request> { 233 struct Request {
289 Request(CopyTextureToImpl* impl, 234 Request(WebGLId texture_,
290 WebGLId texture_,
291 const gfx::Size& size_, 235 const gfx::Size& size_,
292 unsigned char* pixels_, 236 unsigned char* pixels_,
293 const base::Callback<void(bool)>& callback_) 237 const base::Callback<void(bool)>& callback_)
294 : copy_texture_impl(impl), 238 : size(size_),
295 size(size_), 239 callback(callback_),
296 callback(callback_), 240 texture(texture_),
297 lock(), 241 pixels(pixels_),
298 texture(texture_), 242 buffer(0) {
299 pixels(pixels_) {
300 } 243 }
301 244
302 // These members are only accessed on the main thread.
303 GLHelper::CopyTextureToImpl* copy_texture_impl;
304 gfx::Size size; 245 gfx::Size size;
305 base::Callback<void(bool)> callback; 246 base::Callback<void(bool)> callback;
306 247
307 // Locks access to below members, which can be accessed on any thread.
308 base::Lock lock;
309 WebGLId texture; 248 WebGLId texture;
310 unsigned char* pixels; 249 unsigned char* pixels;
311 250 GLuint buffer;
312 private:
313 friend class base::RefCountedThreadSafe<Request>;
314 ~Request() {}
315 }; 251 };
316 252
317 // Copies the block of pixels specified with |src_subrect| from |src_texture|, 253 // Copies the block of pixels specified with |src_subrect| from |src_texture|,
318 // scales it to |dst_size|, writes it into a texture, and returns its ID. 254 // scales it to |dst_size|, writes it into a texture, and returns its ID.
319 // |src_size| is the size of |src_texture|. 255 // |src_size| is the size of |src_texture|.
320 WebGLId ScaleTexture(WebGLId src_texture, 256 WebGLId ScaleTexture(WebGLId src_texture,
321 const gfx::Size& src_size, 257 const gfx::Size& src_size,
322 const gfx::Rect& src_subrect, 258 const gfx::Rect& src_subrect,
323 const gfx::Size& dst_size, 259 const gfx::Size& dst_size,
324 bool vertically_flip_texture); 260 bool vertically_flip_texture);
325 261
326 // Deletes the context for GLHelperThread. 262 void ReadbackDone(Request* request);
327 void DeleteContextForThread(); 263 void FinishRequest(Request* request, bool result);
328 static void ReadBackFramebuffer(scoped_refptr<Request> request,
329 WebGraphicsContext3D* context,
330 scoped_refptr<base::TaskRunner> reply_loop);
331 static void ReadBackFramebufferComplete(scoped_refptr<Request> request,
332 bool result);
333 void FinishRequest(scoped_refptr<Request> request);
334 void CancelRequests(); 264 void CancelRequests();
335 265
336 // Interleaved array of 2-dimentional vertex positions (x, y) and 266 // Interleaved array of 2-dimentional vertex positions (x, y) and
337 // 2-dimentional texture coordinates (s, t). 267 // 2-dimentional texture coordinates (s, t).
338 static const WebKit::WGC3Dfloat kVertexAttributes[]; 268 static const WebKit::WGC3Dfloat kVertexAttributes[];
339 // Interleaved array of 2-dimensional vertex positions (x, y) and 269 // Interleaved array of 2-dimensional vertex positions (x, y) and
340 // 2 dimensional texture coordinates (s, t). 270 // 2 dimensional texture coordinates (s, t).
341 static const WebKit::WGC3Dfloat kFlippedVertexAttributes[]; 271 static const WebKit::WGC3Dfloat kFlippedVertexAttributes[];
342 // Shader sources used for GLHelper::CropScaleReadbackAndCleanTexture and 272 // Shader sources used for GLHelper::CropScaleReadbackAndCleanTexture and
343 // GLHelper::ReadbackTextureSync 273 // GLHelper::ReadbackTextureSync
344 static const WebKit::WGC3Dchar kCopyVertexShader[]; 274 static const WebKit::WGC3Dchar kCopyVertexShader[];
345 static const WebKit::WGC3Dchar kCopyFragmentShader[]; 275 static const WebKit::WGC3Dchar kCopyFragmentShader[];
346 276
347 WebGraphicsContext3D* context_; 277 WebGraphicsContext3DCommandBufferImpl* context_;
348 WebGraphicsContext3D* context_for_thread_;
349 GLHelper* helper_; 278 GLHelper* helper_;
350 279
351 // A scoped flush that will ensure all resource deletions are flushed when 280 // A scoped flush that will ensure all resource deletions are flushed when
352 // this object is destroyed. Must be declared before other Scoped* fields. 281 // this object is destroyed. Must be declared before other Scoped* fields.
353 ScopedFlush flush_; 282 ScopedFlush flush_;
354 // A program for copying a source texture into a destination texture. 283 // A program for copying a source texture into a destination texture.
355 ScopedProgram program_; 284 ScopedProgram program_;
356 // The buffer that holds the vertices and the texture coordinates data for 285 // The buffer that holds the vertices and the texture coordinates data for
357 // drawing a quad. 286 // drawing a quad.
358 ScopedBuffer vertex_attributes_buffer_; 287 ScopedBuffer vertex_attributes_buffer_;
359 ScopedBuffer flipped_vertex_attributes_buffer_; 288 ScopedBuffer flipped_vertex_attributes_buffer_;
360 289
361 // The location of the position in the program. 290 // The location of the position in the program.
362 WebKit::WGC3Dint position_location_; 291 WebKit::WGC3Dint position_location_;
363 // The location of the texture coordinate in the program. 292 // The location of the texture coordinate in the program.
364 WebKit::WGC3Dint texcoord_location_; 293 WebKit::WGC3Dint texcoord_location_;
365 // The location of the source texture in the program. 294 // The location of the source texture in the program.
366 WebKit::WGC3Dint texture_location_; 295 WebKit::WGC3Dint texture_location_;
367 // The location of the texture coordinate of the sub-rectangle in the program. 296 // The location of the texture coordinate of the sub-rectangle in the program.
368 WebKit::WGC3Dint src_subrect_location_; 297 WebKit::WGC3Dint src_subrect_location_;
369 std::queue<scoped_refptr<Request> > request_queue_; 298 std::queue<Request*> request_queue_;
370 }; 299 };
371 300
372 const WebKit::WGC3Dfloat GLHelper::CopyTextureToImpl::kVertexAttributes[] = { 301 const WebKit::WGC3Dfloat GLHelper::CopyTextureToImpl::kVertexAttributes[] = {
373 -1.0f, -1.0f, 0.0f, 0.0f, 302 -1.0f, -1.0f, 0.0f, 0.0f,
374 1.0f, -1.0f, 1.0f, 0.0f, 303 1.0f, -1.0f, 1.0f, 0.0f,
375 -1.0f, 1.0f, 0.0f, 1.0f, 304 -1.0f, 1.0f, 0.0f, 1.0f,
376 1.0f, 1.0f, 1.0f, 1.0f, 305 1.0f, 1.0f, 1.0f, 1.0f,
377 }; 306 };
378 307
379 const WebKit::WGC3Dfloat 308 const WebKit::WGC3Dfloat
380 GLHelper::CopyTextureToImpl::kFlippedVertexAttributes[] = { 309 GLHelper::CopyTextureToImpl::kFlippedVertexAttributes[] = {
381 -1.0f, -1.0f, 0.0f, 1.0f, 310 -1.0f, -1.0f, 0.0f, 1.0f,
382 1.0f, -1.0f, 1.0f, 1.0f, 311 1.0f, -1.0f, 1.0f, 1.0f,
383 -1.0f, 1.0f, 0.0f, 0.0f, 312 -1.0f, 1.0f, 0.0f, 0.0f,
384 1.0f, 1.0f, 1.0f, 0.0f, 313 1.0f, 1.0f, 1.0f, 0.0f,
385 }; 314 };
386 315
387 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyVertexShader[] = 316 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyVertexShader[] =
388 "attribute vec2 a_position;" 317 "attribute vec2 a_position;"
389 "attribute vec2 a_texcoord;" 318 "attribute vec2 a_texcoord;"
390 "varying vec2 v_texcoord;" 319 "varying vec2 v_texcoord;"
391 "uniform vec4 src_subrect;" 320 "uniform vec4 src_subrect;"
392 "void main() {" 321 "void main() {"
393 " gl_Position = vec4(a_position, 0.0, 1.0);" 322 " gl_Position = vec4(a_position, 0.0, 1.0);"
394 " v_texcoord = src_subrect.xy + a_texcoord * src_subrect.zw;" 323 " v_texcoord = src_subrect.xy + a_texcoord * src_subrect.zw;"
395 "}"; 324 "}";
396 325
326
327 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT
397 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] = 328 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] =
398 "precision mediump float;" 329 "precision mediump float;"
399 "varying vec2 v_texcoord;" 330 "varying vec2 v_texcoord;"
331 "uniform sampler2D s_texture;"
332 "void main() {"
333 " gl_FragColor = texture2D(s_texture, v_texcoord).bgra;"
334 "}";
335 #else
336 const WebKit::WGC3Dchar GLHelper::CopyTextureToImpl::kCopyFragmentShader[] =
337 "precision mediump float;"
338 "varying vec2 v_texcoord;"
400 "uniform sampler2D s_texture;" 339 "uniform sampler2D s_texture;"
401 "void main() {" 340 "void main() {"
402 " gl_FragColor = texture2D(s_texture, v_texcoord);" 341 " gl_FragColor = texture2D(s_texture, v_texcoord);"
403 "}"; 342 "}";
343 #endif
344
404 345
405 void GLHelper::CopyTextureToImpl::InitBuffer() { 346 void GLHelper::CopyTextureToImpl::InitBuffer() {
406 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder( 347 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(
407 context_, vertex_attributes_buffer_); 348 context_, vertex_attributes_buffer_);
408 context_->bufferData(GL_ARRAY_BUFFER, 349 context_->bufferData(GL_ARRAY_BUFFER,
409 sizeof(kVertexAttributes), 350 sizeof(kVertexAttributes),
410 kVertexAttributes, 351 kVertexAttributes,
411 GL_STATIC_DRAW); 352 GL_STATIC_DRAW);
412 ScopedBufferBinder<GL_ARRAY_BUFFER> flipped_buffer_binder( 353 ScopedBufferBinder<GL_ARRAY_BUFFER> flipped_buffer_binder(
413 context_, flipped_vertex_attributes_buffer_); 354 context_, flipped_vertex_attributes_buffer_);
(...skipping 30 matching lines...) Expand all
444 385
445 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( 386 WebGLId GLHelper::CopyTextureToImpl::ScaleTexture(
446 WebGLId src_texture, 387 WebGLId src_texture,
447 const gfx::Size& src_size, 388 const gfx::Size& src_size,
448 const gfx::Rect& src_subrect, 389 const gfx::Rect& src_subrect,
449 const gfx::Size& dst_size, 390 const gfx::Size& dst_size,
450 bool vertically_flip_texture) { 391 bool vertically_flip_texture) {
451 WebGLId dst_texture = context_->createTexture(); 392 WebGLId dst_texture = context_->createTexture();
452 { 393 {
453 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); 394 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
454 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( 395 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_,
455 context_, dst_framebuffer); 396 dst_framebuffer);
456 { 397 {
457 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder( 398 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, dst_texture);
458 context_, dst_texture);
459 context_->texImage2D(GL_TEXTURE_2D, 399 context_->texImage2D(GL_TEXTURE_2D,
460 0, 400 0,
461 GL_RGBA, 401 GL_RGBA,
462 dst_size.width(), 402 dst_size.width(),
463 dst_size.height(), 403 dst_size.height(),
464 0, 404 0,
465 GL_RGBA, 405 GL_RGBA,
466 GL_UNSIGNED_BYTE, 406 GL_UNSIGNED_BYTE,
467 NULL); 407 NULL);
468 context_->framebufferTexture2D(GL_FRAMEBUFFER, 408 context_->framebufferTexture2D(GL_FRAMEBUFFER,
469 GL_COLOR_ATTACHMENT0, 409 GL_COLOR_ATTACHMENT0,
470 GL_TEXTURE_2D, 410 GL_TEXTURE_2D,
471 dst_texture, 411 dst_texture,
472 0); 412 0);
473 } 413 }
474 414
475 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, src_texture); 415 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, src_texture);
476 WebKit::WebGLId vertex_attributes_buffer = vertically_flip_texture ? 416 WebKit::WebGLId vertex_attributes_buffer = vertically_flip_texture ?
477 flipped_vertex_attributes_buffer_ : vertex_attributes_buffer_; 417 flipped_vertex_attributes_buffer_ : vertex_attributes_buffer_;
478 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder( 418 ScopedBufferBinder<GL_ARRAY_BUFFER> buffer_binder(context_,
479 context_, vertex_attributes_buffer); 419 vertex_attributes_buffer);
480 420
481 context_->viewport(0, 0, dst_size.width(), dst_size.height()); 421 context_->viewport(0, 0, dst_size.width(), dst_size.height());
482 context_->useProgram(program_); 422 context_->useProgram(program_);
483 423
484 WebKit::WGC3Dintptr offset = 0; 424 WebKit::WGC3Dintptr offset = 0;
485 context_->vertexAttribPointer(position_location_, 425 context_->vertexAttribPointer(position_location_,
486 2, 426 2,
487 GL_FLOAT, 427 GL_FLOAT,
488 GL_FALSE, 428 GL_FALSE,
489 4 * sizeof(WebKit::WGC3Dfloat), 429 4 * sizeof(WebKit::WGC3Dfloat),
(...skipping 20 matching lines...) Expand all
510 }; 450 };
511 451
512 context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord); 452 context_->uniform4fv(src_subrect_location_, 1, src_subrect_texcoord);
513 453
514 // Conduct texture mapping by drawing a quad composed of two triangles. 454 // Conduct texture mapping by drawing a quad composed of two triangles.
515 context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4); 455 context_->drawArrays(GL_TRIANGLE_STRIP, 0, 4);
516 } 456 }
517 return dst_texture; 457 return dst_texture;
518 } 458 }
519 459
520 void GLHelper::CopyTextureToImpl::DeleteContextForThread() {
521 if (!context_for_thread_)
522 return;
523
524 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(
525 FROM_HERE,
526 base::Bind(&DeleteContext,
527 context_for_thread_));
528 context_for_thread_ = NULL;
529 }
530
531 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( 460 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture(
532 WebGLId src_texture, 461 WebGLId src_texture,
533 const gfx::Size& src_size, 462 const gfx::Size& src_size,
534 const gfx::Rect& src_subrect, 463 const gfx::Rect& src_subrect,
535 const gfx::Size& dst_size, 464 const gfx::Size& dst_size,
536 unsigned char* out, 465 unsigned char* out,
537 const base::Callback<void(bool)>& callback) { 466 const base::Callback<void(bool)>& callback) {
538 if (!context_for_thread_) {
539 callback.Run(false);
540 return;
541 }
542
543 WebGLId texture = ScaleTexture(src_texture, 467 WebGLId texture = ScaleTexture(src_texture,
544 src_size, 468 src_size,
545 src_subrect, 469 src_subrect,
546 dst_size, 470 dst_size,
547 false); 471 true);
548 context_->flush(); 472 context_->flush();
549 scoped_refptr<Request> request = 473 Request* request = new Request(texture, dst_size, out, callback);
550 new Request(this, texture, dst_size, out, callback);
551 request_queue_.push(request); 474 request_queue_.push(request);
552 475
553 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(FROM_HERE, 476 ScopedFlush flush(context_);
554 base::Bind(&ReadBackFramebuffer, 477 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
555 request, 478 gfx::Size size;
556 context_for_thread_, 479 size = request->size;
557 base::MessageLoopProxy::current())); 480
481 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_,
482 dst_framebuffer);
483 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, request->texture);
484 context_->framebufferTexture2D(GL_FRAMEBUFFER,
485 GL_COLOR_ATTACHMENT0,
486 GL_TEXTURE_2D,
487 request->texture,
488 0);
489 request->buffer = context_->createBuffer();
490 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
491 request->buffer);
492 context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
493 4 * size.GetArea(),
494 NULL,
495 GL_STREAM_READ);
496
497 context_->readPixels(0, 0, size.width(), size.height(),
498 GL_RGBA, GL_UNSIGNED_BYTE, 0);
499 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
500 context_->GetCommandBufferProxy()->SignalSyncPoint(
501 context_->insertSyncPoint(),
502 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), request));
558 } 503 }
559 504
560 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(WebGLId texture, 505 void GLHelper::CopyTextureToImpl::ReadbackTextureSync(WebGLId texture,
561 const gfx::Rect& src_rect, 506 const gfx::Rect& src_rect,
562 unsigned char* out) { 507 unsigned char* out) {
563 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); 508 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
564 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( 509 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_,
565 context_, dst_framebuffer); 510 dst_framebuffer);
566 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); 511 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture);
567 context_->framebufferTexture2D(GL_FRAMEBUFFER, 512 context_->framebufferTexture2D(GL_FRAMEBUFFER,
568 GL_COLOR_ATTACHMENT0, 513 GL_COLOR_ATTACHMENT0,
569 GL_TEXTURE_2D, 514 GL_TEXTURE_2D,
570 texture, 515 texture,
571 0); 516 0);
572 context_->readPixels(src_rect.x(), 517 context_->readPixels(src_rect.x(),
573 src_rect.y(), 518 src_rect.y(),
574 src_rect.width(), 519 src_rect.width(),
575 src_rect.height(), 520 src_rect.height(),
576 GL_RGBA, 521 GL_RGBA,
577 GL_UNSIGNED_BYTE, 522 GL_UNSIGNED_BYTE,
578 out); 523 out);
579 } 524 }
580 525
581 WebKit::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture( 526 WebKit::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture(
582 WebGLId src_texture, 527 WebGLId src_texture,
583 const gfx::Size& src_size, 528 const gfx::Size& src_size,
584 const gfx::Size& dst_size, 529 const gfx::Size& dst_size,
585 bool vertically_flip_texture) { 530 bool vertically_flip_texture) {
586 return ScaleTexture(src_texture, 531 return ScaleTexture(src_texture,
587 src_size, 532 src_size,
588 gfx::Rect(src_size), 533 gfx::Rect(src_size),
589 dst_size, 534 dst_size,
590 vertically_flip_texture); 535 vertically_flip_texture);
591 } 536 }
592 537
593 void GLHelper::CopyTextureToImpl::ReadBackFramebuffer( 538 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* request) {
594 scoped_refptr<Request> request, 539 TRACE_EVENT0("mirror",
595 WebGraphicsContext3D* context, 540 "GLHelper::CopyTextureToImpl::CheckReadBackFramebufferComplete");
596 scoped_refptr<base::TaskRunner> reply_loop) { 541 DCHECK(request == request_queue_.front());
597 DCHECK(context); 542
598 if (!context->makeContextCurrent() || context->isContextLost()) { 543 bool result = false;
599 base::AutoLock auto_lock(request->lock); 544 if (request->buffer != 0) {
600 if (request->pixels) { 545 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
601 // Only report failure if the request wasn't canceled (otherwise the 546 request->buffer);
602 // failure has already been reported). 547 void* data = context_->mapBufferCHROMIUM(
603 request->pixels = NULL; 548 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY);
604 reply_loop->PostTask( 549
605 FROM_HERE, base::Bind(ReadBackFramebufferComplete, request, false)); 550 if (data) {
551 result = true;
552 memcpy(request->pixels, data, request->size.GetArea() * 4);
553 context_->unmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM);
606 } 554 }
607 return; 555 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
608 } 556 }
609 ScopedFlush flush(context); 557
610 ScopedFramebuffer dst_framebuffer(context, context->createFramebuffer()); 558 FinishRequest(request, result);
611 unsigned char* pixels = NULL;
612 gfx::Size size;
613 {
614 // Note: We don't want to keep the lock while doing the readBack (since we
615 // don't want to block the UI thread). We rely on the fact that once the
616 // texture is bound to a FBO (that isn't current), deleting the texture is
617 // delayed until the FBO is deleted. We ensure ordering by flushing while
618 // the lock is held. Either the main thread cancelled before we get the
619 // lock, and we'll exit early, or we ensure that the texture is bound to the
620 // framebuffer before the main thread has a chance to delete it.
621 base::AutoLock auto_lock(request->lock);
622 if (!request->texture || !request->pixels)
623 return;
624 pixels = request->pixels;
625 request->pixels = NULL;
626 size = request->size;
627 {
628 ScopedFlush flush(context);
629 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(
630 context, dst_framebuffer);
631 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(
632 context, request->texture);
633 context->framebufferTexture2D(GL_FRAMEBUFFER,
634 GL_COLOR_ATTACHMENT0,
635 GL_TEXTURE_2D,
636 request->texture,
637 0);
638 }
639 }
640 bool result = context->readBackFramebuffer(
641 pixels,
642 4 * size.GetArea(),
643 dst_framebuffer.id(),
644 size.width(),
645 size.height());
646 reply_loop->PostTask(
647 FROM_HERE, base::Bind(ReadBackFramebufferComplete, request, result));
648 } 559 }
649 560
650 void GLHelper::CopyTextureToImpl::ReadBackFramebufferComplete( 561 void GLHelper::CopyTextureToImpl::FinishRequest(Request* request, bool result) {
651 scoped_refptr<Request> request, 562 DCHECK(request_queue_.front() == request);
652 bool result) { 563 request_queue_.pop();
653 request->callback.Run(result); 564 request->callback.Run(result);
654 if (request->copy_texture_impl) 565 ScopedFlush flush(context_);
655 request->copy_texture_impl->FinishRequest(request);
656 }
657
658 void GLHelper::CopyTextureToImpl::FinishRequest(
659 scoped_refptr<Request> request) {
660 CHECK(request_queue_.front() == request);
661 request_queue_.pop();
662 base::AutoLock auto_lock(request->lock);
663 if (request->texture != 0) { 566 if (request->texture != 0) {
664 context_->deleteTexture(request->texture); 567 context_->deleteTexture(request->texture);
665 request->texture = 0; 568 request->texture = 0;
666 context_->flush();
667 } 569 }
570 if (request->buffer != 0) {
571 context_->deleteBuffer(request->buffer);
572 request->buffer = 0;
573 }
574 delete request;
668 } 575 }
669 576
670 void GLHelper::CopyTextureToImpl::CancelRequests() { 577 void GLHelper::CopyTextureToImpl::CancelRequests() {
671 while (!request_queue_.empty()) { 578 while (!request_queue_.empty()) {
672 scoped_refptr<Request> request = request_queue_.front(); 579 Request* request = request_queue_.front();
673 request_queue_.pop(); 580 FinishRequest(request, false);
674 request->copy_texture_impl = NULL;
675 bool cancelled = false;
676 {
677 base::AutoLock auto_lock(request->lock);
678 if (request->texture != 0) {
679 context_->deleteTexture(request->texture);
680 request->texture = 0;
681 }
682 if (request->pixels != NULL) {
683 request->pixels = NULL;
684 cancelled = true;
685 }
686 }
687 if (cancelled)
688 request->callback.Run(false);
689 } 581 }
690 } 582 }
691 583
692 base::subtle::Atomic32 GLHelper::count_ = 0; 584 GLHelper::GLHelper(WebGraphicsContext3DCommandBufferImpl* context)
693 585 : context_(context) {
694 GLHelper::GLHelper(WebGraphicsContext3D* context,
695 WebGraphicsContext3D* context_for_thread)
696 : context_(context),
697 context_for_thread_(context_for_thread) {
698 base::subtle::NoBarrier_AtomicIncrement(&count_, 1);
699 } 586 }
700 587
701 GLHelper::~GLHelper() { 588 GLHelper::~GLHelper() {
702 DCHECK_NE(MessageLoop::current(),
703 g_gl_helper_thread.Pointer()->message_loop());
704 base::subtle::Atomic32 decremented_count =
705 base::subtle::NoBarrier_AtomicIncrement(&count_, -1);
706 if (decremented_count == 0) {
707 // When this is the last instance, we synchronize with the pending
708 // operations on GLHelperThread. Otherwise on shutdown we may kill the GPU
709 // process infrastructure (BrowserGpuChannelHostFactory) before they have
710 // a chance to complete, likely leading to a crash.
711 base::WaitableEvent event(false, false);
712 g_gl_helper_thread.Pointer()->message_loop_proxy()->PostTask(
713 FROM_HERE,
714 base::Bind(&SignalWaitableEvent,
715 &event));
716 // http://crbug.com/125415
717 base::ThreadRestrictions::ScopedAllowWait allow_wait;
718 event.Wait();
719 }
720 } 589 }
721 590
722 WebGraphicsContext3D* GLHelper::context() const { 591 WebGraphicsContext3DCommandBufferImpl* GLHelper::context() const {
723 return context_; 592 return context_;
724 } 593 }
725 594
726 void GLHelper::CropScaleReadbackAndCleanTexture( 595 void GLHelper::CropScaleReadbackAndCleanTexture(
727 WebGLId src_texture, 596 WebGLId src_texture,
728 const gfx::Size& src_size, 597 const gfx::Size& src_size,
729 const gfx::Rect& src_subrect, 598 const gfx::Rect& src_subrect,
730 const gfx::Size& dst_size, 599 const gfx::Size& dst_size,
731 unsigned char* out, 600 unsigned char* out,
732 const base::Callback<void(bool)>& callback) { 601 const base::Callback<void(bool)>& callback) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 if (!compile_status) { 648 if (!compile_status) {
780 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8()); 649 LOG(ERROR) << std::string(context_->getShaderInfoLog(shader).utf8());
781 return 0; 650 return 0;
782 } 651 }
783 return shader.Detach(); 652 return shader.Detach();
784 } 653 }
785 654
786 void GLHelper::InitCopyTextToImpl() { 655 void GLHelper::InitCopyTextToImpl() {
787 // Lazily initialize |copy_texture_to_impl_| 656 // Lazily initialize |copy_texture_to_impl_|
788 if (!copy_texture_to_impl_.get()) 657 if (!copy_texture_to_impl_.get())
789 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, 658 copy_texture_to_impl_.reset(new CopyTextureToImpl(context_, this));
790 context_for_thread_,
791 this));
792 } 659 }
793 660
794 void GLHelper::CopySubBufferDamage(WebKit::WebGLId texture, 661 void GLHelper::CopySubBufferDamage(WebKit::WebGLId texture,
795 WebKit::WebGLId previous_texture, 662 WebKit::WebGLId previous_texture,
796 const SkRegion& new_damage, 663 const SkRegion& new_damage,
797 const SkRegion& old_damage) { 664 const SkRegion& old_damage) {
798 SkRegion region(old_damage); 665 SkRegion region(old_damage);
799 if (region.op(new_damage, SkRegion::kDifference_Op)) { 666 if (region.op(new_damage, SkRegion::kDifference_Op)) {
800 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); 667 ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer());
801 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder( 668 ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_,
802 context_, dst_framebuffer); 669 dst_framebuffer);
803 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture); 670 ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, texture);
804 context_->framebufferTexture2D(GL_FRAMEBUFFER, 671 context_->framebufferTexture2D(GL_FRAMEBUFFER,
805 GL_COLOR_ATTACHMENT0, 672 GL_COLOR_ATTACHMENT0,
806 GL_TEXTURE_2D, 673 GL_TEXTURE_2D,
807 previous_texture, 674 previous_texture,
808 0); 675 0);
809 for (SkRegion::Iterator it(region); !it.done(); it.next()) { 676 for (SkRegion::Iterator it(region); !it.done(); it.next()) {
810 const SkIRect& rect = it.rect(); 677 const SkIRect& rect = it.rect();
811 context_->copyTexSubImage2D(GL_TEXTURE_2D, 0, 678 context_->copyTexSubImage2D(GL_TEXTURE_2D, 0,
812 rect.x(), rect.y(), 679 rect.x(), rect.y(),
813 rect.x(), rect.y(), 680 rect.x(), rect.y(),
814 rect.width(), rect.height()); 681 rect.width(), rect.height());
815 } 682 }
816 context_->flush(); 683 context_->flush();
817 } 684 }
818 } 685 }
819 686
820 } // namespace content 687 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/client/gl_helper.h ('k') | gpu/GLES2/gl2extchromium.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698