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

Side by Side Diff: content/common/gpu/client/gl_helper.cc

Issue 16831004: Perform glReadPixels with PBOs in the gpu, if PBOs are available. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: revert gl_in_process_context.cc, deal with out-of-order callbacks in gl_helper.cc Created 7 years, 5 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
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 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 // thread marks that it handles the request by resetting the pixels field 181 // thread marks that it handles the request by resetting the pixels field
182 // (meaning it guarantees that the callback with be called). 182 // (meaning it guarantees that the callback with be called).
183 // In either case, the callback must be called exactly once, and the texture 183 // In either case, the callback must be called exactly once, and the texture
184 // must be deleted by the main thread context. 184 // must be deleted by the main thread context.
185 struct Request { 185 struct Request {
186 Request(const gfx::Size& size_, 186 Request(const gfx::Size& size_,
187 int32 bytes_per_row_, 187 int32 bytes_per_row_,
188 int32 row_stride_bytes_, 188 int32 row_stride_bytes_,
189 unsigned char* pixels_, 189 unsigned char* pixels_,
190 const base::Callback<void(bool)>& callback_) 190 const base::Callback<void(bool)>& callback_)
191 : size(size_), 191 : done(false),
192 size(size_),
192 bytes_per_row(bytes_per_row_), 193 bytes_per_row(bytes_per_row_),
193 row_stride_bytes(row_stride_bytes_), 194 row_stride_bytes(row_stride_bytes_),
194 pixels(pixels_), 195 pixels(pixels_),
195 callback(callback_), 196 callback(callback_),
196 buffer(0) { 197 buffer(0),
198 query(0) {
197 } 199 }
198 200
201 bool done;
199 gfx::Size size; 202 gfx::Size size;
200 int bytes_per_row; 203 int bytes_per_row;
201 int row_stride_bytes; 204 int row_stride_bytes;
202 unsigned char* pixels; 205 unsigned char* pixels;
203 base::Callback<void(bool)> callback; 206 base::Callback<void(bool)> callback;
204 GLuint buffer; 207 GLuint buffer;
208 WebKit::WebGLId query;
205 }; 209 };
206 210
207 // A readback pipeline that also converts the data to YUV before 211 // A readback pipeline that also converts the data to YUV before
208 // reading it back. 212 // reading it back.
209 class ReadbackYUVImpl : public ReadbackYUVInterface { 213 class ReadbackYUVImpl : public ReadbackYUVInterface {
210 public: 214 public:
211 ReadbackYUVImpl(WebGraphicsContext3D* context, 215 ReadbackYUVImpl(WebGraphicsContext3D* context,
212 CopyTextureToImpl* copy_impl, 216 CopyTextureToImpl* copy_impl,
213 GLHelperScaling* scaler_impl, 217 GLHelperScaling* scaler_impl,
214 GLHelper::ScalerQuality quality, 218 GLHelper::ScalerQuality quality,
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 // |src_size| is the size of |src_texture|. 289 // |src_size| is the size of |src_texture|.
286 WebGLId ScaleTexture(WebGLId src_texture, 290 WebGLId ScaleTexture(WebGLId src_texture,
287 const gfx::Size& src_size, 291 const gfx::Size& src_size,
288 const gfx::Rect& src_subrect, 292 const gfx::Rect& src_subrect,
289 const gfx::Size& dst_size, 293 const gfx::Size& dst_size,
290 bool vertically_flip_texture, 294 bool vertically_flip_texture,
291 bool swizzle, 295 bool swizzle,
292 GLHelper::ScalerQuality quality); 296 GLHelper::ScalerQuality quality);
293 297
294 static void nullcallback(bool success) {} 298 static void nullcallback(bool success) {}
295 void ReadbackDone(Request* request); 299 void ReadbackDone(Request *request);
296 void FinishRequest(Request* request, bool result); 300 void FinishRequest(Request* request, bool result);
297 void CancelRequests(); 301 void CancelRequests();
298 302
299 static const float kRGBtoYColorWeights[]; 303 static const float kRGBtoYColorWeights[];
300 static const float kRGBtoUColorWeights[]; 304 static const float kRGBtoUColorWeights[];
301 static const float kRGBtoVColorWeights[]; 305 static const float kRGBtoVColorWeights[];
302 306
303 WebGraphicsContext3D* context_; 307 WebGraphicsContext3D* context_;
304 GLHelper* helper_; 308 GLHelper* helper_;
305 309
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 callback); 377 callback);
374 request_queue_.push(request); 378 request_queue_.push(request);
375 request->buffer = context_->createBuffer(); 379 request->buffer = context_->createBuffer();
376 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 380 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
377 request->buffer); 381 request->buffer);
378 context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 382 context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
379 4 * dst_size.GetArea(), 383 4 * dst_size.GetArea(),
380 NULL, 384 NULL,
381 GL_STREAM_READ); 385 GL_STREAM_READ);
382 386
387 request->query = context_->createQueryEXT();
388 context_->beginQueryEXT(GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM,
389 request->query);
383 context_->readPixels(0, 0, dst_size.width(), dst_size.height(), 390 context_->readPixels(0, 0, dst_size.width(), dst_size.height(),
384 GL_RGBA, GL_UNSIGNED_BYTE, NULL); 391 GL_RGBA, GL_UNSIGNED_BYTE, NULL);
392 context_->endQueryEXT(GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM);
385 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); 393 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
386 cc::SyncPointHelper::SignalSyncPoint( 394 cc::SyncPointHelper::SignalQuery(
387 context_, 395 context_,
388 context_->insertSyncPoint(), 396 request->query,
389 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), request)); 397 base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), request));
390 } 398 }
391 399
392 400
393 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( 401 void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture(
394 WebGLId src_texture, 402 WebGLId src_texture,
395 const gfx::Size& src_size, 403 const gfx::Size& src_size,
396 const gfx::Rect& src_subrect, 404 const gfx::Rect& src_subrect,
397 const gfx::Size& dst_size, 405 const gfx::Size& dst_size,
398 unsigned char* out, 406 unsigned char* out,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 gfx::Rect(src_size), 467 gfx::Rect(src_size),
460 dst_size, 468 dst_size,
461 vertically_flip_texture, 469 vertically_flip_texture,
462 false, 470 false,
463 quality); 471 quality);
464 } 472 }
465 473
466 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* request) { 474 void GLHelper::CopyTextureToImpl::ReadbackDone(Request* request) {
467 TRACE_EVENT0("mirror", 475 TRACE_EVENT0("mirror",
468 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); 476 "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete");
469 DCHECK(request == request_queue_.front()); 477 request->done = true;
470 478
471 bool result = false; 479 // We process transfer requests in the order they were received, regardless
472 if (request->buffer != 0) { 480 // of the order we get the callbacks in.
473 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 481 while (!request_queue_.empty()) {
474 request->buffer); 482 request = request_queue_.front();
piman 2013/07/01 22:24:08 nit: can we avoid hiding the method parameter? It
hubbe 2013/07/01 22:34:41 Done.
475 unsigned char* data = static_cast<unsigned char *>( 483 if (!request->done) break;
piman 2013/07/01 22:24:08 nit: break on next line
hubbe 2013/07/01 22:34:41 Done.
476 context_->mapBufferCHROMIUM( 484
477 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); 485 bool result = false;
478 if (data) { 486 if (request->buffer != 0) {
479 result = true; 487 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
480 if (request->bytes_per_row == request->size.width() * 4 && 488 request->buffer);
481 request->bytes_per_row == request->row_stride_bytes) { 489 unsigned char* data = static_cast<unsigned char *>(
482 memcpy(request->pixels, data, request->size.GetArea() * 4); 490 context_->mapBufferCHROMIUM(
483 } else { 491 GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY));
484 unsigned char* out = request->pixels; 492 if (data) {
485 for (int y = 0; y < request->size.height(); y++) { 493 result = true;
486 memcpy(out, data, request->bytes_per_row); 494 if (request->bytes_per_row == request->size.width() * 4 &&
487 out += request->row_stride_bytes; 495 request->bytes_per_row == request->row_stride_bytes) {
488 data += request->size.width() * 4; 496 memcpy(request->pixels, data, request->size.GetArea() * 4);
497 } else {
498 unsigned char* out = request->pixels;
499 for (int y = 0; y < request->size.height(); y++) {
500 memcpy(out, data, request->bytes_per_row);
501 out += request->row_stride_bytes;
502 data += request->size.width() * 4;
503 }
489 } 504 }
505 context_->unmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM);
490 } 506 }
491 context_->unmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); 507 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
492 } 508 }
493 context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); 509
510 FinishRequest(request, result);
494 } 511 }
495
496 FinishRequest(request, result);
497 } 512 }
498 513
499 void GLHelper::CopyTextureToImpl::FinishRequest(Request* request, 514 void GLHelper::CopyTextureToImpl::FinishRequest(Request* request,
500 bool result) { 515 bool result) {
516 TRACE_EVENT0("mirror", "GLHelper::CopyTextureToImpl::FinishRequest");
501 DCHECK(request_queue_.front() == request); 517 DCHECK(request_queue_.front() == request);
502 request_queue_.pop(); 518 request_queue_.pop();
503 request->callback.Run(result); 519 request->callback.Run(result);
504 ScopedFlush flush(context_); 520 ScopedFlush flush(context_);
521 if (request->query != 0) {
522 context_->deleteQueryEXT(request->query);
523 request->query = 0;
524 }
505 if (request->buffer != 0) { 525 if (request->buffer != 0) {
506 context_->deleteBuffer(request->buffer); 526 context_->deleteBuffer(request->buffer);
507 request->buffer = 0; 527 request->buffer = 0;
508 } 528 }
509 delete request; 529 delete request;
510 } 530 }
511 531
512 void GLHelper::CopyTextureToImpl::CancelRequests() { 532 void GLHelper::CopyTextureToImpl::CancelRequests() {
513 while (!request_queue_.empty()) { 533 while (!request_queue_.empty()) {
514 Request* request = request_queue_.front(); 534 Request* request = request_queue_.front();
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 quality, 980 quality,
961 src_size, 981 src_size,
962 src_subrect, 982 src_subrect,
963 dst_size, 983 dst_size,
964 dst_subrect, 984 dst_subrect,
965 flip_vertically, 985 flip_vertically,
966 use_mrt); 986 use_mrt);
967 } 987 }
968 988
969 } // namespace content 989 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698