| Index: content/common/gpu/client/gl_helper.cc
|
| diff --git a/content/common/gpu/client/gl_helper.cc b/content/common/gpu/client/gl_helper.cc
|
| index 4bfd440755c45ea543476715b45e5aff15cfac0a..5e9f449458ad306da89ad1193fdcab00c0a8ebdd 100644
|
| --- a/content/common/gpu/client/gl_helper.cc
|
| +++ b/content/common/gpu/client/gl_helper.cc
|
| @@ -188,20 +188,24 @@ class GLHelper::CopyTextureToImpl :
|
| int32 row_stride_bytes_,
|
| unsigned char* pixels_,
|
| const base::Callback<void(bool)>& callback_)
|
| - : size(size_),
|
| + : done(false),
|
| + size(size_),
|
| bytes_per_row(bytes_per_row_),
|
| row_stride_bytes(row_stride_bytes_),
|
| pixels(pixels_),
|
| callback(callback_),
|
| - buffer(0) {
|
| + buffer(0),
|
| + query(0) {
|
| }
|
|
|
| + bool done;
|
| gfx::Size size;
|
| int bytes_per_row;
|
| int row_stride_bytes;
|
| unsigned char* pixels;
|
| base::Callback<void(bool)> callback;
|
| GLuint buffer;
|
| + WebKit::WebGLId query;
|
| };
|
|
|
| // A readback pipeline that also converts the data to YUV before
|
| @@ -292,7 +296,7 @@ class GLHelper::CopyTextureToImpl :
|
| GLHelper::ScalerQuality quality);
|
|
|
| static void nullcallback(bool success) {}
|
| - void ReadbackDone(Request* request);
|
| + void ReadbackDone(Request *request);
|
| void FinishRequest(Request* request, bool result);
|
| void CancelRequests();
|
|
|
| @@ -380,12 +384,16 @@ void GLHelper::CopyTextureToImpl::ReadbackAsync(
|
| NULL,
|
| GL_STREAM_READ);
|
|
|
| + request->query = context_->createQueryEXT();
|
| + context_->beginQueryEXT(GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM,
|
| + request->query);
|
| context_->readPixels(0, 0, dst_size.width(), dst_size.height(),
|
| GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
| + context_->endQueryEXT(GL_ASYNC_READ_PIXELS_COMPLETED_CHROMIUM);
|
| context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
|
| - cc::SyncPointHelper::SignalSyncPoint(
|
| + cc::SyncPointHelper::SignalQuery(
|
| context_,
|
| - context_->insertSyncPoint(),
|
| + request->query,
|
| base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), request));
|
| }
|
|
|
| @@ -463,45 +471,59 @@ WebKit::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture(
|
| quality);
|
| }
|
|
|
| -void GLHelper::CopyTextureToImpl::ReadbackDone(Request* request) {
|
| +void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request) {
|
| TRACE_EVENT0("mirror",
|
| "GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete");
|
| - DCHECK(request == request_queue_.front());
|
| + finished_request->done = true;
|
|
|
| - bool result = false;
|
| - if (request->buffer != 0) {
|
| - context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
|
| - request->buffer);
|
| - unsigned char* data = static_cast<unsigned char *>(
|
| - context_->mapBufferCHROMIUM(
|
| - GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY));
|
| - if (data) {
|
| - result = true;
|
| - if (request->bytes_per_row == request->size.width() * 4 &&
|
| - request->bytes_per_row == request->row_stride_bytes) {
|
| - memcpy(request->pixels, data, request->size.GetArea() * 4);
|
| - } else {
|
| - unsigned char* out = request->pixels;
|
| - for (int y = 0; y < request->size.height(); y++) {
|
| - memcpy(out, data, request->bytes_per_row);
|
| - out += request->row_stride_bytes;
|
| - data += request->size.width() * 4;
|
| + // We process transfer requests in the order they were received, regardless
|
| + // of the order we get the callbacks in.
|
| + while (!request_queue_.empty()) {
|
| + Request* request = request_queue_.front();
|
| + if (!request->done) {
|
| + break;
|
| + }
|
| +
|
| + bool result = false;
|
| + if (request->buffer != 0) {
|
| + context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM,
|
| + request->buffer);
|
| + unsigned char* data = static_cast<unsigned char *>(
|
| + context_->mapBufferCHROMIUM(
|
| + GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY));
|
| + if (data) {
|
| + result = true;
|
| + if (request->bytes_per_row == request->size.width() * 4 &&
|
| + request->bytes_per_row == request->row_stride_bytes) {
|
| + memcpy(request->pixels, data, request->size.GetArea() * 4);
|
| + } else {
|
| + unsigned char* out = request->pixels;
|
| + for (int y = 0; y < request->size.height(); y++) {
|
| + memcpy(out, data, request->bytes_per_row);
|
| + out += request->row_stride_bytes;
|
| + data += request->size.width() * 4;
|
| + }
|
| }
|
| + context_->unmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM);
|
| }
|
| - context_->unmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM);
|
| + context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
|
| }
|
| - context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
|
| - }
|
|
|
| - FinishRequest(request, result);
|
| + FinishRequest(request, result);
|
| + }
|
| }
|
|
|
| void GLHelper::CopyTextureToImpl::FinishRequest(Request* request,
|
| bool result) {
|
| + TRACE_EVENT0("mirror", "GLHelper::CopyTextureToImpl::FinishRequest");
|
| DCHECK(request_queue_.front() == request);
|
| request_queue_.pop();
|
| request->callback.Run(result);
|
| ScopedFlush flush(context_);
|
| + if (request->query != 0) {
|
| + context_->deleteQueryEXT(request->query);
|
| + request->query = 0;
|
| + }
|
| if (request->buffer != 0) {
|
| context_->deleteBuffer(request->buffer);
|
| request->buffer = 0;
|
|
|