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 dfdeff072ae45c02ff4b535a53611c12c7dd3a01..aba22c5b782cb5dab50e3ef9e179cb276ef3ee99 100644 |
| --- a/content/common/gpu/client/gl_helper.cc |
| +++ b/content/common/gpu/client/gl_helper.cc |
| @@ -141,7 +141,7 @@ class GLHelper::CopyTextureToImpl |
| const gfx::Rect& src_subrect, |
| const gfx::Size& dst_size, |
| unsigned char* out, |
| - const SkColorType color_type, |
| + const SkColorType out_color_type, |
| const base::Callback<void(bool)>& callback, |
| GLHelper::ScalerQuality quality); |
| @@ -319,6 +319,15 @@ class GLHelper::CopyTextureToImpl |
| SkColorType color_type, |
| GLHelper::ScalerQuality quality); |
| + // Converts each four consecutive pixels of the source texture into one pixel |
| + // in the result texture with each pixel channel representing the grayscale |
| + // color of one of the four original pixels: |
| + // R1B1G1A1 R2B2G2A2 R3B3G3A3 R4G4B4A4 -> X1X2X3X4 |
| + GLuint TransformTextureToGrayscale(GLuint src_texture, |
| + const gfx::Size& src_size, |
| + const gfx::Rect& src_subrect, |
| + bool swizzle); |
| + |
| static void nullcallback(bool success) {} |
| void ReadbackDone(Request *request, int bytes_per_pixel); |
| void FinishRequest(Request* request, bool result); |
| @@ -327,6 +336,7 @@ class GLHelper::CopyTextureToImpl |
| static const float kRGBtoYColorWeights[]; |
| static const float kRGBtoUColorWeights[]; |
| static const float kRGBtoVColorWeights[]; |
| + static const float kRGBtoGrayscaleColorWeights[]; |
| GLES2Interface* gl_; |
| gpu::ContextSupport* context_support_; |
| @@ -407,6 +417,41 @@ GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
| return dst_texture; |
| } |
| +GLuint GLHelper::CopyTextureToImpl::TransformTextureToGrayscale( |
| + GLuint src_texture, |
| + const gfx::Size& src_size, |
| + const gfx::Rect& src_subrect, |
|
no sievers
2014/07/15 19:31:49
|src_subrect| is ignored below?
mfomitchev
2014/07/16 19:16:07
Done.
|
| + bool swizzle) { |
| + LOG(ERROR) << "GLHelper::CopyTextureToImpl::TransformTextureToGrayscale"; |
| + |
| + GLuint dst_texture = 1u; |
|
mfomitchev
2014/07/11 20:21:33
Should we set the id to 0 instead of 1 here? Does
no sievers
2014/07/15 19:31:49
Yea I'd init to 0, it's what we do in other places
mfomitchev
2014/07/16 19:16:06
Done.
|
| + gl_->GenTextures(1, &dst_texture); |
| + { |
| + ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
| + gl_->TexImage2D(GL_TEXTURE_2D, |
| + 0, |
| + GL_BGRA_EXT, |
| + src_size.width(), |
| + src_size.height(), |
|
no sievers
2014/07/15 19:31:49
This is the wrong size, shouldn't it be a fourth o
mfomitchev
2014/07/16 19:16:06
Done.
|
| + 0, |
| + GL_BGRA_EXT, |
| + GL_UNSIGNED_BYTE, |
| + NULL); |
| + } |
| + |
| + helper_->InitScalerImpl(); |
| + scoped_ptr<ScalerInterface> grayscale_scaler( |
| + helper_->scaler_impl_.get()->CreatePlanarScaler( |
| + src_size, |
| + gfx::Rect(0, 0, (src_size.width() + 3) & ~3, src_size.height()), |
| + gfx::Size((src_size.width() + 3) / 4, src_size.height()), |
| + false, |
| + (swizzle == kSwizzleBGRA), |
| + kRGBtoGrayscaleColorWeights)); |
| + grayscale_scaler->Scale(src_texture, dst_texture); |
| + return dst_texture; |
| +} |
| + |
| void GLHelper::CopyTextureToImpl::ReadbackAsync( |
| const gfx::Size& dst_size, |
| int32 bytes_per_row, |
| @@ -415,19 +460,18 @@ void GLHelper::CopyTextureToImpl::ReadbackAsync( |
| const SkColorType color_type, |
| ReadbackSwizzle swizzle, |
| const base::Callback<void(bool)>& callback) { |
| - if (!IsReadbackConfigSupported(color_type)) { |
| + if (color_type != kAlpha_8_SkColorType && |
| + !IsReadbackConfigSupported(color_type)) { |
| callback.Run(false); |
| return; |
| } |
| - Request* request = |
| - new Request(dst_size, bytes_per_row, row_stride_bytes, out, callback); |
| - request_queue_.push(request); |
| - request->buffer = 0u; |
| + |
| // Start with ARGB8888 params as any other format which is not |
| // supported is already asserted above. |
| GLenum format = GL_RGBA, type = GL_UNSIGNED_BYTE; |
| int bytes_per_pixel = 4; |
| + gfx::Size readback_size = dst_size; |
| switch (color_type) { |
| case kN32_SkColorType: |
| if (swizzle == kSwizzleBGRA) |
| @@ -438,27 +482,32 @@ void GLHelper::CopyTextureToImpl::ReadbackAsync( |
| type = GL_UNSIGNED_SHORT_5_6_5; |
| bytes_per_pixel = 2; |
| break; |
| + case kAlpha_8_SkColorType: |
| + // For readback purposes, treat the texture as BGRA of smaller size. |
| + format = GL_BGRA_EXT; |
| + bytes_per_pixel = 4; |
| + readback_size.set_width((dst_size.width() + 3) / 4); |
| default: |
| NOTREACHED(); |
| break; |
| } |
| + |
| + Request* request = new Request( |
| + readback_size, bytes_per_row, row_stride_bytes, out, callback); |
| + request_queue_.push(request); |
| + request->buffer = 0u; |
| gl_->GenBuffers(1, &request->buffer); |
| gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
| gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
| - bytes_per_pixel * dst_size.GetArea(), |
| + bytes_per_pixel * readback_size.GetArea(), |
| NULL, |
| GL_STREAM_READ); |
| request->query = 0u; |
| gl_->GenQueriesEXT(1, &request->query); |
| gl_->BeginQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM, request->query); |
| - gl_->ReadPixels(0, |
| - 0, |
| - dst_size.width(), |
| - dst_size.height(), |
| - format, |
| - type, |
| - NULL); |
| + gl_->ReadPixels( |
| + 0, 0, readback_size.width(), readback_size.height(), format, type, NULL); |
| gl_->EndQueryEXT(GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM); |
| gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0); |
| context_support_->SignalQuery( |
| @@ -466,32 +515,47 @@ void GLHelper::CopyTextureToImpl::ReadbackAsync( |
| 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, |
| - const SkColorType color_type, |
| + const SkColorType out_color_type, |
| const base::Callback<void(bool)>& callback, |
| GLHelper::ScalerQuality quality) { |
| - if (!IsReadbackConfigSupported(color_type)) { |
| + if (out_color_type != kAlpha_8_SkColorType && |
| + !IsReadbackConfigSupported(out_color_type)) { |
| callback.Run(false); |
| return; |
| } |
| - GLuint texture = ScaleTexture(src_texture, |
| - src_size, |
| - src_subrect, |
| - dst_size, |
| - true, |
| + |
| + bool swizzle = |
| #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
| - true, |
| + true; |
| #else |
| - false, |
| + false; |
| #endif |
| - color_type, |
| - quality); |
| + |
| + GLuint texture = |
| + ScaleTexture(src_texture, |
| + src_size, |
| + src_subrect, |
| + dst_size, |
| + true, |
| + swizzle, |
| + out_color_type == kAlpha_8_SkColorType ? kN32_SkColorType |
|
no sievers
2014/07/15 19:31:49
This seems wrong for Alpha_8. If you are using the
mfomitchev
2014/07/16 19:16:06
Done.
|
| + : out_color_type, |
| + quality); |
| DCHECK(texture); |
| + |
| + if (out_color_type == kAlpha_8_SkColorType) { |
| + texture = |
| + TransformTextureToGrayscale(texture, src_size, src_subrect, swizzle); |
|
no sievers
2014/07/15 19:31:49
+hubbe to comment if this can be done in a single
hubbe
2014/07/15 21:05:56
It can, iff quality is SCALER_QUALITY_FAST, search
mfomitchev
2014/07/16 19:16:06
Done. Also added vertically_flip_texture to Encode
mfomitchev
2014/07/16 19:16:06
Also fixed: the second arg should be dst_size, not
|
| + |
| + DCHECK(texture); |
| + } |
| ScopedFramebuffer dst_framebuffer(gl_); |
| ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
| dst_framebuffer); |
| @@ -502,13 +566,16 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
| texture, |
| 0); |
| int bytes_per_pixel = 4; |
| - switch (color_type) { |
| + switch (out_color_type) { |
| case kN32_SkColorType: |
| // Do nothing params already set. |
| break; |
| case kRGB_565_SkColorType: |
| bytes_per_pixel = 2; |
| break; |
| + case kAlpha_8_SkColorType: |
| + bytes_per_pixel = 1; |
| + break; |
| default: |
| NOTREACHED(); |
| break; |
| @@ -517,7 +584,7 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
| dst_size.width() * bytes_per_pixel, |
| dst_size.width() * bytes_per_pixel, |
| out, |
| - color_type, |
| + out_color_type, |
| kSwizzleNone, |
| callback); |
| gl_->DeleteTextures(1, &texture); |
| @@ -682,19 +749,18 @@ void GLHelper::CropScaleReadbackAndCleanTexture( |
| const gfx::Rect& src_subrect, |
| const gfx::Size& dst_size, |
| unsigned char* out, |
| - const SkColorType color_type, |
| + const SkColorType out_color_type, |
| const base::Callback<void(bool)>& callback, |
| GLHelper::ScalerQuality quality) { |
| InitCopyTextToImpl(); |
| - copy_texture_to_impl_->CropScaleReadbackAndCleanTexture( |
| - src_texture, |
| - src_size, |
| - src_subrect, |
| - dst_size, |
| - out, |
| - color_type, |
| - callback, |
| - quality); |
| + copy_texture_to_impl_->CropScaleReadbackAndCleanTexture(src_texture, |
| + src_size, |
| + src_subrect, |
| + dst_size, |
| + out, |
| + out_color_type, |
| + callback, |
| + quality); |
| } |
| void GLHelper::CropScaleReadbackAndCleanMailbox( |
| @@ -704,13 +770,13 @@ void GLHelper::CropScaleReadbackAndCleanMailbox( |
| const gfx::Rect& src_subrect, |
| const gfx::Size& dst_size, |
| unsigned char* out, |
| - const SkColorType color_type, |
| + const SkColorType out_color_type, |
| const base::Callback<void(bool)>& callback, |
| GLHelper::ScalerQuality quality) { |
| GLuint mailbox_texture = ConsumeMailboxToTexture(src_mailbox, sync_point); |
| CropScaleReadbackAndCleanTexture( |
| mailbox_texture, src_size, src_subrect, dst_size, out, |
| - color_type, |
| + out_color_type, |
| callback, |
| quality); |
| gl_->DeleteTextures(1, &mailbox_texture); |
| @@ -928,6 +994,8 @@ const float GLHelper::CopyTextureToImpl::kRGBtoUColorWeights[] = { |
| -0.148f, -0.291f, 0.439f, 0.5f}; |
| const float GLHelper::CopyTextureToImpl::kRGBtoVColorWeights[] = { |
| 0.439f, -0.368f, -0.071f, 0.5f}; |
| +const float GLHelper::CopyTextureToImpl::kRGBtoGrayscaleColorWeights[] = { |
| + 0.213f, 0.715f, 0.072f, 0.0f}; |
| // YUV readback constructors. Initiates the main scaler pipeline and |
| // one planar scaler for each of the Y, U and V planes. |