Index: cc/resource_provider.cc |
diff --git a/cc/resource_provider.cc b/cc/resource_provider.cc |
index 21552241d75f1db5b1540e5ab59aee3ab63163a9..698b0ba58cd3d65cef41b2cd39ac34a51d9d52c1 100644 |
--- a/cc/resource_provider.cc |
+++ b/cc/resource_provider.cc |
@@ -59,6 +59,7 @@ ResourceProvider::Resource::Resource() |
, exported(false) |
, markedForDeletion(false) |
, pendingSetPixels(false) |
+ , allocated(false) |
, size() |
, format(0) |
, filter(0) |
@@ -82,6 +83,7 @@ ResourceProvider::Resource::Resource(unsigned textureId, const gfx::Size& size, |
, exported(false) |
, markedForDeletion(false) |
, pendingSetPixels(false) |
+ , allocated(false) |
, size(size) |
, format(format) |
, filter(filter) |
@@ -101,6 +103,7 @@ ResourceProvider::Resource::Resource(uint8_t* pixels, const gfx::Size& size, GLe |
, exported(false) |
, markedForDeletion(false) |
, pendingSetPixels(false) |
+ , allocated(false) |
, size(size) |
, format(format) |
, filter(filter) |
@@ -187,22 +190,19 @@ ResourceProvider::ResourceId ResourceProvider::createGLTexture(const gfx::Size& |
DCHECK(context3d); |
GLC(context3d, textureId = context3d->createTexture()); |
GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, textureId)); |
+ |
+ // Set texture properties. Allocation is delayed until needed. |
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); |
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); |
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); |
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); |
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_POOL_CHROMIUM, texturePool)); |
- |
if (m_useTextureUsageHint && hint == TextureUsageFramebuffer) |
GLC(context3d, context3d->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_USAGE_ANGLE, GL_FRAMEBUFFER_ATTACHMENT_ANGLE)); |
- if (m_useTextureStorageExt && isTextureFormatSupportedForStorage(format)) { |
- GLenum storageFormat = textureToStorageFormat(format); |
- GLC(context3d, context3d->texStorage2DEXT(GL_TEXTURE_2D, 1, storageFormat, size.width(), size.height())); |
- } else |
- GLC(context3d, context3d->texImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, 0)); |
ResourceId id = m_nextId++; |
Resource resource(textureId, size, format, GL_LINEAR); |
+ resource.allocated = false; |
m_resources[id] = resource; |
return id; |
} |
@@ -215,6 +215,7 @@ ResourceProvider::ResourceId ResourceProvider::createBitmap(const gfx::Size& siz |
ResourceId id = m_nextId++; |
Resource resource(pixels, size, GL_RGBA, GL_LINEAR); |
+ resource.allocated = true; |
m_resources[id] = resource; |
return id; |
} |
@@ -234,6 +235,7 @@ ResourceProvider::ResourceId ResourceProvider::createResourceFromExternalTexture |
ResourceId id = m_nextId++; |
Resource resource(textureId, gfx::Size(), 0, GL_LINEAR); |
resource.external = true; |
+ resource.allocated = true; |
m_resources[id] = resource; |
return id; |
} |
@@ -266,9 +268,9 @@ void ResourceProvider::deleteResource(ResourceId id) |
ResourceMap::iterator it = m_resources.find(id); |
CHECK(it != m_resources.end()); |
Resource* resource = &it->second; |
- DCHECK(!resource->lockedForWrite); |
DCHECK(!resource->lockForReadCount); |
DCHECK(!resource->markedForDeletion); |
+ DCHECK(resource->pendingSetPixels || !resource->lockedForWrite); |
if (resource->exported) { |
resource->markedForDeletion = true; |
@@ -332,8 +334,10 @@ void ResourceProvider::setPixels(ResourceId id, const uint8_t* image, const gfx: |
DCHECK(!resource->lockForReadCount); |
DCHECK(!resource->external); |
DCHECK(!resource->exported); |
+ lazyAllocate(resource); |
if (resource->glId) { |
+ DCHECK(!resource->pendingSetPixels); |
WebGraphicsContext3D* context3d = m_outputSurface->Context3D(); |
DCHECK(context3d); |
DCHECK(m_textureUploader.get()); |
@@ -347,6 +351,7 @@ void ResourceProvider::setPixels(ResourceId id, const uint8_t* image, const gfx: |
} |
if (resource->pixels) { |
+ DCHECK(resource->allocated); |
DCHECK(resource->format == GL_RGBA); |
SkBitmap srcFull; |
srcFull.setConfig(SkBitmap::kARGB_8888_Config, imageRect.width(), imageRect.height()); |
@@ -421,6 +426,8 @@ const ResourceProvider::Resource* ResourceProvider::lockForRead(ResourceId id) |
Resource* resource = &it->second; |
DCHECK(!resource->lockedForWrite); |
DCHECK(!resource->exported); |
+ DCHECK(resource->allocated); // Uninitialized! Call setPixels or lockForWrite first. |
+ |
resource->lockForReadCount++; |
return resource; |
} |
@@ -446,6 +453,8 @@ const ResourceProvider::Resource* ResourceProvider::lockForWrite(ResourceId id) |
DCHECK(!resource->lockForReadCount); |
DCHECK(!resource->exported); |
DCHECK(!resource->external); |
+ lazyAllocate(resource); |
+ |
resource->lockedForWrite = true; |
return resource; |
} |
@@ -682,6 +691,8 @@ void ResourceProvider::receiveFromChild(int child, const TransferableResourceLis |
ResourceId id = m_nextId++; |
Resource resource(textureId, it->size, it->format, it->filter); |
resource.mailbox.setName(it->mailbox.name); |
+ // Don't allocate a texture for a child. |
+ resource.allocated = true; |
m_resources[id] = resource; |
childInfo.parentToChildMap[id] = it->id; |
childInfo.childToParentMap[it->id] = id; |
@@ -722,6 +733,7 @@ bool ResourceProvider::transferResource(WebGraphicsContext3D* context, ResourceI |
DCHECK(!source->lockedForWrite); |
DCHECK(!source->lockForReadCount); |
DCHECK(!source->external || (source->external && !source->mailbox.isZero())); |
+ DCHECK(source->allocated); |
if (source->exported) |
return false; |
resource->id = id; |
@@ -869,6 +881,7 @@ void ResourceProvider::setPixelsFromBuffer(ResourceId id) |
DCHECK(!resource->lockForReadCount); |
DCHECK(!resource->external); |
DCHECK(!resource->exported); |
+ lazyAllocate(resource); |
if (resource->glId) { |
WebGraphicsContext3D* context3d = m_outputSurface->Context3D(); |
@@ -930,7 +943,10 @@ void ResourceProvider::beginSetPixels(ResourceId id) |
CHECK(it != m_resources.end()); |
Resource* resource = &it->second; |
DCHECK(!resource->pendingSetPixels); |
+ DCHECK(resource->glId || resource->allocated); |
+ bool allocate = !resource->allocated; |
+ resource->allocated = true; |
lockForWrite(id); |
if (resource->glId) { |
@@ -946,15 +962,27 @@ void ResourceProvider::beginSetPixels(ResourceId id) |
context3d->beginQueryEXT( |
GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM, |
resource->glUploadQueryId); |
- context3d->asyncTexSubImage2DCHROMIUM(GL_TEXTURE_2D, |
- 0, /* level */ |
- 0, /* x */ |
- 0, /* y */ |
- resource->size.width(), |
- resource->size.height(), |
- resource->format, |
- GL_UNSIGNED_BYTE, |
- NULL); |
+ 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); |
+ } 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->endQueryEXT(GL_ASYNC_PIXEL_TRANSFERS_COMPLETED_CHROMIUM); |
context3d->bindBuffer(GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM, 0); |
} |
@@ -992,4 +1020,31 @@ bool ResourceProvider::didSetPixelsComplete(ResourceId id) { |
return true; |
} |
+void ResourceProvider::allocateForTesting(ResourceId id) { |
+ ResourceMap::iterator it = m_resources.find(id); |
+ CHECK(it != m_resources.end()); |
+ Resource* resource = &it->second; |
+ lazyAllocate(resource); |
+} |
+ |
+void ResourceProvider::lazyAllocate(Resource* resource) { |
+ DCHECK(resource); |
+ DCHECK(resource->glId || resource->allocated); |
+ |
+ if (resource->allocated || !resource->glId) |
+ return; |
+ |
+ resource->allocated = true; |
+ WebGraphicsContext3D* context3d = m_outputSurface->Context3D(); |
+ gfx::Size& size = resource->size; |
+ GLenum format = resource->format; |
+ GLC(context3d, context3d->bindTexture(GL_TEXTURE_2D, resource->glId)); |
+ if (m_useTextureStorageExt && isTextureFormatSupportedForStorage(format)) { |
+ GLenum storageFormat = textureToStorageFormat(format); |
+ GLC(context3d, context3d->texStorage2DEXT(GL_TEXTURE_2D, 1, storageFormat, size.width(), size.height())); |
+ } else |
+ GLC(context3d, context3d->texImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, 0)); |
+} |
+ |
+ |
} // namespace cc |