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 d172c560278a6dc40d0bdcd589a7bb64a7d6cef1..c3f9f37e50280baf09553913a36ed30e4b6aa850 100644 |
--- a/content/common/gpu/client/gl_helper.cc |
+++ b/content/common/gpu/client/gl_helper.cc |
@@ -105,6 +105,7 @@ class ScalerHolder { |
} // namespace |
namespace content { |
+typedef GLHelperReadbackSupport::FormatSupport FormatSupport; |
// Implements GLHelper::CropScaleReadbackAndCleanTexture and encapsulates |
// the data needed for it. |
@@ -162,8 +163,9 @@ class GLHelper::CopyTextureToImpl |
int32 bytes_per_row, // generally dst_size.width() * 4 |
int32 row_stride_bytes, // generally dst_size.width() * 4 |
unsigned char* out, |
- const SkColorType color_type, |
- ReadbackSwizzle swizzle, |
+ GLenum format, |
+ GLenum type, |
+ size_t bytes_per_pixel, |
const base::Callback<void(bool)>& callback); |
void ReadbackPlane(TextureFrameBufferPair* source, |
@@ -193,7 +195,11 @@ class GLHelper::CopyTextureToImpl |
// 0 if GL_EXT_draw_buffers is not available. |
GLint MaxDrawBuffers() const { return max_draw_buffers_; } |
- bool IsReadbackConfigSupported(SkColorType color_type); |
+ FormatSupport GetReadbackConfig(SkColorType color_type, |
+ bool can_swizzle, |
+ GLenum* format, |
+ GLenum* type, |
+ size_t* bytes_per_pixel); |
private: |
// A single request to CropScaleReadbackAndCleanTexture. |
@@ -364,35 +370,19 @@ GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
bool swizzle, |
SkColorType color_type, |
GLHelper::ScalerQuality quality) { |
- if (!IsReadbackConfigSupported(color_type)) |
- return 0; |
- |
- scoped_ptr<ScalerInterface> scaler( |
- helper_->CreateScaler(quality, |
- src_size, |
- src_subrect, |
- dst_size, |
- vertically_flip_texture, |
- swizzle)); |
GLuint dst_texture = 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; |
gl_->GenTextures(1, &dst_texture); |
{ |
+ GLenum format = GL_RGBA, type = GL_UNSIGNED_BYTE; |
ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, dst_texture); |
- switch (color_type) { |
- case kN32_SkColorType: |
- // Do nothing params already set. |
- break; |
- case kRGB_565_SkColorType: |
- format = GL_RGB; |
- type = GL_UNSIGNED_SHORT_5_6_5; |
- break; |
- default: |
- NOTREACHED(); |
- break; |
+ |
+ // Use GL_RGBA for destination/temporary texture unless we're working with |
+ // 16-bit data |
+ if (color_type == kRGB_565_SkColorType) { |
+ format = GL_RGB; |
+ type = GL_UNSIGNED_SHORT_5_6_5; |
} |
+ |
gl_->TexImage2D(GL_TEXTURE_2D, |
0, |
format, |
@@ -403,6 +393,13 @@ GLuint GLHelper::CopyTextureToImpl::ScaleTexture( |
type, |
NULL); |
} |
+ scoped_ptr<ScalerInterface> scaler( |
+ helper_->CreateScaler(quality, |
+ src_size, |
+ src_subrect, |
+ dst_size, |
+ vertically_flip_texture, |
+ swizzle)); |
scaler->Scale(src_texture, dst_texture); |
return dst_texture; |
} |
@@ -412,36 +409,15 @@ void GLHelper::CopyTextureToImpl::ReadbackAsync( |
int32 bytes_per_row, |
int32 row_stride_bytes, |
unsigned char* out, |
- const SkColorType color_type, |
- ReadbackSwizzle swizzle, |
+ GLenum format, |
+ GLenum type, |
+ size_t bytes_per_pixel, |
const base::Callback<void(bool)>& callback) { |
- if (!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; |
- |
- switch (color_type) { |
- case kN32_SkColorType: |
- if (swizzle == kSwizzleBGRA) |
- format = GL_BGRA_EXT; |
- break; |
- case kRGB_565_SkColorType: |
- format = GL_RGB; |
- type = GL_UNSIGNED_SHORT_5_6_5; |
- bytes_per_pixel = 2; |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
+ |
gl_->GenBuffers(1, &request->buffer); |
gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, request->buffer); |
gl_->BufferData(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, |
@@ -475,20 +451,21 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
const SkColorType color_type, |
const base::Callback<void(bool)>& callback, |
GLHelper::ScalerQuality quality) { |
- if (!IsReadbackConfigSupported(color_type)) { |
+ GLenum format, type; |
+ size_t bytes_per_pixel; |
+ FormatSupport supported = |
+ GetReadbackConfig(color_type, true, &format, &type, &bytes_per_pixel); |
+ if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { |
callback.Run(false); |
return; |
} |
+ |
GLuint texture = ScaleTexture(src_texture, |
src_size, |
src_subrect, |
dst_size, |
true, |
-#if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
- true, |
-#else |
- false, |
-#endif |
+ (supported == GLHelperReadbackSupport::SWIZZLE), |
color_type, |
quality); |
DCHECK(texture); |
@@ -501,24 +478,13 @@ void GLHelper::CopyTextureToImpl::CropScaleReadbackAndCleanTexture( |
GL_TEXTURE_2D, |
texture, |
0); |
- int bytes_per_pixel = 4; |
- switch (color_type) { |
- case kN32_SkColorType: |
- // Do nothing params already set. |
- break; |
- case kRGB_565_SkColorType: |
- bytes_per_pixel = 2; |
- break; |
- default: |
- NOTREACHED(); |
- break; |
- } |
ReadbackAsync(dst_size, |
dst_size.width() * bytes_per_pixel, |
dst_size.width() * bytes_per_pixel, |
out, |
- color_type, |
- kSwizzleNone, |
+ format, |
+ type, |
+ bytes_per_pixel, |
callback); |
gl_->DeleteTextures(1, &texture); |
} |
@@ -528,8 +494,13 @@ void GLHelper::CopyTextureToImpl::ReadbackTextureSync( |
const gfx::Rect& src_rect, |
unsigned char* out, |
SkColorType color_type) { |
- if (!IsReadbackConfigSupported(color_type)) |
+ GLenum format, type; |
+ size_t bytes_per_pixel; |
+ FormatSupport supported = |
+ GetReadbackConfig(color_type, false, &format, &type, &bytes_per_pixel); |
+ if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { |
return; |
+ } |
ScopedFramebuffer dst_framebuffer(gl_); |
ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
@@ -537,11 +508,6 @@ void GLHelper::CopyTextureToImpl::ReadbackTextureSync( |
ScopedTextureBinder<GL_TEXTURE_2D> texture_binder(gl_, texture); |
gl_->FramebufferTexture2D( |
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); |
- GLenum format = |
- (color_type == kRGB_565_SkColorType) ? GL_RGB : GL_RGBA; |
- GLenum type = (color_type == kRGB_565_SkColorType) |
- ? GL_UNSIGNED_SHORT_5_6_5 |
- : GL_UNSIGNED_BYTE; |
gl_->ReadPixels(src_rect.x(), |
src_rect.y(), |
src_rect.width(), |
@@ -557,8 +523,14 @@ void GLHelper::CopyTextureToImpl::ReadbackTextureAsync( |
unsigned char* out, |
SkColorType color_type, |
const base::Callback<void(bool)>& callback) { |
- if (!IsReadbackConfigSupported(color_type)) |
+ GLenum format, type; |
+ size_t bytes_per_pixel; |
+ FormatSupport supported = |
+ GetReadbackConfig(color_type, false, &format, &type, &bytes_per_pixel); |
+ if (supported == GLHelperReadbackSupport::NOT_SUPPORTED) { |
+ callback.Run(false); |
return; |
+ } |
ScopedFramebuffer dst_framebuffer(gl_); |
ScopedFramebufferBinder<GL_FRAMEBUFFER> framebuffer_binder(gl_, |
@@ -569,13 +541,13 @@ void GLHelper::CopyTextureToImpl::ReadbackTextureAsync( |
GL_TEXTURE_2D, |
texture, |
0); |
- int bytes_per_pixel = (color_type == kRGB_565_SkColorType) ? 2 : 4; |
ReadbackAsync(dst_size, |
dst_size.width() * bytes_per_pixel, |
dst_size.width() * bytes_per_pixel, |
out, |
- color_type, |
- kSwizzleNone, |
+ format, |
+ type, |
+ bytes_per_pixel, |
callback); |
} |
@@ -591,19 +563,10 @@ GLuint GLHelper::CopyTextureToImpl::CopyAndScaleTexture( |
dst_size, |
vertically_flip_texture, |
false, |
- kN32_SkColorType, |
+ kRGBA_8888_SkColorType, // GL_RGBA |
quality); |
} |
-bool GLHelper::CopyTextureToImpl::IsReadbackConfigSupported( |
- SkColorType color_type) { |
- if (!helper_) { |
- DCHECK(helper_); |
- return false; |
- } |
- return helper_->IsReadbackConfigSupported(color_type); |
-} |
- |
void GLHelper::CopyTextureToImpl::ReadbackDone(Request* finished_request, |
int bytes_per_pixel) { |
TRACE_EVENT0("mirror", |
@@ -669,6 +632,16 @@ void GLHelper::CopyTextureToImpl::CancelRequests() { |
} |
} |
+FormatSupport GLHelper::CopyTextureToImpl::GetReadbackConfig( |
+ SkColorType color_type, |
+ bool can_swizzle, |
+ GLenum* format, |
+ GLenum* type, |
+ size_t* bytes_per_pixel) { |
+ return helper_->readback_support_->GetReadbackConfig( |
+ color_type, can_swizzle, format, type, bytes_per_pixel); |
+} |
+ |
GLHelper::GLHelper(GLES2Interface* gl, gpu::ContextSupport* context_support) |
: gl_(gl), |
context_support_(context_support), |
@@ -915,8 +888,9 @@ void GLHelper::CopyTextureToImpl::ReadbackPlane( |
dst_subrect.width() >> size_shift, |
target->stride(plane), |
target->data(plane) + offset, |
- kN32_SkColorType, |
- swizzle, |
+ (swizzle == kSwizzleBGRA) ? GL_BGRA_EXT : GL_RGBA, |
+ GL_UNSIGNED_BYTE, |
+ 4, |
callback); |
} |
@@ -1192,9 +1166,14 @@ void GLHelper::CopyTextureToImpl::ReadbackYUV_MRT::ReadbackYUV( |
media::LetterboxYUV(target, dst_subrect_); |
} |
-bool GLHelper::IsReadbackConfigSupported(SkColorType texture_format) { |
+bool GLHelper::IsReadbackConfigSupported(SkColorType color_type) { |
DCHECK(readback_support_.get()); |
- return readback_support_.get()->IsReadbackConfigSupported(texture_format); |
+ GLenum format, type; |
+ size_t bytes_per_pixel; |
+ FormatSupport support = readback_support_->GetReadbackConfig( |
+ color_type, false, &format, &type, &bytes_per_pixel); |
+ |
+ return (support == GLHelperReadbackSupport::SUPPORTED); |
} |
ReadbackYUVInterface* GLHelper::CopyTextureToImpl::CreateReadbackPipelineYUV( |
@@ -1206,15 +1185,19 @@ ReadbackYUVInterface* GLHelper::CopyTextureToImpl::CreateReadbackPipelineYUV( |
bool flip_vertically, |
bool use_mrt) { |
helper_->InitScalerImpl(); |
- // Query preferred format for glReadPixels, if is is GL_BGRA then use that |
- // and trigger the appropriate swizzle in the YUV shaders. |
- GLint format = 0, type = 0; |
+ // Just query if the best readback configuration needs a swizzle In |
+ // ReadbackPlane() we will choose GL_RGBA/GL_BGRA_EXT based on swizzle |
+ GLenum format, type; |
+ size_t bytes_per_pixel; |
+ FormatSupport supported = GetReadbackConfig( |
+ kRGBA_8888_SkColorType, true, &format, &type, &bytes_per_pixel); |
+ DCHECK((format == GL_RGBA || format == GL_BGRA_EXT) && |
+ type == GL_UNSIGNED_BYTE); |
+ |
ReadbackSwizzle swizzle = kSwizzleNone; |
- helper_->readback_support_.get()->GetAdditionalFormat(GL_RGBA, |
- GL_UNSIGNED_BYTE, |
- &format, &type); |
- if (format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) |
+ if (supported == GLHelperReadbackSupport::SWIZZLE) |
swizzle = kSwizzleBGRA; |
+ |
if (max_draw_buffers_ >= 2 && use_mrt) { |
return new ReadbackYUV_MRT(gl_, |
this, |