<commit_before>#include "gtest/gtest.h"

#include "IFile.h"
#include "IFolder.h"
#include "IMediaLibrary.h"

#include "filesystem/IDirectory.h"
#include "filesystem/IFile.h"
#include "Utils.h"

#include <memory>
#include <unordered_map>

namespace mock
{

class File : public fs::IFile
{
public:
    File( const std::string& filePath )
        : m_name( utils::file::fileName( filePath ) )
        , m_path( utils::file::directory( filePath ) )
        , m_fullPath( filePath )
        , m_extension( utils::file::extension( filePath ) )
        , m_lastModification( 0 )
    {
    }

    File( const File& ) = default;

    virtual const std::string& name() const override
    {
        return m_name;
    }

    virtual const std::string& path() const override
    {
        return m_path;
    }

    virtual const std::string& fullPath() const override
    {
        return m_fullPath;
    }

    virtual const std::string& extension() const override
    {
        return m_extension;
    }

    virtual unsigned int lastModificationDate() const override
    {
        return m_lastModification;
    }

    std::string m_name;
    std::string m_path;
    std::string m_fullPath;
    std::string m_extension;
    unsigned int m_lastModification;
};

class Directory : public fs::IDirectory
{
public:
    Directory( const std::string& path, unsigned int lastModif )
        : m_path( path )
        , m_lastModificationDate( lastModif )
    {
    }

    virtual const std::string& path() const
    {
        return m_path;
    }

    virtual const std::vector<std::string>& files() const
    {
        return m_files;
    }

    virtual const std::vector<std::string>& dirs() const
    {
        return m_dirs;
    }

    virtual unsigned int lastModificationDate() const override
    {
        return m_lastModificationDate;
    }

    void addFile( const std::string& fileName )
    {
        m_files.emplace_back( m_path + fileName );
        m_lastModificationDate++;
    }

    void addFolder( const std::string& folder )
    {
        m_dirs.emplace_back( m_path + folder );
        m_lastModificationDate++;
    }

private:
    std::string m_path;
    std::vector<std::string> m_files;
    std::vector<std::string> m_dirs;
    unsigned int m_lastModificationDate;
};

struct FileSystemFactory : public factory::IFileSystem
{
    static constexpr const char* Root = "/a/";
    static constexpr const char* SubFolder = "/a/folder/";

    FileSystemFactory()
    {
        dirs[Root] = std::unique_ptr<mock::Directory>( new Directory{ Root, 123 } );
            addFile( Root, "video.avi" );
            addFile( Root, "audio.mp3" );
            addFile( Root, "not_a_media.something" );
            addFile( Root, "some_other_file.seaotter" );
            addFolder( Root, "folder/", 456 );
                addFile( SubFolder, "subfile.mp4" );
    }

    void addFile( const std::string& path, const std::string& fileName )
    {
        dirs[path]->addFile( fileName );
        files[path + fileName] = std::unique_ptr<mock::File>( new mock::File( path + fileName ) );
    }

    void addFolder( const std::string& parentPath, const std::string& path, unsigned int lastModif )
    {
        auto parent = dirs[parentPath];
        parent->addFolder( path );
        dirs[parentPath + path] = std::unique_ptr<mock::Directory>( new Directory( parent, parentPath + path, lastModif ) );
    }

    virtual std::unique_ptr<fs::IDirectory> createDirectory(const std::string& path) override
    {
        mock::Directory* res = nullptr;
        if ( path == "." )
        {
            res = dirs[Root].get();
        }
        else
        {
            auto it = dirs.find( path );
            if ( it != end( dirs ) )
                res = it->second.get();
        }
        if ( res == nullptr )
            throw std::runtime_error("Invalid path");
        return std::unique_ptr<fs::IDirectory>( new Directory( *res ) );
    }

    virtual std::unique_ptr<fs::IFile> createFile( const std::string &filePath ) override
    {
        const auto it = files.find( filePath );
        if ( it == end( files ) )
            files[filePath].reset( new File( filePath ) );
        return std::unique_ptr<fs::IFile>( new File( static_cast<const mock::File&>( * it->second.get() ) ) );
    }

    std::unordered_map<std::string, std::unique_ptr<mock::File>> files;
    std::unordered_map<std::string, std::unique_ptr<mock::Directory>> dirs;
};

}

class Folders : public testing::Test
{
    public:
        static std::unique_ptr<IMediaLibrary> ml;
        std::shared_ptr<mock::FileSystemFactory> fsMock;

    protected:
        virtual void Reload()
        {
            ml.reset( MediaLibraryFactory::create() );
            bool res = ml->initialize( "test.db", fsMock );
            ASSERT_TRUE( res );
        }

        virtual void SetUp()
        {
            fsMock.reset( new mock::FileSystemFactory );
            Reload();
        }

        virtual void TearDown()
        {
            ml.reset();
            unlink("test.db");
        }
};

std::unique_ptr<IMediaLibrary> Folders::ml;

TEST_F( Folders, Add )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f, nullptr );

    auto files = ml->files();

    ASSERT_EQ( files.size(), 3u );
    ASSERT_FALSE( files[0]->isStandAlone() );
}

TEST_F( Folders, Delete )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f, nullptr );

    auto folderPath = f->path();

    auto files = ml->files();
    ASSERT_EQ( files.size(), 3u );

    auto filePath = files[0]->mrl();

    ml->deleteFolder( f );

    f = ml->folder( folderPath );
    ASSERT_EQ( nullptr, f );

    files = ml->files();
    ASSERT_EQ( files.size(), 0u );

    // Check the file isn't cached anymore:
    auto file = ml->file( filePath );
    ASSERT_EQ( nullptr, file );

    SetUp();

    // Recheck folder deletion from DB:
    f = ml->folder( folderPath );
    ASSERT_EQ( nullptr, f );
}

TEST_F( Folders, Load )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f, nullptr );

    SetUp();

    auto files = ml->files();
    ASSERT_EQ( files.size(), 3u );
    for ( auto& f : files )
        ASSERT_FALSE( f->isStandAlone() );
}

TEST_F( Folders, InvalidPath )
{
    auto f = ml->addFolder( "/invalid/path" );
    ASSERT_EQ( f, nullptr );

    auto files = ml->files();
    ASSERT_EQ( files.size(), 0u );
}

TEST_F( Folders, List )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f, nullptr );

    auto files = f->files();
    ASSERT_EQ( files.size(), 2u );

    SetUp();

    f = ml->folder( f->path() );
    files = f->files();
    ASSERT_EQ( files.size(), 2u );
}

TEST_F( Folders, AbsolutePath )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f->path(), "." );
}

TEST_F( Folders, ListFolders )
{
    auto f = ml->addFolder( "." );
    auto subFolders = f->folders();
    ASSERT_EQ( 1u, subFolders.size() );

    auto subFolder = subFolders[0];
    auto subFiles = subFolder->files();
    ASSERT_EQ( 1u, subFiles.size() );

    auto file = subFiles[0];
    ASSERT_EQ( std::string{ mock::FileSystemFactory::SubFolder } + "subfile.mp4", file->mrl() );

    // Now again, without cache
    SetUp();

    f = ml->folder( f->path() );
    subFolders = f->folders();
    ASSERT_EQ( 1u, subFolders.size() );

    subFolder = subFolders[0];
    subFiles = subFolder->files();
    ASSERT_EQ( 1u, subFiles.size() );

    file = subFiles[0];
    ASSERT_EQ( std::string{ mock::FileSystemFactory::SubFolder } + "subfile.mp4", file->mrl() );
}

TEST_F( Folders, LastModificationDate )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( 0u, f->lastModificationDate() );
    auto subFolders = f->folders();
    ASSERT_NE( 0u, subFolders[0]->lastModificationDate() );

    SetUp();

    f = ml->folder( f->path() );
    ASSERT_NE( 0u, f->lastModificationDate() );
    subFolders = f->folders();
    ASSERT_NE( 0u, subFolders[0]->lastModificationDate() );
}

TEST_F( Folders, NewFile )
{
    ml->addFolder( "." );

    ASSERT_EQ( 3u, ml->files().size() );
    // Do not watch for live changes
    ml.reset();
    auto newFolder = std::string(mock::FileSystemFactory::Root) + "newfolder/";
    fsMock->addFolder( mock::FileSystemFactory::Root, "newfolder/", time( nullptr ) );
    fsMock->addFile( newFolder, "newfile.avi" );

    Reload();

    ASSERT_EQ( 4u, ml->files().size() );
    auto file = ml->file( newFolder + "newfile.avi" );
    ASSERT_NE( nullptr, file );
}
<commit_msg>tests: FS mock: Propagate changes to parent folders<commit_after>#include "gtest/gtest.h"

#include "IFile.h"
#include "IFolder.h"
#include "IMediaLibrary.h"

#include "filesystem/IDirectory.h"
#include "filesystem/IFile.h"
#include "Utils.h"

#include <memory>
#include <unordered_map>

namespace mock
{

class File : public fs::IFile
{
public:
    File( const std::string& filePath )
        : m_name( utils::file::fileName( filePath ) )
        , m_path( utils::file::directory( filePath ) )
        , m_fullPath( filePath )
        , m_extension( utils::file::extension( filePath ) )
        , m_lastModification( 0 )
    {
    }

    File( const File& ) = default;

    virtual const std::string& name() const override
    {
        return m_name;
    }

    virtual const std::string& path() const override
    {
        return m_path;
    }

    virtual const std::string& fullPath() const override
    {
        return m_fullPath;
    }

    virtual const std::string& extension() const override
    {
        return m_extension;
    }

    virtual unsigned int lastModificationDate() const override
    {
        return m_lastModification;
    }

    std::string m_name;
    std::string m_path;
    std::string m_fullPath;
    std::string m_extension;
    unsigned int m_lastModification;
};

class Directory : public fs::IDirectory
{
public:
    Directory( std::shared_ptr<mock::Directory> parent, const std::string& path, unsigned int lastModif )
        : m_path( path )
        , m_parent( parent )
        , m_lastModificationDate( lastModif )
    {
    }

    virtual const std::string& path() const
    {
        return m_path;
    }

    virtual const std::vector<std::string>& files() const
    {
        return m_files;
    }

    virtual const std::vector<std::string>& dirs() const
    {
        return m_dirs;
    }

    virtual unsigned int lastModificationDate() const override
    {
        return m_lastModificationDate;
    }

    void addFile( const std::string& fileName )
    {
        m_files.emplace_back( m_path + fileName );
        markAsModified();
    }

    void addFolder( const std::string& folder )
    {
        m_dirs.emplace_back( m_path + folder );
        markAsModified();
    }

    void markAsModified()
    {
        if ( m_parent != nullptr )
            m_parent->markAsModified();
        m_lastModificationDate++;
    }

private:
    std::string m_path;
    std::vector<std::string> m_files;
    std::vector<std::string> m_dirs;
    std::shared_ptr<mock::Directory> m_parent;
    unsigned int m_lastModificationDate;
};

struct FileSystemFactory : public factory::IFileSystem
{
    static constexpr const char* Root = "/a/";
    static constexpr const char* SubFolder = "/a/folder/";

    FileSystemFactory()
    {
        dirs[Root] = std::unique_ptr<mock::Directory>( new Directory{ nullptr, Root, 123 } );
            addFile( Root, "video.avi" );
            addFile( Root, "audio.mp3" );
            addFile( Root, "not_a_media.something" );
            addFile( Root, "some_other_file.seaotter" );
            addFolder( Root, "folder/", 456 );
                addFile( SubFolder, "subfile.mp4" );
    }

    void addFile( const std::string& path, const std::string& fileName )
    {
        dirs[path]->addFile( fileName );
        files[path + fileName] = std::unique_ptr<mock::File>( new mock::File( path + fileName ) );
    }

    void addFolder( const std::string& parentPath, const std::string& path, unsigned int lastModif )
    {
        auto parent = dirs[parentPath];
        parent->addFolder( path );
        dirs[parentPath + path] = std::unique_ptr<mock::Directory>( new Directory( parent, parentPath + path, lastModif ) );
    }

    virtual std::unique_ptr<fs::IDirectory> createDirectory(const std::string& path) override
    {
        mock::Directory* res = nullptr;
        if ( path == "." )
        {
            res = dirs[Root].get();
        }
        else
        {
            auto it = dirs.find( path );
            if ( it != end( dirs ) )
                res = it->second.get();
        }
        if ( res == nullptr )
            throw std::runtime_error("Invalid path");
        return std::unique_ptr<fs::IDirectory>( new Directory( *res ) );
    }

    virtual std::unique_ptr<fs::IFile> createFile( const std::string &filePath ) override
    {
        const auto it = files.find( filePath );
        if ( it == end( files ) )
            files[filePath].reset( new File( filePath ) );
        return std::unique_ptr<fs::IFile>( new File( static_cast<const mock::File&>( * it->second.get() ) ) );
    }

    std::unordered_map<std::string, std::shared_ptr<mock::File>> files;
    std::unordered_map<std::string, std::shared_ptr<mock::Directory>> dirs;
};

}

class Folders : public testing::Test
{
    public:
        static std::unique_ptr<IMediaLibrary> ml;
        std::shared_ptr<mock::FileSystemFactory> fsMock;

    protected:
        virtual void Reload()
        {
            ml.reset( MediaLibraryFactory::create() );
            bool res = ml->initialize( "test.db", fsMock );
            ASSERT_TRUE( res );
        }

        virtual void SetUp()
        {
            fsMock.reset( new mock::FileSystemFactory );
            Reload();
        }

        virtual void TearDown()
        {
            ml.reset();
            unlink("test.db");
        }
};

std::unique_ptr<IMediaLibrary> Folders::ml;

TEST_F( Folders, Add )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f, nullptr );

    auto files = ml->files();

    ASSERT_EQ( files.size(), 3u );
    ASSERT_FALSE( files[0]->isStandAlone() );
}

TEST_F( Folders, Delete )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f, nullptr );

    auto folderPath = f->path();

    auto files = ml->files();
    ASSERT_EQ( files.size(), 3u );

    auto filePath = files[0]->mrl();

    ml->deleteFolder( f );

    f = ml->folder( folderPath );
    ASSERT_EQ( nullptr, f );

    files = ml->files();
    ASSERT_EQ( files.size(), 0u );

    // Check the file isn't cached anymore:
    auto file = ml->file( filePath );
    ASSERT_EQ( nullptr, file );

    SetUp();

    // Recheck folder deletion from DB:
    f = ml->folder( folderPath );
    ASSERT_EQ( nullptr, f );
}

TEST_F( Folders, Load )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f, nullptr );

    SetUp();

    auto files = ml->files();
    ASSERT_EQ( files.size(), 3u );
    for ( auto& f : files )
        ASSERT_FALSE( f->isStandAlone() );
}

TEST_F( Folders, InvalidPath )
{
    auto f = ml->addFolder( "/invalid/path" );
    ASSERT_EQ( f, nullptr );

    auto files = ml->files();
    ASSERT_EQ( files.size(), 0u );
}

TEST_F( Folders, List )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f, nullptr );

    auto files = f->files();
    ASSERT_EQ( files.size(), 2u );

    SetUp();

    f = ml->folder( f->path() );
    files = f->files();
    ASSERT_EQ( files.size(), 2u );
}

TEST_F( Folders, AbsolutePath )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( f->path(), "." );
}

TEST_F( Folders, ListFolders )
{
    auto f = ml->addFolder( "." );
    auto subFolders = f->folders();
    ASSERT_EQ( 1u, subFolders.size() );

    auto subFolder = subFolders[0];
    auto subFiles = subFolder->files();
    ASSERT_EQ( 1u, subFiles.size() );

    auto file = subFiles[0];
    ASSERT_EQ( std::string{ mock::FileSystemFactory::SubFolder } + "subfile.mp4", file->mrl() );

    // Now again, without cache
    SetUp();

    f = ml->folder( f->path() );
    subFolders = f->folders();
    ASSERT_EQ( 1u, subFolders.size() );

    subFolder = subFolders[0];
    subFiles = subFolder->files();
    ASSERT_EQ( 1u, subFiles.size() );

    file = subFiles[0];
    ASSERT_EQ( std::string{ mock::FileSystemFactory::SubFolder } + "subfile.mp4", file->mrl() );
}

TEST_F( Folders, LastModificationDate )
{
    auto f = ml->addFolder( "." );
    ASSERT_NE( 0u, f->lastModificationDate() );
    auto subFolders = f->folders();
    ASSERT_NE( 0u, subFolders[0]->lastModificationDate() );

    SetUp();

    f = ml->folder( f->path() );
    ASSERT_NE( 0u, f->lastModificationDate() );
    subFolders = f->folders();
    ASSERT_NE( 0u, subFolders[0]->lastModificationDate() );
}

TEST_F( Folders, NewFile )
{
    ml->addFolder( "." );

    ASSERT_EQ( 3u, ml->files().size() );
    // Do not watch for live changes
    ml.reset();
    auto newFolder = std::string(mock::FileSystemFactory::Root) + "newfolder/";
    fsMock->addFolder( mock::FileSystemFactory::Root, "newfolder/", time( nullptr ) );
    fsMock->addFile( newFolder, "newfile.avi" );

    Reload();

    ASSERT_EQ( 4u, ml->files().size() );
    auto file = ml->file( newFolder + "newfile.avi" );
    ASSERT_NE( nullptr, file );
}
<|endoftext|>


<commit_before>#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/viz/vizcore.hpp>
#include <kfusion/kinfu.hpp>
#include <io/capture.hpp>

using namespace kfusion;

struct KinFuApp
{
    static void KeyboardCallback(const cv::viz::KeyboardEvent& event, void* pthis)
    {
        KinFuApp& kinfu = *static_cast<KinFuApp*>(pthis);

        if(event.action != cv::viz::KeyboardEvent::KEY_DOWN)
            return;

        if(event.code == 't' || event.code == 'T')
            kinfu.take_cloud(*kinfu.kinfu_);

        if(event.code == 'i' || event.code == 'I')
            kinfu.iteractive_mode_ = !kinfu.iteractive_mode_;
    }

    KinFuApp(OpenNISource& source) : exit_ (false),  iteractive_mode_(false), capture_ (source), pause_(false)
    {
        KinFuParams params = KinFuParams::default_params();
        kinfu_ = KinFu::Ptr( new KinFu(params) );

        capture_.setRegistration(true);

        cv::viz::WCube cube(cv::Vec3d::all(0), cv::Vec3d(params.volume_size), true, cv::viz::Color::apricot());
        viz.showWidget("cube", cube, params.volume_pose);
        viz.showWidget("coor", cv::viz::WCoordinateSystem(0.1));
        viz.registerKeyboardCallback(KeyboardCallback, this);
    }

    void show_depth(const cv::Mat& depth)
    {
        cv::Mat display;
        //cv::normalize(depth, display, 0, 255, cv::NORM_MINMAX, CV_8U);
        depth.convertTo(display, CV_8U, 255.0/4000);
        cv::imshow("Depth", display);
    }

    void show_raycasted(KinFu& kinfu)
    {
        const int mode = 3;
        if (iteractive_mode_)
            kinfu.renderImage(view_device_, viz.getViewerPose(), mode);
        else
            kinfu.renderImage(view_device_, mode);

        view_host_.create(view_device_.rows(), view_device_.cols(), CV_8UC4);
        view_device_.download(view_host_.ptr<void>(), view_host_.step);
        cv::imshow("Scene", view_host_);
    }

    void take_cloud(KinFu& kinfu)
    {
        cuda::DeviceArray<Point> cloud = kinfu.tsdf().fetchCloud(cloud_buffer);
        cv::Mat cloud_host(1, (int)cloud.size(), CV_32FC4);
        cloud.download(cloud_host.ptr<Point>());
        viz.showWidget("cloud", cv::viz::WCloud(cloud_host));
        //viz.showWidget("cloud", cv::viz::WPaintedCloud(cloud_host));
    }

    bool execute()
    {
        KinFu& kinfu = *kinfu_;
        cv::Mat depth, image;
        double time_ms = 0;
        bool has_image = false;

        for (int i = 0; !exit_ && !viz.wasStopped(); ++i)
        {
            bool has_frame = capture_.grab(depth, image);
            if (!has_frame)
                return std::cout << "Can't grab" << std::endl, false;

            depth_device_.upload(depth.data, depth.step, depth.rows, depth.cols);

            {
                SampledScopeTime fps(time_ms); (void)fps;
                has_image = kinfu(depth_device_);
            }

            if (has_image)
                show_raycasted(kinfu);

            show_depth(depth);
            //cv::imshow("Image", image);

            if (!iteractive_mode_)
                viz.setViewerPose(kinfu.getCameraPose());

            int key = cv::waitKey(pause_ ? 0 : 3);

            switch(key)
            {
            case 't': case 'T' : take_cloud(kinfu); break;
            case 'i': case 'I' : iteractive_mode_ = !iteractive_mode_; break;
            case 27: exit_ = true; break;
            case 32: pause_ = !pause_; break;
            }

            //exit_ = exit_ || i > 100;
            viz.spinOnce(3, true);
        }
        return true;
    }

    bool pause_ /*= false*/;
    bool exit_, iteractive_mode_;
    OpenNISource& capture_;
    KinFu::Ptr kinfu_;
    cv::viz::Viz3d viz;

    cv::Mat view_host_;
    cuda::Image view_device_;
    cuda::Depth depth_device_;
    cuda::DeviceArray<Point> cloud_buffer;
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int main (int argc, char* argv[])
{
    int device = 0;
    cuda::setDevice (device);
    cuda::printShortCudaDeviceInfo (device);

    if(cuda::checkIfPreFermiGPU(device))
        return std::cout << std::endl << "Kinfu is not supported for pre-Fermi GPU architectures, and not built for them by default. Exiting..." << std::endl, 1;

    OpenNISource capture;
    capture.open(argv[1]);

    KinFuApp app (capture);

    // executing
    try { app.execute (); }
    catch (const std::bad_alloc& /*e*/) { std::cout << "Bad alloc" << std::endl; }
    catch (const std::exception& /*e*/) { std::cout << "Exception" << std::endl; }

    return 0;
}
<commit_msg>fixed typos<commit_after>#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/viz/vizcore.hpp>
#include <kfusion/kinfu.hpp>
#include <io/capture.hpp>

using namespace kfusion;

struct KinFuApp
{
    static void KeyboardCallback(const cv::viz::KeyboardEvent& event, void* pthis)
    {
        KinFuApp& kinfu = *static_cast<KinFuApp*>(pthis);

        if(event.action != cv::viz::KeyboardEvent::KEY_DOWN)
            return;

        if(event.code == 't' || event.code == 'T')
            kinfu.take_cloud(*kinfu.kinfu_);

        if(event.code == 'i' || event.code == 'I')
            kinfu.interactive_mode_ = !kinfu.interactive_mode_;
    }

    KinFuApp(OpenNISource& source) : exit_ (false),  interactive_mode_(false), capture_ (source), pause_(false)
    {
        KinFuParams params = KinFuParams::default_params();
        kinfu_ = KinFu::Ptr( new KinFu(params) );

        capture_.setRegistration(true);

        cv::viz::WCube cube(cv::Vec3d::all(0), cv::Vec3d(params.volume_size), true, cv::viz::Color::apricot());
        viz.showWidget("cube", cube, params.volume_pose);
        viz.showWidget("coor", cv::viz::WCoordinateSystem(0.1));
        viz.registerKeyboardCallback(KeyboardCallback, this);
    }

    void show_depth(const cv::Mat& depth)
    {
        cv::Mat display;
        //cv::normalize(depth, display, 0, 255, cv::NORM_MINMAX, CV_8U);
        depth.convertTo(display, CV_8U, 255.0/4000);
        cv::imshow("Depth", display);
    }

    void show_raycasted(KinFu& kinfu)
    {
        const int mode = 3;
        if (interactive_mode_)
            kinfu.renderImage(view_device_, viz.getViewerPose(), mode);
        else
            kinfu.renderImage(view_device_, mode);

        view_host_.create(view_device_.rows(), view_device_.cols(), CV_8UC4);
        view_device_.download(view_host_.ptr<void>(), view_host_.step);
        cv::imshow("Scene", view_host_);
    }

    void take_cloud(KinFu& kinfu)
    {
        cuda::DeviceArray<Point> cloud = kinfu.tsdf().fetchCloud(cloud_buffer);
        cv::Mat cloud_host(1, (int)cloud.size(), CV_32FC4);
        cloud.download(cloud_host.ptr<Point>());
        viz.showWidget("cloud", cv::viz::WCloud(cloud_host));
//        viz.showWidget("cloud", cv::viz::WPaintedCloud(cloud_host));
    }

    bool execute()
    {
        KinFu& kinfu = *kinfu_;
        cv::Mat depth, image;
        double time_ms = 0;
        bool has_image = false;

        for (int i = 0; !exit_ && !viz.wasStopped(); ++i)
        {
            bool has_frame = capture_.grab(depth, image);
            if (!has_frame)
                return std::cout << "Can't grab" << std::endl, false;

            depth_device_.upload(depth.data, depth.step, depth.rows, depth.cols);

            {
                SampledScopeTime fps(time_ms); (void)fps;
                has_image = kinfu(depth_device_);
            }

            if (has_image)
                show_raycasted(kinfu);

            show_depth(depth);
            //cv::imshow("Image", image);

            if (!interactive_mode_)
                viz.setViewerPose(kinfu.getCameraPose());

            int key = cv::waitKey(pause_ ? 0 : 3);

            switch(key)
            {
            case 't': case 'T' : take_cloud(kinfu); break;
            case 'i': case 'I' : interactive_mode_ = !interactive_mode_; break;
            case 27: exit_ = true; break;
            case 32: pause_ = !pause_; break;
            }

            //exit_ = exit_ || i > 100;
            viz.spinOnce(3, true);
        }
        return true;
    }

    bool pause_ /*= false*/;
    bool exit_, interactive_mode_;
    OpenNISource& capture_;
    KinFu::Ptr kinfu_;
    cv::viz::Viz3d viz;

    cv::Mat view_host_;
    cuda::Image view_device_;
    cuda::Depth depth_device_;
    cuda::DeviceArray<Point> cloud_buffer;
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

int main (int argc, char* argv[])
{
    int device = 0;
    cuda::setDevice (device);
    cuda::printShortCudaDeviceInfo (device);

    if(cuda::checkIfPreFermiGPU(device))
        return std::cout << std::endl << "Kinfu is not supported for pre-Fermi GPU architectures, and not built for them by default. Exiting..." << std::endl, 1;

    OpenNISource capture;
    capture.open(argv[1]);

    KinFuApp app (capture);

    // executing
    try { app.execute (); }
    catch (const std::bad_alloc& /*e*/) { std::cout << "Bad alloc" << std::endl; }
    catch (const std::exception& /*e*/) { std::cout << "Exception" << std::endl; }

    return 0;
}
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include <glog/logging.h>
#include "unsupported/Eigen/CXX11/Tensor"

namespace paddle {

template <class T>
struct EigenBlasGemm {
  typedef Eigen::TensorMap<Eigen::Tensor<T, 2, Eigen::RowMajor, int>,
                           Eigen::Aligned>
      Matrix;

  static void compute(const bool transA,
                      const bool transB,
                      const int M,
                      const int N,
                      const int K,
                      const T alpha,
                      const T* A,
                      const int lda,
                      const T* B,
                      const int ldb,
                      const T beta,
                      T* C,
                      const int ldc) {
    Eigen::array<int, 2> sizeA;
    if (transA) {
      sizeA[0] = K;
      sizeA[1] = M;
      CHECK_EQ(M, lda);
    } else {
      sizeA[0] = M;
      sizeA[1] = K;
      CHECK_EQ(K, lda);
    }
    Eigen::array<int, 2> sizeB;
    if (transB) {
      sizeB[0] = N;
      sizeB[1] = K;
      CHECK_EQ(K, ldb);
    } else {
      sizeB[0] = K;
      sizeB[1] = N;
      CHECK_EQ(N, ldb);
    }
    Eigen::array<int, 2> sizeC;
    sizeC[0] = M;
    sizeC[1] = N;
    CHECK_EQ(N, ldc);

    const Matrix a(const_cast<T*>(A), sizeA);
    const Matrix b(const_cast<T*>(B), sizeB);
    Matrix c(C, sizeC);

    typedef typename Eigen::Tensor<T, 2>::DimensionPair DimPair;
    Eigen::array<DimPair, 1> dims;
    dims[0] = DimPair(1, 0);
    dims[0].first = transA ? 0 : 1;
    dims[0].second = transB ? 1 : 0;

    Eigen::DefaultDevice device;
    if (alpha == T(1) && beta == T(0)) {
      c.device(device) = a.contract(b, dims);
    } else if (alpha == T(1) && beta == T(1)) {
      c.device(device) += a.contract(b, dims);
    } else {
      c.device(device) = alpha * a.contract(b, dims) + beta * c;
    }
  }
};

#ifdef PADDLE_TYPE_DOUBLE
template struct EigenBlasGemm<double>;
#else
template struct EigenBlasGemm<float>;
#endif

}  // namespace paddle
<commit_msg>Enable the case N != ldc in EigenBlasGemm. (#5976)<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserve.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

#include <glog/logging.h>
#include "unsupported/Eigen/CXX11/Tensor"

namespace paddle {

template <class T>
struct EigenBlasGemm {
  typedef Eigen::TensorMap<Eigen::Tensor<T, 2, Eigen::RowMajor, int>,
                           Eigen::Aligned>
      EigenMatrix;

  static void compute(const bool transA,
                      const bool transB,
                      const int M,
                      const int N,
                      const int K,
                      const T alpha,
                      const T* A,
                      const int lda,
                      const T* B,
                      const int ldb,
                      const T beta,
                      T* C,
                      const int ldc) {
    Eigen::array<int, 2> sizeA;
    if (transA) {
      sizeA[0] = K;
      sizeA[1] = M;
      CHECK_EQ(M, lda);
    } else {
      sizeA[0] = M;
      sizeA[1] = K;
      CHECK_EQ(K, lda);
    }
    Eigen::array<int, 2> sizeB;
    if (transB) {
      sizeB[0] = N;
      sizeB[1] = K;
      CHECK_EQ(K, ldb);
    } else {
      sizeB[0] = K;
      sizeB[1] = N;
      CHECK_EQ(N, ldb);
    }
    Eigen::array<int, 2> sizeC = {{M, ldc}};
    Eigen::array<int, 2> offsetC = {{0, 0}};
    Eigen::array<int, 2> extentC = {{M, N}};

    const EigenMatrix a(const_cast<T*>(A), sizeA);
    const EigenMatrix b(const_cast<T*>(B), sizeB);
    EigenMatrix c(C, sizeC);

    typedef typename Eigen::Tensor<T, 2>::DimensionPair DimPair;
    Eigen::array<DimPair, 1> dims;
    dims[0] = DimPair(1, 0);
    dims[0].first = transA ? 0 : 1;
    dims[0].second = transB ? 1 : 0;

    Eigen::DefaultDevice device;
    if (N == ldc) {
      if (alpha == T(1) && beta == T(0)) {
        c.device(device) = a.contract(b, dims);
      } else if (alpha == T(1) && beta == T(1)) {
        c.device(device) += a.contract(b, dims);
      } else {
        c.device(device) = alpha * a.contract(b, dims) + beta * c;
      }
    } else {
      if (alpha == T(1) && beta == T(0)) {
        c.slice(offsetC, extentC).device(device) = a.contract(b, dims);
      } else if (alpha == T(1) && beta == T(1)) {
        c.slice(offsetC, extentC).device(device) += a.contract(b, dims);
      } else {
        c.slice(offsetC, extentC).device(device) =
            alpha * a.contract(b, dims) + beta * c.slice(offsetC, extentC);
      }
    }
  }
};

#ifdef PADDLE_TYPE_DOUBLE
template struct EigenBlasGemm<double>;
#else
template struct EigenBlasGemm<float>;
#endif

}  // namespace paddle
<|endoftext|>


<commit_before>#include "dumper.hpp"

#include "../coding/multilang_utf8_string.hpp"

#include "../indexer/classificator.hpp"
#include "../indexer/feature_processor.hpp"

#include "../std/algorithm.hpp"
#include "../std/bind.hpp"
#include "../std/iostream.hpp"
#include "../std/map.hpp"
#include "../std/vector.hpp"

namespace feature
{
  class TypesCollector
  {
    vector<uint32_t> m_currFeatureTypes;

  public:
    typedef map<vector<uint32_t>, size_t> value_type;
    value_type m_stats;
    size_t m_namesCount;
    size_t m_totalCount;

    TypesCollector() : m_namesCount(0), m_totalCount(0) {}

    void operator()(FeatureType & f, uint32_t)
    {
      ++m_totalCount;
      if (!f.GetPreferredDrawableName().empty())
        ++m_namesCount;

      m_currFeatureTypes.clear();
      f.ForEachTypeRef(*this);
      CHECK(!m_currFeatureTypes.empty(), ("Feature without any type???"));
      pair<value_type::iterator, bool> found = m_stats.insert(make_pair(m_currFeatureTypes, 1));
      if (!found.second)
        found.first->second++;
    }

    void operator()(uint32_t type)
    {
      m_currFeatureTypes.push_back(type);
    }
  };

  template <class T>
  static bool SortFunc(T const & first, T const & second)
  {
    return first.second > second.second;
  }

  void DumpTypes(string const & fPath)
  {
    TypesCollector doClass;
    feature::ForEachFromDat(fPath, doClass);

    typedef pair<vector<uint32_t>, size_t> stats_elem_type;
    typedef vector<stats_elem_type> vec_to_sort;
    vec_to_sort vecToSort(doClass.m_stats.begin(), doClass.m_stats.end());
    sort(vecToSort.begin(), vecToSort.end(), &SortFunc<stats_elem_type>);

    for (vec_to_sort::iterator it = vecToSort.begin(); it != vecToSort.end(); ++it)
    {
      cout << it->second << " ";
      for (size_t i = 0; i < it->first.size(); ++i)
        cout << classif().GetFullObjectName(it->first[i]) << " ";
      cout << endl;
    }
    cout << "Total features: " << doClass.m_totalCount << endl;
    cout << "Features with names: " << doClass.m_namesCount << endl;
  }

  ///////////////////////////////////////////////////////////////////

  typedef map<int8_t, map<string, size_t> > TokensContainerT;
  class PrefixesCollector
  {
  public:
    TokensContainerT m_stats;

    bool operator()(int8_t langCode, string const & name)
    {
      CHECK(!name.empty(), ("Feature name is empty"));

      vector<string> tokens;
      strings::SimpleTokenizer tok(name, " ");
      while (tok)
      {
        tokens.push_back(*tok);
        ++tok;
      }

      if (tokens.empty())
        return true;
      // ignore token if it's first letter is an uppercase letter
      strings::UniString const s1 = strings::MakeUniString(tokens[0]);
      strings::UniString const s2 = strings::MakeLowerCase(s1);
      if (s1[0] != s2[0])
        return true;

      for (size_t i = 1; i < tokens.size(); ++i)
      {
        string s;
        for (size_t numTokens = 0; numTokens < i; ++numTokens)
        {
          s += tokens[numTokens];
          s += " ";
        }
        pair<TokensContainerT::mapped_type::iterator, bool> found = m_stats[langCode].insert(make_pair(s, 1));
        if (!found.second)
          found.first->second++;
      }
      return true;
    }

    void operator()(FeatureType & f, uint32_t)
    {
      f.ForEachNameRef(*this);
    }
  };

  static size_t const MIN_OCCURRENCE = 3;

  void Print(int8_t langCode, TokensContainerT::mapped_type const & container)
  {
    typedef pair<string, size_t> NameElemT;
    typedef vector<NameElemT> VecToSortT;
    VecToSortT v(container.begin(), container.end());
    sort(v.begin(), v.end(), &SortFunc<NameElemT>);

    // do not display prefixes with low occurrences
    if (v[0].second > MIN_OCCURRENCE)
    {
      cout << "Language code: " << StringUtf8Multilang::GetLangByCode(langCode) << endl;

      for (VecToSortT::iterator it = v.begin(); it != v.end(); ++it)
      {
        if (it->second <= MIN_OCCURRENCE)
          break;
        cout << it->second << " " << it->first << endl;
      }
    }
  }

  void DumpPrefixes(string const & fPath)
  {
    PrefixesCollector doClass;
    feature::ForEachFromDat(fPath, doClass);
    for (TokensContainerT::iterator it = doClass.m_stats.begin();
         it != doClass.m_stats.end(); ++it)
    {
      Print(it->first, it->second);
    }

  }

}
<commit_msg>[generator] Output sample names in --dump_prefixes.<commit_after>#include "dumper.hpp"

#include "../coding/multilang_utf8_string.hpp"

#include "../indexer/classificator.hpp"
#include "../indexer/feature_processor.hpp"

#include "../std/algorithm.hpp"
#include "../std/bind.hpp"
#include "../std/iostream.hpp"
#include "../std/map.hpp"
#include "../std/vector.hpp"

namespace feature
{
  class TypesCollector
  {
    vector<uint32_t> m_currFeatureTypes;

  public:
    typedef map<vector<uint32_t>, size_t> value_type;
    value_type m_stats;
    size_t m_namesCount;
    size_t m_totalCount;

    TypesCollector() : m_namesCount(0), m_totalCount(0) {}

    void operator()(FeatureType & f, uint32_t)
    {
      ++m_totalCount;
      if (!f.GetPreferredDrawableName().empty())
        ++m_namesCount;

      m_currFeatureTypes.clear();
      f.ForEachTypeRef(*this);
      CHECK(!m_currFeatureTypes.empty(), ("Feature without any type???"));
      pair<value_type::iterator, bool> found = m_stats.insert(make_pair(m_currFeatureTypes, 1));
      if (!found.second)
        found.first->second++;
    }

    void operator()(uint32_t type)
    {
      m_currFeatureTypes.push_back(type);
    }
  };

  template <class T>
  static bool SortFunc(T const & first, T const & second)
  {
    return first.second > second.second;
  }

  void DumpTypes(string const & fPath)
  {
    TypesCollector doClass;
    feature::ForEachFromDat(fPath, doClass);

    typedef pair<vector<uint32_t>, size_t> stats_elem_type;
    typedef vector<stats_elem_type> vec_to_sort;
    vec_to_sort vecToSort(doClass.m_stats.begin(), doClass.m_stats.end());
    sort(vecToSort.begin(), vecToSort.end(), &SortFunc<stats_elem_type>);

    for (vec_to_sort::iterator it = vecToSort.begin(); it != vecToSort.end(); ++it)
    {
      cout << it->second << " ";
      for (size_t i = 0; i < it->first.size(); ++i)
        cout << classif().GetFullObjectName(it->first[i]) << " ";
      cout << endl;
    }
    cout << "Total features: " << doClass.m_totalCount << endl;
    cout << "Features with names: " << doClass.m_namesCount << endl;
  }

  ///////////////////////////////////////////////////////////////////

  typedef map<int8_t, map<string, pair<unsigned int, string> > > TokensContainerT;
  class PrefixesCollector
  {
  public:
    TokensContainerT m_stats;

    bool operator()(int8_t langCode, string const & name)
    {
      CHECK(!name.empty(), ("Feature name is empty"));

      vector<string> tokens;
      strings::SimpleTokenizer tok(name, " ");
      while (tok)
      {
        tokens.push_back(*tok);
        ++tok;
      }

      if (tokens.empty())
        return true;
      // ignore token if it's first letter is an uppercase letter
      strings::UniString const s1 = strings::MakeUniString(tokens[0]);
      strings::UniString const s2 = strings::MakeLowerCase(s1);
      if (s1[0] != s2[0])
        return true;

      for (size_t i = 1; i < tokens.size(); ++i)
      {
        string s;
        for (size_t numTokens = 0; numTokens < i; ++numTokens)
        {
          s += tokens[numTokens];
          s += " ";
        }
        pair<TokensContainerT::mapped_type::iterator, bool> found =
            m_stats[langCode].insert(make_pair(s, make_pair(1U, name)));
        if (!found.second)
          found.first->second.first++;
      }
      return true;
    }

    void operator()(FeatureType & f, uint32_t)
    {
      f.ForEachNameRef(*this);
    }
  };

  static size_t const MIN_OCCURRENCE = 3;

  void Print(int8_t langCode, TokensContainerT::mapped_type const & container)
  {
    typedef pair<string, pair<unsigned int, string> > NameElemT;
    typedef vector<NameElemT> VecToSortT;
    VecToSortT v(container.begin(), container.end());
    sort(v.begin(), v.end(), &SortFunc<NameElemT>);

    // do not display prefixes with low occurrences
    if (v[0].second.first > MIN_OCCURRENCE)
    {
      cout << "Language code: " << StringUtf8Multilang::GetLangByCode(langCode) << endl;

      for (VecToSortT::iterator it = v.begin(); it != v.end(); ++it)
      {
        if (it->second.first <= MIN_OCCURRENCE)
          break;
        cout << it->second.first << " " << it->first << " \"" << it->second.second << "\"" << endl;
      }
    }
  }

  void DumpPrefixes(string const & fPath)
  {
    PrefixesCollector doClass;
    feature::ForEachFromDat(fPath, doClass);
    for (TokensContainerT::iterator it = doClass.m_stats.begin();
         it != doClass.m_stats.end(); ++it)
    {
      Print(it->first, it->second);
    }

  }

}
<|endoftext|>


<commit_before>#include "photoeffects.hpp"
#include <math.h>

using namespace cv;

#define MAX_KERNELSIZE 15
#define PI 3.14159265359

int edgeBlur(InputArray src, OutputArray dst, int indentTop, int indentLeft)
{
    CV_Assert(src.type() == CV_8UC3);
    Mat image = src.getMat(), outputImage(image.size(), CV_8UC3);
    float kSizeEdges = (image.rows / 2.0f)
                    * (image.rows / 2.0f)
                    / (image.rows / 2.0f - indentTop)
                    / (image.rows / 2.0f - indentTop)

                    + (image.cols / 2.0f)
                    * (image.cols / 2.0f)
                    / (image.cols / 2.0f - indentLeft)
                    / (image.cols / 2.0f - indentLeft);
    if (kSizeEdges > MAX_KERNELSIZE)
    {
        kSizeEdges = MAX_KERNELSIZE;
    }
    Mat bearingImage(image.rows + 2 * kSizeEdges,
                    image.cols + 2 * kSizeEdges,
                    CV_8UC3);
    copyMakeBorder(image, bearingImage, kSizeEdges, kSizeEdges,
        kSizeEdges, kSizeEdges, BORDER_REPLICATE);

    float radius;
    int size;
    float B, G, R, sumC;
    Vec3b Color;
    float coeff;
    for (int i = kSizeEdges; i < (bearingImage.rows - kSizeEdges); i++)
    {
        for (int j = kSizeEdges; j < (bearingImage.cols - kSizeEdges); j++)
        {
            radius = (bearingImage.rows / 2.0f - i)
                    * (bearingImage.rows / 2.0f - i)
                    / (image.rows / 2.0f - indentTop)
                    / (image.rows / 2.0f - indentTop)

                    + (bearingImage.cols / 2.0f - j)
                    * (bearingImage.cols / 2.0f - j)
                    / (image.cols / 2.0f - indentLeft)
                    / (image.cols / 2.0f - indentLeft);
            if (radius < 1.0f)
            {
                outputImage.at<Vec3b>(i - kSizeEdges, j - kSizeEdges) =
                    bearingImage.at<Vec3b>(i, j);
                continue;
            }
            else
            {
                R = G = B = sumC = 0.0f;
                size = radius;
                radius -= 0.5f;
                radius *= radius;
                if (size > kSizeEdges)
                {
                    size = kSizeEdges;
                }
                for (int x = i - size; x <= i + size; x++)
                {
                    for (int y = j - size; y <= j + size; y++)
                    {
                        coeff = 1.0f / (2.0f * PI * radius)
                                * exp(- ((x - i)*(x - i) + (y - j)*(y - j))
                                      / (2.0f * radius));

                        Color = bearingImage.at<Vec3b>(x, y);
                        B = B + coeff * Color[0];
                        G = G + coeff * Color[1];
                        R = R + coeff * Color[2];
                        sumC += coeff;
                    }
                }
                B /= sumC;
                G /= sumC;
                R /= sumC;
                Color = Vec3b(B, G, R);
                outputImage.at<Vec3b>(i - kSizeEdges, j - kSizeEdges) = Color;
            }
        }
    }

    outputImage.convertTo(dst, CV_8UC3);
    return 0;
}
<commit_msg>Assert<commit_after>#include "photoeffects.hpp"
#include <math.h>

using namespace cv;

#define MAX_KERNELSIZE 15
#define PI 3.14159265359

int edgeBlur(InputArray src, OutputArray dst, int indentTop, int indentLeft)
{
    CV_Assert(src.type() == CV_8UC3);
    Mat image = src.getMat(), outputImage(image.size(), CV_8UC3);

    CV_Assert(indentTop >= 0 && indentTop <= (image.rows / 2.0f - 10));
    CV_Assert(indentLeft >= 0 && indentLeft <= (image.cols / 2.0f - 10));

    float kSizeEdges = (image.rows / 2.0f)
                    * (image.rows / 2.0f)
                    / (image.rows / 2.0f - indentTop)
                    / (image.rows / 2.0f - indentTop)

                    + (image.cols / 2.0f)
                    * (image.cols / 2.0f)
                    / (image.cols / 2.0f - indentLeft)
                    / (image.cols / 2.0f - indentLeft);
    if (kSizeEdges > MAX_KERNELSIZE)
    {
        kSizeEdges = MAX_KERNELSIZE;
    }
    Mat bearingImage(image.rows + 2 * kSizeEdges,
                    image.cols + 2 * kSizeEdges,
                    CV_8UC3);
    copyMakeBorder(image, bearingImage, kSizeEdges, kSizeEdges,
        kSizeEdges, kSizeEdges, BORDER_REPLICATE);

    float radius;
    int size;
    float B, G, R, sumC;
    Vec3b Color;
    float coeff;
    for (int i = kSizeEdges; i < (bearingImage.rows - kSizeEdges); i++)
    {
        for (int j = kSizeEdges; j < (bearingImage.cols - kSizeEdges); j++)
        {
            radius = (bearingImage.rows / 2.0f - i)
                    * (bearingImage.rows / 2.0f - i)
                    / (image.rows / 2.0f - indentTop)
                    / (image.rows / 2.0f - indentTop)

                    + (bearingImage.cols / 2.0f - j)
                    * (bearingImage.cols / 2.0f - j)
                    / (image.cols / 2.0f - indentLeft)
                    / (image.cols / 2.0f - indentLeft);
            if (radius < 1.0f)
            {
                outputImage.at<Vec3b>(i - kSizeEdges, j - kSizeEdges) =
                    bearingImage.at<Vec3b>(i, j);
                continue;
            }
            else
            {
                R = G = B = sumC = 0.0f;
                size = radius;
                radius -= 0.5f;
                radius *= radius;
                if (size > kSizeEdges)
                {
                    size = kSizeEdges;
                }
                for (int x = i - size; x <= i + size; x++)
                {
                    for (int y = j - size; y <= j + size; y++)
                    {
                        coeff = 1.0f / (2.0f * PI * radius)
                                * exp(- ((x - i)*(x - i) + (y - j)*(y - j))
                                      / (2.0f * radius));

                        Color = bearingImage.at<Vec3b>(x, y);
                        B = B + coeff * Color[0];
                        G = G + coeff * Color[1];
                        R = R + coeff * Color[2];
                        sumC += coeff;
                    }
                }
                B /= sumC;
                G /= sumC;
                R /= sumC;
                Color = Vec3b(B, G, R);
                outputImage.at<Vec3b>(i - kSizeEdges, j - kSizeEdges) = Color;
            }
        }
    }

    outputImage.convertTo(dst, CV_8UC3);
    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <zorba/zorba.h>

#include <fstream>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <memory>

// tests are allowed to use internals
#include "api/unmarshaller.h"
#include "zorbatypes/xqpstring.h"
#include "util/properties.h"

#include <zorba/util/path.h>

#include "store/api/item.h"
#include "zorba_test_setting.h"
#ifndef ZORBA_MINIMAL_STORE
#include <simplestore/simplestore.h>
#include "store/naive/simple_store.h"
#else
#include "store/minimal/min_store.h"
#endif

using namespace zorba;
using namespace std;

void set_var (string name, string val, DynamicContext* dctx)
{
  if (name [name.size () - 1] == ':')
  {
    Item lItem = Zorba::getInstance(NULL)->getItemFactory()->createString(val);
		if(name != ".") {
			dctx->setVariable(name.substr (0, name.size () - 1), lItem);
		} else
			dctx->setContextItem(lItem);
  }
  else if (name[name.size () - 1] != ':')
  {
    ifstream* is = new ifstream(val.c_str ());
    assert (*is);
		if(name != ".")
			dctx->setVariableAsDocument(name, val.c_str(), std::auto_ptr<std::istream>(is));
		else
			dctx->setContextItemAsDocument(val.c_str(), std::auto_ptr<std::istream>(is));
  }
}

// TODO: for now apitest users expect 0 even for error results; this should change
#ifndef _WIN32_WCE
int main(int argc, char* argv[])
#else
int _tmain(int argc, _TCHAR* argv[])
#endif
{
  // read the command file properties
  if (! Properties::load(argc,argv))
    return 4;

  Properties* lProp = Properties::instance();
  if (! lProp->hasSingleQuery ()) {
    cout << "Error: either a single inline query or a single query file must be supplied" << endl;
    return 4;
  }
  Zorba_CompilerHints chints;
  chints.opt_level = (lProp->optimizer () ?
                      ZORBA_OPT_LEVEL_O1:
                      ZORBA_OPT_LEVEL_O0);

  // output file (either a file or the standard out if no file is specified)
  auto_ptr<ostream> outputFile (lProp->resultFile ().empty ()
                                ? NULL : new ofstream (lProp->resultFile().c_str()));
  ostream *resultFile = outputFile.get ();
  if (resultFile == NULL)
    resultFile = &cout;

  // input file (either from a file or given as parameter)
  auto_ptr<istream> qfile;
  filesystem_path path;

  if (! lProp->inlineQuery()) {
    path = lProp->queryFile ();
    path.resolve_relative ();
    std::string fname = path.get_path ();
    qfile.reset (new ifstream (fname.c_str ()));
    if (!qfile->good() || qfile->eof()) {
      cerr << "no query given or not readable " << fname  << endl;
      return 3;
    }
  } else {
    qfile.reset (new istringstream(lProp->query ()));
  }

  // print the query if requested
  if (lProp->printQuery()) {
    cout << "Query text:\n";
    copy (istreambuf_iterator<char> (*qfile), istreambuf_iterator<char> (), ostreambuf_iterator<char> (cout));
    cout << "\n" << endl;
    qfile->seekg(0); // go back to the beginning
  }

  // Instantiate the simple store
#ifdef ZORBA_MINIMAL_STORE
  zorba::storeminimal::SimpleStore* store =
        zorba::storeminimal::SimpleStore::getInstance();
#else
  zorba::simplestore::SimpleStore* store =
        zorba::simplestore::SimpleStoreManager::getStore();
#endif

  // start processing
  Zorba* zengine = Zorba::getInstance(store);

  // start parsing the query
  XQuery_t query = zengine->createQuery ();
#ifdef ZORBA_DEBUGGER
 query->setDebugMode(lProp->debug());
#endif
  if (! lProp->inlineQuery())
    query->setFileName (path.get_path ());

  try {
    query->compile(*qfile, chints);
  } catch (ZorbaException &e) {
    // no need to close because the object is not valid
    cerr << "Compilation error: " << e << endl;
    return 1;
  }

  // set external variables
  vector<pair <string, string> > ext_vars = lProp->getExternalVars ();
  DynamicContext* dctx = query->getDynamicContext ();
  dctx->setImplicitTimezone (lProp->tz ());
  for (vector<pair <string, string> >::const_iterator iter = ext_vars.begin ();
       iter != ext_vars.end (); iter++) {
    set_var (iter->first, iter->second, dctx);
  }

  if (! lProp->compileOnly ()) {
    // output the result (either using xml serialization or using show)
    // cout << "Running query and printing result..." << endl;

    try {
      if (lProp->useSerializer()) {
        if (query->isUpdateQuery()) {
          query->applyUpdates();
        } else {
          Zorba_SerializerOptions opts = Zorba_SerializerOptions::SerializerOptionsFromStringParams(lProp->getSerializerParameters());
          query->serialize(*resultFile, &opts);
          // *resultFile << query;
        }
      } else {
        if (query->isUpdateQuery()) {
          query->applyUpdates();
        } else {
          ResultIterator_t result = query->iterator();
          result->open();
          Item lItem;
          while (result->next(lItem)) {
            // unmarshall the store item from the api item
            store::Item_t lStoreItem = Unmarshaller::getInternalItem(lItem);
            *resultFile << lStoreItem->show() << endl;
          }
          result->close();
        }
      }
    } catch (ZorbaException &e) {
      query->close();
      zengine->shutdown();
      store->shutdown();
      cerr << "Execution error: ";
      if (dynamic_cast<QueryException *> (&e) != NULL)
        cerr << (QueryException &) e;
      else
        cerr << e;
      cerr << endl;
      return 2;
    }
  }

  query->close();
  zengine->shutdown();
  store->shutdown();
  return 0;
}
<commit_msg>Changed apitest to process also .xqx XQueryX files.<commit_after>/*
 * Copyright 2006-2008 The FLWOR Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <zorba/zorba.h>

#include <fstream>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <memory>

// tests are allowed to use internals
#include "api/unmarshaller.h"
#include "zorbatypes/xqpstring.h"
#include "util/properties.h"

#include <zorba/util/path.h>

#include "store/api/item.h"
#include "zorba_test_setting.h"
#ifndef ZORBA_MINIMAL_STORE
#include <simplestore/simplestore.h>
#include "store/naive/simple_store.h"
#else
#include "store/minimal/min_store.h"
#endif

using namespace zorba;
using namespace std;

void set_var (string name, string val, DynamicContext* dctx)
{
  if (name [name.size () - 1] == ':')
  {
    Item lItem = Zorba::getInstance(NULL)->getItemFactory()->createString(val);
		if(name != ".") {
			dctx->setVariable(name.substr (0, name.size () - 1), lItem);
		} else
			dctx->setContextItem(lItem);
  }
  else if (name[name.size () - 1] != ':')
  {
    ifstream* is = new ifstream(val.c_str ());
    assert (*is);
		if(name != ".")
			dctx->setVariableAsDocument(name, val.c_str(), std::auto_ptr<std::istream>(is));
		else
			dctx->setContextItemAsDocument(val.c_str(), std::auto_ptr<std::istream>(is));
  }
}

// TODO: for now apitest users expect 0 even for error results; this should change
#ifndef _WIN32_WCE
int main(int argc, char* argv[])
#else
int _tmain(int argc, _TCHAR* argv[])
#endif
{
  // read the command file properties
  if (! Properties::load(argc,argv))
    return 4;

  Properties* lProp = Properties::instance();
  if (! lProp->hasSingleQuery ()) {
    cout << "Error: either a single inline query or a single query file must be supplied" << endl;
    return 4;
  }
  Zorba_CompilerHints chints;
  chints.opt_level = (lProp->optimizer () ?
                      ZORBA_OPT_LEVEL_O1:
                      ZORBA_OPT_LEVEL_O0);

  // output file (either a file or the standard out if no file is specified)
  auto_ptr<ostream> outputFile (lProp->resultFile ().empty ()
                                ? NULL : new ofstream (lProp->resultFile().c_str()));
  ostream *resultFile = outputFile.get ();
  if (resultFile == NULL)
    resultFile = &cout;

  // input file (either from a file or given as parameter)
  auto_ptr<istream> qfile;
  filesystem_path path;
  bool  is_xqueryx = false;

  if (! lProp->inlineQuery()) {
    path = lProp->queryFile ();
    path.resolve_relative ();
    std::string fname = path.get_path ();
    if(fname.substr(fname.length()-4) == ".xqx")
      is_xqueryx = true;
    qfile.reset (new ifstream (fname.c_str ()));
    if (!qfile->good() || qfile->eof()) {
      cerr << "no query given or not readable " << fname  << endl;
      return 3;
    }
  } else {
    qfile.reset (new istringstream(lProp->query ()));
  }

  // print the query if requested
  if (lProp->printQuery()) {
    cout << "Query text:\n";
    copy (istreambuf_iterator<char> (*qfile), istreambuf_iterator<char> (), ostreambuf_iterator<char> (cout));
    cout << "\n" << endl;
    qfile->seekg(0); // go back to the beginning
  }

  // Instantiate the simple store
#ifdef ZORBA_MINIMAL_STORE
  zorba::storeminimal::SimpleStore* store =
        zorba::storeminimal::SimpleStore::getInstance();
#else
  zorba::simplestore::SimpleStore* store =
        zorba::simplestore::SimpleStoreManager::getStore();
#endif

  // start processing
  Zorba* zengine = Zorba::getInstance(store);

  // start parsing the query
  XQuery_t query;
  if(!is_xqueryx)
    query = zengine->createQuery ();
  else
    query = zengine->createXQueryX ();
#ifdef ZORBA_DEBUGGER
 query->setDebugMode(lProp->debug());
#endif
  if (! lProp->inlineQuery())
    query->setFileName (path.get_path ());

  try {
    query->compile(*qfile, chints);
  } catch (ZorbaException &e) {
    // no need to close because the object is not valid
    cerr << "Compilation error: " << e << endl;
    return 1;
  }

  // set external variables
  vector<pair <string, string> > ext_vars = lProp->getExternalVars ();
  DynamicContext* dctx = query->getDynamicContext ();
  dctx->setImplicitTimezone (lProp->tz ());
  for (vector<pair <string, string> >::const_iterator iter = ext_vars.begin ();
       iter != ext_vars.end (); iter++) {
    set_var (iter->first, iter->second, dctx);
  }

  if (! lProp->compileOnly ()) {
    // output the result (either using xml serialization or using show)
    // cout << "Running query and printing result..." << endl;

    try {
      if (lProp->useSerializer()) {
        if (query->isUpdateQuery()) {
          query->applyUpdates();
        } else {
          Zorba_SerializerOptions opts = Zorba_SerializerOptions::SerializerOptionsFromStringParams(lProp->getSerializerParameters());
          query->serialize(*resultFile, &opts);
          // *resultFile << query;
        }
      } else {
        if (query->isUpdateQuery()) {
          query->applyUpdates();
        } else {
          ResultIterator_t result = query->iterator();
          result->open();
          Item lItem;
          while (result->next(lItem)) {
            // unmarshall the store item from the api item
            store::Item_t lStoreItem = Unmarshaller::getInternalItem(lItem);
            *resultFile << lStoreItem->show() << endl;
          }
          result->close();
        }
      }
    } catch (ZorbaException &e) {
      query->close();
      zengine->shutdown();
      store->shutdown();
      cerr << "Execution error: ";
      if (dynamic_cast<QueryException *> (&e) != NULL)
        cerr << (QueryException &) e;
      else
        cerr << e;
      cerr << endl;
      return 2;
    }
  }

  query->close();
  zengine->shutdown();
  store->shutdown();
  return 0;
}
<|endoftext|>


<commit_before>#ifndef HASHTABLE_HH
#define HASHTABLE_HH

#include "khmer.hh"
#include <fstream>
#include <string>

#define MAX_COUNT 255

namespace khmer {
  typedef unsigned char BoundedCounterType;

  class Hashtable {
  protected:
    const WordLength _ksize;
    const HashIntoType _tablesize;

    BoundedCounterType * _counts;

    void _allocate_counters() {
      _counts = new BoundedCounterType[_tablesize];
      memset(_counts, 0, _tablesize * sizeof(BoundedCounterType));
    }

  public:
    Hashtable(WordLength ksize, HashIntoType tablesize) :
      _ksize(ksize), _tablesize(tablesize) {
      _allocate_counters();
    }

    ~Hashtable() {
      delete _counts; _counts = NULL;
    }

    // accessor to get 'k'
    const WordLength ksize() const { return _ksize; }

    // accessors to get table info
    const HashIntoType n_entries() const { return _tablesize; }

    void count(const char * kmer) {
      HashIntoType bin = _hash(kmer, _ksize) % _tablesize;
      if (_counts[bin] == MAX_COUNT) { return; }
      _counts[bin]++;
    }

    void count(HashIntoType khash) {
      HashIntoType bin = khash % _tablesize;
      if (_counts[bin] == MAX_COUNT) { return; }
      _counts[bin]++;
    }

    // get the count for the given k-mer.
    const BoundedCounterType get_count(const char * kmer) const {
      HashIntoType bin = _hash(kmer, _ksize) % _tablesize;
      return _counts[bin];
    }

    // get the count for the given k-mer hash.
    const BoundedCounterType get_count(HashIntoType khash) const {
      HashIntoType bin = khash % _tablesize;
      return _counts[bin];
    }

    // count every k-mer in the string.
    unsigned int consume_string(const std::string &s,
				HashIntoType lower_bound = 0,
				HashIntoType upper_bound = 0);

    // checks each read for non-ACGT characters
    unsigned int checkAndProcessRead(const std::string &read,
                                HashIntoType lower_bound = 0,
                                HashIntoType upper_bound = 0);

    // count every k-mer in the FASTA file.
    unsigned int consume_fasta(const std::string &filename,
			       HashIntoType lower_bound = 0,
			       HashIntoType upper_bound = 0);

    // filter/trim through the given FASTA file.
    void filter_fasta_file(const std::string &inputfile,
                           const std::string &outputfile,
                           int minLength,
                           int threshold);

    // @@CTB doc
    BoundedCounterType get_min_count(const std::string &s,
				     HashIntoType lower_bound = 0,
				     HashIntoType upper_bound = 0);

    BoundedCounterType get_max_count(const std::string &s,
				     HashIntoType lower_bound = 0,
				     HashIntoType upper_bound = 0);
  };

  class HashtableIntersect {
  protected:
    khmer::Hashtable * _kh1;
    khmer::Hashtable * _kh2;

  public:
    HashtableIntersect(WordLength ksize,
		       HashIntoType tablesize1, HashIntoType tablesize2)
    {
      _kh1 = new Hashtable(ksize, tablesize1);
      _kh2 = new Hashtable(ksize, tablesize2);
    }

    ~HashtableIntersect()
    {
      delete _kh1;
      delete _kh2;
    }

    // count every k-mer in the string.
    void consume_string(const std::string &s)
    {
      _kh1->consume_string(s);
      _kh2->consume_string(s);
    }

    BoundedCounterType get_min_count(const std::string &s)
    {
      BoundedCounterType kh1Min = _kh1->get_min_count(s);
      BoundedCounterType kh2Min = _kh2->get_min_count(s);

      if (kh1Min < kh2Min) {
        return kh1Min;
      } else {
        return kh2Min;
      }
    }

    BoundedCounterType get_max_count(const std::string &s)
    {
      BoundedCounterType kh1Max = _kh1->get_max_count(s);
      BoundedCounterType kh2Max = _kh2->get_max_count(s);

      if (kh1Max > kh2Max) {
        return kh1Max;
      } else {
        return kh2Max;
      }
    }
  };
};

#endif // HASHTABLE_HH
<commit_msg>put guard around _counts<commit_after>#ifndef HASHTABLE_HH
#define HASHTABLE_HH

#include "khmer.hh"
#include <fstream>
#include <string>

#define MAX_COUNT 255

namespace khmer {
  typedef unsigned char BoundedCounterType;

  class Hashtable {
  protected:
    const WordLength _ksize;
    const HashIntoType _tablesize;

    BoundedCounterType * _counts;

    void _allocate_counters() {
      _counts = new BoundedCounterType[_tablesize];
      memset(_counts, 0, _tablesize * sizeof(BoundedCounterType));
    }

  public:
    Hashtable(WordLength ksize, HashIntoType tablesize) :
      _ksize(ksize), _tablesize(tablesize) {
      _allocate_counters();
    }

    ~Hashtable() {
      if (_counts) { delete _counts; _counts = NULL; }
    }

    // accessor to get 'k'
    const WordLength ksize() const { return _ksize; }

    // accessors to get table info
    const HashIntoType n_entries() const { return _tablesize; }

    void count(const char * kmer) {
      HashIntoType bin = _hash(kmer, _ksize) % _tablesize;
      if (_counts[bin] == MAX_COUNT) { return; }
      _counts[bin]++;
    }

    void count(HashIntoType khash) {
      HashIntoType bin = khash % _tablesize;
      if (_counts[bin] == MAX_COUNT) { return; }
      _counts[bin]++;
    }

    // get the count for the given k-mer.
    const BoundedCounterType get_count(const char * kmer) const {
      HashIntoType bin = _hash(kmer, _ksize) % _tablesize;
      return _counts[bin];
    }

    // get the count for the given k-mer hash.
    const BoundedCounterType get_count(HashIntoType khash) const {
      HashIntoType bin = khash % _tablesize;
      return _counts[bin];
    }

    // count every k-mer in the string.
    unsigned int consume_string(const std::string &s,
				HashIntoType lower_bound = 0,
				HashIntoType upper_bound = 0);

    // checks each read for non-ACGT characters
    unsigned int checkAndProcessRead(const std::string &read,
                                HashIntoType lower_bound = 0,
                                HashIntoType upper_bound = 0);

    // count every k-mer in the FASTA file.
    unsigned int consume_fasta(const std::string &filename,
			       HashIntoType lower_bound = 0,
			       HashIntoType upper_bound = 0);

    // filter/trim through the given FASTA file.
    void filter_fasta_file(const std::string &inputfile,
                           const std::string &outputfile,
                           int minLength,
                           int threshold);

    // @@CTB doc
    BoundedCounterType get_min_count(const std::string &s,
				     HashIntoType lower_bound = 0,
				     HashIntoType upper_bound = 0);

    BoundedCounterType get_max_count(const std::string &s,
				     HashIntoType lower_bound = 0,
				     HashIntoType upper_bound = 0);
  };

  class HashtableIntersect {
  protected:
    khmer::Hashtable * _kh1;
    khmer::Hashtable * _kh2;

  public:
    HashtableIntersect(WordLength ksize,
		       HashIntoType tablesize1, HashIntoType tablesize2)
    {
      _kh1 = new Hashtable(ksize, tablesize1);
      _kh2 = new Hashtable(ksize, tablesize2);
    }

    ~HashtableIntersect()
    {
      delete _kh1;
      delete _kh2;
    }

    // count every k-mer in the string.
    void consume_string(const std::string &s)
    {
      _kh1->consume_string(s);
      _kh2->consume_string(s);
    }

    BoundedCounterType get_min_count(const std::string &s)
    {
      BoundedCounterType kh1Min = _kh1->get_min_count(s);
      BoundedCounterType kh2Min = _kh2->get_min_count(s);

      if (kh1Min < kh2Min) {
        return kh1Min;
      } else {
        return kh2Min;
      }
    }

    BoundedCounterType get_max_count(const std::string &s)
    {
      BoundedCounterType kh1Max = _kh1->get_max_count(s);
      BoundedCounterType kh2Max = _kh2->get_max_count(s);

      if (kh1Max > kh2Max) {
        return kh1Max;
      } else {
        return kh2Max;
      }
    }
  };
};

#endif // HASHTABLE_HH
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2010 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    context.cpp
  \author  Tom Fogal
           SCI Institute
           University of Utah
  \brief   Establishes an OpenGL context.
*/
#include "StdTuvokDefines.h"
#ifdef DETECTED_OS_WINDOWS
# include <GL/wgl.h>
# include <windows.h>
#elif defined(DETECTED_OS_LINUX)
# include <GL/glx.h>
# include <X11/Xlib.h>
#endif
#include "Controller/Controller.h"

#include "context.h"

TvkContext::~TvkContext() { }

#ifdef DETECTED_OS_LINUX
struct xinfo {
  Display *display;
  XVisualInfo *visual;
  Window win;
  GLXContext ctx;
  Colormap cmap;
};

class TvkGLXContext: public TvkContext {
  public:
    TvkGLXContext(uint32_t w, uint32_t h, uint8_t color_bits,
                  uint8_t depth_bits, uint8_t stencil_bits,
                  bool double_buffer);
    virtual ~TvkGLXContext();

    bool isValid() const;
    bool makeCurrent();
    bool swapBuffers();

  private:
    struct xinfo xi;
};
#endif

class TvkWGLContext: public TvkContext {
  public:
    TvkWGLContext(uint32_t w, uint32_t h, uint8_t color_bits,
                  uint8_t depth_bits, uint8_t stencil_bits,
                  bool double_buffer);
    virtual ~TvkWGLContext() {}

    bool isValid() const;
    bool makeCurrent();
    bool swapBuffers();

  private:
#ifdef DETECTED_OS_WINDOWS
    HDC deviceContext;
    HGLRC renderingContext;
    HWND window;
#endif
};

TvkContext* TvkContext::Create(uint32_t width, uint32_t height,
                               uint8_t color_bits, uint8_t depth_bits,
                               uint8_t stencil_bits, bool double_buffer)
{
#ifdef DETECTED_OS_WINDOWS
  return new TvkWGLContext(width, height, color_bits, depth_bits, stencil_bits,
                           double_buffer);
#else
  return new TvkGLXContext(width, height, color_bits, depth_bits, stencil_bits,
                           double_buffer);
#endif
}

#ifdef DETECTED_OS_LINUX
static struct xinfo x_connect(uint32_t, uint32_t, bool);
static XVisualInfo* find_visual(Display*, bool);
static void glx_init(Display*, XVisualInfo*, Window, GLXContext&);

TvkGLXContext::TvkGLXContext(uint32_t w, uint32_t h, uint8_t,
                             uint8_t, uint8_t,
                             bool double_buffer)
{
  // if you *really* require a specific value... just hack this class
  // to your liking.  You probably want to add those parameters to x_connect
  // and use them there.
  WARNING("Ignoring color, depth, stencil bits.  For many applications, it "
          "is better to let the GLX library choose the \"best\" visual.");
  this->xi = x_connect(w, h, double_buffer);
  glx_init(xi.display, xi.visual, xi.win, xi.ctx);
}

TvkGLXContext::~TvkGLXContext()
{
  glXDestroyContext(xi.display, xi.ctx);
  XDestroyWindow(xi.display, xi.win);
  XFree(xi.visual);
  XCloseDisplay(xi.display);
}

bool TvkGLXContext::isValid() const
{
  return this->xi.display != NULL && this->xi.ctx != NULL;
}

bool TvkGLXContext::makeCurrent()
{
  if(glXMakeCurrent(this->xi.display, this->xi.win, this->xi.ctx) != True) {
    T_ERROR("Could not make context current!");
    return false;
  }
  return true;
}

bool TvkGLXContext::swapBuffers()
{
  glXSwapBuffers(this->xi.display, this->xi.win);
  // SwapBuffers generates an X error if it fails.
  return true;
}

static struct xinfo
x_connect(uint32_t width, uint32_t height, bool dbl_buffer)
{
  struct xinfo rv;

  rv.display = XOpenDisplay(NULL);
  if(rv.display == NULL) {
    T_ERROR("Could not connect to display: '%s'!", XDisplayName(NULL));
    throw NoAvailableContext();
  }
  XSynchronize(rv.display, True);

  rv.visual = find_visual(rv.display, dbl_buffer);

  Window parent = RootWindow(rv.display, rv.visual->screen);

  XSetWindowAttributes xw_attr;
  xw_attr.override_redirect = False;
  xw_attr.background_pixel = 0;
  xw_attr.colormap = XCreateColormap(rv.display, parent, rv.visual->visual,
                                     AllocNone);
  xw_attr.event_mask = StructureNotifyMask | ExposureMask;

  rv.win = XCreateWindow(rv.display, parent, 0,0, width,height, 0,
                         rv.visual->depth,
                         InputOutput, rv.visual->visual,
                         CWBackPixel | CWBorderPixel | CWColormap |
                         CWOverrideRedirect | CWEventMask,
                         &xw_attr);
  XStoreName(rv.display, rv.win, "Tuvok testing");
  XSync(rv.display, False);

  return rv;
}

static void
glx_init(Display *disp, XVisualInfo *visual, Window win, GLXContext& ctx)
{
  if(!glXQueryExtension(disp, NULL, NULL)) {
    T_ERROR("Display does not support glX.");
    return;
  }

  ctx = glXCreateContext(disp, visual, 0, GL_TRUE);
  if(!ctx) {
    T_ERROR("glX Context creation failed.");
  }

  if(glXMakeCurrent(disp, win, ctx) == True) {
    MESSAGE("Make current succeeded: %p", glXGetCurrentContext());
  } else {
    T_ERROR("make current FAILED: %p", glXGetCurrentContext());
    return;
  }
}

static XVisualInfo *
find_visual(Display *d, bool double_buffered)
{
    XVisualInfo *ret_v;
    // GLX_USE_GL is basically a no-op, so this provides a convenient
    // way of specifying double buffering or not.
    int att_buf = double_buffered ? GLX_DOUBLEBUFFER : GLX_USE_GL;
    int attr[] = {
      GLX_RGBA,
      att_buf,
      GLX_RED_SIZE,         5,
      GLX_GREEN_SIZE,       6,
      GLX_BLUE_SIZE,        5,
      GLX_ALPHA_SIZE,       8,
      GLX_DEPTH_SIZE,       8,
      GLX_ACCUM_RED_SIZE,   1,
      GLX_ACCUM_GREEN_SIZE, 1,
      GLX_ACCUM_BLUE_SIZE,  1,
      None
    };

    ret_v = glXChooseVisual(d, DefaultScreen(d), attr);
    MESSAGE("ChooseVisual got us %p", (const void*)ret_v);
    return ret_v;
}
#endif

#ifdef DETECTED_OS_WINDOWS
#endif
<commit_msg>Use classes' makeCurrent instead of duplicating.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2010 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    context.cpp
  \author  Tom Fogal
           SCI Institute
           University of Utah
  \brief   Establishes an OpenGL context.
*/
#include "StdTuvokDefines.h"
#ifdef DETECTED_OS_WINDOWS
# include <GL/wgl.h>
# include <windows.h>
#elif defined(DETECTED_OS_LINUX)
# include <GL/glx.h>
# include <X11/Xlib.h>
#endif
#include "Controller/Controller.h"

#include "context.h"

TvkContext::~TvkContext() { }

#ifdef DETECTED_OS_LINUX
struct xinfo {
  Display *display;
  XVisualInfo *visual;
  Window win;
  GLXContext ctx;
  Colormap cmap;
};

class TvkGLXContext: public TvkContext {
  public:
    TvkGLXContext(uint32_t w, uint32_t h, uint8_t color_bits,
                  uint8_t depth_bits, uint8_t stencil_bits,
                  bool double_buffer);
    virtual ~TvkGLXContext();

    bool isValid() const;
    bool makeCurrent();
    bool swapBuffers();

  private:
    struct xinfo xi;
};
#endif

class TvkWGLContext: public TvkContext {
  public:
    TvkWGLContext(uint32_t w, uint32_t h, uint8_t color_bits,
                  uint8_t depth_bits, uint8_t stencil_bits,
                  bool double_buffer);
    virtual ~TvkWGLContext() {}

    bool isValid() const;
    bool makeCurrent();
    bool swapBuffers();

  private:
#ifdef DETECTED_OS_WINDOWS
    HDC deviceContext;
    HGLRC renderingContext;
    HWND window;
#endif
};

TvkContext* TvkContext::Create(uint32_t width, uint32_t height,
                               uint8_t color_bits, uint8_t depth_bits,
                               uint8_t stencil_bits, bool double_buffer)
{
#ifdef DETECTED_OS_WINDOWS
  return new TvkWGLContext(width, height, color_bits, depth_bits, stencil_bits,
                           double_buffer);
#else
  return new TvkGLXContext(width, height, color_bits, depth_bits, stencil_bits,
                           double_buffer);
#endif
}

#ifdef DETECTED_OS_LINUX
static struct xinfo x_connect(uint32_t, uint32_t, bool);
static XVisualInfo* find_visual(Display*, bool);
static void glx_init(Display*, XVisualInfo*, GLXContext&);

TvkGLXContext::TvkGLXContext(uint32_t w, uint32_t h, uint8_t,
                             uint8_t, uint8_t,
                             bool double_buffer)
{
  // if you *really* require a specific value... just hack this class
  // to your liking.  You probably want to add those parameters to x_connect
  // and use them there.
  WARNING("Ignoring color, depth, stencil bits.  For many applications, it "
          "is better to let the GLX library choose the \"best\" visual.");
  this->xi = x_connect(w, h, double_buffer);
  glx_init(xi.display, xi.visual, xi.ctx);
  this->makeCurrent();
  MESSAGE("Current context: %p", glXGetCurrentContext());
}

TvkGLXContext::~TvkGLXContext()
{
  glXDestroyContext(xi.display, xi.ctx);
  XDestroyWindow(xi.display, xi.win);
  XFree(xi.visual);
  XCloseDisplay(xi.display);
}

bool TvkGLXContext::isValid() const
{
  return this->xi.display != NULL && this->xi.ctx != NULL;
}

bool TvkGLXContext::makeCurrent()
{
  if(glXMakeCurrent(this->xi.display, this->xi.win, this->xi.ctx) != True) {
    T_ERROR("Could not make context current!");
    return false;
  }
  return true;
}

bool TvkGLXContext::swapBuffers()
{
  glXSwapBuffers(this->xi.display, this->xi.win);
  // SwapBuffers generates an X error if it fails.
  return true;
}

static struct xinfo
x_connect(uint32_t width, uint32_t height, bool dbl_buffer)
{
  struct xinfo rv;

  rv.display = XOpenDisplay(NULL);
  if(rv.display == NULL) {
    T_ERROR("Could not connect to display: '%s'!", XDisplayName(NULL));
    throw NoAvailableContext();
  }
  XSynchronize(rv.display, True);

  rv.visual = find_visual(rv.display, dbl_buffer);

  Window parent = RootWindow(rv.display, rv.visual->screen);

  XSetWindowAttributes xw_attr;
  xw_attr.override_redirect = False;
  xw_attr.background_pixel = 0;
  xw_attr.colormap = XCreateColormap(rv.display, parent, rv.visual->visual,
                                     AllocNone);
  xw_attr.event_mask = StructureNotifyMask | ExposureMask;

  rv.win = XCreateWindow(rv.display, parent, 0,0, width,height, 0,
                         rv.visual->depth,
                         InputOutput, rv.visual->visual,
                         CWBackPixel | CWBorderPixel | CWColormap |
                         CWOverrideRedirect | CWEventMask,
                         &xw_attr);
  XStoreName(rv.display, rv.win, "Tuvok testing");
  XSync(rv.display, False);

  return rv;
}

static void
glx_init(Display *disp, XVisualInfo *visual, GLXContext& ctx)
{
  if(!glXQueryExtension(disp, NULL, NULL)) {
    T_ERROR("Display does not support glX.");
    return;
  }

  ctx = glXCreateContext(disp, visual, 0, GL_TRUE);
  if(!ctx) {
    T_ERROR("glX Context creation failed.");
  }
}

static XVisualInfo *
find_visual(Display *d, bool double_buffered)
{
    XVisualInfo *ret_v;
    // GLX_USE_GL is basically a no-op, so this provides a convenient
    // way of specifying double buffering or not.
    int att_buf = double_buffered ? GLX_DOUBLEBUFFER : GLX_USE_GL;
    int attr[] = {
      GLX_RGBA,
      att_buf,
      GLX_RED_SIZE,         5,
      GLX_GREEN_SIZE,       6,
      GLX_BLUE_SIZE,        5,
      GLX_ALPHA_SIZE,       8,
      GLX_DEPTH_SIZE,       8,
      GLX_ACCUM_RED_SIZE,   1,
      GLX_ACCUM_GREEN_SIZE, 1,
      GLX_ACCUM_BLUE_SIZE,  1,
      None
    };

    ret_v = glXChooseVisual(d, DefaultScreen(d), attr);
    MESSAGE("ChooseVisual got us %p", (const void*)ret_v);
    return ret_v;
}
#endif

#ifdef DETECTED_OS_WINDOWS
#endif
<|endoftext|>


<commit_before>/* cuda_wrapper/texture.hpp
 *
 * Copyright (C) 2007  Peter Colberg
 *
 * This file is part of HALMD.
 *
 * HALMD is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef CUDA_TEXTURE_HPP
#define CUDA_TEXTURE_HPP

#include <cuda_runtime.h>

#ifndef __CUDACC__
# include <cuda_wrapper/error.hpp>
# include <cuda_wrapper/vector.hpp>
#endif

/*
 * CUDA texture management
 */

namespace cuda
{

template<class T>
class texture
{
public:
#ifdef __CUDACC__
    /**
     * type-safe constructor for CUDA host code
     */
    texture(::texture<T, 1, cudaReadModeElementType> const& tex) : tex(tex) {}
#else
    /**
     * bind CUDA texture to device memory array
     */
    void bind(cuda::vector<T> const& g_array)
    {
        CUDA_CALL(cudaBindTexture(NULL, &tex, g_array.data(), &tex.channelDesc));
    }

    /**
     * unbind CUDA texture
     */
    void unbind()
    {
        CUDA_CALL(cudaUnbindTexture(&tex));
    }

private:
    /**
     * bogus constructor to avoid GCC 4.4 compiler warning
     */
    texture(textureReference const& tex) : tex(tex) {}
#endif

private:
    textureReference const& tex;
};

}

#endif /* ! CUDA_TEXTURE_HPP */
<commit_msg>Implement cuda::texture following RAII pattern<commit_after>/* cuda_wrapper/texture.hpp
 *
 * Copyright (C) 2007  Peter Colberg
 *
 * This file is part of HALMD.
 *
 * HALMD is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef CUDA_TEXTURE_HPP
#define CUDA_TEXTURE_HPP

#include <boost/noncopyable.hpp>
#include <cuda_runtime.h>

#ifndef __CUDACC__
# include <cuda_wrapper/error.hpp>
# include <cuda_wrapper/vector.hpp>
#endif

/*
 * CUDA texture management
 */

namespace cuda
{

template<class T>
class texture
  : boost::noncopyable
{
public:
#ifndef __CUDACC__
    /**
     * bind CUDA texture to device memory array
     */
    texture(texture const& texture_, vector<T> const& vector_)
      : texref_(texture_.texref_)
    {
        CUDA_CALL(cudaBindTexture(NULL, &texref_, vector_.data(), &texref_.channelDesc));
    }

    /**
     * unbind CUDA texture
     */
    ~texture()
    {
        CUDA_CALL(cudaUnbindTexture(&texref_));
    }
#else
    /**
     * store CUDA texture reference
     */
    texture(::texture<T> const& texref)
      : texref_(texref)
    {}
#endif

private:
    ::textureReference const& texref_;
};

}

#endif /* ! CUDA_TEXTURE_HPP */
<|endoftext|>


<commit_before>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "RenderDevice.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace graphics
    {
        RenderDevice::RenderDevice(Renderer::Driver aDriver):
            driver(aDriver),
            projectionTransform(Matrix4::IDENTITY),
            renderTargetProjectionTransform(Matrix4::IDENTITY),
            refillQueue(true),
            currentFPS(0.0f),
            accumulatedFPS(0.0f)
        {
        }

        RenderDevice::~RenderDevice()
        {
        }

        bool RenderDevice::init(Window* newWindow,
                                const Size2& newSize,
                                uint32_t newSampleCount,
                                Texture::Filter newTextureFilter,
                                uint32_t newMaxAnisotropy,
                                bool newVerticalSync,
                                bool newDepth,
                                bool newDebugRenderer)
        {
            window = newWindow;
            size = newSize;
            sampleCount = newSampleCount;
            textureFilter = newTextureFilter;
            maxAnisotropy = newMaxAnisotropy;
            verticalSync = newVerticalSync;
            depth = newDepth;
            debugRenderer = newDebugRenderer;
            clearColor = Color::BLACK;

            previousFrameTime = std::chrono::steady_clock::now();

            return true;
        }

        bool RenderDevice::process()
        {
            std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now();
            auto diff = std::chrono::duration_cast<std::chrono::nanoseconds>(currentTime - previousFrameTime);
            previousFrameTime = currentTime;

            float delta = diff.count() / 1000000000.0f;

            if (delta > 0.0f)
            {
                currentFPS = 1.0f / delta;
            }

            accumulatedTime += delta;
            currentAccumulatedFPS += 1.0f;

            if (accumulatedTime > 1.0f)
            {
                accumulatedFPS = currentAccumulatedFPS;
                accumulatedTime = 0.0f;
                currentAccumulatedFPS = 0.0f;
            }

            std::vector<DrawCommand> drawCommands;
            {
#if OUZEL_MULTITHREADED
                std::unique_lock<std::mutex> lock(drawQueueMutex);

                while (!queueFinished)
                {
                    queueCondition.wait(lock);
                }
#endif

                drawCommands = std::move(drawQueue);
                drawQueue.reserve(drawCommands.size());

                queueFinished = false;
            }

            std::vector<std::unique_ptr<Resource>> deleteResources;
            {
                std::lock_guard<std::mutex> lock(resourceMutex);
                deleteResources = std::move(resourceDeleteSet);
            }

            // refills the draw queue
            refillQueue = true;

            executeAll();

            ++currentFrame;

            if (!draw(drawCommands))
            {
                return false;
            }

            deleteResources.clear(); // delete all resources in delete set

            return true;
        }

        void RenderDevice::setClearColorBuffer(bool clear)
        {
            clearColorBuffer = clear;
        }

        void RenderDevice::setClearDepthBuffer(bool clear)
        {
            clearDepthBuffer = clear;
        }

        void RenderDevice::setClearColor(Color color)
        {
            clearColor = color;
        }

        void RenderDevice::setClearDepth(float newClearDepth)
        {
            clearDepth = newClearDepth;
        }

        void RenderDevice::setSize(const Size2& newSize)
        {
            size = newSize;
        }

        std::vector<Size2> RenderDevice::getSupportedResolutions() const
        {
            return std::vector<Size2>();
        }

        void RenderDevice::deleteResource(Resource* resource)
        {
            std::lock_guard<std::mutex> lock(resourceMutex);

            auto resourceIterator = std::find_if(resources.begin(), resources.end(), [resource](const std::unique_ptr<Resource>& ptr) {
                return ptr.get() == resource;
            });

            if (resourceIterator != resources.end())
            {
                resourceDeleteSet.push_back(std::move(*resourceIterator));
                resources.erase(resourceIterator);
            }
        }

        bool RenderDevice::addDrawCommand(const DrawCommand& drawCommand)
        {
            std::lock_guard<std::mutex> lock(drawQueueMutex);

            drawQueue.push_back(drawCommand);

            return true;
        }

        void RenderDevice::flushCommands()
        {
            refillQueue = false;

            {
                std::lock_guard<std::mutex> lock(drawQueueMutex);
                queueFinished = true;
                drawCallCount = static_cast<uint32_t>(drawQueue.size());
            }

#if OUZEL_MULTITHREADED
            queueCondition.notify_one();
#endif
        }

        bool RenderDevice::generateScreenshot(const std::string&)
        {
            return true;
        }

        void RenderDevice::executeOnRenderThread(const std::function<void(void)>& func)
        {
            std::lock_guard<std::mutex> lock(executeMutex);

            executeQueue.push(func);
        }

        void RenderDevice::executeAll()
        {
            std::function<void(void)> func;

            for (;;)
            {
                {
                    std::lock_guard<std::mutex> lock(executeMutex);

                    if (executeQueue.empty())
                    {
                        break;
                    }

                    func = std::move(executeQueue.front());
                    executeQueue.pop();
                }

                if (func)
                {
                    func();
                }
            }
        }
    } // namespace graphics
} // namespace ouzel
<commit_msg>Don't erase and recreate draw queue<commit_after>// Copyright (C) 2017 Elviss Strazdins
// This file is part of the Ouzel engine.

#include <algorithm>
#include "RenderDevice.hpp"
#include "utils/Log.hpp"

namespace ouzel
{
    namespace graphics
    {
        RenderDevice::RenderDevice(Renderer::Driver aDriver):
            driver(aDriver),
            projectionTransform(Matrix4::IDENTITY),
            renderTargetProjectionTransform(Matrix4::IDENTITY),
            refillQueue(true),
            currentFPS(0.0f),
            accumulatedFPS(0.0f)
        {
        }

        RenderDevice::~RenderDevice()
        {
        }

        bool RenderDevice::init(Window* newWindow,
                                const Size2& newSize,
                                uint32_t newSampleCount,
                                Texture::Filter newTextureFilter,
                                uint32_t newMaxAnisotropy,
                                bool newVerticalSync,
                                bool newDepth,
                                bool newDebugRenderer)
        {
            window = newWindow;
            size = newSize;
            sampleCount = newSampleCount;
            textureFilter = newTextureFilter;
            maxAnisotropy = newMaxAnisotropy;
            verticalSync = newVerticalSync;
            depth = newDepth;
            debugRenderer = newDebugRenderer;
            clearColor = Color::BLACK;

            previousFrameTime = std::chrono::steady_clock::now();

            return true;
        }

        bool RenderDevice::process()
        {
            std::chrono::steady_clock::time_point currentTime = std::chrono::steady_clock::now();
            auto diff = std::chrono::duration_cast<std::chrono::nanoseconds>(currentTime - previousFrameTime);
            previousFrameTime = currentTime;

            float delta = diff.count() / 1000000000.0f;

            if (delta > 0.0f)
            {
                currentFPS = 1.0f / delta;
            }

            accumulatedTime += delta;
            currentAccumulatedFPS += 1.0f;

            if (accumulatedTime > 1.0f)
            {
                accumulatedFPS = currentAccumulatedFPS;
                accumulatedTime = 0.0f;
                currentAccumulatedFPS = 0.0f;
            }

            std::vector<DrawCommand> drawCommands;
            {
#if OUZEL_MULTITHREADED
                std::unique_lock<std::mutex> lock(drawQueueMutex);

                while (!queueFinished)
                {
                    queueCondition.wait(lock);
                }
#endif

                drawCommands = drawQueue;
                drawQueue.clear();

                queueFinished = false;
            }

            std::vector<std::unique_ptr<Resource>> deleteResources;
            {
                std::lock_guard<std::mutex> lock(resourceMutex);
                deleteResources = std::move(resourceDeleteSet);
            }

            // refills the draw queue
            refillQueue = true;

            executeAll();

            ++currentFrame;

            if (!draw(drawCommands))
            {
                return false;
            }

            deleteResources.clear(); // delete all resources in delete set

            return true;
        }

        void RenderDevice::setClearColorBuffer(bool clear)
        {
            clearColorBuffer = clear;
        }

        void RenderDevice::setClearDepthBuffer(bool clear)
        {
            clearDepthBuffer = clear;
        }

        void RenderDevice::setClearColor(Color color)
        {
            clearColor = color;
        }

        void RenderDevice::setClearDepth(float newClearDepth)
        {
            clearDepth = newClearDepth;
        }

        void RenderDevice::setSize(const Size2& newSize)
        {
            size = newSize;
        }

        std::vector<Size2> RenderDevice::getSupportedResolutions() const
        {
            return std::vector<Size2>();
        }

        void RenderDevice::deleteResource(Resource* resource)
        {
            std::lock_guard<std::mutex> lock(resourceMutex);

            auto resourceIterator = std::find_if(resources.begin(), resources.end(), [resource](const std::unique_ptr<Resource>& ptr) {
                return ptr.get() == resource;
            });

            if (resourceIterator != resources.end())
            {
                resourceDeleteSet.push_back(std::move(*resourceIterator));
                resources.erase(resourceIterator);
            }
        }

        bool RenderDevice::addDrawCommand(const DrawCommand& drawCommand)
        {
            std::lock_guard<std::mutex> lock(drawQueueMutex);

            drawQueue.push_back(drawCommand);

            return true;
        }

        void RenderDevice::flushCommands()
        {
            refillQueue = false;

            {
                std::lock_guard<std::mutex> lock(drawQueueMutex);
                queueFinished = true;
                drawCallCount = static_cast<uint32_t>(drawQueue.size());
            }

#if OUZEL_MULTITHREADED
            queueCondition.notify_one();
#endif
        }

        bool RenderDevice::generateScreenshot(const std::string&)
        {
            return true;
        }

        void RenderDevice::executeOnRenderThread(const std::function<void(void)>& func)
        {
            std::lock_guard<std::mutex> lock(executeMutex);

            executeQueue.push(func);
        }

        void RenderDevice::executeAll()
        {
            std::function<void(void)> func;

            for (;;)
            {
                {
                    std::lock_guard<std::mutex> lock(executeMutex);

                    if (executeQueue.empty())
                    {
                        break;
                    }

                    func = std::move(executeQueue.front());
                    executeQueue.pop();
                }

                if (func)
                {
                    func();
                }
            }
        }
    } // namespace graphics
} // namespace ouzel
<|endoftext|>