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 3ea2557a69dbb970af8e6b656a62001b30e82d50..b860669cafa832608e6c660bcd023658f95e8901 100644 |
--- a/content/common/gpu/client/gl_helper.cc |
+++ b/content/common/gpu/client/gl_helper.cc |
@@ -139,6 +139,7 @@ class GLHelper::CopyTextureToImpl : |
const gfx::Rect& src_subrect, |
const gfx::Size& dst_size, |
unsigned char* out, |
+ bool readback_config_rgb565, |
const base::Callback<void(bool)>& callback, |
GLHelper::ScalerQuality quality); |
@@ -153,6 +154,7 @@ class GLHelper::CopyTextureToImpl : |
int32 bytes_per_row, // generally dst_size.width() * 4 |
int32 row_stride_bytes, // generally dst_size.width() * 4 |
unsigned char* out, |
+ bool readback_config_rgb565, |
const base::Callback<void(bool)>& callback); |
void ReadbackPlane(TextureFrameBufferPair* source, |
@@ -305,10 +307,11 @@ class GLHelper::CopyTextureToImpl : |
const gfx::Size& dst_size, |
bool vertically_flip_texture, |
bool swizzle, |
+ bool readback_config_rgb565, |
no sievers
2014/01/07 16:26:02
nit: two spaces
sivag
2014/01/09 14:51:50
DOne.
|
GLHelper::ScalerQuality quality); |
static void nullcallback(bool success) {} |
- void ReadbackDone(Request *request); |
+ void ReadbackDone(Request *request,int bytes_per_pixel); |
no sievers
2014/01/07 16:26:02
nit: space after comma missing
sivag
2014/01/09 14:51:50
Done.
|
void FinishRequest(Request* request, bool result); |
void CancelRequests(); |
@@ -351,6 +354,7 @@ WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( |
const gfx::Size& dst_size, |
bool vertically_flip_texture, |
bool swizzle, |
+ bool readback_config_rgb565, |
no sievers
2014/01/07 16:26:02
nit: two spaces
sivag
2014/01/09 14:51:50
Done
|
GLHelper::ScalerQuality quality) { |
scoped_ptr<ScalerInterface> scaler( |
helper_->CreateScaler(quality, |
@@ -363,16 +367,28 @@ WebGLId GLHelper::CopyTextureToImpl::ScaleTexture( |
WebGLId dst_texture = context_->createTexture(); |
{ |
ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, dst_texture); |
- context_->texImage2D(GL_TEXTURE_2D, |
- 0, |
- GL_RGBA, |
- dst_size.width(), |
- dst_size.height(), |
- 0, |
- GL_RGBA, |
- GL_UNSIGNED_BYTE, |
- NULL); |
- } |
+ if(readback_config_rgb565){ |
no sievers
2014/01/07 16:26:02
nit: space missing
sivag
2014/01/09 14:51:50
Done.
|
+ context_->texImage2D(GL_TEXTURE_2D, |
+ 0, |
+ GL_RGB, |
+ dst_size.width(), |
+ dst_size.height(), |
+ 0, |
+ GL_RGB, |
+ GL_UNSIGNED_SHORT_5_6_5, |
+ NULL); |
+ }else{ |
no sievers
2014/01/07 16:26:02
nit: spaces missing
sivag
2014/01/09 14:51:50
Done.
|
+ context_->texImage2D(GL_TEXTURE_2D, |
+ 0, |
+ GL_RGBA, |
+ dst_size.width(), |
+ dst_size.height(), |
+ 0, |
+ GL_RGBA, |
+ GL_UNSIGNED_BYTE, |
+ NULL); |
+ } |
+} |
scaler->Scale(src_texture, dst_texture); |
return dst_texture; |
} |
@@ -382,6 +398,7 @@ void GLHelper::CopyTextureToImpl::ReadbackAsync( |
int32 bytes_per_row, |
int32 row_stride_bytes, |
unsigned char* out, |
+ bool readback_config_rgb565, |
const base::Callback<void(bool)>& callback) { |
no sievers
2014/01/07 16:26:02
Can you add a check for GL_IMPLEMENTATION_COLOR_RE
sivag
2014/01/09 14:51:50
Is this needed as we are already doing the check a
|
Request* request = new Request(dst_size, |
bytes_per_row, |
@@ -390,32 +407,37 @@ void GLHelper::CopyTextureToImpl::ReadbackAsync( |
callback); |
request_queue_.push(request); |
request->buffer = context_->createBuffer(); |
+ int bytes_per_pixel = readback_config_rgb565 ? 2 : 4; |
context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
request->buffer); |
context_->bufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
- 4 * dst_size.GetArea(), |
+ bytes_per_pixel * dst_size.GetArea(), |
NULL, |
GL_STREAM_READ); |
- |
request->query = context_->createQueryEXT(); |
context_->beginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, |
request->query); |
- context_->readPixels(0, 0, dst_size.width(), dst_size.height(), |
+ if(readback_config_rgb565){ |
no sievers
2014/01/07 16:26:02
nit: space missing in between ')' and '{'
sivag
2014/01/09 14:51:50
Done.
|
+ context_->readPixels(0, 0, dst_size.width(), dst_size.height(), |
+ GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); |
no sievers
2014/01/07 16:26:02
nit: indent here and in 425.
sivag
2014/01/09 14:51:50
Done.
|
+ }else{ |
+ context_->readPixels(0, 0, dst_size.width(), dst_size.height(), |
GL_RGBA, GL_UNSIGNED_BYTE, NULL); |
+ } |
context_->endQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); |
context_->bindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
context_support_->SignalQuery( |
request->query, |
- base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), request)); |
+ base::Bind(&CopyTextureToImpl::ReadbackDone, AsWeakPtr(), |
+ request, bytes_per_pixel)); |
} |
- |
- |
void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
WebGLId src_texture, |
const gfx::Size& src_size, |
const gfx::Rect& src_subrect, |
const gfx::Size& dst_size, |
unsigned char* out, |
+ bool readback_config_rgb565, |
const base::Callback<void(bool)>& callback, |
GLHelper::ScalerQuality quality) { |
WebGLId texture = ScaleTexture(src_texture, |
@@ -428,6 +450,7 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
#else |
false, |
#endif |
+ readback_config_rgb565, |
quality); |
ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); |
ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_, |
@@ -438,10 +461,12 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
GL_TEXTURE_2D, |
texture, |
0); |
+ int bytes_per_pixel = readback_config_rgb565 ? 2 : 4; |
ReadbackAsync(dst_size, |
- dst_size.width() * 4, |
- dst_size.width() * 4, |
+ dst_size.width() * bytes_per_pixel, |
+ dst_size.width() * bytes_per_pixel, |
out, |
+ readback_config_rgb565, |
callback); |
context_->deleteTexture(texture); |
} |
@@ -480,10 +505,12 @@ blink::WebGLId GLHelper::CopyTextureToImpl::CopyAndScaleTexture( |
dst_size, |
vertically_flip_texture, |
false, |
+ false, |
quality); |
} |
-void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request) { |
+void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request, |
+ int bytes_per_pixel) { |
TRACE_EVENT0("mirror", |
"GLHelper::CopyTextureToImpl::CheckReadbackFramebufferComplete"); |
finished_request->done = true; |
@@ -505,15 +532,16 @@ void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request) { |
GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, GL_READ_ONLY)); |
if (data) { |
result = true; |
- if (request->bytes_per_row == request->size.width() * 4 && |
+ if (request->bytes_per_row == request->size.width() * bytes_per_pixel && |
request->bytes_per_row == request->row_stride_bytes) { |
- memcpy(request->pixels, data, request->size.GetArea() * 4); |
+ memcpy(request->pixels, data, |
+ request->size.GetArea() * bytes_per_pixel); |
} 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; |
+ data += request->size.width() * bytes_per_pixel; |
} |
} |
context_->unmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); |
@@ -565,6 +593,7 @@ void GLHelper::CropScaleReadbackAndCleanTexture( |
const gfx::Rect& src_subrect, |
const gfx::Size& dst_size, |
unsigned char* out, |
+ bool readback_config_rgb565, |
const base::Callback<void(bool)>& callback) { |
InitCopyTextToImpl(); |
copy_texture_to_impl_->CropScaleReadbackAndCleanTexture( |
@@ -573,6 +602,7 @@ void GLHelper::CropScaleReadbackAndCleanTexture( |
src_subrect, |
dst_size, |
out, |
+ readback_config_rgb565, |
callback, |
GLHelper::SCALER_QUALITY_FAST); |
} |
@@ -584,10 +614,13 @@ void GLHelper::CropScaleReadbackAndCleanMailbox( |
const gfx::Rect& src_subrect, |
const gfx::Size& dst_size, |
unsigned char* out, |
+ bool readback_config_rgb565, |
const base::Callback<void(bool)>& callback) { |
WebGLId mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_point); |
CropScaleReadbackAndCleanTexture( |
- mailbox_texture, src_size, src_subrect, dst_size, out, callback); |
+ mailbox_texture, src_size, src_subrect, dst_size, out, |
+ readback_config_rgb565, |
+ callback); |
context_->deleteTexture(mailbox_texture); |
} |
@@ -757,7 +790,33 @@ void GLHelper::CopyTextureFullImage(blink::WebGLId texture, |
0, 0, |
size.width(), size.height(), 0); |
} |
- |
+bool GLHelper::CanUseRgb565Readback() { |
+ const int test_size = 100; |
no sievers
2014/01/07 16:26:02
Can you use something power of two?
sivag
2014/01/09 14:51:50
Done.
|
+ WebGLId dst_texture = context_->createTexture(); |
+ ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(context_, dst_texture); |
+ context_->texImage2D(GL_TEXTURE_2D, |
no sievers
2014/01/07 16:26:02
nit: indent
sivag
2014/01/09 14:51:50
Done.
|
+ 0, |
+ GL_RGB, |
+ test_size, |
+ test_size, |
+ 0, |
+ GL_RGB, |
+ GL_UNSIGNED_SHORT_5_6_5, |
+ NULL); |
no sievers
2014/01/07 16:26:02
The texture is incomplete because the default min_
sivag
2014/01/09 14:51:50
Done.
|
+ ScopedFramebuffer dst_framebuffer(context_, context_->createFramebuffer()); |
+ ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(context_, |
+ dst_framebuffer); |
+ context_->framebufferTexture2D(GL_FRAMEBUFFER, |
+ GL_COLOR_ATTACHMENT0, |
+ GL_TEXTURE_2D, |
+ dst_texture, |
+ 0); |
+ int ext_format, ext_type; |
+ context_->getIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &ext_format); |
+ context_->getIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &ext_type); |
+ context_->deleteTexture(dst_texture); |
+ return ((ext_format == GL_RGB) && (ext_type == GL_UNSIGNED_SHORT_5_6_5)); |
+} |
void GLHelper::CopyTextureToImpl::ReadbackPlane( |
TextureFrameBufferPair* source, |
const scoped_refptr<media::VideoFrame>& target, |
@@ -773,6 +832,7 @@ void GLHelper::CopyTextureToImpl::ReadbackPlane( |
dst_subrect.width() >> size_shift, |
target->stride(plane), |
target->data(plane) + offset, |
+ false, |
callback); |
} |