| Index: cc/resources/resource_provider.cc
|
| diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc
|
| index 017c2e9cacebe3501bf24af8e4552d7086f12a97..e1cbba56053bdb6b3ddfd43bad47cbebda23d31e 100644
|
| --- a/cc/resources/resource_provider.cc
|
| +++ b/cc/resources/resource_provider.cc
|
| @@ -12,6 +12,7 @@
|
| #include "base/stl_util.h"
|
| #include "base/strings/string_split.h"
|
| #include "base/strings/string_util.h"
|
| +#include "cc/base/util.h"
|
| #include "cc/output/gl_renderer.h" // For the GLC() macro.
|
| #include "cc/resources/platform_color.h"
|
| #include "cc/resources/returned_resource.h"
|
| @@ -34,24 +35,31 @@ namespace {
|
| const double kSoftwareUploadTickRate = 0.000250;
|
| const double kTextureUploadTickRate = 0.004;
|
|
|
| -GLenum TextureToStorageFormat(GLenum texture_format) {
|
| +GLenum TextureToStorageFormat(ResourceFormat format) {
|
| GLenum storage_format = GL_RGBA8_OES;
|
| - switch (texture_format) {
|
| - case GL_RGBA:
|
| + switch (format) {
|
| + case RGBA_8888:
|
| + case RGBA_4444:
|
| + case LUMINANCE_8:
|
| break;
|
| - case GL_BGRA_EXT:
|
| + case BGRA_8888:
|
| storage_format = GL_BGRA8_EXT;
|
| break;
|
| - default:
|
| - NOTREACHED();
|
| - break;
|
| }
|
|
|
| return storage_format;
|
| }
|
|
|
| -bool IsTextureFormatSupportedForStorage(GLenum format) {
|
| - return (format == GL_RGBA || format == GL_BGRA_EXT);
|
| +bool IsFormatSupportedForStorage(ResourceFormat format) {
|
| + switch (format) {
|
| + case RGBA_8888:
|
| + case BGRA_8888:
|
| + return true;
|
| + case RGBA_4444:
|
| + case LUMINANCE_8:
|
| + return false;
|
| + }
|
| + return false;
|
| }
|
|
|
| class ScopedSetActiveTexture {
|
| @@ -95,7 +103,6 @@ ResourceProvider::Resource::Resource()
|
| enable_read_lock_fences(false),
|
| read_lock_fence(NULL),
|
| size(),
|
| - format(0),
|
| original_filter(0),
|
| filter(0),
|
| target(0),
|
| @@ -103,18 +110,19 @@ ResourceProvider::Resource::Resource()
|
| texture_pool(0),
|
| wrap_mode(0),
|
| hint(TextureUsageAny),
|
| - type(static_cast<ResourceType>(0)) {}
|
| + type(static_cast<ResourceType>(0)),
|
| + format(RGBA_8888) {}
|
|
|
| ResourceProvider::Resource::~Resource() {}
|
|
|
| ResourceProvider::Resource::Resource(
|
| unsigned texture_id,
|
| gfx::Size size,
|
| - GLenum format,
|
| GLenum filter,
|
| GLenum texture_pool,
|
| GLint wrap_mode,
|
| - TextureUsageHint hint)
|
| + TextureUsageHint hint,
|
| + ResourceFormat format)
|
| : gl_id(texture_id),
|
| gl_pixel_buffer_id(0),
|
| gl_upload_query_id(0),
|
| @@ -132,7 +140,6 @@ ResourceProvider::Resource::Resource(
|
| enable_read_lock_fences(false),
|
| read_lock_fence(NULL),
|
| size(size),
|
| - format(format),
|
| original_filter(filter),
|
| filter(filter),
|
| target(0),
|
| @@ -140,14 +147,14 @@ ResourceProvider::Resource::Resource(
|
| texture_pool(texture_pool),
|
| wrap_mode(wrap_mode),
|
| hint(hint),
|
| - type(GLTexture) {
|
| + type(GLTexture),
|
| + format(format) {
|
| DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
|
| }
|
|
|
| ResourceProvider::Resource::Resource(
|
| uint8_t* pixels,
|
| gfx::Size size,
|
| - GLenum format,
|
| GLenum filter,
|
| GLint wrap_mode)
|
| : gl_id(0),
|
| @@ -167,7 +174,6 @@ ResourceProvider::Resource::Resource(
|
| enable_read_lock_fences(false),
|
| read_lock_fence(NULL),
|
| size(size),
|
| - format(format),
|
| original_filter(filter),
|
| filter(filter),
|
| target(0),
|
| @@ -175,7 +181,8 @@ ResourceProvider::Resource::Resource(
|
| texture_pool(0),
|
| wrap_mode(wrap_mode),
|
| hint(TextureUsageAny),
|
| - type(Bitmap) {
|
| + type(Bitmap),
|
| + format(RGBA_8888) {
|
| DCHECK(wrap_mode == GL_CLAMP_TO_EDGE || wrap_mode == GL_REPEAT);
|
| }
|
|
|
| @@ -185,9 +192,12 @@ ResourceProvider::Child::~Child() {}
|
|
|
| scoped_ptr<ResourceProvider> ResourceProvider::Create(
|
| OutputSurface* output_surface,
|
| - int highp_threshold_min) {
|
| + int highp_threshold_min,
|
| + bool use_rgba_4444_texture_format) {
|
| scoped_ptr<ResourceProvider> resource_provider(
|
| - new ResourceProvider(output_surface, highp_threshold_min));
|
| + new ResourceProvider(output_surface,
|
| + highp_threshold_min,
|
| + use_rgba_4444_texture_format));
|
|
|
| bool success = false;
|
| if (resource_provider->Context3d()) {
|
| @@ -217,17 +227,20 @@ bool ResourceProvider::InUseByConsumer(ResourceId id) {
|
| }
|
|
|
| ResourceProvider::ResourceId ResourceProvider::CreateResource(
|
| - gfx::Size size, GLenum format, GLint wrap_mode, TextureUsageHint hint) {
|
| + gfx::Size size,
|
| + GLint wrap_mode,
|
| + TextureUsageHint hint,
|
| + ResourceFormat format) {
|
| DCHECK(!size.IsEmpty());
|
| switch (default_resource_type_) {
|
| case GLTexture:
|
| - return CreateGLTexture(size, format, GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
|
| - wrap_mode, hint);
|
| + return CreateGLTexture(size,
|
| + GL_TEXTURE_POOL_UNMANAGED_CHROMIUM,
|
| + wrap_mode,
|
| + hint,
|
| + format);
|
| case Bitmap:
|
| - // The only wrap_mode currently implemented in software mode is
|
| - // GL_CLAMP_TO_EDGE.
|
| - // http://crbug.com/284796
|
| - DCHECK(format == GL_RGBA);
|
| + DCHECK_EQ(RGBA_8888, format);
|
| return CreateBitmap(size);
|
| case InvalidType:
|
| break;
|
| @@ -238,14 +251,20 @@ ResourceProvider::ResourceId ResourceProvider::CreateResource(
|
| }
|
|
|
| ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
|
| - gfx::Size size, GLenum format, GLint wrap_mode, TextureUsageHint hint) {
|
| + gfx::Size size,
|
| + GLint wrap_mode,
|
| + TextureUsageHint hint,
|
| + ResourceFormat format) {
|
| DCHECK(!size.IsEmpty());
|
| switch (default_resource_type_) {
|
| case GLTexture:
|
| - return CreateGLTexture(size, format, GL_TEXTURE_POOL_MANAGED_CHROMIUM,
|
| - wrap_mode, hint);
|
| + return CreateGLTexture(size,
|
| + GL_TEXTURE_POOL_MANAGED_CHROMIUM,
|
| + wrap_mode,
|
| + hint,
|
| + format);
|
| case Bitmap:
|
| - DCHECK(format == GL_RGBA);
|
| + DCHECK_EQ(RGBA_8888, format);
|
| return CreateBitmap(size);
|
| case InvalidType:
|
| break;
|
| @@ -257,16 +276,16 @@ ResourceProvider::ResourceId ResourceProvider::CreateManagedResource(
|
|
|
| ResourceProvider::ResourceId ResourceProvider::CreateGLTexture(
|
| gfx::Size size,
|
| - GLenum format,
|
| GLenum texture_pool,
|
| GLint wrap_mode,
|
| - TextureUsageHint hint) {
|
| + TextureUsageHint hint,
|
| + ResourceFormat format) {
|
| 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, GL_LINEAR, texture_pool, wrap_mode, hint, format);
|
| resource.allocated = false;
|
| resources_[id] = resource;
|
| return id;
|
| @@ -278,7 +297,7 @@ ResourceProvider::ResourceId ResourceProvider::CreateBitmap(gfx::Size size) {
|
| uint8_t* pixels = new uint8_t[4 * size.GetArea()];
|
|
|
| ResourceId id = next_id_++;
|
| - Resource resource(pixels, size, GL_RGBA, GL_LINEAR, GL_CLAMP_TO_EDGE);
|
| + Resource resource(pixels, size, GL_LINEAR, GL_CLAMP_TO_EDGE);
|
| resource.allocated = true;
|
| resources_[id] = resource;
|
| return id;
|
| @@ -303,8 +322,13 @@ 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(),
|
| + GL_LINEAR,
|
| + 0,
|
| + GL_CLAMP_TO_EDGE,
|
| + TextureUsageAny,
|
| + RGBA_8888);
|
| resource.external = true;
|
| resource.allocated = true;
|
| resources_[id] = resource;
|
| @@ -320,15 +344,20 @@ 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(),
|
| + GL_LINEAR,
|
| + 0,
|
| + GL_CLAMP_TO_EDGE,
|
| + TextureUsageAny,
|
| + RGBA_8888);
|
| } else {
|
| DCHECK(mailbox.IsSharedMemory());
|
| base::SharedMemory* shared_memory = mailbox.shared_memory();
|
| DCHECK(shared_memory->memory());
|
| uint8_t* pixels = reinterpret_cast<uint8_t*>(shared_memory->memory());
|
| - resource = Resource(pixels, mailbox.shared_memory_size(),
|
| - GL_RGBA, GL_LINEAR, GL_CLAMP_TO_EDGE);
|
| + resource = Resource(
|
| + pixels, mailbox.shared_memory_size(), GL_LINEAR, GL_CLAMP_TO_EDGE);
|
| }
|
| resource.external = true;
|
| resource.allocated = true;
|
| @@ -448,7 +477,7 @@ void ResourceProvider::SetPixels(ResourceId id,
|
|
|
| if (resource->pixels) {
|
| DCHECK(resource->allocated);
|
| - DCHECK(resource->format == GL_RGBA);
|
| + DCHECK_EQ(RGBA_8888, resource->format);
|
| SkBitmap src_full;
|
| src_full.setConfig(
|
| SkBitmap::kARGB_8888_Config, image_rect.width(), image_rect.height());
|
| @@ -672,7 +701,7 @@ ResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() {
|
| void ResourceProvider::PopulateSkBitmapWithResource(
|
| SkBitmap* sk_bitmap, const Resource* resource) {
|
| DCHECK(resource->pixels);
|
| - DCHECK(resource->format == GL_RGBA);
|
| + DCHECK_EQ(RGBA_8888, resource->format);
|
| sk_bitmap->setConfig(SkBitmap::kARGB_8888_Config,
|
| resource->size.width(),
|
| resource->size.height());
|
| @@ -707,7 +736,8 @@ ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() {
|
| }
|
|
|
| ResourceProvider::ResourceProvider(OutputSurface* output_surface,
|
| - int highp_threshold_min)
|
| + int highp_threshold_min,
|
| + bool use_rgba_4444_texture_format)
|
| : output_surface_(output_surface),
|
| lost_output_surface_(false),
|
| highp_threshold_min_(highp_threshold_min),
|
| @@ -718,7 +748,8 @@ ResourceProvider::ResourceProvider(OutputSurface* output_surface,
|
| use_texture_usage_hint_(false),
|
| use_shallow_flush_(false),
|
| max_texture_size_(0),
|
| - best_texture_format_(0) {
|
| + best_texture_format_(RGBA_8888),
|
| + use_rgba_4444_texture_format_(use_rgba_4444_texture_format) {
|
| DCHECK(output_surface_->HasClient());
|
| }
|
|
|
| @@ -730,7 +761,7 @@ void ResourceProvider::InitializeSoftware() {
|
|
|
| default_resource_type_ = Bitmap;
|
| max_texture_size_ = INT_MAX / 2;
|
| - best_texture_format_ = GL_RGBA;
|
| + best_texture_format_ = RGBA_8888;
|
| }
|
|
|
| bool ResourceProvider::InitializeGL() {
|
| @@ -931,10 +962,16 @@ void ResourceProvider::ReceiveFromChild(
|
| GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, texture_id));
|
| GLC(context3d, context3d->consumeTextureCHROMIUM(GL_TEXTURE_2D,
|
| 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->filter,
|
| + 0,
|
| + GL_CLAMP_TO_EDGE,
|
| + TextureUsageAny,
|
| + it->format);
|
| resource.mailbox.SetName(it->mailbox);
|
| // Don't allocate a texture for a child.
|
| resource.allocated = true;
|
| @@ -1023,9 +1060,11 @@ void ResourceProvider::AcquirePixelBuffer(ResourceId id) {
|
| context3d->bindBuffer(
|
| GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
|
| resource->gl_pixel_buffer_id);
|
| + unsigned bytes_per_pixel = BytesPerPixel(resource->format);
|
| context3d->bufferData(
|
| GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM,
|
| - 4 * resource->size.GetArea(),
|
| + resource->size.height() * RoundUp(bytes_per_pixel
|
| + * resource->size.width(), 4u),
|
| NULL,
|
| GL_DYNAMIC_DRAW);
|
| context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
|
| @@ -1201,25 +1240,27 @@ void ResourceProvider::BeginSetPixels(ResourceId id) {
|
| GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM,
|
| resource->gl_upload_query_id);
|
| if (allocate) {
|
| - context3d->asyncTexImage2DCHROMIUM(GL_TEXTURE_2D,
|
| - 0, /* level */
|
| - resource->format,
|
| - resource->size.width(),
|
| - resource->size.height(),
|
| - 0, /* border */
|
| - resource->format,
|
| - GL_UNSIGNED_BYTE,
|
| - NULL);
|
| + context3d->asyncTexImage2DCHROMIUM(
|
| + GL_TEXTURE_2D,
|
| + 0, /* level */
|
| + GetGLInternalFormat(resource->format),
|
| + resource->size.width(),
|
| + resource->size.height(),
|
| + 0, /* border */
|
| + GetGLDataFormat(resource->format),
|
| + GetGLDataType(resource->format),
|
| + NULL);
|
| } else {
|
| - context3d->asyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D,
|
| - 0, /* level */
|
| - 0, /* x */
|
| - 0, /* y */
|
| - resource->size.width(),
|
| - resource->size.height(),
|
| - resource->format,
|
| - GL_UNSIGNED_BYTE,
|
| - NULL);
|
| + context3d->asyncTexSubImage2DCHROMIUM(
|
| + GL_TEXTURE_2D,
|
| + 0, /* level */
|
| + 0, /* x */
|
| + 0, /* y */
|
| + resource->size.width(),
|
| + resource->size.height(),
|
| + GetGLDataFormat(resource->format),
|
| + GetGLDataType(resource->format),
|
| + NULL);
|
| }
|
| context3d->endQueryEXT(GL_ASYNC_PIXEL_UNPACK_COMPLETED_CHROMIUM);
|
| context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0);
|
| @@ -1228,7 +1269,7 @@ void ResourceProvider::BeginSetPixels(ResourceId id) {
|
| if (resource->pixels) {
|
| DCHECK(!resource->mailbox.IsValid());
|
| DCHECK(resource->pixel_buffer);
|
| - DCHECK(resource->format == GL_RGBA);
|
| + DCHECK_EQ(RGBA_8888, resource->format);
|
|
|
| std::swap(resource->pixels, resource->pixel_buffer);
|
| delete[] resource->pixel_buffer;
|
| @@ -1334,9 +1375,9 @@ void ResourceProvider::LazyAllocate(Resource* resource) {
|
| resource->allocated = true;
|
| WebGraphicsContext3D* context3d = Context3d();
|
| gfx::Size& size = resource->size;
|
| - GLenum format = resource->format;
|
| + ResourceFormat format = resource->format;
|
| GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, resource->gl_id));
|
| - if (use_texture_storage_ext_ && IsTextureFormatSupportedForStorage(format)) {
|
| + if (use_texture_storage_ext_ && IsFormatSupportedForStorage(format)) {
|
| GLenum storage_format = TextureToStorageFormat(format);
|
| GLC(context3d, context3d->texStorage2DEXT(GL_TEXTURE_2D,
|
| 1,
|
| @@ -1346,12 +1387,12 @@ void ResourceProvider::LazyAllocate(Resource* resource) {
|
| } else {
|
| GLC(context3d, context3d->texImage2D(GL_TEXTURE_2D,
|
| 0,
|
| - format,
|
| + GetGLInternalFormat(format),
|
| size.width(),
|
| size.height(),
|
| 0,
|
| - format,
|
| - GL_UNSIGNED_BYTE,
|
| + GetGLDataFormat(format),
|
| + GetGLDataType(format),
|
| NULL));
|
| }
|
| }
|
| @@ -1376,7 +1417,7 @@ void ResourceProvider::AcquireImage(ResourceId id) {
|
| resource->allocated = true;
|
| WebGraphicsContext3D* context3d = Context3d();
|
| DCHECK(context3d);
|
| - DCHECK_EQ(static_cast<GLenum>(GL_RGBA), resource->format);
|
| + DCHECK_EQ(RGBA_8888, resource->format);
|
| resource->image_id = context3d->createImageCHROMIUM(
|
| resource->size.width(), resource->size.height(), GL_RGBA8_OES);
|
| DCHECK(resource->image_id);
|
| @@ -1456,4 +1497,62 @@ WebKit::WebGraphicsContext3D* ResourceProvider::Context3d() const {
|
| return context_provider ? context_provider->Context3d() : NULL;
|
| }
|
|
|
| +size_t ResourceProvider::BytesPerPixel(ResourceFormat format) {
|
| + size_t components_per_pixel = 0;
|
| + switch (format) {
|
| + case RGBA_8888:
|
| + case RGBA_4444:
|
| + case BGRA_8888:
|
| + components_per_pixel = 4;
|
| + break;
|
| + case LUMINANCE_8:
|
| + components_per_pixel = 1;
|
| + break;
|
| + }
|
| + size_t bits_per_component = 0;
|
| + switch (format) {
|
| + case RGBA_8888:
|
| + case BGRA_8888:
|
| + case LUMINANCE_8:
|
| + bits_per_component = 8;
|
| + break;
|
| + case RGBA_4444:
|
| + bits_per_component = 4;
|
| + break;
|
| + }
|
| + const size_t kBitsPerByte = 8;
|
| + return (components_per_pixel * bits_per_component) / kBitsPerByte;
|
| +}
|
| +
|
| +GLenum ResourceProvider::GetGLDataType(ResourceFormat format) {
|
| + switch (format) {
|
| + case RGBA_4444:
|
| + return GL_UNSIGNED_SHORT_4_4_4_4;
|
| + case RGBA_8888:
|
| + case BGRA_8888:
|
| + case LUMINANCE_8:
|
| + return GL_UNSIGNED_BYTE;
|
| + }
|
| + NOTREACHED();
|
| + return GL_UNSIGNED_BYTE;
|
| +}
|
| +
|
| +GLenum ResourceProvider::GetGLDataFormat(ResourceFormat format) {
|
| + switch (format) {
|
| + case RGBA_8888:
|
| + case RGBA_4444:
|
| + return GL_RGBA;
|
| + case BGRA_8888:
|
| + return GL_BGRA_EXT;
|
| + case LUMINANCE_8:
|
| + return GL_LUMINANCE;
|
| + }
|
| + NOTREACHED();
|
| + return GL_RGBA;
|
| +}
|
| +
|
| +GLenum ResourceProvider::GetGLInternalFormat(ResourceFormat format) {
|
| + return GetGLDataFormat(format);
|
| +}
|
| +
|
| } // namespace cc
|
|
|