diff options
Diffstat (limited to 'cc/resource_provider.cc')
-rw-r--r-- | cc/resource_provider.cc | 708 |
1 files changed, 708 insertions, 0 deletions
diff --git a/cc/resource_provider.cc b/cc/resource_provider.cc new file mode 100644 index 0000000..29ca7d4 --- /dev/null +++ b/cc/resource_provider.cc @@ -0,0 +1,708 @@ +// Copyright 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "config.h" + +#include "CCResourceProvider.h" +#ifdef LOG +#undef LOG +#endif + +#include <limits.h> + +#include "base/debug/alias.h" +#include "base/hash_tables.h" +#include "base/stl_util.h" +#include "base/string_split.h" +#include "base/string_util.h" +#include "CCProxy.h" +#include "CCRendererGL.h" // For the GLC() macro. +#include "Extensions3DChromium.h" +#include "IntRect.h" +#include "LayerTextureSubImage.h" +#include "ThrottledTextureUploader.h" +#include "UnthrottledTextureUploader.h" +#include <public/WebGraphicsContext3D.h> + +using WebKit::WebGraphicsContext3D; + +namespace cc { + +static GC3Denum textureToStorageFormat(GC3Denum textureFormat) +{ + GC3Denum storageFormat = Extensions3D::RGBA8_OES; + switch (textureFormat) { + case GraphicsContext3D::RGBA: + break; + case Extensions3D::BGRA_EXT: + storageFormat = Extensions3DChromium::BGRA8_EXT; + break; + default: + ASSERT_NOT_REACHED(); + break; + } + + return storageFormat; +} + +static bool isTextureFormatSupportedForStorage(GC3Denum format) +{ + return (format == GraphicsContext3D::RGBA || format == Extensions3D::BGRA_EXT); +} + +CCResourceProvider::TransferableResourceList::TransferableResourceList() +{ +} + +CCResourceProvider::TransferableResourceList::~TransferableResourceList() +{ +} + +CCResourceProvider::Resource::Resource() + : glId(0) + , pixels(0) + , pool(0) + , lockForReadCount(0) + , lockedForWrite(false) + , external(false) + , exported(false) + , size() + , format(0) + , type(static_cast<ResourceType>(0)) +{ +} + +CCResourceProvider::Resource::Resource(unsigned textureId, int pool, const IntSize& size, GC3Denum format) + : glId(textureId) + , pixels(0) + , pool(pool) + , lockForReadCount(0) + , lockedForWrite(false) + , external(false) + , exported(false) + , size(size) + , format(format) + , type(GLTexture) +{ +} + +CCResourceProvider::Resource::Resource(uint8_t* pixels, int pool, const IntSize& size, GC3Denum format) + : glId(0) + , pixels(pixels) + , pool(pool) + , lockForReadCount(0) + , lockedForWrite(false) + , external(false) + , exported(false) + , size(size) + , format(format) + , type(Bitmap) +{ +} + +CCResourceProvider::Child::Child() +{ +} + +CCResourceProvider::Child::~Child() +{ +} + +PassOwnPtr<CCResourceProvider> CCResourceProvider::create(CCGraphicsContext* context) +{ + OwnPtr<CCResourceProvider> resourceProvider(adoptPtr(new CCResourceProvider(context))); + if (!resourceProvider->initialize()) + return nullptr; + return resourceProvider.release(); +} + +CCResourceProvider::~CCResourceProvider() +{ + WebGraphicsContext3D* context3d = m_context->context3D(); + if (!context3d || !context3d->makeContextCurrent()) + return; + m_textureUploader.clear(); + m_textureCopier.clear(); +} + +WebGraphicsContext3D* CCResourceProvider::graphicsContext3D() +{ + ASSERT(CCProxy::isImplThread()); + return m_context->context3D(); +} + +bool CCResourceProvider::inUseByConsumer(ResourceId id) +{ + ASSERT(CCProxy::isImplThread()); + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Resource* resource = &it->value; +#else + Resource* resource = &it->second; +#endif + return !!resource->lockForReadCount || resource->exported; +} + +CCResourceProvider::ResourceId CCResourceProvider::createResource(int pool, const IntSize& size, GC3Denum format, TextureUsageHint hint) +{ + switch (m_defaultResourceType) { + case GLTexture: + return createGLTexture(pool, size, format, hint); + case Bitmap: + ASSERT(format == GraphicsContext3D::RGBA); + return createBitmap(pool, size); + } + + CRASH(); + return 0; +} + +CCResourceProvider::ResourceId CCResourceProvider::createGLTexture(int pool, const IntSize& size, GC3Denum format, TextureUsageHint hint) +{ + ASSERT(CCProxy::isImplThread()); + unsigned textureId = 0; + WebGraphicsContext3D* context3d = m_context->context3D(); + ASSERT(context3d); + GLC(context3d, textureId = context3d->createTexture()); + GLC(context3d, context3d->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); + GLC(context3d, context3d->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); + GLC(context3d, context3d->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); + GLC(context3d, context3d->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE)); + GLC(context3d, context3d->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE)); + + if (m_useTextureUsageHint && hint == TextureUsageFramebuffer) + GLC(context3d, context3d->texParameteri(GraphicsContext3D::TEXTURE_2D, Extensions3DChromium::GL_TEXTURE_USAGE_ANGLE, Extensions3DChromium::GL_FRAMEBUFFER_ATTACHMENT_ANGLE)); + if (m_useTextureStorageExt && isTextureFormatSupportedForStorage(format)) { + GC3Denum storageFormat = textureToStorageFormat(format); + GLC(context3d, context3d->texStorage2DEXT(GraphicsContext3D::TEXTURE_2D, 1, storageFormat, size.width(), size.height())); + } else + GLC(context3d, context3d->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GraphicsContext3D::UNSIGNED_BYTE, 0)); + ResourceId id = m_nextId++; + Resource resource(textureId, pool, size, format); + m_resources.add(id, resource); + return id; +} + +CCResourceProvider::ResourceId CCResourceProvider::createBitmap(int pool, const IntSize& size) +{ + ASSERT(CCProxy::isImplThread()); + + uint8_t* pixels = new uint8_t[size.width() * size.height() * 4]; + + ResourceId id = m_nextId++; + Resource resource(pixels, pool, size, GraphicsContext3D::RGBA); + m_resources.add(id, resource); + return id; +} + +CCResourceProvider::ResourceId CCResourceProvider::createResourceFromExternalTexture(unsigned textureId) +{ + ASSERT(CCProxy::isImplThread()); + ASSERT(m_context->context3D()); + ResourceId id = m_nextId++; + Resource resource(textureId, 0, IntSize(), 0); + resource.external = true; + m_resources.add(id, resource); + return id; +} + +void CCResourceProvider::deleteResource(ResourceId id) +{ + ASSERT(CCProxy::isImplThread()); + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Resource* resource = &it->value; +#else + Resource* resource = &it->second; +#endif + ASSERT(!resource->lockedForWrite); + ASSERT(!resource->lockForReadCount); + + if (resource->glId && !resource->external) { + WebGraphicsContext3D* context3d = m_context->context3D(); + ASSERT(context3d); + GLC(context3d, context3d->deleteTexture(resource->glId)); + } + if (resource->pixels) + delete resource->pixels; + + m_resources.remove(it); +} + +void CCResourceProvider::deleteOwnedResources(int pool) +{ + ASSERT(CCProxy::isImplThread()); + ResourceIdArray toDelete; + for (ResourceMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) { +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + if (it->value.pool == pool && !it->value.external) + toDelete.append(it->key); +#else + if (it->second.pool == pool && !it->second.external) + toDelete.append(it->first); +#endif + } + for (ResourceIdArray::iterator it = toDelete.begin(); it != toDelete.end(); ++it) + deleteResource(*it); +} + +CCResourceProvider::ResourceType CCResourceProvider::resourceType(ResourceId id) +{ + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Resource* resource = &it->value; +#else + Resource* resource = &it->second; +#endif + return resource->type; +} + +void CCResourceProvider::upload(ResourceId id, const uint8_t* image, const IntRect& imageRect, const IntRect& sourceRect, const IntSize& destOffset) +{ + ASSERT(CCProxy::isImplThread()); + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Resource* resource = &it->value; +#else + Resource* resource = &it->second; +#endif + ASSERT(!resource->lockedForWrite); + ASSERT(!resource->lockForReadCount); + ASSERT(!resource->external); + + if (resource->glId) { + WebGraphicsContext3D* context3d = m_context->context3D(); + ASSERT(context3d); + ASSERT(m_texSubImage.get()); + context3d->bindTexture(GraphicsContext3D::TEXTURE_2D, resource->glId); + m_texSubImage->upload(image, imageRect, sourceRect, destOffset, resource->format, context3d); + } + + if (resource->pixels) { + SkBitmap srcFull; + srcFull.setConfig(SkBitmap::kARGB_8888_Config, imageRect.width(), imageRect.height()); + srcFull.setPixels(const_cast<uint8_t*>(image)); + SkBitmap srcSubset; + SkIRect skSourceRect = SkIRect::MakeXYWH(sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height()); + skSourceRect.offset(-imageRect.x(), -imageRect.y()); + srcFull.extractSubset(&srcSubset, skSourceRect); + + ScopedWriteLockSoftware lock(this, id); + SkCanvas* dest = lock.skCanvas(); + dest->writePixels(srcSubset, destOffset.width(), destOffset.height()); + } +} + +void CCResourceProvider::flush() +{ + ASSERT(CCProxy::isImplThread()); + WebGraphicsContext3D* context3d = m_context->context3D(); + if (context3d) + context3d->flush(); +} + +bool CCResourceProvider::shallowFlushIfSupported() +{ + ASSERT(CCProxy::isImplThread()); + WebGraphicsContext3D* context3d = m_context->context3D(); + if (!context3d || !m_useShallowFlush) + return false; + + context3d->shallowFlushCHROMIUM(); + return true; +} + +const CCResourceProvider::Resource* CCResourceProvider::lockForRead(ResourceId id) +{ + ASSERT(CCProxy::isImplThread()); + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); + +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Resource* resource = &it->value; +#else + Resource* resource = &it->second; +#endif + ASSERT(!resource->lockedForWrite); + resource->lockForReadCount++; + return resource; +} + +void CCResourceProvider::unlockForRead(ResourceId id) +{ + ASSERT(CCProxy::isImplThread()); + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Resource* resource = &it->value; +#else + Resource* resource = &it->second; +#endif + ASSERT(resource->lockForReadCount > 0); + resource->lockForReadCount--; +} + +const CCResourceProvider::Resource* CCResourceProvider::lockForWrite(ResourceId id) +{ + ASSERT(CCProxy::isImplThread()); + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Resource* resource = &it->value; +#else + Resource* resource = &it->second; +#endif + ASSERT(!resource->lockedForWrite); + ASSERT(!resource->lockForReadCount); + ASSERT(!resource->external); + resource->lockedForWrite = true; + return resource; +} + +void CCResourceProvider::unlockForWrite(ResourceId id) +{ + ASSERT(CCProxy::isImplThread()); + ResourceMap::iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Resource* resource = &it->value; +#else + Resource* resource = &it->second; +#endif + ASSERT(resource->lockedForWrite); + ASSERT(!resource->external); + resource->lockedForWrite = false; +} + +CCResourceProvider::ScopedReadLockGL::ScopedReadLockGL(CCResourceProvider* resourceProvider, CCResourceProvider::ResourceId resourceId) + : m_resourceProvider(resourceProvider) + , m_resourceId(resourceId) + , m_textureId(resourceProvider->lockForRead(resourceId)->glId) +{ + ASSERT(m_textureId); +} + +CCResourceProvider::ScopedReadLockGL::~ScopedReadLockGL() +{ + m_resourceProvider->unlockForRead(m_resourceId); +} + +CCResourceProvider::ScopedWriteLockGL::ScopedWriteLockGL(CCResourceProvider* resourceProvider, CCResourceProvider::ResourceId resourceId) + : m_resourceProvider(resourceProvider) + , m_resourceId(resourceId) + , m_textureId(resourceProvider->lockForWrite(resourceId)->glId) +{ + ASSERT(m_textureId); +} + +CCResourceProvider::ScopedWriteLockGL::~ScopedWriteLockGL() +{ + m_resourceProvider->unlockForWrite(m_resourceId); +} + +void CCResourceProvider::populateSkBitmapWithResource(SkBitmap* skBitmap, const Resource* resource) +{ + ASSERT(resource->pixels); + ASSERT(resource->format == GraphicsContext3D::RGBA); + skBitmap->setConfig(SkBitmap::kARGB_8888_Config, resource->size.width(), resource->size.height()); + skBitmap->setPixels(resource->pixels); +} + +CCResourceProvider::ScopedReadLockSoftware::ScopedReadLockSoftware(CCResourceProvider* resourceProvider, CCResourceProvider::ResourceId resourceId) + : m_resourceProvider(resourceProvider) + , m_resourceId(resourceId) +{ + CCResourceProvider::populateSkBitmapWithResource(&m_skBitmap, resourceProvider->lockForRead(resourceId)); +} + +CCResourceProvider::ScopedReadLockSoftware::~ScopedReadLockSoftware() +{ + m_resourceProvider->unlockForRead(m_resourceId); +} + +CCResourceProvider::ScopedWriteLockSoftware::ScopedWriteLockSoftware(CCResourceProvider* resourceProvider, CCResourceProvider::ResourceId resourceId) + : m_resourceProvider(resourceProvider) + , m_resourceId(resourceId) +{ + CCResourceProvider::populateSkBitmapWithResource(&m_skBitmap, resourceProvider->lockForWrite(resourceId)); + m_skCanvas = adoptPtr(new SkCanvas(m_skBitmap)); +} + +CCResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() +{ + m_resourceProvider->unlockForWrite(m_resourceId); +} + +CCResourceProvider::CCResourceProvider(CCGraphicsContext* context) + : m_context(context) + , m_nextId(1) + , m_nextChild(1) + , m_defaultResourceType(GLTexture) + , m_useTextureStorageExt(false) + , m_useTextureUsageHint(false) + , m_useShallowFlush(false) + , m_maxTextureSize(0) +{ +} + +bool CCResourceProvider::initialize() +{ + ASSERT(CCProxy::isImplThread()); + WebGraphicsContext3D* context3d = m_context->context3D(); + if (!context3d) { + m_maxTextureSize = INT_MAX / 2; + m_textureUploader = UnthrottledTextureUploader::create(); + return true; + } + if (!context3d->makeContextCurrent()) + return false; + + std::string extensionsString = UTF16ToASCII(context3d->getString(GraphicsContext3D::EXTENSIONS)); + std::vector<std::string> extensions; + base::SplitString(extensionsString, ' ', &extensions); + bool useMapSub = false; + bool useBindUniform = false; + for (size_t i = 0; i < extensions.size(); ++i) { + if (extensions[i] == "GL_EXT_texture_storage") + m_useTextureStorageExt = true; + else if (extensions[i] == "GL_ANGLE_texture_usage") + m_useTextureUsageHint = true; + else if (extensions[i] == "GL_CHROMIUM_map_sub") + useMapSub = true; + else if (extensions[i] == "GL_CHROMIUM_shallow_flush") + m_useShallowFlush = true; + else if (extensions[i] == "GL_CHROMIUM_bind_uniform_location") + useBindUniform = true; + } + + m_texSubImage = adoptPtr(new LayerTextureSubImage(useMapSub)); + m_textureCopier = AcceleratedTextureCopier::create(context3d, useBindUniform); + + m_textureUploader = ThrottledTextureUploader::create(context3d); + GLC(context3d, context3d->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize)); + return true; +} + +int CCResourceProvider::createChild(int pool) +{ + ASSERT(CCProxy::isImplThread()); + Child childInfo; + childInfo.pool = pool; + int child = m_nextChild++; + m_children.add(child, childInfo); + return child; +} + +void CCResourceProvider::destroyChild(int child) +{ + ASSERT(CCProxy::isImplThread()); + ChildMap::iterator it = m_children.find(child); + ASSERT(it != m_children.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + deleteOwnedResources(it->value.pool); +#else + deleteOwnedResources(it->second.pool); +#endif + m_children.remove(it); + trimMailboxDeque(); +} + +const CCResourceProvider::ResourceIdMap& CCResourceProvider::getChildToParentMap(int child) const +{ + ASSERT(CCProxy::isImplThread()); + ChildMap::const_iterator it = m_children.find(child); + ASSERT(it != m_children.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + return it->value.childToParentMap; +#else + return it->second.childToParentMap; +#endif +} + +CCResourceProvider::TransferableResourceList CCResourceProvider::prepareSendToParent(const ResourceIdArray& resources) +{ + ASSERT(CCProxy::isImplThread()); + TransferableResourceList list; + list.syncPoint = 0; + WebGraphicsContext3D* context3d = m_context->context3D(); + if (!context3d || !context3d->makeContextCurrent()) { + // FIXME: Implement this path for software compositing. + return list; + } + for (ResourceIdArray::const_iterator it = resources.begin(); it != resources.end(); ++it) { + TransferableResource resource; + if (transferResource(context3d, *it, &resource)) { +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + m_resources.find(*it)->value.exported = true; +#else + m_resources.find(*it)->second.exported = true; +#endif + list.resources.append(resource); + } + } + if (list.resources.size()) + list.syncPoint = context3d->insertSyncPoint(); + return list; +} + +CCResourceProvider::TransferableResourceList CCResourceProvider::prepareSendToChild(int child, const ResourceIdArray& resources) +{ + ASSERT(CCProxy::isImplThread()); + TransferableResourceList list; + list.syncPoint = 0; + WebGraphicsContext3D* context3d = m_context->context3D(); + if (!context3d || !context3d->makeContextCurrent()) { + // FIXME: Implement this path for software compositing. + return list; + } +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Child& childInfo = m_children.find(child)->value; +#else + Child& childInfo = m_children.find(child)->second; +#endif + for (ResourceIdArray::const_iterator it = resources.begin(); it != resources.end(); ++it) { + TransferableResource resource; + if (!transferResource(context3d, *it, &resource)) + ASSERT_NOT_REACHED(); + resource.id = childInfo.parentToChildMap.get(*it); + childInfo.parentToChildMap.remove(*it); + childInfo.childToParentMap.remove(resource.id); + list.resources.append(resource); + deleteResource(*it); + } + if (list.resources.size()) + list.syncPoint = context3d->insertSyncPoint(); + return list; +} + +void CCResourceProvider::receiveFromChild(int child, const TransferableResourceList& resources) +{ + ASSERT(CCProxy::isImplThread()); + WebGraphicsContext3D* context3d = m_context->context3D(); + if (!context3d || !context3d->makeContextCurrent()) { + // FIXME: Implement this path for software compositing. + return; + } + if (resources.syncPoint) { + // NOTE: If the parent is a browser and the child a renderer, the parent + // is not supposed to have its context wait, because that could induce + // deadlocks and/or security issues. The caller is responsible for + // waiting asynchronously, and resetting syncPoint before calling this. + // However if the parent is a renderer (e.g. browser tag), it may be ok + // (and is simpler) to wait. + GLC(context3d, context3d->waitSyncPoint(resources.syncPoint)); + } +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Child& childInfo = m_children.find(child)->value; +#else + Child& childInfo = m_children.find(child)->second; +#endif + for (Vector<TransferableResource>::const_iterator it = resources.resources.begin(); it != resources.resources.end(); ++it) { + unsigned textureId; + GLC(context3d, textureId = context3d->createTexture()); + GLC(context3d, context3d->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); + GLC(context3d, context3d->consumeTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, it->mailbox.name)); + ResourceId id = m_nextId++; + Resource resource(textureId, childInfo.pool, it->size, it->format); + m_resources.add(id, resource); + m_mailboxes.append(it->mailbox); + childInfo.parentToChildMap.add(id, it->id); + childInfo.childToParentMap.add(it->id, id); + } +} + +void CCResourceProvider::receiveFromParent(const TransferableResourceList& resources) +{ + ASSERT(CCProxy::isImplThread()); + WebGraphicsContext3D* context3d = m_context->context3D(); + if (!context3d || !context3d->makeContextCurrent()) { + // FIXME: Implement this path for software compositing. + return; + } + if (resources.syncPoint) + GLC(context3d, context3d->waitSyncPoint(resources.syncPoint)); + for (Vector<TransferableResource>::const_iterator it = resources.resources.begin(); it != resources.resources.end(); ++it) { +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + Resource* resource = &m_resources.find(it->id)->value; +#else + Resource* resource = &m_resources.find(it->id)->second; +#endif + ASSERT(resource->exported); + resource->exported = false; + GLC(context3d, context3d->bindTexture(GraphicsContext3D::TEXTURE_2D, resource->glId)); + GLC(context3d, context3d->consumeTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, it->mailbox.name)); + m_mailboxes.append(it->mailbox); + } +} + +bool CCResourceProvider::transferResource(WebGraphicsContext3D* context, ResourceId id, TransferableResource* resource) +{ + ASSERT(CCProxy::isImplThread()); + ResourceMap::const_iterator it = m_resources.find(id); + CHECK(it != m_resources.end()); +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + const Resource* source = &it->value; +#else + const Resource* source = &it->second; +#endif + ASSERT(!source->lockedForWrite); + ASSERT(!source->lockForReadCount); + ASSERT(!source->external); + if (source->exported) + return false; + resource->id = id; + resource->format = source->format; + resource->size = source->size; + if (!m_mailboxes.isEmpty()) + resource->mailbox = m_mailboxes.takeFirst(); + else + GLC(context, context->genMailboxCHROMIUM(resource->mailbox.name)); + GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, source->glId)); + GLC(context, context->produceTextureCHROMIUM(GraphicsContext3D::TEXTURE_2D, resource->mailbox.name)); + return true; +} + +void CCResourceProvider::trimMailboxDeque() +{ + // Trim the mailbox deque to the maximum number of resources we may need to + // send. + // If we have a parent, any non-external resource not already transfered is + // eligible to be sent to the parent. Otherwise, all resources belonging to + // a child might need to be sent back to the child. + size_t maxMailboxCount = 0; + if (m_context->capabilities().hasParentCompositor) { + for (ResourceMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) { +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + if (!it->value.exported && !it->value.external) +#else + if (!it->second.exported && !it->second.external) +#endif + ++maxMailboxCount; + } + } else { + base::hash_set<int> childPoolSet; + for (ChildMap::iterator it = m_children.begin(); it != m_children.end(); ++it) +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + childPoolSet.insert(it->value.pool); +#else + childPoolSet.insert(it->second.pool); +#endif + for (ResourceMap::iterator it = m_resources.begin(); it != m_resources.end(); ++it) { +#if WTF_NEW_HASHMAP_ITERATORS_INTERFACE + if (ContainsKey(childPoolSet, it->value.pool)) +#else + if (ContainsKey(childPoolSet, it->second.pool)) +#endif + ++maxMailboxCount; + } + } + while (m_mailboxes.size() > maxMailboxCount) + m_mailboxes.removeFirst(); +} + +} |