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

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