summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchristiank <christiank@opera.com>2015-02-25 01:41:25 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-25 09:42:00 +0000
commit07b6d8b077f5a5e09b1106c7aa6d916e5d4f9e63 (patch)
tree4fd65d9fe165b0a23afef4bb64a5e6aa806168e7
parent3d8d4115aa6c0f1a34081e1553a724c5f4247c6c (diff)
downloadchromium_src-07b6d8b077f5a5e09b1106c7aa6d916e5d4f9e63.zip
chromium_src-07b6d8b077f5a5e09b1106c7aa6d916e5d4f9e63.tar.gz
chromium_src-07b6d8b077f5a5e09b1106c7aa6d916e5d4f9e63.tar.bz2
Add support for compressed GPU memory buffers.
This CL adds support for compressed GPU buffer formats. BUG=434699 Committed: https://crrev.com/3113db1250a2687c030585f6045f2ef242b98db6 Cr-Commit-Position: refs/heads/master@{#317765} Review URL: https://codereview.chromium.org/916083002 Cr-Commit-Position: refs/heads/master@{#318004}
-rw-r--r--cc/test/test_gpu_memory_buffer_manager.cc8
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl.cc16
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc5
-rw-r--r--content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc5
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc28
-rw-r--r--content/common/gpu/gpu_memory_buffer_factory_io_surface.cc10
-rw-r--r--gpu/command_buffer/common/capabilities.cc3
-rw-r--r--gpu/command_buffer/common/capabilities.h3
-rw-r--r--gpu/command_buffer/service/feature_info.cc18
-rw-r--r--gpu/command_buffer/service/feature_info.h3
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc6
-rw-r--r--gpu/command_buffer/service/image_factory.cc20
-rw-r--r--gpu/command_buffer/tests/gl_manager.cc8
-rw-r--r--gpu/ipc/gpu_command_buffer_traits_multi.h3
-rw-r--r--ui/gfx/gpu_memory_buffer.h13
-rw-r--r--ui/gl/gl_image_linux_dma_buffer.cc25
-rw-r--r--ui/gl/gl_image_memory.cc188
-rw-r--r--ui/gl/gl_image_memory.h3
-rw-r--r--ui/gl/gl_image_shared_memory.cc3
-rw-r--r--ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc5
20 files changed, 340 insertions, 33 deletions
diff --git a/cc/test/test_gpu_memory_buffer_manager.cc b/cc/test/test_gpu_memory_buffer_manager.cc
index 196922f..7430051 100644
--- a/cc/test/test_gpu_memory_buffer_manager.cc
+++ b/cc/test/test_gpu_memory_buffer_manager.cc
@@ -12,6 +12,14 @@ namespace {
size_t StrideInBytes(size_t width, gfx::GpuMemoryBuffer::Format format) {
switch (format) {
+ case gfx::GpuMemoryBuffer::ATCIA:
+ case gfx::GpuMemoryBuffer::DXT5:
+ return width;
+ case gfx::GpuMemoryBuffer::ATC:
+ case gfx::GpuMemoryBuffer::DXT1:
+ case gfx::GpuMemoryBuffer::ETC1:
+ DCHECK_EQ(width % 2, 0U);
+ return width / 2;
case gfx::GpuMemoryBuffer::RGBA_8888:
case gfx::GpuMemoryBuffer::RGBX_8888:
case gfx::GpuMemoryBuffer::BGRA_8888:
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl.cc b/content/common/gpu/client/gpu_memory_buffer_impl.cc
index 4b05bbf..e2a48be 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl.cc
@@ -8,6 +8,7 @@
#include "base/numerics/safe_math.h"
#include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
#include "ui/gl/gl_bindings.h"
+#include "ui/gl/gl_image_memory.h"
#if defined(OS_MACOSX)
#include "content/common/gpu/client/gpu_memory_buffer_impl_io_surface.h"
@@ -33,6 +34,7 @@ GpuMemoryBufferImpl::GpuMemoryBufferImpl(gfx::GpuMemoryBufferId id,
callback_(callback),
mapped_(false),
destruction_sync_point_(0) {
+ DCHECK(gfx::GLImageMemory::ValidSize(size, format));
}
GpuMemoryBufferImpl::~GpuMemoryBufferImpl() {
@@ -82,6 +84,20 @@ bool GpuMemoryBufferImpl::StrideInBytes(size_t width,
size_t* stride_in_bytes) {
base::CheckedNumeric<size_t> s = width;
switch (format) {
+ case ATCIA:
+ case DXT5:
+ *stride_in_bytes = width;
+ return true;
+ case ATC:
+ case DXT1:
+ case ETC1:
+ DCHECK_EQ(width % 2, 0U);
+ s /= 2;
+ if (!s.IsValid())
+ return false;
+
+ *stride_in_bytes = s.ValueOrDie();
+ return true;
case RGBA_8888:
case RGBX_8888:
case BGRA_8888:
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc
index 1ea7301..ade8e1a 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.cc
@@ -115,6 +115,11 @@ GpuMemoryBufferImplSharedMemory::CreateFromHandle(
// static
bool GpuMemoryBufferImplSharedMemory::IsFormatSupported(Format format) {
switch (format) {
+ case ATC:
+ case ATCIA:
+ case DXT1:
+ case DXT5:
+ case ETC1:
case RGBA_8888:
case BGRA_8888:
return true;
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc
index b645b8c..440dbfc 100644
--- a/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_surface_texture.cc
@@ -16,6 +16,11 @@ int WindowFormat(gfx::GpuMemoryBuffer::Format format) {
switch (format) {
case gfx::GpuMemoryBuffer::RGBA_8888:
return WINDOW_FORMAT_RGBA_8888;
+ 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:
case gfx::GpuMemoryBuffer::BGRA_8888:
NOTREACHED();
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index 87f0d05..c108a99 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -140,6 +140,29 @@ DevToolsChannelData::CreateForChannel(GpuChannel* channel) {
return new DevToolsChannelData(res.release());
}
+bool IsSupportedImageFormat(const gpu::Capabilities& capabilities,
+ gfx::GpuMemoryBuffer::Format format) {
+ switch (format) {
+ case gfx::GpuMemoryBuffer::ATC:
+ case gfx::GpuMemoryBuffer::ATCIA:
+ return capabilities.texture_format_atc;
+ case gfx::GpuMemoryBuffer::BGRA_8888:
+ return capabilities.texture_format_bgra8888;
+ case gfx::GpuMemoryBuffer::DXT1:
+ return capabilities.texture_format_dxt1;
+ case gfx::GpuMemoryBuffer::DXT5:
+ return capabilities.texture_format_dxt5;
+ case gfx::GpuMemoryBuffer::ETC1:
+ return capabilities.texture_format_etc1;
+ case gfx::GpuMemoryBuffer::RGBA_8888:
+ case gfx::GpuMemoryBuffer::RGBX_8888:
+ return true;
+ }
+
+ NOTREACHED();
+ return false;
+}
+
} // namespace
GpuCommandBufferStub::GpuCommandBufferStub(
@@ -956,6 +979,11 @@ void GpuCommandBufferStub::OnCreateImage(int32 id,
return;
}
+ if (!IsSupportedImageFormat(decoder_->GetCapabilities(), format)) {
+ LOG(ERROR) << "Image format is not supported.";
+ return;
+ }
+
scoped_refptr<gfx::GLImage> image = channel()->CreateImageForGpuMemoryBuffer(
handle, size, format, internalformat);
if (!image.get())
diff --git a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
index ba00ea2..604c1b4 100644
--- a/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
+++ b/content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
@@ -31,6 +31,11 @@ int32 BytesPerPixel(gfx::GpuMemoryBuffer::Format format) {
switch (format) {
case gfx::GpuMemoryBuffer::BGRA_8888:
return 4;
+ 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::RGBX_8888:
NOTREACHED();
@@ -45,6 +50,11 @@ int32 PixelFormat(gfx::GpuMemoryBuffer::Format format) {
switch (format) {
case gfx::GpuMemoryBuffer::BGRA_8888:
return 'BGRA';
+ 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::RGBX_8888:
NOTREACHED();
diff --git a/gpu/command_buffer/common/capabilities.cc b/gpu/command_buffer/common/capabilities.cc
index 97c26d8..58efef0 100644
--- a/gpu/command_buffer/common/capabilities.cc
+++ b/gpu/command_buffer/common/capabilities.cc
@@ -28,7 +28,10 @@ Capabilities::Capabilities()
uniform_buffer_offset_alignment(1),
post_sub_buffer(false),
egl_image_external(false),
+ texture_format_atc(false),
texture_format_bgra8888(false),
+ texture_format_dxt1(false),
+ texture_format_dxt5(false),
texture_format_etc1(false),
texture_format_etc1_npot(false),
texture_rectangle(false),
diff --git a/gpu/command_buffer/common/capabilities.h b/gpu/command_buffer/common/capabilities.h
index 92c3c19..b749d5c 100644
--- a/gpu/command_buffer/common/capabilities.h
+++ b/gpu/command_buffer/common/capabilities.h
@@ -81,7 +81,10 @@ struct GPU_EXPORT Capabilities {
bool post_sub_buffer;
bool egl_image_external;
+ bool texture_format_atc;
bool texture_format_bgra8888;
+ bool texture_format_dxt1;
+ bool texture_format_dxt5;
bool texture_format_etc1;
bool texture_format_etc1_npot;
bool texture_rectangle;
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index 79cc361..897afd3 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -132,7 +132,10 @@ FeatureInfo::FeatureFlags::FeatureFlags()
use_arb_occlusion_query2_for_occlusion_query_boolean(false),
use_arb_occlusion_query_for_occlusion_query_boolean(false),
native_vertex_array_object(false),
+ ext_texture_format_atc(false),
ext_texture_format_bgra8888(false),
+ ext_texture_format_dxt1(false),
+ ext_texture_format_dxt5(false),
enable_shader_name_hashing(false),
enable_samplers(false),
ext_draw_buffers(false),
@@ -333,6 +336,8 @@ void FeatureInfo::InitializeFeatures() {
}
if (enable_dxt1) {
+ feature_flags_.ext_texture_format_dxt1 = true;
+
AddExtensionString("GL_EXT_texture_compression_dxt1");
validators_.compressed_texture_format.AddValue(
GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
@@ -350,6 +355,8 @@ void FeatureInfo::InitializeFeatures() {
}
if (enable_dxt5) {
+ feature_flags_.ext_texture_format_dxt5 = true;
+
// The difference between GL_EXT_texture_compression_s3tc and
// GL_CHROMIUM_texture_compression_dxt5 is that the former
// requires on the fly compression. The latter does not.
@@ -358,6 +365,17 @@ void FeatureInfo::InitializeFeatures() {
GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
}
+ bool have_atc = extensions.Contains("GL_AMD_compressed_ATC_texture") ||
+ extensions.Contains("GL_ATI_texture_compression_atitc");
+ if (have_atc) {
+ feature_flags_.ext_texture_format_atc = true;
+
+ AddExtensionString("GL_AMD_compressed_ATC_texture");
+ validators_.compressed_texture_format.AddValue(GL_ATC_RGB_AMD);
+ validators_.compressed_texture_format.AddValue(
+ GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD);
+ }
+
// Check if we should enable GL_EXT_texture_filter_anisotropic.
if (extensions.Contains("GL_EXT_texture_filter_anisotropic")) {
AddExtensionString("GL_EXT_texture_filter_anisotropic");
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index 8bc3e4f..1a1870d 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -56,7 +56,10 @@ class GPU_EXPORT FeatureInfo : public base::RefCounted<FeatureInfo> {
bool use_arb_occlusion_query2_for_occlusion_query_boolean;
bool use_arb_occlusion_query_for_occlusion_query_boolean;
bool native_vertex_array_object;
+ bool ext_texture_format_atc;
bool ext_texture_format_bgra8888;
+ bool ext_texture_format_dxt1;
+ bool ext_texture_format_dxt5;
bool enable_shader_name_hashing;
bool enable_samplers;
bool ext_draw_buffers;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index e61dc22..50ae103 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -2858,8 +2858,14 @@ Capabilities GLES2DecoderImpl::GetCapabilities() {
caps.egl_image_external =
feature_info_->feature_flags().oes_egl_image_external;
+ caps.texture_format_atc =
+ feature_info_->feature_flags().ext_texture_format_atc;
caps.texture_format_bgra8888 =
feature_info_->feature_flags().ext_texture_format_bgra8888;
+ caps.texture_format_dxt1 =
+ feature_info_->feature_flags().ext_texture_format_dxt1;
+ caps.texture_format_dxt5 =
+ feature_info_->feature_flags().ext_texture_format_dxt5;
caps.texture_format_etc1 =
feature_info_->feature_flags().oes_compressed_etc1_rgb8_texture;
caps.texture_format_etc1_npot =
diff --git a/gpu/command_buffer/service/image_factory.cc b/gpu/command_buffer/service/image_factory.cc
index 0b740d8..1665c1e 100644
--- a/gpu/command_buffer/service/image_factory.cc
+++ b/gpu/command_buffer/service/image_factory.cc
@@ -22,6 +22,16 @@ gfx::GpuMemoryBuffer::Format ImageFactory::ImageFormatToGpuMemoryBufferFormat(
return gfx::GpuMemoryBuffer::RGBX_8888;
case GL_RGBA:
return gfx::GpuMemoryBuffer::RGBA_8888;
+ case GL_ATC_RGB_AMD:
+ return gfx::GpuMemoryBuffer::ATC;
+ case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ return gfx::GpuMemoryBuffer::ATCIA;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return gfx::GpuMemoryBuffer::DXT1;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ return gfx::GpuMemoryBuffer::DXT5;
+ case GL_ETC1_RGB8_OES:
+ return gfx::GpuMemoryBuffer::ETC1;
default:
NOTREACHED();
return gfx::GpuMemoryBuffer::RGBA_8888;
@@ -49,6 +59,11 @@ bool ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat(
switch (internalformat) {
case GL_RGB:
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::RGBX_8888:
return true;
case gfx::GpuMemoryBuffer::RGBA_8888:
@@ -61,6 +76,11 @@ bool ImageFactory::IsImageFormatCompatibleWithGpuMemoryBufferFormat(
switch (format) {
case gfx::GpuMemoryBuffer::RGBX_8888:
return false;
+ 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;
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 43120b9..4e4eccb 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -40,6 +40,14 @@ namespace {
size_t StrideInBytes(size_t width, gfx::GpuMemoryBuffer::Format format) {
switch (format) {
+ case gfx::GpuMemoryBuffer::ATCIA:
+ case gfx::GpuMemoryBuffer::DXT5:
+ return width;
+ case gfx::GpuMemoryBuffer::ATC:
+ case gfx::GpuMemoryBuffer::DXT1:
+ case gfx::GpuMemoryBuffer::ETC1:
+ DCHECK_EQ(width % 2, 0U);
+ return width / 2;
case gfx::GpuMemoryBuffer::RGBA_8888:
case gfx::GpuMemoryBuffer::BGRA_8888:
return width * 4;
diff --git a/gpu/ipc/gpu_command_buffer_traits_multi.h b/gpu/ipc/gpu_command_buffer_traits_multi.h
index 2f834a0..810dbf8 100644
--- a/gpu/ipc/gpu_command_buffer_traits_multi.h
+++ b/gpu/ipc/gpu_command_buffer_traits_multi.h
@@ -47,7 +47,10 @@ IPC_STRUCT_TRAITS_BEGIN(gpu::Capabilities)
IPC_STRUCT_TRAITS_MEMBER(uniform_buffer_offset_alignment)
IPC_STRUCT_TRAITS_MEMBER(post_sub_buffer)
IPC_STRUCT_TRAITS_MEMBER(egl_image_external)
+ IPC_STRUCT_TRAITS_MEMBER(texture_format_atc)
IPC_STRUCT_TRAITS_MEMBER(texture_format_bgra8888)
+ IPC_STRUCT_TRAITS_MEMBER(texture_format_dxt1)
+ IPC_STRUCT_TRAITS_MEMBER(texture_format_dxt5)
IPC_STRUCT_TRAITS_MEMBER(texture_format_etc1)
IPC_STRUCT_TRAITS_MEMBER(texture_format_etc1_npot)
IPC_STRUCT_TRAITS_MEMBER(texture_rectangle)
diff --git a/ui/gfx/gpu_memory_buffer.h b/ui/gfx/gpu_memory_buffer.h
index e6ce5d2..3aa0964 100644
--- a/ui/gfx/gpu_memory_buffer.h
+++ b/ui/gfx/gpu_memory_buffer.h
@@ -42,7 +42,18 @@ class GFX_EXPORT GpuMemoryBuffer {
public:
// The format needs to be taken into account when mapping a buffer into the
// client's address space.
- enum Format { RGBA_8888, RGBX_8888, BGRA_8888, FORMAT_LAST = BGRA_8888 };
+ enum Format {
+ ATC,
+ ATCIA,
+ DXT1,
+ DXT5,
+ ETC1,
+ RGBA_8888,
+ RGBX_8888,
+ BGRA_8888,
+
+ FORMAT_LAST = BGRA_8888
+ };
// The usage mode affects how a buffer can be used. Only buffers created with
// MAP can be mapped into the client's address space and accessed by the CPU.
diff --git a/ui/gl/gl_image_linux_dma_buffer.cc b/ui/gl/gl_image_linux_dma_buffer.cc
index 1dec942..04ad06b 100644
--- a/ui/gl/gl_image_linux_dma_buffer.cc
+++ b/ui/gl/gl_image_linux_dma_buffer.cc
@@ -18,10 +18,25 @@ namespace {
bool ValidFormat(unsigned internalformat, gfx::GpuMemoryBuffer::Format format) {
switch (internalformat) {
+ case GL_ATC_RGB_AMD:
+ return format == gfx::GpuMemoryBuffer::ATC;
+ case GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+ return format == gfx::GpuMemoryBuffer::ATCIA;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ return format == gfx::GpuMemoryBuffer::DXT1;
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ return format == gfx::GpuMemoryBuffer::DXT5;
+ case GL_ETC1_RGB8_OES:
+ return format == gfx::GpuMemoryBuffer::ETC1;
case GL_RGB:
switch (format) {
case gfx::GpuMemoryBuffer::RGBX_8888:
return true;
+ 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 false;
@@ -32,6 +47,11 @@ bool ValidFormat(unsigned internalformat, gfx::GpuMemoryBuffer::Format format) {
switch (format) {
case gfx::GpuMemoryBuffer::BGRA_8888:
return true;
+ 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:
case gfx::GpuMemoryBuffer::RGBA_8888:
return false;
@@ -49,6 +69,11 @@ EGLint FourCC(gfx::GpuMemoryBuffer::Format format) {
return DRM_FORMAT_ARGB8888;
case gfx::GpuMemoryBuffer::RGBX_8888:
return DRM_FORMAT_XRGB8888;
+ 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:
NOTREACHED();
return 0;
diff --git a/ui/gl/gl_image_memory.cc b/ui/gl/gl_image_memory.cc
index e92cc1f..6b9a519 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
diff --git a/ui/gl/gl_image_memory.h b/ui/gl/gl_image_memory.h
index a50a380..befc3a8 100644
--- a/ui/gl/gl_image_memory.h
+++ b/ui/gl/gl_image_memory.h
@@ -26,6 +26,9 @@ class GL_EXPORT GLImageMemory : public GLImage {
gfx::GpuMemoryBuffer::Format format,
size_t* stride_in_bytes);
+ static bool ValidSize(const gfx::Size& size,
+ gfx::GpuMemoryBuffer::Format format);
+
bool Initialize(const unsigned char* memory,
gfx::GpuMemoryBuffer::Format format);
diff --git a/ui/gl/gl_image_shared_memory.cc b/ui/gl/gl_image_shared_memory.cc
index d9e31a7..363ebf5 100644
--- a/ui/gl/gl_image_shared_memory.cc
+++ b/ui/gl/gl_image_shared_memory.cc
@@ -18,6 +18,9 @@ bool SizeInBytes(const gfx::Size& size,
if (size.IsEmpty())
return false;
+ if (!GLImageMemory::ValidSize(size, format))
+ return false;
+
size_t stride_in_bytes = 0;
if (!GLImageMemory::StrideInBytes(size.width(), format, &stride_in_bytes))
return false;
diff --git a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc
index 9b463b9..8d6d8142 100644
--- a/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc
+++ b/ui/ozone/gpu/gpu_memory_buffer_factory_ozone_native_buffer.cc
@@ -80,6 +80,11 @@ SurfaceFactoryOzone::BufferFormat GetOzoneFormatFor(
return SurfaceFactoryOzone::RGBA_8888;
case gfx::GpuMemoryBuffer::RGBX_8888:
return SurfaceFactoryOzone::RGBX_8888;
+ case gfx::GpuMemoryBuffer::ATC:
+ case gfx::GpuMemoryBuffer::ATCIA:
+ case gfx::GpuMemoryBuffer::DXT1:
+ case gfx::GpuMemoryBuffer::DXT5:
+ case gfx::GpuMemoryBuffer::ETC1:
case gfx::GpuMemoryBuffer::BGRA_8888:
NOTREACHED();
return SurfaceFactoryOzone::RGBA_8888;