Index: cc/resources/resource_provider.cc |
diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc |
index 787757c3b86f62847ec3ae99a27747bd0553b414..f1e5e326f1ddeca2838fb8d1c29cdd9981146c7d 100644 |
--- a/cc/resources/resource_provider.cc |
+++ b/cc/resources/resource_provider.cc |
@@ -112,7 +112,8 @@ ResourceProvider::Resource::Resource( |
GLenum filter, |
GLenum texture_pool, |
GLint wrap_mode, |
- TextureUsageHint hint) |
+ TextureUsageHint hint, |
+ TextureType texture_type) |
: gl_id(texture_id), |
gl_pixel_buffer_id(0), |
gl_upload_query_id(0), |
@@ -136,7 +137,8 @@ ResourceProvider::Resource::Resource( |
texture_pool(texture_pool), |
wrap_mode(wrap_mode), |
hint(hint), |
- type(GLTexture) { |
+ type(GLTexture), |
+ texture_type(texture_type) { |
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT); |
} |
@@ -169,7 +171,8 @@ ResourceProvider::Resource::Resource( |
texture_pool(0), |
wrap_mode(wrap_mode), |
hint(TextureUsageAny), |
- type(Bitmap) { |
+ type(Bitmap), |
+ texture_type(INVALID_TYPE) { |
DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT); |
} |
@@ -181,7 +184,8 @@ scoped_ptr<ResourceProvider> ResourceProvider::Create( |
OutputSurface* output_surface, |
int highp_threshold_min) { |
scoped_ptr<ResourceProvider> resource_provider( |
- new ResourceProvider(output_surface, highp_threshold_min)); |
+ new ResourceProvider(output_surface, |
+ highp_threshold_min)); |
bool success = false; |
if (resource_provider->Context3d()) { |
@@ -211,12 +215,20 @@ bool ResourceProvider::InUseByConsumer(ResourceId id) { |
} |
ResourceProvider::ResourceId ResourceProvider::CreateResource( |
- gfx::Size size, GLenum format, GLint wrap_mode, TextureUsageHint hint) { |
+ gfx::Size size, |
+ GLenum format, |
+ GLint wrap_mode, |
+ TextureUsageHint hint, |
+ TextureType texture_type) { |
DCHECK(!size.IsEmpty()); |
switch (default_resource_type_) { |
case GLTexture: |
- return CreateGLTexture(size, format, GL_TEXTURE_POOL_UNMANAGED_CHROMIUM, |
- wrap_mode, hint); |
+ return CreateGLTexture(size, |
+ format, |
+ GL_TEXTURE_POOL_UNMANAGED_CHROMIUM, |
+ wrap_mode, |
+ hint, |
+ texture_type); |
case Bitmap: |
// The only wrap_mode currently implemented in software mode is |
// GL_CLAMP_TO_EDGE. |
@@ -232,12 +244,20 @@ ResourceProvider::ResourceId ResourceProvider::CreateResource( |
} |
ResourceProvider::ResourceId ResourceProvider::CreateManagedResource( |
- gfx::Size size, GLenum format, GLint wrap_mode, TextureUsageHint hint) { |
+ gfx::Size size, |
+ GLenum format, |
+ GLint wrap_mode, |
+ TextureUsageHint hint, |
+ TextureType texture_type) { |
DCHECK(!size.IsEmpty()); |
switch (default_resource_type_) { |
case GLTexture: |
- return CreateGLTexture(size, format, GL_TEXTURE_POOL_MANAGED_CHROMIUM, |
- wrap_mode, hint); |
+ return CreateGLTexture(size, |
+ format, |
+ GL_TEXTURE_POOL_MANAGED_CHROMIUM, |
+ wrap_mode, |
+ hint, |
+ texture_type); |
case Bitmap: |
DCHECK(format == GL_RGBA); |
return CreateBitmap(size); |
@@ -254,13 +274,15 @@ ResourceProvider::ResourceId ResourceProvider::CreateGLTexture( |
GLenum format, |
GLenum texture_pool, |
GLint wrap_mode, |
- TextureUsageHint hint) { |
+ TextureUsageHint hint, |
+ TextureType texture_type) { |
DCHECK_LE(size.width(), max_texture_size_); |
DCHECK_LE(size.height(), max_texture_size_); |
DCHECK(thread_checker_.CalledOnValidThread()); |
ResourceId id = next_id_++; |
- Resource resource(0, size, format, GL_LINEAR, texture_pool, wrap_mode, hint); |
+ Resource resource( |
+ 0, size, format, GL_LINEAR, texture_pool, wrap_mode, hint, texture_type); |
resource.allocated = false; |
resources_[id] = resource; |
return id; |
@@ -297,8 +319,14 @@ ResourceProvider::CreateResourceFromExternalTexture( |
texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
ResourceId id = next_id_++; |
- Resource resource(texture_id, gfx::Size(), 0, GL_LINEAR, 0, GL_CLAMP_TO_EDGE, |
- TextureUsageAny); |
+ Resource resource(texture_id, |
+ gfx::Size(), |
+ 0, |
+ GL_LINEAR, |
+ 0, |
+ GL_CLAMP_TO_EDGE, |
+ TextureUsageAny, |
+ INVALID_TYPE); |
resource.external = true; |
resource.allocated = true; |
resources_[id] = resource; |
@@ -313,8 +341,14 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox( |
DCHECK(mailbox.IsValid()); |
Resource& resource = resources_[id]; |
if (mailbox.IsTexture()) { |
- resource = Resource(0, gfx::Size(), 0, GL_LINEAR, 0, GL_CLAMP_TO_EDGE, |
- TextureUsageAny); |
+ resource = Resource(0, |
+ gfx::Size(), |
+ 0, |
+ GL_LINEAR, |
+ 0, |
+ GL_CLAMP_TO_EDGE, |
+ TextureUsageAny, |
+ INVALID_TYPE); |
} else { |
DCHECK(mailbox.IsSharedMemory()); |
base::SharedMemory* shared_memory = mailbox.shared_memory(); |
@@ -433,7 +467,8 @@ void ResourceProvider::SetPixels(ResourceId id, |
source_rect, |
dest_offset, |
resource->format, |
- resource->size); |
+ resource->size, |
+ resource->texture_type); |
} |
if (resource->pixels) { |
@@ -746,7 +781,9 @@ bool ResourceProvider::InitializeGL() { |
use_texture_usage_hint_ = caps.texture_usage; |
texture_uploader_ = |
- TextureUploader::Create(context3d, use_map_sub, use_shallow_flush_); |
+ TextureUploader::Create(context3d, |
+ use_map_sub, |
+ use_shallow_flush_); |
GLC(context3d, context3d->getIntegerv(GL_MAX_TEXTURE_SIZE, |
&max_texture_size_)); |
best_texture_format_ = PlatformColor::BestTextureFormat(use_bgra); |
@@ -911,8 +948,14 @@ void ResourceProvider::ReceiveFromChild( |
it->mailbox.name)); |
ResourceId id = next_id_++; |
Resource resource( |
- texture_id, it->size, it->format, it->filter, 0, GL_CLAMP_TO_EDGE, |
- TextureUsageAny); |
+ texture_id, |
+ it->size, |
+ it->format, |
+ it->filter, |
+ 0, |
+ GL_CLAMP_TO_EDGE, |
+ TextureUsageAny, |
+ static_cast<TextureType>(it->texture_type)); |
resource.mailbox.SetName(it->mailbox); |
// Don't allocate a texture for a child. |
resource.allocated = true; |
@@ -967,6 +1010,7 @@ void ResourceProvider::TransferResource(WebGraphicsContext3D* context, |
resource->format = source->format; |
resource->filter = source->filter; |
resource->size = source->size; |
+ resource->texture_type = source->texture_type; |
// TODO(skaslev) Implement this path for shared memory resources. |
DCHECK(!source->mailbox.IsSharedMemory()); |
@@ -1003,9 +1047,11 @@ void ResourceProvider::AcquirePixelBuffer(ResourceId id) { |
context3d->bindBuffer( |
GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, |
resource->gl_pixel_buffer_id); |
+ size_t bytes_per_pixel = |
+ BytesPerPixel(best_texture_format_, resource->texture_type); |
context3d->bufferData( |
GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, |
- 4 * resource->size.GetArea(), |
+ bytes_per_pixel * resource->size.GetArea(), |
NULL, |
GL_DYNAMIC_DRAW); |
context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); |
@@ -1176,6 +1222,7 @@ void ResourceProvider::BeginSetPixels(ResourceId id) { |
context3d->beginQueryEXT( |
GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM, |
resource->gl_upload_query_id); |
+ GLenum texture_data_type = GetTextureDataType(resource->texture_type); |
if (allocate) { |
context3d->asyncTexImage2DCHROMIUM(GL_TEXTURE_2D, |
0, /* level */ |
@@ -1184,7 +1231,7 @@ void ResourceProvider::BeginSetPixels(ResourceId id) { |
resource->size.height(), |
0, /* border */ |
resource->format, |
- GL_UNSIGNED_BYTE, |
+ texture_data_type, |
NULL); |
} else { |
context3d->asyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D, |
@@ -1194,7 +1241,7 @@ void ResourceProvider::BeginSetPixels(ResourceId id) { |
resource->size.width(), |
resource->size.height(), |
resource->format, |
- GL_UNSIGNED_BYTE, |
+ texture_data_type, |
NULL); |
} |
context3d->endQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM); |
@@ -1327,7 +1374,8 @@ void ResourceProvider::LazyAllocate(Resource* resource) { |
size.height(), |
0, |
format, |
- GL_UNSIGNED_BYTE, |
+ GetTextureDataType( |
+ resource->texture_type), |
NULL)); |
} |
} |
@@ -1432,4 +1480,51 @@ WebKit::WebGraphicsContext3D* ResourceProvider::Context3d() const { |
return context_provider ? context_provider->Context3d() : NULL; |
} |
+size_t ResourceProvider::BytesPerPixel(GLenum format, TextureType type) { |
+ size_t components_per_pixel = 0; |
+ switch (format) { |
+ case GL_RGBA: |
+ components_per_pixel = 4; |
+ break; |
+ case GL_BGRA_EXT: |
+ components_per_pixel = 4; |
+ break; |
+ case GL_LUMINANCE: |
+ components_per_pixel = 1; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+ size_t bits_per_component = 0; |
+ switch (type) { |
+ case RGBA_8888: |
+ case BGRA_8888: |
+ bits_per_component = 8; |
+ break; |
+ case RGBA_4444: |
+ bits_per_component = 4; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ } |
+ const size_t kBitsPerByte = 8; |
+ return (components_per_pixel * bits_per_component) / kBitsPerByte; |
+} |
+ |
+GLenum ResourceProvider::GetTextureDataType(GLenum texture_type) { |
+ GLenum texture_data_type = GL_UNSIGNED_BYTE; |
+ switch (texture_type) { |
+ case RGBA_4444: |
+ texture_data_type = GL_UNSIGNED_SHORT_4_4_4_4; |
+ break; |
+ case RGBA_8888: |
+ texture_data_type = GL_UNSIGNED_BYTE; |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
+ } |
+ return texture_data_type; |
+} |
+ |
} // namespace cc |