Index: cc/resources/resource_provider.cc |
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc |
index c0e8f1bd205ddd938390c8cbf10b0b46ce466904..89e619098f33d94eca7d2d0f99d0afb9fc1baa48 100644 |
--- a/cc/resources/resource_provider.cc |
+++ b/cc/resources/resource_provider.cc |
@@ -75,6 +75,10 @@ GLenum TextureToStorageFormat(ResourceFormat format) { |
case ALPHA_8: |
case LUMINANCE_8: |
case RGB_565: |
+ case ATC: |
+ case ATC_IA: |
+ case DXT1: |
+ case DXT5: |
case ETC1: |
case RED_8: |
NOTREACHED(); |
@@ -94,6 +98,10 @@ bool IsFormatSupportedForStorage(ResourceFormat format, bool use_bgra) { |
case ALPHA_8: |
case LUMINANCE_8: |
case RGB_565: |
+ case ATC: |
+ case ATC_IA: |
+ case DXT1: |
+ case DXT5: |
case ETC1: |
case RED_8: |
return false; |
@@ -122,12 +130,21 @@ gfx::GpuMemoryBuffer::Format ToGpuMemoryBufferFormat(ResourceFormat format) { |
return gfx::GpuMemoryBuffer::Format::RGBA_8888; |
case BGRA_8888: |
return gfx::GpuMemoryBuffer::Format::BGRA_8888; |
+ case ATC: |
+ return gfx::GpuMemoryBuffer::Format::ATC; |
+ case ATC_IA: |
+ return gfx::GpuMemoryBuffer::Format::ATCIA; |
+ case DXT1: |
+ return gfx::GpuMemoryBuffer::Format::DXT1; |
+ case DXT5: |
+ return gfx::GpuMemoryBuffer::Format::DXT5; |
+ case ETC1: |
+ return gfx::GpuMemoryBuffer::Format::ETC1; |
+ case RED_8: |
case RGBA_4444: |
case ALPHA_8: |
case LUMINANCE_8: |
case RGB_565: |
- case ETC1: |
- case RED_8: |
break; |
} |
NOTREACHED(); |
@@ -419,6 +436,25 @@ ResourceProvider::Resource::Resource(const SharedBitmapId& bitmap_id, |
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT); |
} |
+bool ResourceProvider::Resource::IsCompressed() const { |
+ return IsFormatCompressed(format); |
+} |
+ |
+size_t ResourceProvider::Resource::CompressedSize() const { |
+ switch (format) { |
+ case ATC: |
+ case DXT1: |
+ case ETC1: |
+ return size.width() * size.height() / 2; |
+ case ATC_IA: |
+ case DXT5: |
+ return size.width() * size.height(); |
+ default: |
+ NOTREACHED(); |
+ return 0; |
+ } |
+} |
+ |
ResourceProvider::Child::Child() : marked_for_deletion(false) {} |
ResourceProvider::Child::~Child() {} |
@@ -430,15 +466,13 @@ scoped_ptr<ResourceProvider> ResourceProvider::Create( |
BlockingTaskRunner* blocking_main_thread_task_runner, |
int highp_threshold_min, |
bool use_rgba_4444_texture_format, |
+ bool use_texture_compression, |
size_t id_allocation_chunk_size) { |
- scoped_ptr<ResourceProvider> resource_provider( |
- new ResourceProvider(output_surface, |
- shared_bitmap_manager, |
- gpu_memory_buffer_manager, |
- blocking_main_thread_task_runner, |
- highp_threshold_min, |
- use_rgba_4444_texture_format, |
- id_allocation_chunk_size)); |
+ scoped_ptr<ResourceProvider> resource_provider(new ResourceProvider( |
+ output_surface, shared_bitmap_manager, gpu_memory_buffer_manager, |
+ blocking_main_thread_task_runner, highp_threshold_min, |
+ use_rgba_4444_texture_format, use_texture_compression, |
+ id_allocation_chunk_size)); |
if (resource_provider->ContextGL()) |
resource_provider->InitializeGL(); |
@@ -458,6 +492,43 @@ ResourceProvider::~ResourceProvider() { |
CleanUpGLIfNeeded(); |
} |
+ResourceFormat ResourceProvider::memory_efficient_texture_format( |
+ ResourceFormatUsage usage) const { |
+ if (use_texture_compression_ && usage != FORMAT_USAGE_NATIVE) { |
+ // Try to select the prefered compression method. |
+ switch (preferred_tile_compression_method_) { |
+ case TILE_COMPRESSION_METHOD_ATC: |
+ if (use_compressed_texture_atc_) { |
+ return usage == FORMAT_USAGE_OPAQUE ? ATC : ATC_IA; |
+ } |
+ break; |
+ case TILE_COMPRESSION_METHOD_DXT: |
+ if (use_compressed_texture_dxt_) { |
+ return usage == FORMAT_USAGE_OPAQUE ? DXT1 : DXT5; |
+ } |
+ break; |
+ case TILE_COMPRESSION_METHOD_ETC: |
+ if (use_compressed_texture_etc1_ && usage == FORMAT_USAGE_OPAQUE) { |
+ return ETC1; |
+ } |
+ break; |
+ default: |
+ break; |
+ } |
+ |
+ // Check the formats in preferred order, based on encoding speed and |
+ // compression ratio. |
+ if (use_compressed_texture_atc_) { |
+ return usage == FORMAT_USAGE_OPAQUE ? ATC : ATC_IA; |
+ } |
+ if (use_compressed_texture_dxt_) { |
+ return usage == FORMAT_USAGE_OPAQUE ? DXT1 : DXT5; |
+ } |
+ } |
+ |
+ return use_rgba_4444_texture_format_ ? RGBA_4444 : best_texture_format_; |
+} |
+ |
bool ResourceProvider::InUseByConsumer(ResourceId id) { |
Resource* resource = GetResource(id); |
return resource->lock_for_read_count > 0 || resource->exported_count > 0 || |
@@ -1205,6 +1276,7 @@ ResourceProvider::ResourceProvider( |
BlockingTaskRunner* blocking_main_thread_task_runner, |
int highp_threshold_min, |
bool use_rgba_4444_texture_format, |
+ bool use_texture_compression, |
size_t id_allocation_chunk_size) |
: output_surface_(output_surface), |
shared_bitmap_manager_(shared_bitmap_manager), |
@@ -1218,11 +1290,14 @@ ResourceProvider::ResourceProvider( |
use_texture_storage_ext_(false), |
use_texture_format_bgra_(false), |
use_texture_usage_hint_(false), |
+ use_compressed_texture_atc_(false), |
+ use_compressed_texture_dxt_(false), |
use_compressed_texture_etc1_(false), |
yuv_resource_format_(LUMINANCE_8), |
max_texture_size_(0), |
best_texture_format_(RGBA_8888), |
use_rgba_4444_texture_format_(use_rgba_4444_texture_format), |
+ use_texture_compression_(use_texture_compression), |
id_allocation_chunk_size_(id_allocation_chunk_size), |
use_sync_query_(false) { |
DCHECK(output_surface_->HasClient()); |
@@ -1257,6 +1332,8 @@ void ResourceProvider::InitializeGL() { |
use_texture_storage_ext_ = caps.gpu.texture_storage; |
use_texture_format_bgra_ = caps.gpu.texture_format_bgra8888; |
use_texture_usage_hint_ = caps.gpu.texture_usage; |
+ use_compressed_texture_atc_ = caps.gpu.texture_format_atc; |
+ use_compressed_texture_dxt_ = caps.gpu.texture_format_dxt; |
use_compressed_texture_etc1_ = caps.gpu.texture_format_etc1; |
yuv_resource_format_ = caps.gpu.texture_rg ? RED_8 : LUMINANCE_8; |
use_sync_query_ = caps.gpu.sync_query; |
@@ -1732,7 +1809,6 @@ void ResourceProvider::AcquirePixelBuffer(ResourceId id) { |
DCHECK(resource->origin == Resource::Internal); |
DCHECK_EQ(resource->exported_count, 0); |
DCHECK(!resource->image_id); |
- DCHECK_NE(ETC1, resource->format); |
DCHECK_EQ(GLTexture, resource->type); |
GLES2Interface* gl = ContextGL(); |
@@ -1741,11 +1817,11 @@ void ResourceProvider::AcquirePixelBuffer(ResourceId id) { |
resource->gl_pixel_buffer_id = buffer_id_allocator_->NextId(); |
gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, |
resource->gl_pixel_buffer_id); |
- unsigned bytes_per_pixel = BitsPerPixel(resource->format) / 8; |
- gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, |
- resource->size.height() * |
- RoundUp(bytes_per_pixel * resource->size.width(), 4u), |
- NULL, |
+ unsigned width_in_bytes = |
+ BitsPerPixel(resource->format) * resource->size.width() / 8; |
+ unsigned image_size = resource->size.height() * RoundUp(width_in_bytes, 4u); |
+ DCHECK(image_size); |
+ gl->BufferData(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, image_size, NULL, |
GL_DYNAMIC_DRAW); |
gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); |
} |
@@ -1882,26 +1958,33 @@ void ResourceProvider::BeginSetPixels(ResourceId id) { |
gl->GenQueriesEXT(1, &resource->gl_upload_query_id); |
gl->BeginQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, |
resource->gl_upload_query_id); |
- if (allocate) { |
- gl->AsyncTexImage2DCHROMIUM(GL_TEXTURE_2D, |
- 0, /* level */ |
- GLInternalFormat(resource->format), |
- resource->size.width(), |
- resource->size.height(), |
- 0, /* border */ |
- GLDataFormat(resource->format), |
- GLDataType(resource->format), |
- NULL); |
+ if (resource->IsCompressed()) { |
+ if (allocate) { |
+ gl->AsyncCompressedTexImage2DCHROMIUM( |
+ GL_TEXTURE_2D, 0 /* level */, GLInternalFormat(resource->format), |
+ resource->size.width(), resource->size.height(), 0 /* border */, |
+ resource->CompressedSize(), NULL); |
+ } else { |
+ gl->AsyncCompressedTexSubImage2DCHROMIUM( |
+ GL_TEXTURE_2D, 0 /* level */, 0 /* x */, 0 /* y */, |
+ resource->size.width(), resource->size.height(), |
+ GLInternalFormat(resource->format), resource->CompressedSize(), NULL); |
+ } |
} else { |
- gl->AsyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D, |
- 0, /* level */ |
- 0, /* x */ |
- 0, /* y */ |
- resource->size.width(), |
- resource->size.height(), |
- GLDataFormat(resource->format), |
- GLDataType(resource->format), |
- NULL); |
+ if (allocate) { |
+ gl->AsyncTexImage2DCHROMIUM( |
+ GL_TEXTURE_2D, 0, /* level */ |
+ GLInternalFormat(resource->format), resource->size.width(), |
+ resource->size.height(), 0, /* border */ |
+ GLDataFormat(resource->format), GLDataType(resource->format), NULL); |
+ } else { |
+ gl->AsyncTexSubImage2DCHROMIUM( |
+ GL_TEXTURE_2D, 0, /* level */ |
+ 0, /* x */ |
+ 0, /* y */ |
+ resource->size.width(), resource->size.height(), |
+ GLDataFormat(resource->format), GLDataType(resource->format), NULL); |
+ } |
} |
gl->EndQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM); |
gl->BindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); |
@@ -2035,8 +2118,8 @@ void ResourceProvider::LazyAllocate(Resource* resource) { |
gl->TexStorage2DEXT( |
GL_TEXTURE_2D, 1, storage_format, size.width(), size.height())); |
} else { |
- // ETC1 does not support preallocation. |
- if (format != ETC1) { |
+ // Compressed formats does not support preallocation. |
+ if (!IsFormatCompressed(format)) { |
GLC(gl, |
gl->TexImage2D(GL_TEXTURE_2D, |
0, |
@@ -2101,12 +2184,17 @@ void ResourceProvider::CopyResource(ResourceId source_id, ResourceId dest_id) { |
} |
DCHECK(!dest_resource->image_id); |
dest_resource->allocated = true; |
- gl->CopyTextureCHROMIUM(dest_resource->target, |
- source_resource->gl_id, |
- dest_resource->gl_id, |
- 0, |
- GLInternalFormat(dest_resource->format), |
- GLDataType(dest_resource->format)); |
+ if (!source_resource->IsCompressed()) { |
+ gl->CopyTextureCHROMIUM(dest_resource->target, source_resource->gl_id, |
+ dest_resource->gl_id, 0, |
+ GLInternalFormat(dest_resource->format), |
+ GLDataType(dest_resource->format)); |
+ } else { |
+ gl->CopyCompressedTextureCHROMIUM( |
+ dest_resource->target, source_resource->gl_id, dest_resource->gl_id, |
+ GLInternalFormat(dest_resource->format), |
+ GLDataType(dest_resource->format)); |
+ } |
if (source_resource->gl_read_lock_query_id) { |
// End query and create a read lock fence that will prevent access to |
// source resource until CopyTextureCHROMIUM command has completed. |