Index: ui/gl/gl_image_memory.cc |
diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc |
index e92cc1f34ed6438f90f6ee64968eedf6660a8120..6b9a51967a0f2e42d41dc192585a4160236ef923 100644 |
--- a/ui/gl/gl_image_memory.cc |
+++ b/ui/gl/gl_image_memory.cc |
@@ -28,6 +28,11 @@ bool ValidInternalFormat(unsigned internalformat) { |
bool ValidFormat(gfx::GpuMemoryBuffer::Format format) { |
switch (format) { |
+ case gfx::GpuMemoryBuffer::ATC: |
+ case gfx::GpuMemoryBuffer::ATCIA: |
+ case gfx::GpuMemoryBuffer::DXT1: |
+ case gfx::GpuMemoryBuffer::DXT5: |
+ case gfx::GpuMemoryBuffer::ETC1: |
case gfx::GpuMemoryBuffer::RGBA_8888: |
case gfx::GpuMemoryBuffer::BGRA_8888: |
return true; |
@@ -39,8 +44,36 @@ bool ValidFormat(gfx::GpuMemoryBuffer::Format format) { |
return false; |
} |
+bool IsCompressedFormat(gfx::GpuMemoryBuffer::Format format) { |
+ switch (format) { |
+ case gfx::GpuMemoryBuffer::ATC: |
+ case gfx::GpuMemoryBuffer::ATCIA: |
+ case gfx::GpuMemoryBuffer::DXT1: |
+ case gfx::GpuMemoryBuffer::DXT5: |
+ case gfx::GpuMemoryBuffer::ETC1: |
+ return true; |
+ case gfx::GpuMemoryBuffer::RGBA_8888: |
+ case gfx::GpuMemoryBuffer::BGRA_8888: |
+ case gfx::GpuMemoryBuffer::RGBX_8888: |
+ return false; |
+ } |
+ |
+ NOTREACHED(); |
+ return false; |
+} |
+ |
GLenum TextureFormat(gfx::GpuMemoryBuffer::Format format) { |
switch (format) { |
+ case gfx::GpuMemoryBuffer::ATC: |
+ return GL_ATC_RGB_AMD; |
+ case gfx::GpuMemoryBuffer::ATCIA: |
+ return GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD; |
+ case gfx::GpuMemoryBuffer::DXT1: |
+ return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; |
+ case gfx::GpuMemoryBuffer::DXT5: |
+ return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; |
+ case gfx::GpuMemoryBuffer::ETC1: |
+ return GL_ETC1_RGB8_OES; |
case gfx::GpuMemoryBuffer::RGBA_8888: |
return GL_RGBA; |
case gfx::GpuMemoryBuffer::BGRA_8888: |
@@ -63,6 +96,11 @@ GLenum DataType(gfx::GpuMemoryBuffer::Format format) { |
case gfx::GpuMemoryBuffer::RGBA_8888: |
case gfx::GpuMemoryBuffer::BGRA_8888: |
return GL_UNSIGNED_BYTE; |
+ case gfx::GpuMemoryBuffer::ATC: |
+ case gfx::GpuMemoryBuffer::ATCIA: |
+ case gfx::GpuMemoryBuffer::DXT1: |
+ case gfx::GpuMemoryBuffer::DXT5: |
+ case gfx::GpuMemoryBuffer::ETC1: |
case gfx::GpuMemoryBuffer::RGBX_8888: |
NOTREACHED(); |
return 0; |
@@ -72,6 +110,15 @@ GLenum DataType(gfx::GpuMemoryBuffer::Format format) { |
return 0; |
} |
+GLsizei SizeInBytes(const gfx::Size& size, |
+ gfx::GpuMemoryBuffer::Format format) { |
+ size_t stride_in_bytes = 0; |
+ bool valid_stride = GLImageMemory::StrideInBytes( |
+ size.width(), format, &stride_in_bytes); |
+ DCHECK(valid_stride); |
+ return static_cast<GLsizei>(stride_in_bytes * size.height()); |
+} |
+ |
} // namespace |
GLImageMemory::GLImageMemory(const gfx::Size& size, unsigned internalformat) |
@@ -105,6 +152,20 @@ bool GLImageMemory::StrideInBytes(size_t width, |
size_t* stride_in_bytes) { |
base::CheckedNumeric<size_t> s = width; |
switch (format) { |
+ case gfx::GpuMemoryBuffer::ATCIA: |
+ case gfx::GpuMemoryBuffer::DXT5: |
+ *stride_in_bytes = width; |
+ return true; |
+ case gfx::GpuMemoryBuffer::ATC: |
+ case gfx::GpuMemoryBuffer::DXT1: |
+ case gfx::GpuMemoryBuffer::ETC1: |
+ DCHECK_EQ(width % 2, 0U); |
+ s /= 2; |
+ if (!s.IsValid()) |
+ return false; |
+ |
+ *stride_in_bytes = s.ValueOrDie(); |
+ return true; |
case gfx::GpuMemoryBuffer::RGBA_8888: |
case gfx::GpuMemoryBuffer::BGRA_8888: |
s *= 4; |
@@ -122,6 +183,30 @@ bool GLImageMemory::StrideInBytes(size_t width, |
return false; |
} |
+// static |
+bool GLImageMemory::ValidSize(const gfx::Size& size, |
+ gfx::GpuMemoryBuffer::Format format) { |
+ switch (format) { |
+ case gfx::GpuMemoryBuffer::ATC: |
+ case gfx::GpuMemoryBuffer::ATCIA: |
+ case gfx::GpuMemoryBuffer::DXT1: |
+ case gfx::GpuMemoryBuffer::DXT5: |
+ case gfx::GpuMemoryBuffer::ETC1: |
+ // Compressed images must have a width and height that's evenly divisible |
+ // by the block size. |
+ return size.width() % 4 == 0 && size.height() % 4 == 0; |
+ case gfx::GpuMemoryBuffer::RGBA_8888: |
+ case gfx::GpuMemoryBuffer::BGRA_8888: |
+ return true; |
+ case gfx::GpuMemoryBuffer::RGBX_8888: |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ NOTREACHED(); |
+ return false; |
+} |
+ |
bool GLImageMemory::Initialize(const unsigned char* memory, |
gfx::GpuMemoryBuffer::Format format) { |
if (!ValidInternalFormat(internalformat_)) { |
@@ -187,11 +272,21 @@ bool GLImageMemory::CopyTexImage(unsigned target) { |
return false; |
DCHECK(memory_); |
- glTexSubImage2D(target, 0, // level |
- 0, // x |
- 0, // y |
- size_.width(), size_.height(), DataFormat(format_), |
- DataType(format_), memory_); |
+ if (IsCompressedFormat(format_)) { |
+ glCompressedTexSubImage2D(target, |
+ 0, // level |
+ 0, // x-offset |
+ 0, // y-offset |
+ size_.width(), size_.height(), |
+ DataFormat(format_), SizeInBytes(size_, format_), |
+ memory_); |
+ } else { |
+ glTexSubImage2D(target, 0, // level |
+ 0, // x |
+ 0, // y |
+ size_.width(), size_.height(), DataFormat(format_), |
+ DataType(format_), memory_); |
+ } |
return true; |
} |
@@ -240,15 +335,24 @@ void GLImageMemory::DoBindTexImage(unsigned target) { |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
- glTexImage2D(GL_TEXTURE_2D, |
- 0, // mip level |
- TextureFormat(format_), |
- size_.width(), |
- size_.height(), |
- 0, // border |
- DataFormat(format_), |
- DataType(format_), |
- memory_); |
+ if (IsCompressedFormat(format_)) { |
+ glCompressedTexImage2D(GL_TEXTURE_2D, |
+ 0, // mip level |
+ TextureFormat(format_), size_.width(), |
+ size_.height(), |
+ 0, // border |
+ SizeInBytes(size_, format_), memory_); |
+ } else { |
+ glTexImage2D(GL_TEXTURE_2D, |
+ 0, // mip level |
+ TextureFormat(format_), |
+ size_.width(), |
+ size_.height(), |
+ 0, // border |
+ DataFormat(format_), |
+ DataType(format_), |
+ memory_); |
+ } |
} |
EGLint attrs[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; |
@@ -265,15 +369,26 @@ void GLImageMemory::DoBindTexImage(unsigned target) { |
} else { |
ScopedTextureBinder texture_binder(GL_TEXTURE_2D, egl_texture_id_); |
- glTexSubImage2D(GL_TEXTURE_2D, |
- 0, // mip level |
- 0, // x-offset |
- 0, // y-offset |
- size_.width(), |
- size_.height(), |
- DataFormat(format_), |
- DataType(format_), |
- memory_); |
+ if (IsCompressedFormat(format_)) { |
+ glCompressedTexSubImage2D(GL_TEXTURE_2D, |
+ 0, // mip level |
+ 0, // x-offset |
+ 0, // y-offset |
+ size_.width(), size_.height(), |
+ DataFormat(format_), |
+ SizeInBytes(size_, format_), |
+ memory_); |
+ } else { |
+ glTexSubImage2D(GL_TEXTURE_2D, |
+ 0, // mip level |
+ 0, // x-offset |
+ 0, // y-offset |
+ size_.width(), |
+ size_.height(), |
+ DataFormat(format_), |
+ DataType(format_), |
+ memory_); |
+ } |
} |
glEGLImageTargetTexture2DOES(target, egl_image_); |
@@ -283,15 +398,24 @@ void GLImageMemory::DoBindTexImage(unsigned target) { |
#endif |
DCHECK_NE(static_cast<GLenum>(GL_TEXTURE_EXTERNAL_OES), target); |
- glTexImage2D(target, |
- 0, // mip level |
- TextureFormat(format_), |
- size_.width(), |
- size_.height(), |
- 0, // border |
- DataFormat(format_), |
- DataType(format_), |
- memory_); |
+ if (IsCompressedFormat(format_)) { |
+ glCompressedTexImage2D(target, |
+ 0, // mip level |
+ TextureFormat(format_), size_.width(), |
+ size_.height(), |
+ 0, // border |
+ SizeInBytes(size_, format_), memory_); |
+ } else { |
+ glTexImage2D(target, |
+ 0, // mip level |
+ TextureFormat(format_), |
+ size_.width(), |
+ size_.height(), |
+ 0, // border |
+ DataFormat(format_), |
+ DataType(format_), |
+ memory_); |
+ } |
} |
} // namespace gfx |