TextureLoadAsync.h#

Parent directory (texture)

Contains classes and functions to load textures on a worker thread. Only contains functionality for loading into CPU-side memory (not API textures)

Includes#

  • PVRCore/IAssetProvider.h

  • PVRCore/Threading.h

  • PVRCore/texture/TextureLoad.h

Namespaces#

Classes#

Functions#

Typedefs#

Source Code#

#pragma once
#include "PVRCore/texture/TextureLoad.h"
#include "PVRCore/Threading.h"
#include "PVRCore/IAssetProvider.h"

namespace pvr {
namespace async {

typedef std::shared_ptr<Texture> TexturePtr;

struct TextureLoadFuture_ : public IFrameworkAsyncResult<TexturePtr>, public std::enable_shared_from_this<TextureLoadFuture_>
{
public:
    typedef IFrameworkAsyncResult<TexturePtr> MyBase;
    typedef MyBase::Callback CallbackType;

    TextureLoadFuture_() {}

    Semaphore* workSemaphore;
    std::string filename;
    IAssetProvider* loader;
    TextureFileFormat format;
    mutable SemaphorePtr resultSemaphore;
    TexturePtr result;
    std::exception_ptr exception;

    void loadNow()
    {
        std::unique_ptr<Stream> stream = loader->getAssetStream(filename);
        _successful = false;
        try
        {
            *result = textureLoad(*stream, format);
            _successful = true;
        }
        catch (...)
        {
            exception = std::current_exception();
            _successful = false;
        }

        resultSemaphore->signal();
        executeCallBack(shared_from_this());
    }
    void setCallBack(CallbackType callback) { setTheCallback(callback); }

private:
    TexturePtr get_() const
    {
        if (!_inCallback)
        {
            resultSemaphore->wait();
            resultSemaphore->signal();
        }
        return result;
    }
    bool isComplete_() const
    {
        if (resultSemaphore->tryWait())
        {
            resultSemaphore->signal();
            return true;
        }
        return false;
    }
    void cleanup_() {}
    void destroyObject() {}
};

typedef std::shared_ptr<TextureLoadFuture_> TextureLoadFuture;

namespace impl {
inline void textureLoadAsyncWorker(TextureLoadFuture future) { future->loadNow(); }
} // namespace impl

class TextureAsyncLoader : public AsyncScheduler<TexturePtr, TextureLoadFuture, &impl::textureLoadAsyncWorker>
{
public:
    TextureAsyncLoader() { _myInfo = "TextureAsyncLoader"; }
    AsyncResult loadTextureAsync(const std::string& filename, IAssetProvider* loader, TextureFileFormat format, AsyncResult::element_type::Callback callback = NULL)
    {
        auto future = std::make_shared<TextureLoadFuture_>();
        auto& params = *future;
        params.filename = filename;
        params.format = format;
        params.loader = loader;
        params.result = std::make_shared<Texture>();
        params.resultSemaphore = std::make_shared<Semaphore>();
        params.workSemaphore = &_workSemaphore;
        params.setCallBack(callback);
        _queueSemaphore.wait();
        _queue.emplace_back(future);
        _queueSemaphore.signal();
        _workSemaphore.signal();
        return future;
    }
};
} // namespace async
} // namespace pvr