Esempio n. 1
0
bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike, const GrGlyph* glyph) {
    SkASSERT(preserveStrike);

    int index = mask_format_to_atlas_index(glyph->fMaskFormat);
    GrAtlas* atlas = fAtlases[index];
    GrPlot* plot = atlas->getUnusedPlot();
    if (NULL == plot) {
        return false;
    }
    plot->resetRects();

    GrTextStrike* strike = fHead;
    while (strike) {
        GrTextStrike* strikeToPurge = strike;
        strike = strikeToPurge->fNext;
        strikeToPurge->removePlot(plot);

        // clear out any empty strikes (except this one)
        if (strikeToPurge != preserveStrike && strikeToPurge->fPlotUsage.isEmpty()) {
            this->purgeStrike(strikeToPurge);
        }
    }

#if FONT_CACHE_STATS
    ++g_PurgeCount;
#endif

    return true;
}
Esempio n. 2
0
bool GrFontCache::freeUnusedPlot(GrTextStrike* preserveStrike) {
    SkASSERT(preserveStrike);

    GrAtlas* atlas = preserveStrike->fAtlas;
    GrPlot* plot = atlas->getUnusedPlot();
    if (NULL == plot) {
        return false;
    }
    plot->resetRects();

    GrTextStrike* strike = fHead;
    GrMaskFormat maskFormat = preserveStrike->fMaskFormat;
    while (strike) {
        if (maskFormat != strike->fMaskFormat) {
            strike = strike->fNext;
            continue;
        }

        GrTextStrike* strikeToPurge = strike;
        strike = strikeToPurge->fNext;
        strikeToPurge->removePlot(plot);

        // clear out any empty strikes (except this one)
        if (strikeToPurge != preserveStrike && strikeToPurge->fPlotUsage.isEmpty()) {
            this->purgeStrike(strikeToPurge);
        }
    }

#if FONT_CACHE_STATS
    ++g_PurgeCount;
#endif

    return true;
}
Esempio n. 3
0
GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas** atlas,
                                int width, int height, const void* image,
                                GrMaskFormat format,
                                GrIPoint16* loc) {
    SkASSERT(NULL == *atlas || (*atlas)->getMaskFormat() == format);

    // iterate through entire atlas list, see if we can find a hole
    GrAtlas* atlasIter = *atlas;
    while (atlasIter) {
        if (atlasIter->addSubImage(width, height, image, loc)) {
            return atlasIter;
        }
        atlasIter = atlasIter->fNext;
    }

    // If the above fails, then either we have no starting atlas, or the current
    // atlas list is full. Either way we need to allocate a new atlas

    GrIPoint16 plot;
    if (!fPlotMgr[format]->newPlot(&plot)) {
        return NULL;
    }

    SkASSERT(0 == kA8_GrMaskFormat);
    SkASSERT(1 == kA565_GrMaskFormat);
    if (NULL == fTexture[format]) {
        // TODO: Update this to use the cache rather than directly creating a texture.
        GrTextureDesc desc;
        desc.fFlags = kDynamicUpdate_GrTextureFlagBit;
        desc.fWidth = GR_ATLAS_TEXTURE_WIDTH;
        desc.fHeight = GR_ATLAS_TEXTURE_HEIGHT;
        desc.fConfig = maskformat2pixelconfig(format);

        fTexture[format] = fGpu->createTexture(desc, NULL, 0);
        if (NULL == fTexture[format]) {
            return NULL;
        }
    }

    GrAtlas* newAtlas = SkNEW_ARGS(GrAtlas, (this, plot.fX, plot.fY, format));
    if (!newAtlas->addSubImage(width, height, image, loc)) {
        delete newAtlas;
        return NULL;
    }

    // new atlas, put at head
    newAtlas->fNext = *atlas;
    *atlas = newAtlas;

    return newAtlas;
}
Esempio n. 4
0
GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
                                int width, int height, const void* image,
                                GrMaskFormat format,
                                GrIPoint16* loc) {
    GrAssert(NULL == atlas || atlas->getMaskFormat() == format);

    if (atlas && atlas->addSubImage(width, height, image, loc)) {
        return atlas;
    }

    // If the above fails, then either we have no starting atlas, or the current
    // one is full. Either way we need to allocate a new atlas

    GrIPoint16 plot;
    if (!fPlotMgr->newPlot(&plot)) {
        return NULL;
    }

    GrAssert(0 == kA8_GrMaskFormat);
    GrAssert(1 == kA565_GrMaskFormat);
    if (NULL == fTexture[format]) {
        GrTextureDesc desc = {
            kDynamicUpdate_GrTextureFlagBit,
            GR_ATLAS_TEXTURE_WIDTH,
            GR_ATLAS_TEXTURE_HEIGHT,
            maskformat2pixelconfig(format),
            0 // samples
        };
        fTexture[format] = fGpu->createTexture(desc, NULL, 0);
        if (NULL == fTexture[format]) {
            return NULL;
        }
    }

    GrAtlas* newAtlas = new GrAtlas(this, plot.fX, plot.fY, format);
    if (!newAtlas->addSubImage(width, height, image, loc)) {
        delete newAtlas;
        return NULL;
    }

    newAtlas->fNext = atlas;
    return newAtlas;
}
Esempio n. 5
0
bool GrAtlas::RemoveUnusedAtlases(GrAtlasMgr* atlasMgr, GrAtlas** startAtlas) {
    // GrAtlas** is used so that a pointer to the head element can be passed in and
    // modified when the first element is deleted
    GrAtlas** atlasRef = startAtlas;
    GrAtlas* atlas = *startAtlas;
    bool removed = false;
    while (NULL != atlas) {
        if (atlas->drawToken().isIssued()) {
            *atlasRef = atlas->fNext;
            atlasMgr->deleteAtlas(atlas);
            atlas = *atlasRef;
            removed = true;
        } else {
            atlasRef = &atlas->fNext;
            atlas = atlas->fNext;
        }
    }

    return removed;
}