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. |