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 c61737bce38d9d8bd727adce27d32bcf958b1ef9..392a15e89dcf0751f588d95791a21685ffc5312c 100644 |
--- a/content/common/gpu/client/gl_helper.cc |
+++ b/content/common/gpu/client/gl_helper.cc |
@@ -319,6 +319,20 @@ class GLHelper::CopyTextureToImpl |
SkBitmap::Config config, |
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 |
+ // The resulting texture is an RGBA texture which is 4 times narrower than the |
+ // original, but when read back the pixel data can be used to construct the |
danakj
2014/07/10 19:13:02
just drop the reference to bitmaps here, this func
mfomitchev
2014/07/11 19:46:08
Done. See if you like the new version.
|
+ // kA8_Config bitmap representing the grayscale version of the original |
+ // texture. |
+ GLuint TransformTextureToA8(GLuint src_texture, |
danakj
2014/07/10 19:13:03
TransformTextureToGrayscale. There's no A8 bitmaps
mfomitchev
2014/07/11 19:46:07
Done.
|
+ const gfx::Size& src_size, |
+ const gfx::Rect& src_subrect, |
+ gfx::Size* const result_size, |
+ bool swizzle); |
+ |
static void nullcallback(bool success) {} |
void ReadbackDone(Request *request, int bytes_per_pixel); |
void FinishRequest(Request* request, bool result); |
@@ -327,6 +341,7 @@ class GLHelper::CopyTextureToImpl |
static const float kRGBtoYColorWeights[]; |
static const float kRGBtoUColorWeights[]; |
static const float kRGBtoVColorWeights[]; |
+ static const float kRGBtoA8ColorWeights[]; |
danakj
2014/07/10 19:13:03
toGrayscale
mfomitchev
2014/07/11 19:46:07
Done.
|
GLES2Interface* gl_; |
gpu::ContextSupport* context_support_; |
@@ -407,6 +422,45 @@ GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
return dst_texture; |
} |
+GLuint GLHelper::CopyTextureToImpl::TransformTextureToA8( |
+ GLuint src_texture, |
+ const gfx::Size& src_size, |
+ const gfx::Rect& src_subrect, |
+ gfx::Size* const result_size, |
+ bool swizzle) { |
+ |
+ LOG(ERROR) << "GLHelper::CopyTextureToImpl::TransformTextureToA8"; |
+ |
+ GLuint dst_texture = 1u; |
+ 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(), |
+ 0, |
+ GL_BGRA_EXT, |
+ GL_UNSIGNED_BYTE, |
+ NULL); |
+ } |
+ |
+ // The size of the transformed texture size |
+ *result_size = gfx::Size((src_size.width() + 3) / 4, src_size.height()); |
danakj
2014/07/10 19:13:02
hm, doing this here feels awkward, cuz there's som
mfomitchev
2014/07/11 19:46:07
Got rid of result_size.
|
+ helper_->InitScalerImpl(); |
+ scoped_ptr<ScalerInterface> |
+ a8_scaler(helper_->scaler_impl_.get()->CreatePlanarScaler( |
+ src_size, |
+ gfx::Rect(0, 0, (src_size.width() + 3) & ~3, src_size.height()), |
+ *result_size, |
+ false, |
+ (swizzle == kSwizzleBGRA), |
+ kRGBtoA8ColorWeights)); |
+ a8_scaler->Scale(src_texture, dst_texture); |
+ return dst_texture; |
+} |
+ |
void GLHelper::CopyTextureToImpl::ReadbackAsync( |
const gfx::Size& dst_size, |
int32 bytes_per_row, |
@@ -475,23 +529,45 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
const SkBitmap::Config bitmap_config, |
const base::Callback<void(bool)>& callback, |
GLHelper::ScalerQuality quality) { |
- if (!IsReadbackConfigSupported(bitmap_config)) { |
+ if (bitmap_config != SkBitmap::kA8_Config && |
danakj
2014/07/10 19:13:02
why is this here instead of deciding A8 is ok insi
mfomitchev
2014/07/11 19:46:07
Responded separately in the reply.
|
+ !IsReadbackConfigSupported(bitmap_config)) { |
callback.Run(false); |
return; |
} |
+ |
+ SkBitmap::Config texture_config = bitmap_config; |
+ if (bitmap_config == SkBitmap::kA8_Config) { |
+ // For readback purposes, treat the resulting texture as ARGB of smaller |
danakj
2014/07/10 19:13:02
What does it look like if you teach ReadbackAsync
mfomitchev
2014/07/11 19:46:07
Done. If the new version looks ok, I will make sim
|
+ // size. |
+ texture_config = SkBitmap::kARGB_8888_Config; |
+ } |
+ |
+ bool swizzle = |
+#if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
+ true; |
+#else |
+ false; |
+#endif |
+ |
GLuint texture = ScaleTexture(src_texture, |
src_size, |
src_subrect, |
dst_size, |
true, |
-#if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
- true, |
-#else |
- false, |
-#endif |
- bitmap_config, |
+ swizzle, |
+ texture_config, |
quality); |
- DCHECK(texture); |
+ |
+ gfx::Size texture_size = dst_size; |
+ if (bitmap_config == SkBitmap::kA8_Config) { |
+ texture = TransformTextureToA8(texture, |
+ src_size, |
danakj
2014/07/10 19:13:03
git cl format
mfomitchev
2014/07/11 19:46:08
Done.
|
+ src_subrect, |
+ &texture_size, |
+ swizzle); |
+ |
+ DCHECK(texture); |
+ } |
ScopedFramebuffer dst_framebuffer(gl_); |
ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
dst_framebuffer); |
@@ -502,6 +578,7 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
texture, |
0); |
int bytes_per_pixel = 4; |
+ |
switch (bitmap_config) { |
case SkBitmap::kARGB_8888_Config: |
// Do nothing params already set. |
@@ -509,16 +586,20 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
case SkBitmap::kRGB_565_Config: |
bytes_per_pixel = 2; |
break; |
+ case SkBitmap::kA8_Config: |
+ bytes_per_pixel = 1; |
+ break; |
default: |
NOTREACHED(); |
break; |
} |
- ReadbackAsync(dst_size, |
+ |
+ ReadbackAsync(texture_size, |
dst_size.width() * bytes_per_pixel, |
dst_size.width() * bytes_per_pixel, |
out, |
- bitmap_config, |
- kSwizzleNone, |
+ texture_config, |
+ kSwizzleBGRA, |
mfomitchev
2014/07/09 18:02:10
The config and swizzle for the A8 case are picked
danakj
2014/07/10 19:13:03
This None->BGRA will affect more than the A8 path.
mfomitchev
2014/07/11 19:46:07
Good point, changed it back. I will separate this
|
callback); |
gl_->DeleteTextures(1, &texture); |
} |
@@ -625,6 +706,7 @@ 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() * bytes_per_pixel && |
request->bytes_per_row == request->row_stride_bytes) { |
memcpy(request->pixels, data, |
@@ -928,6 +1010,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::kRGBtoA8ColorWeights[] = { |
+ 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. |