Chromium Code Reviews| 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..fc24261c6cbeb2ef10306518d52cb2adad38c5c7 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 CompressedFormat(gfx::GpuMemoryBuffer::Format format) { |
|
piman
2015/02/19 23:52:04
nit: IsCompressedFormat?
christiank
2015/02/20 08:32:14
Fixed! I originally went with CompressedFormat to
|
| + 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; |
| } |
| +size_t 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 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 (CompressedFormat(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 (CompressedFormat(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 (CompressedFormat(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 (CompressedFormat(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 |