void TextureUploaderGL::AllocateUploadBuffer(const UploadBufferDesc& Desc, bool IsRenderThread, IUploadBuffer **ppBuffer)
    {
        *ppBuffer = nullptr;
        RefCntAutoPtr<UploadBufferGL> pUploadBuffer;

        {
            std::lock_guard<std::mutex> CacheLock(m_pInternalData->m_UploadBuffCacheMtx);
            auto &Cache = m_pInternalData->m_UploadBufferCache;
            if (!Cache.empty())
            {
                auto DequeIt = Cache.find(Desc);
                if (DequeIt != Cache.end())
                {
                    auto &Deque = DequeIt->second;
                    if (!Deque.empty())
                    {
                        pUploadBuffer.Attach(Deque.front().Detach());
                        Deque.pop_front();
                    }
                }
            }
        }

        if( !pUploadBuffer )
        {
            pUploadBuffer = MakeNewRCObj<UploadBufferGL>()(Desc);
            LOG_INFO_MESSAGE("TextureUploaderGL: created upload buffer for ", Desc.Width, 'x', Desc.Height, 'x', Desc.Depth, ' ', m_pDevice->GetTextureFormatInfo(Desc.Format).Name, " texture" )
        }
/**
* Initialize an EGL context for the current display.
*/
int Engine::InitDisplay()
{
    if( !initialized_resources_ )
    {
        EngineCreationAttribs EngineCreationAttribs;
        EngineCreationAttribs.strShaderCachePath = "/tmp/ShaderCache";
        RefCntAutoPtr<Diligent::IRenderDevice> pRenderDevice;
        SwapChainDesc SwapChainDesc;
        CreateDeviceAndSwapChainGL( EngineCreationAttribs, &pRenderDevice, &pDeviceContext_, SwapChainDesc, app_->window, &pSwapChain_ );

        Diligent::IRenderDeviceGLES *pRenderDeviceOpenGLES;
        pRenderDevice->QueryInterface( Diligent::IID_RenderDeviceGLES, reinterpret_cast<IObject**>(&pRenderDeviceOpenGLES) );
        pRenderDevice_.Attach( pRenderDeviceOpenGLES );

        LoadResources();
        initialized_resources_ = true;

        // Set font scaling
        TwDefine(" GLOBAL fontscaling=3");

        // TW_OPENGL and TW_OPENGL_CORE were designed to select rendering with 
        // very old GL specification. Using these modes results in applying some 
        // odd offsets which distorts everything
        // Latest OpenGL works very much like Direct3D11, and 
        // Tweak Bar will never know if D3D or OpenGL is actually used
        if (!TwInit(TW_DIRECT3D11, pRenderDevice_.RawPtr(), pDeviceContext_.RawPtr(), SwapChainDesc.ColorBufferFormat))
        {
            LOGE( "Failed to Init Ant tweak bar" );
            return 0;
        }

        sample_.reset( CreateSample(pRenderDevice, pDeviceContext_, pSwapChain_) );
    }
    else
    {
        // initialize OpenGL ES and EGL
        if( EGL_SUCCESS != pRenderDevice_->Resume( app_->window ) )
        {
            UnloadResources();
            LoadResources();
        }
    }

    ShowUI();

    auto width = pSwapChain_->GetDesc().Width;
    auto height = pSwapChain_->GetDesc().Height;

    //Note that screen size might have been changed
    pDeviceContext_->SetViewports( 1, nullptr, width, height );
    //renderer_.UpdateViewport();
    
    sample_->WindowResize(width, height);

    // Send the new window size to AntTweakBar
    TwWindowSize(width, height);


    //tap_camera_.SetFlip( 1.f, -1.f, -1.f );
    //tap_camera_.SetPinchTransformFactor( 2.f, 2.f, 8.f );

    return 0;
}