Esempio n. 1
0
GrContext::TextureCacheEntry sk_gr_create_bitmap_texture(GrContext* ctx,
                                                GrContext::TextureKey key,
                                                const GrSamplerState& sampler,
                                                const SkBitmap& origBitmap) {
    SkAutoLockPixels alp(origBitmap);
    GrContext::TextureCacheEntry entry;

    if (!origBitmap.readyToDraw()) {
        return entry;
    }

    SkBitmap tmpBitmap;

    const SkBitmap* bitmap = &origBitmap;

    GrTextureDesc desc = {
        kNone_GrTextureFlags,
        kNone_GrAALevel,
        bitmap->width(),
        bitmap->height(),
        SkGr::Bitmap2PixelConfig(*bitmap)
    };

    if (SkBitmap::kIndex8_Config == bitmap->config()) {
        // build_compressed_data doesn't do npot->pot expansion
        // and paletted textures can't be sub-updated
        if (ctx->supportsIndex8PixelConfig(sampler,
                                           bitmap->width(), bitmap->height())) {
            size_t imagesize = bitmap->width() * bitmap->height() +
                                kGrColorTableSize;
            SkAutoMalloc storage(imagesize);

            build_compressed_data(storage.get(), origBitmap);

            // our compressed data will be trimmed, so pass width() for its
            // "rowBytes", since they are the same now.
            
            if (gUNCACHED_KEY != key) {
                return ctx->createAndLockTexture(key, sampler, desc, storage.get(),
                                                 bitmap->width());
            } else {
                entry = ctx->lockScratchTexture(desc,
                                        GrContext::kExact_ScratchTexMatch);
                entry.texture()->writePixels(0, 0, bitmap->width(), 
                                             bitmap->height(), desc.fConfig,
                                             storage.get(), 0);
                return entry;
            }

        } else {
            origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
            // now bitmap points to our temp, which has been promoted to 32bits
            bitmap = &tmpBitmap;
        }
    }

    desc.fConfig = SkGr::Bitmap2PixelConfig(*bitmap);
    if (gUNCACHED_KEY != key) {
        return ctx->createAndLockTexture(key, sampler, desc,
                                         bitmap->getPixels(),
                                         bitmap->rowBytes());
    } else {
        entry = ctx->lockScratchTexture(desc,
                                        GrContext::kExact_ScratchTexMatch);
        entry.texture()->writePixels(0, 0,
                                     bitmap->width(), bitmap->height(),
                                     desc.fConfig,
                                     bitmap->getPixels(),
                                     bitmap->rowBytes());
        return entry;
    }
}
Esempio n. 2
0
GLuint SkGL::BindNewTexture(const SkBitmap& origBitmap, SkPoint* max) {
    SkBitmap tmpBitmap;
    const SkBitmap* bitmap = &origBitmap;

    if (needToPromoteTo32bit(origBitmap)) {
        origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
        // now bitmap points to our temp, which has been promoted to 32bits
        bitmap = &tmpBitmap;
    }

    GLenum format, type;
    if (!canBeTexture(*bitmap, &format, &type)) {
        return 0;
    }

    SkAutoLockPixels alp(*bitmap);
    if (!bitmap->readyToDraw()) {
        return 0;
    }

    GLuint  textureName;
    glGenTextures(1, &textureName);

    glBindTexture(GL_TEXTURE_2D, textureName);

    // express rowbytes as a number of pixels for ow
    int ow = bitmap->rowBytesAsPixels();
    int oh = bitmap->height();
    int nw = SkNextPow2(ow);
    int nh = SkNextPow2(oh);

    glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());

    // check if we need to scale to create power-of-2 dimensions
#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D
    if (SkBitmap::kIndex8_Config == bitmap->config()) {
        size_t imagesize = bitmap->getSize() + SK_GL_SIZE_OF_PALETTE;
        SkAutoMalloc storage(imagesize);

        build_compressed_data(storage.get(), *bitmap);
        // we only support POW2 here (GLES 1.0 restriction)
        SkASSERT(ow == nw);
        SkASSERT(oh == nh);
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, ow, oh, 0,
                               imagesize, storage.get());
    } else  // fall through to non-compressed logic
#endif
    {
        if (ow != nw || oh != nh) {
            glTexImage2D(GL_TEXTURE_2D, 0, format, nw, nh, 0,
                         format, type, NULL);
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ow, oh,
                            format, type, bitmap->getPixels());
        } else {
            // easy case, the bitmap is already pow2
            glTexImage2D(GL_TEXTURE_2D, 0, format, ow, oh, 0,
                         format, type, bitmap->getPixels());
        }
    }

#ifdef TRACE_TEXTURE_CREATION
    SkDebugf("--- new texture [%d] size=(%d %d) bpp=%d\n", textureName, ow, oh,
             bitmap->bytesPerPixel());
#endif

    if (max) {
        max->fX = SkFixedToScalar(bitmap->width() << (16 - SkNextLog2(nw)));
        max->fY = SkFixedToScalar(oh << (16 - SkNextLog2(nh)));
    }
    return textureName;
}
Esempio n. 3
0
static GrTexture* sk_gr_create_bitmap_texture(GrContext* ctx,
                                              bool cache,
                                              const GrTextureParams* params,
                                              const SkBitmap& origBitmap) {
    SkAutoLockPixels alp(origBitmap);

    if (!origBitmap.readyToDraw()) {
        return NULL;
    }

    SkBitmap tmpBitmap;

    const SkBitmap* bitmap = &origBitmap;

    GrTextureDesc desc;
    generate_bitmap_texture_desc(*bitmap, &desc);

    if (SkBitmap::kIndex8_Config == bitmap->config()) {
        // build_compressed_data doesn't do npot->pot expansion
        // and paletted textures can't be sub-updated
        if (ctx->supportsIndex8PixelConfig(params,
                                           bitmap->width(), bitmap->height())) {
            size_t imagesize = bitmap->width() * bitmap->height() +
                                kGrColorTableSize;
            SkAutoMalloc storage(imagesize);

            build_compressed_data(storage.get(), origBitmap);

            // our compressed data will be trimmed, so pass width() for its
            // "rowBytes", since they are the same now.

            if (cache) {
                GrCacheID cacheID;
                generate_bitmap_cache_id(origBitmap, &cacheID);
                return ctx->createTexture(params, desc, cacheID, storage.get(), bitmap->width());
            } else {
                GrTexture* result = ctx->lockAndRefScratchTexture(desc,
                                                            GrContext::kExact_ScratchTexMatch);
                result->writePixels(0, 0, bitmap->width(),
                                    bitmap->height(), desc.fConfig,
                                    storage.get());
                return result;
            }
        } else {
            origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
            // now bitmap points to our temp, which has been promoted to 32bits
            bitmap = &tmpBitmap;
            desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap->config());
        }
    }

    if (cache) {
        // This texture is likely to be used again so leave it in the cache
        GrCacheID cacheID;
        generate_bitmap_cache_id(origBitmap, &cacheID);
        return ctx->createTexture(params, desc, cacheID, bitmap->getPixels(), bitmap->rowBytes());
    } else {
        // This texture is unlikely to be used again (in its present form) so
        // just use a scratch texture. This will remove the texture from the
        // cache so no one else can find it. Additionally, once unlocked, the
        // scratch texture will go to the end of the list for purging so will
        // likely be available for this volatile bitmap the next time around.
        GrTexture* result = ctx->lockAndRefScratchTexture(desc, GrContext::kExact_ScratchTexMatch);
        result->writePixels(0, 0,
                            bitmap->width(), bitmap->height(),
                            desc.fConfig,
                            bitmap->getPixels(),
                            bitmap->rowBytes());
        return result;
    }
}