Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1092)

Unified Diff: content/common/gpu/client/gl_helper.cc

Issue 88033002: Add RGB565 Texture readback support in gl_helper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased to ToT! Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « content/common/gpu/client/gl_helper.h ('k') | content/common/gpu/client/gl_helper_benchmark.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..017ed977eda441116657751ee6d9524ad03f3b0d 100644
--- a/content/common/gpu/client/gl_helper.cc
+++ b/content/common/gpu/client/gl_helper.cc
@@ -127,12 +127,14 @@ 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);
void ReadbackTextureSync(GLuint texture,
const gfx::Rect& src_rect,
- unsigned char* out);
+ unsigned char* out,
+ SkBitmap::Config format);
// Reads back bytes from the currently bound frame buffer.
// Note that dst_size is specified in bytes, not pixels.
@@ -140,6 +142,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 +288,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 +334,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 +348,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 +371,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,33 +425,51 @@ 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);
}
void GLHelper::CopyTextureToImpl::ReadbackTextureSync(GLuint texture,
const gfx::Rect& src_rect,
- unsigned char* out) {
+ unsigned char* out,
+ SkBitmap::Config config) {
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);
+ DCHECK((config == SkBitmap::kRGB_565_Config) ||
+ (config == SkBitmap::kARGB_8888_Config));
+ GLenum format = (config == SkBitmap::kRGB_565_Config) ?
+ GL_RGB :
+ GL_RGBA;
+ GLenum type = (config == SkBitmap::kRGB_565_Config) ?
+ GL_UNSIGNED_SHORT_5_6_5 :
+ GL_UNSIGNED_BYTE;
gl_->ReadPixels(src_rect.x(),
src_rect.y(),
src_rect.width(),
src_rect.height(),
- GL_RGBA,
- GL_UNSIGNED_BYTE,
+ format,
+ type,
out);
}
@@ -451,10 +485,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,22 +510,22 @@ 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);
}
gl_->BindBuffer(GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM, 0);
}
-
FinishRequest(request, result);
}
}
@@ -519,7 +555,10 @@ void GLHelper::CopyTextureToImpl::CancelRequests() {
}
GLHelper::GLHelper(GLES2Interface* gl, gpu::ContextSupport* context_support)
- : gl_(gl), context_support_(context_support) {}
+ : gl_(gl),
+ context_support_(context_support),
+ initialized_565_format_check_(false),
+ support_565_format_(false) {}
GLHelper::~GLHelper() {}
@@ -529,6 +568,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 +577,7 @@ void GLHelper::CropScaleReadbackAndCleanTexture(
src_subrect,
dst_size,
out,
+ readback_config_rgb565,
callback,
GLHelper::SCALER_QUALITY_FAST);
}
@@ -548,18 +589,22 @@ 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);
}
void GLHelper::ReadbackTextureSync(GLuint texture,
const gfx::Rect& src_rect,
- unsigned char* out) {
+ unsigned char* out,
+ SkBitmap::Config format) {
InitCopyTextToImpl();
- copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out);
+ copy_texture_to_impl_->ReadbackTextureSync(texture, src_rect, out, format);
}
GLuint GLHelper::CopyTexture(GLuint texture, const gfx::Size& size) {
@@ -727,6 +772,46 @@ void GLHelper::CopyTextureFullImage(GLuint texture, const gfx::Size& size) {
GL_TEXTURE_2D, 0, GL_RGB, 0, 0, size.width(), size.height(), 0);
}
+bool GLHelper::CanUseRgb565Readback() {
+ if(initialized_565_format_check_){
+ return support_565_format_;
+ }
+ const int kTestSize = 64;
+ 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,
+ kTestSize,
+ kTestSize,
+ 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);
+ if ((ext_format == GL_RGB) && (ext_type == GL_UNSIGNED_SHORT_5_6_5)) {
+ support_565_format_ = true;
+ }
+ initialized_565_format_check_ = true;
+ return support_565_format_;
+}
+
void GLHelper::CopyTextureToImpl::ReadbackPlane(
TextureFrameBufferPair* source,
const scoped_refptr<media::VideoFrame>& target,
@@ -736,11 +821,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);
}
« no previous file with comments | « content/common/gpu/client/gl_helper.h ('k') | content/common/gpu/client/gl_helper_benchmark.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698