Ejemplo n.º 1
0
void CCPrioritizedTextureManager::reduceMemory(size_t limitBytes, CCResourceProvider* resourceProvider)
{
    if (memoryUseBytes() <= limitBytes)
        return;
    // Destroy backings until we are below the limit,
    // or until all backings remaining are above the cutoff.
    while (memoryUseBytes() > limitBytes && m_backings.size() > 0) {
        BackingSet::iterator it = m_backings.begin();
        if ((*it)->owner() && (*it)->owner()->isAbovePriorityCutoff())
            break;
        destroyBacking((*it), resourceProvider);
    }
}
Ejemplo n.º 2
0
unsigned TextureManager::requestTexture(TextureToken token, IntSize size, unsigned format, bool* newTexture)
{
    if (size.width() > m_maxTextureSize || size.height() > m_maxTextureSize)
        return 0;

    TextureMap::iterator it = m_textures.find(token);
    if (it != m_textures.end()) {
        ASSERT(it->second.size != size || it->second.format != format);
        removeTexture(token, it->second);
    }

    size_t memoryRequiredBytes = memoryUseBytes(size, format);
    if (memoryRequiredBytes > m_memoryLimitBytes || !reduceMemoryToLimit(m_memoryLimitBytes - memoryRequiredBytes))
        return 0;

    unsigned textureId = m_context->createTexture();
    GLC(m_context.get(), textureId = m_context->createTexture());
    GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
    // Do basic linear filtering on resize.
    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
    // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE.
    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
    GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
    GLC(m_context.get(), m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GraphicsContext3D::UNSIGNED_BYTE));
    TextureInfo info;
    info.size = size;
    info.format = format;
    info.textureId = textureId;
    info.isProtected = true;
    addTexture(token, info);
    return textureId;
}
Ejemplo n.º 3
0
bool TextureManager::requestTexture(TextureToken token, IntSize size, unsigned format)
{
    if (size.width() > m_maxTextureSize || size.height() > m_maxTextureSize)
        return false;

    TextureMap::iterator it = m_textures.find(token);
    if (it != m_textures.end()) {
        ASSERT(it->second.size != size || it->second.format != format);
        removeTexture(token, it->second);
    }

    size_t memoryRequiredBytes = memoryUseBytes(size, format);
    if (memoryRequiredBytes > m_maxMemoryLimitBytes)
        return false;

    reduceMemoryToLimit(m_maxMemoryLimitBytes - memoryRequiredBytes);
    if (m_memoryUseBytes + memoryRequiredBytes > m_maxMemoryLimitBytes)
        return false;

    TextureInfo info;
    info.size = size;
    info.format = format;
    info.textureId = 0;
    info.isProtected = true;
#ifndef NDEBUG
    info.allocator = 0;
#endif
    addTexture(token, info);
    return true;
}
Ejemplo n.º 4
0
void TextureManager::addTexture(TextureToken token, TextureInfo info)
{
    ASSERT(!m_textureLRUSet.contains(token));
    ASSERT(!m_textures.contains(token));
    m_memoryUseBytes += memoryUseBytes(info.size, info.format);
    m_textures.set(token, info);
    m_textureLRUSet.add(token);
}
Ejemplo n.º 5
0
void TextureManager::removeTexture(TextureToken token, TextureInfo info)
{
    ASSERT(m_textureLRUSet.contains(token));
    ASSERT(m_textures.contains(token));
    m_memoryUseBytes -= memoryUseBytes(info.size, info.format);
    m_textures.remove(token);
    ASSERT(m_textureLRUSet.contains(token));
    m_textureLRUSet.remove(token);
    GLC(m_context.get(), m_context->deleteTexture(info.textureId));
}
Ejemplo n.º 6
0
void CCPrioritizedTextureManager::reduceMemory(CCResourceProvider* resourceProvider)
{
    reduceMemory(m_memoryAvailableBytes, resourceProvider);
    ASSERT(memoryUseBytes() <= maxMemoryLimitBytes());

    // We currently collect backings from deleted textures for later recycling.
    // However, if we do that forever we will always use the max limit even if
    // we really need very little memory. This should probably be solved by reducing the
    // limit externally, but until then this just does some "clean up" of unused
    // backing textures (any more than 10%).
    size_t wastedMemory = 0;
    for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) {
        if ((*it)->owner())
            break;
        wastedMemory += (*it)->bytes();
    }
    size_t tenPercentOfMemory = m_memoryAvailableBytes / 10;
    if (wastedMemory <= tenPercentOfMemory)
        return;
    reduceMemory(memoryUseBytes() - (wastedMemory - tenPercentOfMemory), resourceProvider);
}
Ejemplo n.º 7
0
void TextureManager::removeTexture(TextureToken token, TextureInfo info)
{
    ASSERT(m_textureLRUSet.contains(token));
    ASSERT(m_textures.contains(token));
    m_memoryUseBytes -= memoryUseBytes(info.size, info.format);
    m_textures.remove(token);
    ASSERT(m_textureLRUSet.contains(token));
    m_textureLRUSet.remove(token);
    EvictionEntry entry;
    entry.textureId = info.textureId;
    entry.size = info.size;
    entry.format = info.format;
#ifndef NDEBUG
    entry.allocator = info.allocator;
#endif
    m_evictedTextures.append(entry);
}
Ejemplo n.º 8
0
bool TextureManager::requestTexture(TextureToken token, IntSize size, unsigned format, unsigned& textureId)
{
    textureId = 0;

    if (size.width() > m_maxTextureSize || size.height() > m_maxTextureSize)
        return false;

    TextureMap::iterator it = m_textures.find(token);
    if (it != m_textures.end()) {
        ASSERT(it->second.size != size || it->second.format != format);
        removeTexture(token, it->second);
    }

    size_t memoryRequiredBytes = memoryUseBytes(size, format);
    if (memoryRequiredBytes > m_maxMemoryLimitBytes)
        return false;

    reduceMemoryToLimit(m_maxMemoryLimitBytes - memoryRequiredBytes);
    if (m_memoryUseBytes + memoryRequiredBytes > m_maxMemoryLimitBytes)
        return false;

    TextureInfo info;
    info.size = size;
    info.format = format;
    info.textureId = 0;
    info.isProtected = true;
#ifndef NDEBUG
    info.allocator = 0;
#endif
    // Avoid churning by reusing the texture if it is about to be reclaimed and
    // it has the same size and format as the requesting texture.
    if (m_memoryUseBytes + memoryRequiredBytes > m_preferredMemoryLimitBytes) {
        textureId = replaceTexture(token, info);
        if (textureId)
            return true;
    }
    addTexture(token, info);
    return true;
}