Skip to content

Commit

Permalink
Add support for compressed GPU memory buffers.
Browse files Browse the repository at this point in the history
This CL adds support for compressed GPU buffer formats.

BUG=434699

Review URL: https://codereview.chromium.org/916083002

Cr-Commit-Position: refs/heads/master@{#317765}
  • Loading branch information
christiank authored and Commit bot committed Feb 24, 2015
1 parent 35e044a commit 3113db1
Show file tree
Hide file tree
Showing 19 changed files with 335 additions and 33 deletions.
8 changes: 8 additions & 0 deletions cc/test/test_gpu_memory_buffer_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
16 changes: 16 additions & 0 deletions content/common/gpu/client/gpu_memory_buffer_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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() {
Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
28 changes: 28 additions & 0 deletions content/common/gpu/gpu_command_buffer_stub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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())
Expand Down
10 changes: 10 additions & 0 deletions content/common/gpu/gpu_memory_buffer_factory_io_surface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down
3 changes: 3 additions & 0 deletions gpu/command_buffer/common/capabilities.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
3 changes: 3 additions & 0 deletions gpu/command_buffer/common/capabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
18 changes: 18 additions & 0 deletions gpu/command_buffer/service/feature_info.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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);
Expand All @@ -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.
Expand All @@ -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");
Expand Down
3 changes: 3 additions & 0 deletions gpu/command_buffer/service/feature_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions gpu/command_buffer/service/gles2_cmd_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down
20 changes: 20 additions & 0 deletions gpu/command_buffer/service/image_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand All @@ -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;
Expand Down
8 changes: 8 additions & 0 deletions gpu/command_buffer/tests/gl_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions gpu/ipc/gpu_command_buffer_traits_multi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
13 changes: 12 additions & 1 deletion ui/gfx/gpu_memory_buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
25 changes: 25 additions & 0 deletions ui/gl/gl_image_linux_dma_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 3113db1

Please sign in to comment.