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

Unified Diff: ui/gl/gl_image_memory.cc

Issue 1403283007: Re-land: ui: Add custom stride support to GLImageMemory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more missing static_casts Created 5 years, 1 month 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 | « ui/gl/gl_image_memory.h ('k') | ui/gl/gl_image_ref_counted_memory.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/gl/gl_image_memory.cc
diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc
index 03391ba2a60493cc964ca83c0c4aff89b1aebcb2..3bdf596144679c517ce8e9e2dcd9abc636ddbef7 100644
--- a/ui/gl/gl_image_memory.cc
+++ b/ui/gl/gl_image_memory.cc
@@ -5,6 +5,7 @@
#include "ui/gl/gl_image_memory.h"
#include "base/logging.h"
+#include "base/numerics/safe_conversions.h"
#include "base/trace_event/trace_event.h"
#include "ui/gfx/buffer_format_util.h"
#include "ui/gl/gl_bindings.h"
@@ -71,9 +72,11 @@ bool IsCompressedFormat(BufferFormat format) {
case BufferFormat::RGBA_8888:
case BufferFormat::BGRX_8888:
case BufferFormat::BGRA_8888:
+ return false;
case BufferFormat::YUV_420:
case BufferFormat::YUV_420_BIPLANAR:
case BufferFormat::UYVY_422:
+ NOTREACHED();
return false;
}
@@ -129,10 +132,12 @@ GLenum DataFormat(BufferFormat format) {
case BufferFormat::DXT1:
case BufferFormat::DXT5:
case BufferFormat::ETC1:
+ return TextureFormat(format);
case BufferFormat::YUV_420:
case BufferFormat::YUV_420_BIPLANAR:
case BufferFormat::UYVY_422:
- return TextureFormat(format);
+ NOTREACHED();
+ return 0;
}
NOTREACHED();
@@ -165,13 +170,42 @@ GLenum DataType(BufferFormat format) {
return 0;
}
+GLint DataRowLength(size_t stride, BufferFormat format) {
+ switch (format) {
+ case BufferFormat::RGBA_4444:
+ return base::checked_cast<GLint>(stride) / 2;
+ case BufferFormat::RGBX_8888:
+ case BufferFormat::RGBA_8888:
+ case BufferFormat::BGRX_8888:
+ case BufferFormat::BGRA_8888:
+ return base::checked_cast<GLint>(stride) / 4;
+ case BufferFormat::R_8:
+ return base::checked_cast<GLint>(stride);
+ case BufferFormat::ATC:
+ case BufferFormat::ATCIA:
+ case BufferFormat::DXT1:
+ case BufferFormat::DXT5:
+ case BufferFormat::ETC1:
+ case BufferFormat::YUV_420:
+ case BufferFormat::YUV_420_BIPLANAR:
+ case BufferFormat::UYVY_422:
+ NOTREACHED();
+ return 0;
+ }
+
+ NOTREACHED();
+ return 0;
+}
+
template <typename F>
scoped_ptr<uint8_t[]> GLES2RGBData(const gfx::Size& size,
BufferFormat format,
+ size_t stride,
const uint8_t* data,
F const& data_to_rgb,
GLenum* data_format,
- GLenum* data_type) {
+ GLenum* data_type,
+ GLint* data_row_length) {
TRACE_EVENT2("gpu", "GLES2RGBData", "width", size.width(), "height",
size.height());
@@ -180,58 +214,78 @@ scoped_ptr<uint8_t[]> GLES2RGBData(const gfx::Size& size,
size_t gles2_rgb_data_stride = (size.width() * 3 + 3) & ~3;
scoped_ptr<uint8_t[]> gles2_rgb_data(
new uint8_t[gles2_rgb_data_stride * size.height()]);
- size_t data_stride = RowSizeForBufferFormat(size.width(), format, 0);
for (int y = 0; y < size.height(); ++y) {
for (int x = 0; x < size.width(); ++x) {
- data_to_rgb(&data[y * data_stride + x * 4],
+ data_to_rgb(&data[y * stride + x * 4],
&gles2_rgb_data[y * gles2_rgb_data_stride + x * 3]);
}
}
*data_format = GL_RGB;
*data_type = GL_UNSIGNED_BYTE;
+ *data_row_length = size.width();
return gles2_rgb_data.Pass();
}
scoped_ptr<uint8_t[]> GLES2Data(const gfx::Size& size,
BufferFormat format,
+ size_t stride,
const uint8_t* data,
GLenum* data_format,
- GLenum* data_type) {
+ GLenum* data_type,
+ GLint* data_row_length) {
+ TRACE_EVENT2("gpu", "GLES2Data", "width", size.width(), "height",
+ size.height());
+
switch (format) {
case BufferFormat::RGBX_8888:
- return GLES2RGBData(size, format,
+ return GLES2RGBData(size, format, stride,
data, [](const uint8_t* src, uint8_t* dst) {
dst[0] = src[0];
dst[1] = src[1];
dst[2] = src[2];
- }, data_format, data_type);
+ }, data_format, data_type, data_row_length);
case BufferFormat::BGRX_8888:
- return GLES2RGBData(size, format,
+ return GLES2RGBData(size, format, stride,
data, [](const uint8_t* src, uint8_t* dst) {
dst[0] = src[2];
dst[1] = src[1];
dst[2] = src[0];
- }, data_format, data_type);
+ }, data_format, data_type, data_row_length);
case BufferFormat::RGBA_4444:
case BufferFormat::RGBA_8888:
case BufferFormat::BGRA_8888:
- case BufferFormat::R_8:
+ case BufferFormat::R_8: {
+ size_t gles2_data_stride =
+ RowSizeForBufferFormat(size.width(), format, 0);
+ if (stride == gles2_data_stride)
+ return nullptr; // No data conversion needed
+
+ scoped_ptr<uint8_t[]> gles2_data(
+ new uint8_t[gles2_data_stride * size.height()]);
+ for (int y = 0; y < size.height(); ++y) {
+ memcpy(&gles2_data[y * gles2_data_stride], &data[y * stride],
+ gles2_data_stride);
+ }
+ *data_row_length = size.width();
+ return gles2_data.Pass();
+ }
case BufferFormat::ATC:
case BufferFormat::ATCIA:
case BufferFormat::DXT1:
case BufferFormat::DXT5:
case BufferFormat::ETC1:
+ return nullptr; // No data conversion needed
case BufferFormat::YUV_420:
case BufferFormat::YUV_420_BIPLANAR:
case BufferFormat::UYVY_422:
- // No data conversion needed.
+ NOTREACHED();
return nullptr;
}
NOTREACHED();
- return 0;
+ return nullptr;
}
} // namespace
@@ -240,14 +294,16 @@ GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat)
: size_(size),
internalformat_(internalformat),
memory_(nullptr),
- format_(BufferFormat::RGBA_8888) {}
+ format_(BufferFormat::RGBA_8888),
+ stride_(0) {}
GLImageMemory::~GLImageMemory() {
DCHECK(!memory_);
}
bool GLImageMemory::Initialize(const unsigned char* memory,
- BufferFormat format) {
+ BufferFormat format,
+ size_t stride) {
if (!ValidInternalFormat(internalformat_)) {
LOG(ERROR) << "Invalid internalformat: " << internalformat_;
return false;
@@ -258,12 +314,18 @@ bool GLImageMemory::Initialize(const unsigned char* memory,
return false;
}
+ if (stride < RowSizeForBufferFormat(size_.width(), format, 0) || stride & 3) {
+ LOG(ERROR) << "Invalid stride: " << stride;
+ return false;
+ }
+
DCHECK(memory);
DCHECK(!memory_);
DCHECK(!IsCompressedFormat(format) || size_.width() % 4 == 0);
DCHECK(!IsCompressedFormat(format) || size_.height() % 4 == 0);
memory_ = memory;
format_ = format;
+ stride_ = stride;
return true;
}
@@ -297,16 +359,25 @@ bool GLImageMemory::CopyTexImage(unsigned target) {
static_cast<GLsizei>(BufferSizeForBufferFormat(size_, format_)),
memory_);
} else {
- scoped_ptr<uint8_t[]> gles2_data;
GLenum data_format = DataFormat(format_);
GLenum data_type = DataType(format_);
+ GLint data_row_length = DataRowLength(stride_, format_);
+ scoped_ptr<uint8_t[]> gles2_data;
+
+ if (gfx::GLContext::GetCurrent()->GetVersionInfo()->is_es) {
+ gles2_data = GLES2Data(size_, format_, stride_, memory_, &data_format,
+ &data_type, &data_row_length);
+ }
- if (gfx::GLContext::GetCurrent()->GetVersionInfo()->is_es)
- gles2_data = GLES2Data(size_, format_, memory_, &data_format, &data_type);
+ if (data_row_length != size_.width())
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, data_row_length);
glTexImage2D(target, 0, TextureFormat(format_), size_.width(),
size_.height(), 0, data_format, data_type,
gles2_data ? gles2_data.get() : memory_);
+
+ if (data_row_length != size_.width())
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
return true;
@@ -326,13 +397,12 @@ bool GLImageMemory::CopyTexSubImage(unsigned target,
if (rect.width() != size_.width())
return false;
- // Height must be a multiple of 4 if compressed.
- if (IsCompressedFormat(format_) && rect.height() % 4)
- return false;
-
- const uint8_t* data =
- memory_ + rect.y() * RowSizeForBufferFormat(size_.width(), format_, 0);
+ const uint8_t* data = memory_ + rect.y() * stride_;
if (IsCompressedFormat(format_)) {
+ // Height must be a multiple of 4.
+ if (rect.height() % 4)
+ return false;
+
glCompressedTexSubImage2D(
target, 0, offset.x(), offset.y(), rect.width(), rect.height(),
DataFormat(format_),
@@ -341,16 +411,23 @@ bool GLImageMemory::CopyTexSubImage(unsigned target,
} else {
GLenum data_format = DataFormat(format_);
GLenum data_type = DataType(format_);
+ GLint data_row_length = DataRowLength(stride_, format_);
scoped_ptr<uint8_t[]> gles2_data;
if (gfx::GLContext::GetCurrent()->GetVersionInfo()->is_es) {
- gles2_data =
- GLES2Data(rect.size(), format_, data, &data_format, &data_type);
+ gles2_data = GLES2Data(rect.size(), format_, stride_, data, &data_format,
+ &data_type, &data_row_length);
}
+ if (data_row_length != rect.width())
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, data_row_length);
+
glTexSubImage2D(target, 0, offset.x(), offset.y(), rect.width(),
rect.height(), data_format, data_type,
gles2_data ? gles2_data.get() : data);
+
+ if (data_row_length != rect.width())
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
}
return true;
« no previous file with comments | « ui/gl/gl_image_memory.h ('k') | ui/gl/gl_image_ref_counted_memory.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698