| 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
|
|
|