Changeset 2559


Ignore:
Timestamp:
Mar 6, 2013, 4:20:00 PM (8 years ago)
Author:
sam
Message:

image: try to reuse existing images when loading them, and don't unload
tilesets yet, but make sure the architecture will allow it.

Location:
trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/image/image-private.h

    r2551 r2559  
    2020{
    2121
    22 class ImageLoader
     22class ImageCodec
    2323{
    24     friend class Image;
     24    friend class ImageLoader;
    2525    friend class ImageData;
    2626
    2727public:
    2828    ImageData *(*fun)(char const *path);
    29     ImageLoader *next;
     29    ImageCodec *next;
    3030    int priority;
    3131
    32     static void RegisterLoader(ImageLoader *loader)
     32    static void RegisterLoader(ImageCodec *loader)
    3333    {
    3434        Helper(loader);
     
    3838    static ImageData *Load(char const *path)
    3939    {
    40         ImageLoader *parser = Helper(nullptr);
     40        ImageCodec *parser = Helper(nullptr);
    4141        ImageData *ret = nullptr;
    4242
     
    5050    }
    5151
    52     static ImageLoader *Helper(ImageLoader *set)
     52    static ImageCodec *Helper(ImageCodec *set)
    5353    {
    54         static ImageLoader *loaders = nullptr;
     54        static ImageCodec *loaders = nullptr;
    5555
    5656        if (!set)
    5757            return loaders;
    5858
    59         ImageLoader **parser = &loaders;
     59        ImageCodec **parser = &loaders;
    6060        while (*parser && (*parser)->priority > set->priority)
    6161            parser = &(*parser)->next;
     
    7070{
    7171    friend class Image;
     72    friend class ImageLoader;
    7273
    7374public:
     75    inline ImageData()
     76      : m_size(0, 0),
     77        m_format(PixelFormat::Unknown),
     78        m_refcount(0)
     79    { }
     80
    7481    virtual ~ImageData() {}
    7582
     
    8289    ivec2 m_size;
    8390    PixelFormat m_format;
     91    int m_refcount;
    8492};
    8593
     
    8997
    9098#define DECLARE_IMAGE_LOADER(name, prio) \
    91     template<typename T> class name##ImageLoader : public ImageLoader \
     99    template<typename T> class name##ImageCodec : public ImageCodec \
    92100    { \
    93101    public: \
    94         name##ImageLoader() \
     102        name##ImageCodec() \
    95103        { \
    96             static ImageLoader loader; \
     104            static ImageCodec loader; \
    97105            loader.fun = Load; \
    98106            loader.priority = prio; \
     
    111119    }; \
    112120    class name; \
    113     name##ImageLoader<name> name##ImageLoaderInstance; \
     121    name##ImageCodec<name> name##ImageCodecInstance; \
    114122    void Register##name() \
    115123    { \
    116         (void)&name##ImageLoaderInstance; \
     124        (void)&name##ImageCodecInstance; \
    117125    } \
    118126    class name : public ImageData
  • trunk/src/image/image.cpp

    r2553 r2559  
    2121{
    2222
     23/* HACK: We cannot make this an ImageCodec member function, because the
     24 * REGISTER_IMAGE_LOADER macro forward-declares free functions from
     25 * the "lol" namespace. An apparent bug in Visual Studio's compiler
     26 * makes it think these functions are actually in the top-level
     27 * namespace when the forward declaration is in a class member function.
     28 * To avoid the problem, we make the forward declaration in a free
     29 * function.
     30 * The bug was reported to Microsoft and fixed by them, but the fix
     31 * is not yet available.
     32 * https://connect.microsoft.com/VisualStudio/feedback/details/730878/ */
    2333static bool RegisterAllLoaders()
    2434{
    25     /* HACK: We cannot make this an ImageLoader member function, because the
    26      * REGISTER_IMAGE_LOADER macro forward-declares free functions from
    27      * the "lol" namespace. An apparent bug in Visual Studio's compiler
    28      * makes it think these functions are actually in the top-level
    29      * namespace when the forward declaration is in a class member function.
    30      * To avoid the problem, we make the forward declaration in a free
    31      * function.
    32      * The bug was reported to Microsoft and fixed by them, but the fix
    33      * is not yet available.
    34      * https://connect.microsoft.com/VisualStudio/feedback/details/730878/ */
    3535#if defined __ANDROID__
    3636    REGISTER_IMAGE_LOADER(AndroidImageData)
     
    5454
    5555/*
    56  * Static image loader
     56 * Our static image loader
    5757 */
    5858
    59 Image *Image::Create(char const *path)
     59static class ImageLoader
     60{
     61public:
     62    Image *Create(char const *path);
     63    void Destroy(Image *img);
     64
     65private:
     66    Map<String, Image *> m_images;
     67}
     68image_loader;
     69
     70Image *ImageLoader::Create(char const *path)
    6071{
    6172    /* Initialise loaders (see above) */
     
    6374    UNUSED(init);
    6475
    65     Image *ret = new Image();
    66     ret->m_data = ImageLoader::Load(path);
    67     return ret;
     76    /* Is our image already in the bank? If so, no need to create it. */
     77    Image *img;
     78
     79    if (m_images.HasKey(path))
     80    {
     81        img = m_images[path];
     82    }
     83    else
     84    {
     85        img = new Image();
     86        img->m_data = ImageCodec::Load(path);
     87        m_images[path] = img;
     88    }
     89
     90    ++img->m_data->m_refcount;
     91    return img;
     92}
     93
     94void ImageLoader::Destroy(Image *img)
     95{
     96    ASSERT(img->m_data->m_refcount > 0);
     97    if (--img->m_data->m_refcount == 0)
     98    {
     99        /* FIXME: unload images etc. here */
     100        /* XXX: we’re gonna hit a problem here because we didn’t keep
     101         * the image path within the object, so unless we store it
     102         * ourselves we’re good for a O(n) lookup… which we can’t do
     103         * on Map objects anyway. */
     104        /* TODO: 1. remove image from Map
     105                 2. delete img; */
     106    }
     107}
     108
     109
     110/*
     111 * Static image methods
     112 */
     113
     114Image *Image::Create(char const *path)
     115{
     116    return image_loader.Create(path);
    68117}
    69118
    70119void Image::Destroy(Image *img)
    71120{
    72     delete img;
     121    return image_loader.Destroy(img);
    73122}
    74123
  • trunk/src/lol/image/image.h

    r2553 r2559  
    2424class Image
    2525{
     26    friend class ImageLoader;
     27
    2628public:
    2729    static Image *Create(char const *path);
Note: See TracChangeset for help on using the changeset viewer.