Chromium Code Reviews| 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 3b7e23abb4731302787f644b1312965e43222943..e1d807ff103589ba6e833cbdc113b9dd55febf62 100644 |
| --- a/content/common/gpu/client/gl_helper.cc |
| +++ b/content/common/gpu/client/gl_helper.cc |
| @@ -127,6 +127,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); |
| @@ -140,6 +141,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, |
| @@ -285,10 +287,11 @@ class GLHelper::CopyTextureToImpl |
| const gfx::Size& dst_size, |
| bool vertically_flip_texture, |
| bool swizzle, |
| + bool readback_config_rgb565, |
| GLHelper::ScalerQuality quality); |
| static void nullcallback(bool success) {} |
| - void ReadbackDone(Request* request); |
| + void ReadbackDone(Request *request, int bytes_per_pixel); |
| void FinishRequest(Request* request, bool result); |
| void CancelRequests(); |
| @@ -330,6 +333,7 @@ GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
| const gfx::Size& dst_size, |
| bool vertically_flip_texture, |
| bool swizzle, |
| + bool readback_config_rgb565, |
| GLHelper::ScalerQuality quality) { |
| scoped_ptr<ScalerInterface> scaler( |
| helper_->CreateScaler(quality, |
| @@ -343,14 +347,18 @@ GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
| gl_->GenTextures(1, &dst_texture); |
| { |
| ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
| + GLenum format = readback_config_rgb565 ? GL_RGB : GL_RGBA; |
| + GLenum type = readback_config_rgb565 ? |
| + GL_UNSIGNED_SHORT_5_6_5 : |
| + GL_UNSIGNED_BYTE; |
| gl_->TexImage2D(GL_TEXTURE_2D, |
| 0, |
| - GL_RGBA, |
| + format, |
| dst_size.width(), |
| dst_size.height(), |
| 0, |
| - GL_RGBA, |
| - GL_UNSIGNED_BYTE, |
| + format, |
| + type, |
| NULL); |
| } |
| scaler->Scale(src_texture, dst_texture); |
| @@ -362,41 +370,48 @@ 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) { |
| Request* request = |
| new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback); |
| request_queue_.push(request); |
| request->buffer = 0u; |
| + int bytes_per_pixel = readback_config_rgb565 ? 2 : 4; |
| gl_->GenBuffers(1, &request->buffer); |
| gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
| gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| - 4 * dst_size.GetArea(), |
| + bytes_per_pixel * dst_size.GetArea(), |
| NULL, |
| GL_STREAM_READ); |
| request->query = 0u; |
| gl_->GenQueriesEXT(1, &request->query); |
| gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query); |
| + GLenum format = readback_config_rgb565 ? GL_RGB : GL_RGBA; |
| + GLenum type = readback_config_rgb565 ? |
| + GL_UNSIGNED_SHORT_5_6_5 : |
| + GL_UNSIGNED_BYTE; |
| gl_->ReadPixels(0, |
| 0, |
| dst_size.width(), |
| dst_size.height(), |
| - GL_RGBA, |
| - GL_UNSIGNED_BYTE, |
| + format, |
| + type, |
| NULL); |
| gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); |
| gl_->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( |
| GLuint 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) { |
| GLuint texture = ScaleTexture(src_texture, |
| @@ -409,15 +424,24 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
| #else |
| false, |
| #endif |
| + readback_config_rgb565, |
| quality); |
| ScopedFramebuffer dst_framebuffer(gl_); |
| ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| dst_framebuffer); |
| ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
| - gl_->FramebufferTexture2D( |
| - GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); |
| - ReadbackAsync( |
| - dst_size, dst_size.width() * 4, dst_size.width() * 4, out, callback); |
| + gl_->FramebufferTexture2D(GL_FRAMEBUFFER, |
| + GL_COLOR_ATTACHMENT0, |
| + GL_TEXTURE_2D, |
| + texture, |
| + 0); |
| + int bytes_per_pixel = readback_config_rgb565 ? 2 : 4; |
| + ReadbackAsync(dst_size, |
| + dst_size.width() * bytes_per_pixel, |
| + dst_size.width() * bytes_per_pixel, |
| + out, |
| + readback_config_rgb565, |
| + callback); |
| gl_->DeleteTextures(1, &texture); |
| } |
| @@ -451,10 +475,12 @@ GLuint 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; |
| @@ -474,15 +500,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; |
| } |
| } |
| gl_->UnmapBufferCHROMIUM(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM); |
| @@ -529,6 +556,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( |
| @@ -537,6 +565,7 @@ void GLHelper::CropScaleReadbackAndCleanTexture( |
| src_subrect, |
| dst_size, |
| out, |
| + readback_config_rgb565, |
| callback, |
| GLHelper::SCALER_QUALITY_FAST); |
| } |
| @@ -548,10 +577,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) { |
| GLuint 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); |
| gl_->DeleteTextures(1, &mailbox_texture); |
| } |
| @@ -726,7 +758,38 @@ void GLHelper::CopyTextureFullImage(GLuint texture, const gfx::Size& size) { |
| gl_->CopyTexImage2D( |
| GL_TEXTURE_2D, 0, GL_RGB, 0, 0, size.width(), size.height(), 0); |
| } |
|
piman
2014/01/09 18:12:15
nit: add empty line
sivag
2014/01/10 12:20:01
Done.
|
| - |
| +bool GLHelper::CanUseRgb565Readback() { |
| + const int test_size = 64; |
|
piman
2014/01/09 18:12:15
nit: kTestSize
sivag
2014/01/10 12:20:01
Done.
|
| + GLuint dst_texture = 0u; |
| + gl_->GenTextures(1, &dst_texture); |
| + ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
| + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| + gl_->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| + gl_->TexImage2D(GL_TEXTURE_2D, |
| + 0, |
| + GL_RGB, |
| + test_size, |
| + test_size, |
| + 0, |
| + GL_RGB, |
| + GL_UNSIGNED_SHORT_5_6_5, |
| + NULL); |
| + ScopedFramebuffer dst_framebuffer(gl_); |
| + ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| + dst_framebuffer); |
| + gl_->FramebufferTexture2D(GL_FRAMEBUFFER, |
| + GL_COLOR_ATTACHMENT0, |
| + GL_TEXTURE_2D, |
| + dst_texture, |
| + 0); |
| + int ext_format, ext_type; |
| + gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &ext_format); |
| + gl_->GetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &ext_type); |
| + gl_->DeleteTextures(1, &dst_texture); |
| + return ((ext_format == GL_RGB) && (ext_type == GL_UNSIGNED_SHORT_5_6_5)); |
|
piman
2014/01/09 18:12:15
nit: no need for outer ()
sivag
2014/01/10 12:20:01
Done.
|
| +} |
|
piman
2014/01/09 18:12:15
nit: add empty line
|
| void GLHelper::CopyTextureToImpl::ReadbackPlane( |
| TextureFrameBufferPair* source, |
| const scoped_refptr<media::VideoFrame>& target, |
| @@ -736,11 +799,12 @@ void GLHelper::CopyTextureToImpl::ReadbackPlane( |
| const base::Callback<void(bool)>& callback) { |
| gl_->BindFramebuffer(GL_FRAMEBUFFER, source->framebuffer()); |
| size_t offset = target->stride(plane) * (dst_subrect.y() >> size_shift) + |
| - (dst_subrect.x() >> size_shift); |
| + (dst_subrect.x() >> size_shift); |
| ReadbackAsync(source->size(), |
| dst_subrect.width() >> size_shift, |
| target->stride(plane), |
| target->data(plane) + offset, |
| + false, |
| callback); |
| } |