<commit_before>// For conditions of distribution and use, see copyright notice in LICENSE

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "OgreRenderingModule.h"
#include "Renderer.h"
#include "EC_Placeable.h"
#include "EC_Mesh.h"
#include "EC_OgreCustomObject.h"
#include "EC_AnimationController.h"
#include "EC_Camera.h"
#include "EC_Light.h"
#include "EC_OgreCompositor.h"
#include "EC_RttTarget.h"
#include "EC_SelectionBox.h"
#include "EC_Material.h"
#include "OgreWorld.h"
#include "OgreMeshAsset.h"
#include "OgreParticleAsset.h"
#include "OgreSkeletonAsset.h"
#include "OgreMaterialAsset.h"
#include "OgreProfiler.h"
#ifdef OGRE_HAS_PROFILER_HOOKS
#include "OgreProfilerHook.h"
#endif
#include "TextureAsset.h"

#include "Application.h"
#include "Entity.h"
#include "Scene.h"
#include "AssetAPI.h"
#include "AssetCache.h"
#include "GenericAssetFactory.h"
#include "NullAssetFactory.h"
#include "Profiler.h"
#include "ConsoleAPI.h"
#include "SceneAPI.h"
#include "IComponentFactory.h"

#include "MemoryLeakCheck.h"

namespace OgreRenderer
{

std::string OgreRenderingModule::CACHE_RESOURCE_GROUP = "CACHED_ASSETS_GROUP";

#ifdef OGRE_HAS_PROFILER_HOOKS

DWORD mainThreadId;
void Profiler_BeginBlock(const char *name)
{
#ifdef PROFILING
    if (GetCurrentThreadId() != mainThreadId)
        return;
    Framework *fw = Framework::Instance();
    Profiler *p = fw ? fw->GetProfiler() : 0;
    if (p)
        p->StartBlock((std::string("OGRE_") + name).c_str());
#endif
}

void Profiler_EndBlock()
{
#ifdef PROFILING
    if (GetCurrentThreadId() != mainThreadId)
        return;
    Framework *fw = Framework::Instance();
    Profiler *p = fw ? fw->GetProfiler() : 0;
    if (p)
    {
        ProfilerNodeTree *treeNode = p->CurrentNode();
        if (!treeNode)
            return;
        p->EndBlock(treeNode->Name());
    }
#endif
}

#endif

OgreRenderingModule::OgreRenderingModule() :
    IModule("OgreRendering")
{
#ifdef OGRE_HAS_PROFILER_HOOKS
    mainThreadId = GetCurrentThreadId();
    OgreProfiler_BeginBlock = Profiler_BeginBlock;
    OgreProfiler_EndBlock = Profiler_EndBlock;
#endif
}

OgreRenderingModule::~OgreRenderingModule()
{
}

void OgreRenderingModule::Load()
{
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Placeable>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Mesh>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Light>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_OgreCustomObject>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_AnimationController>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Camera>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_OgreCompositor>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_RttTarget>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_SelectionBox>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Material>));

    // Create asset type factories for each asset OgreRenderingModule provides to the system.
    framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<OgreMeshAsset>("OgreMesh")));

    // Loading materials crashes Ogre in headless mode because we don't have Ogre Renderer running, so only register the Ogre material asset type if not in headless mode.
    if (!framework_->IsHeadless())
    {
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<OgreMaterialAsset>("OgreMaterial")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<TextureAsset>("Texture")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<OgreParticleAsset>("OgreParticle")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<OgreSkeletonAsset>("OgreSkeleton")));
    }
    else
    {
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new NullAssetFactory("OgreMaterial")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new NullAssetFactory("Texture")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new NullAssetFactory("OgreParticle")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new NullAssetFactory("OgreSkeleton")));
    }
}

void OgreRenderingModule::Initialize()
{
    std::string ogreConfigFilename = Application::InstallationDirectory().toStdString() + "ogre.cfg"; ///\todo Unicode support!
#if defined (_WINDOWS) && (_DEBUG)
    std::string pluginsFilename = "pluginsd.cfg";
#elif defined (_WINDOWS)
    std::string pluginsFilename = "plugins.cfg";
#elif defined(__APPLE__)
    std::string pluginsFilename = "plugins-mac.cfg";
#else
    std::string pluginsFilename = "plugins-unix.cfg";
#endif

    pluginsFilename = Application::InstallationDirectory().toStdString() + pluginsFilename; ///\todo Unicode support!

    std::string windowTitle = Application::FullIdentifier().toStdString();

    renderer = boost::make_shared<OgreRenderer::Renderer>(framework_, ogreConfigFilename, pluginsFilename, windowTitle);
    assert(renderer);
    assert(!renderer->IsInitialized());

    // Initializing the Renderer crashes inside Ogre if the current working directory is not the same as the directory where Ogre plugins reside in.
    // So, temporarily set the working dir to the installation directory, and restore it after succeeding to load the plugins.
    QString cwd = Application::CurrentWorkingDirectory();
    Application::SetCurrentWorkingDirectory(Application::InstallationDirectory());

    framework_->App()->SetSplashMessage("Initializing Ogre");
    renderer->Initialize();

    // Restore the original cwd to not disturb the environment we are running in.
    Application::SetCurrentWorkingDirectory(cwd);

    // Register renderer.
    framework_->RegisterRenderer(renderer.get());
    framework_->RegisterDynamicObject("renderer", renderer.get());

    // Connect to scene change signals.
    connect(framework_->Scene(), SIGNAL(SceneAdded(const QString&)), this, SLOT(OnSceneAdded(const QString&)));
    connect(framework_->Scene(), SIGNAL(SceneRemoved(const QString&)), this, SLOT(OnSceneRemoved(const QString&)));

    // Add asset cache directory as its own resource group to ogre to support threaded loading.
    if (GetFramework()->Asset()->GetAssetCache())
    {
        std::string cacheResourceDir = GetFramework()->Asset()->GetAssetCache()->CacheDirectory().toStdString();
        if (!Ogre::ResourceGroupManager::getSingleton().resourceLocationExists(cacheResourceDir, CACHE_RESOURCE_GROUP))
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(cacheResourceDir, "FileSystem", CACHE_RESOURCE_GROUP);
    }

    framework_->Console()->RegisterCommand("renderStats", "Prints out render statistics.",
        this, SLOT(ConsoleStats()));
#if OGRE_PROFILING == 1
    framework_->Console()->RegisterCommand("ogreProf", "Toggles visibility of the Ogre profiler overlay.",
        this, SLOT(ToggleOgreProfilerOverlay()));
#endif
    framework_->Console()->RegisterCommand("setMaterialAttribute", "Sets an attribute on a material asset",
        this, SLOT(SetMaterialAttribute(const QStringList &)));
}

void OgreRenderingModule::Uninitialize()
{
    // We're shutting down. Force a release of all loaded asset objects from the Asset API so that
    // no refs to Ogre assets remain - below 'renderer.reset()' is going to delete Ogre::Root.
    framework_->Asset()->ForgetAllAssets();

    // Clear up the renderer object, so that it will not be left dangling.
    framework_->RegisterRenderer(0);
}

void OgreRenderingModule::ConsoleStats()
{
    if (framework_->IsHeadless())
        return;
    if (renderer)
    {
        const Ogre::RenderTarget::FrameStats& stats = renderer->GetCurrentRenderWindow()->getStatistics();
        ConsoleAPI *c = framework_->Console();
        c->Print("Average FPS: " + QString::number(stats.avgFPS));
        c->Print("Worst FPS: " + QString::number(stats.worstFPS));
        c->Print("Best FPS: " + QString::number(stats.bestFPS));
        c->Print("Triangles: " + QString::number(stats.triangleCount));
        c->Print("Batches: " + QString::number(stats.batchCount));
        return;
    }
    else
        LogError("No renderer found!");
}

void OgreRenderingModule::ToggleOgreProfilerOverlay()
{
#if OGRE_PROFILING == 1
    if (!framework_->IsHeadless())
    {
        bool enabled = Ogre::Profiler::getSingleton().getEnabled();
        Ogre::Profiler::getSingleton().setEnabled(!enabled);
    }
#else
    LogError("OgreRenderingModule::ToggleOgreProfilerOverlay: Ogre built without profiling support, cannot show profiler overlay.");
#endif
}

void OgreRenderingModule::OnSceneAdded(const QString& name)
{
    ScenePtr scene = GetFramework()->Scene()->GetScene(name);
    if (!scene)
    {
        LogError("OgreRenderingModule::OnSceneAdded: Could not find created scene");
        return;
    }

    // Add an OgreWorld to the scene
    OgreWorldPtr newWorld = boost::make_shared<OgreWorld>(renderer.get(), scene);
    renderer->ogreWorlds[scene.get()] = newWorld;
    scene->setProperty(OgreWorld::PropertyName(), QVariant::fromValue<QObject*>(newWorld.get()));
}

void OgreRenderingModule::OnSceneRemoved(const QString& name)
{
    // Remove the OgreWorld from the scene
    ScenePtr scene = GetFramework()->Scene()->GetScene(name);
    if (!scene)
    {
        LogError("OgreRenderingModule::OnSceneRemoved: Could not find scene about to be removed");
        return;
    }

    OgreWorld* worldPtr = scene->GetWorld<OgreWorld>().get();
    if (worldPtr)
    {
        scene->setProperty(OgreWorld::PropertyName(), QVariant());
        renderer->ogreWorlds.erase(scene.get());
    }
}

void OgreRenderingModule::SetMaterialAttribute(const QStringList &params)
{
    if (params.size() < 3)
    {
        LogError("OgreRenderingModule::SetMaterialAttribute: Usage: SetMaterialAttribute(asset,attribute,value)");
        return;
    }
    AssetPtr assetPtr = framework_->Asset()->GetAsset(framework_->Asset()->ResolveAssetRef("", params[0]));
    if (!assetPtr || !assetPtr->IsLoaded())
    {
        LogError("OgreRenderingModule::SetMaterialAttribute: No asset found or not loaded");
        return;
    }
    OgreMaterialAsset* matAsset = dynamic_cast<OgreMaterialAsset*>(assetPtr.get());
    if (!matAsset)
    {
        LogError("OgreRenderingModule::SetMaterialAttribute: Not a material asset");
        return;
    }
    matAsset->SetAttribute(params[1], params[2]);
}

} // ~namespace OgreRenderer

using namespace OgreRenderer;

extern "C"
{
DLLEXPORT void TundraPluginMain(Framework *fw)
{
    Framework::SetInstance(fw); // Inside this DLL, remember the pointer to the global framework object.
    fw->RegisterModule(new OgreRenderer::OgreRenderingModule());
}
}
<commit_msg>Implement cross-platform build for ogre profiling code.<commit_after>// For conditions of distribution and use, see copyright notice in LICENSE

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "OgreRenderingModule.h"
#include "Renderer.h"
#include "EC_Placeable.h"
#include "EC_Mesh.h"
#include "EC_OgreCustomObject.h"
#include "EC_AnimationController.h"
#include "EC_Camera.h"
#include "EC_Light.h"
#include "EC_OgreCompositor.h"
#include "EC_RttTarget.h"
#include "EC_SelectionBox.h"
#include "EC_Material.h"
#include "OgreWorld.h"
#include "OgreMeshAsset.h"
#include "OgreParticleAsset.h"
#include "OgreSkeletonAsset.h"
#include "OgreMaterialAsset.h"
#include "OgreProfiler.h"
#ifdef OGRE_HAS_PROFILER_HOOKS
#include "OgreProfilerHook.h"
#endif
#include "TextureAsset.h"

#include "Application.h"
#include "Entity.h"
#include "Scene.h"
#include "AssetAPI.h"
#include "AssetCache.h"
#include "GenericAssetFactory.h"
#include "NullAssetFactory.h"
#include "Profiler.h"
#include "ConsoleAPI.h"
#include "SceneAPI.h"
#include "IComponentFactory.h"

#include "MemoryLeakCheck.h"

namespace OgreRenderer
{

std::string OgreRenderingModule::CACHE_RESOURCE_GROUP = "CACHED_ASSETS_GROUP";

#ifdef OGRE_HAS_PROFILER_HOOKS

#ifdef WIN32
DWORD mainThreadId;
#endif

void Profiler_BeginBlock(const char *name)
{
#if defined(PROFILING) && defined(WIN32)
    if (GetCurrentThreadId() != mainThreadId)
        return;
    Framework *fw = Framework::Instance();
    Profiler *p = fw ? fw->GetProfiler() : 0;
    if (p)
        p->StartBlock((std::string("OGRE_") + name).c_str());
#endif
}

void Profiler_EndBlock()
{
#if defined(PROFILING) && defined(WIN32)
    if (GetCurrentThreadId() != mainThreadId)
        return;
    Framework *fw = Framework::Instance();
    Profiler *p = fw ? fw->GetProfiler() : 0;
    if (p)
    {
        ProfilerNodeTree *treeNode = p->CurrentNode();
        if (!treeNode)
            return;
        p->EndBlock(treeNode->Name());
    }
#endif
}

#endif

OgreRenderingModule::OgreRenderingModule() :
    IModule("OgreRendering")
{
#ifdef OGRE_HAS_PROFILER_HOOKS
#ifdef WIN32
    mainThreadId = GetCurrentThreadId();
#endif
    OgreProfiler_BeginBlock = Profiler_BeginBlock;
    OgreProfiler_EndBlock = Profiler_EndBlock;
#endif
}

OgreRenderingModule::~OgreRenderingModule()
{
}

void OgreRenderingModule::Load()
{
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Placeable>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Mesh>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Light>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_OgreCustomObject>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_AnimationController>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Camera>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_OgreCompositor>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_RttTarget>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_SelectionBox>));
    framework_->Scene()->RegisterComponentFactory(ComponentFactoryPtr(new GenericComponentFactory<EC_Material>));

    // Create asset type factories for each asset OgreRenderingModule provides to the system.
    framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<OgreMeshAsset>("OgreMesh")));

    // Loading materials crashes Ogre in headless mode because we don't have Ogre Renderer running, so only register the Ogre material asset type if not in headless mode.
    if (!framework_->IsHeadless())
    {
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<OgreMaterialAsset>("OgreMaterial")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<TextureAsset>("Texture")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<OgreParticleAsset>("OgreParticle")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new GenericAssetFactory<OgreSkeletonAsset>("OgreSkeleton")));
    }
    else
    {
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new NullAssetFactory("OgreMaterial")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new NullAssetFactory("Texture")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new NullAssetFactory("OgreParticle")));
        framework_->Asset()->RegisterAssetTypeFactory(AssetTypeFactoryPtr(new NullAssetFactory("OgreSkeleton")));
    }
}

void OgreRenderingModule::Initialize()
{
    std::string ogreConfigFilename = Application::InstallationDirectory().toStdString() + "ogre.cfg"; ///\todo Unicode support!
#if defined (_WINDOWS) && (_DEBUG)
    std::string pluginsFilename = "pluginsd.cfg";
#elif defined (_WINDOWS)
    std::string pluginsFilename = "plugins.cfg";
#elif defined(__APPLE__)
    std::string pluginsFilename = "plugins-mac.cfg";
#else
    std::string pluginsFilename = "plugins-unix.cfg";
#endif

    pluginsFilename = Application::InstallationDirectory().toStdString() + pluginsFilename; ///\todo Unicode support!

    std::string windowTitle = Application::FullIdentifier().toStdString();

    renderer = boost::make_shared<OgreRenderer::Renderer>(framework_, ogreConfigFilename, pluginsFilename, windowTitle);
    assert(renderer);
    assert(!renderer->IsInitialized());

    // Initializing the Renderer crashes inside Ogre if the current working directory is not the same as the directory where Ogre plugins reside in.
    // So, temporarily set the working dir to the installation directory, and restore it after succeeding to load the plugins.
    QString cwd = Application::CurrentWorkingDirectory();
    Application::SetCurrentWorkingDirectory(Application::InstallationDirectory());

    framework_->App()->SetSplashMessage("Initializing Ogre");
    renderer->Initialize();

    // Restore the original cwd to not disturb the environment we are running in.
    Application::SetCurrentWorkingDirectory(cwd);

    // Register renderer.
    framework_->RegisterRenderer(renderer.get());
    framework_->RegisterDynamicObject("renderer", renderer.get());

    // Connect to scene change signals.
    connect(framework_->Scene(), SIGNAL(SceneAdded(const QString&)), this, SLOT(OnSceneAdded(const QString&)));
    connect(framework_->Scene(), SIGNAL(SceneRemoved(const QString&)), this, SLOT(OnSceneRemoved(const QString&)));

    // Add asset cache directory as its own resource group to ogre to support threaded loading.
    if (GetFramework()->Asset()->GetAssetCache())
    {
        std::string cacheResourceDir = GetFramework()->Asset()->GetAssetCache()->CacheDirectory().toStdString();
        if (!Ogre::ResourceGroupManager::getSingleton().resourceLocationExists(cacheResourceDir, CACHE_RESOURCE_GROUP))
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(cacheResourceDir, "FileSystem", CACHE_RESOURCE_GROUP);
    }

    framework_->Console()->RegisterCommand("renderStats", "Prints out render statistics.",
        this, SLOT(ConsoleStats()));
#if OGRE_PROFILING == 1
    framework_->Console()->RegisterCommand("ogreProf", "Toggles visibility of the Ogre profiler overlay.",
        this, SLOT(ToggleOgreProfilerOverlay()));
#endif
    framework_->Console()->RegisterCommand("setMaterialAttribute", "Sets an attribute on a material asset",
        this, SLOT(SetMaterialAttribute(const QStringList &)));
}

void OgreRenderingModule::Uninitialize()
{
    // We're shutting down. Force a release of all loaded asset objects from the Asset API so that
    // no refs to Ogre assets remain - below 'renderer.reset()' is going to delete Ogre::Root.
    framework_->Asset()->ForgetAllAssets();

    // Clear up the renderer object, so that it will not be left dangling.
    framework_->RegisterRenderer(0);
}

void OgreRenderingModule::ConsoleStats()
{
    if (framework_->IsHeadless())
        return;
    if (renderer)
    {
        const Ogre::RenderTarget::FrameStats& stats = renderer->GetCurrentRenderWindow()->getStatistics();
        ConsoleAPI *c = framework_->Console();
        c->Print("Average FPS: " + QString::number(stats.avgFPS));
        c->Print("Worst FPS: " + QString::number(stats.worstFPS));
        c->Print("Best FPS: " + QString::number(stats.bestFPS));
        c->Print("Triangles: " + QString::number(stats.triangleCount));
        c->Print("Batches: " + QString::number(stats.batchCount));
        return;
    }
    else
        LogError("No renderer found!");
}

void OgreRenderingModule::ToggleOgreProfilerOverlay()
{
#if OGRE_PROFILING == 1
    if (!framework_->IsHeadless())
    {
        bool enabled = Ogre::Profiler::getSingleton().getEnabled();
        Ogre::Profiler::getSingleton().setEnabled(!enabled);
    }
#else
    LogError("OgreRenderingModule::ToggleOgreProfilerOverlay: Ogre built without profiling support, cannot show profiler overlay.");
#endif
}

void OgreRenderingModule::OnSceneAdded(const QString& name)
{
    ScenePtr scene = GetFramework()->Scene()->GetScene(name);
    if (!scene)
    {
        LogError("OgreRenderingModule::OnSceneAdded: Could not find created scene");
        return;
    }

    // Add an OgreWorld to the scene
    OgreWorldPtr newWorld = boost::make_shared<OgreWorld>(renderer.get(), scene);
    renderer->ogreWorlds[scene.get()] = newWorld;
    scene->setProperty(OgreWorld::PropertyName(), QVariant::fromValue<QObject*>(newWorld.get()));
}

void OgreRenderingModule::OnSceneRemoved(const QString& name)
{
    // Remove the OgreWorld from the scene
    ScenePtr scene = GetFramework()->Scene()->GetScene(name);
    if (!scene)
    {
        LogError("OgreRenderingModule::OnSceneRemoved: Could not find scene about to be removed");
        return;
    }

    OgreWorld* worldPtr = scene->GetWorld<OgreWorld>().get();
    if (worldPtr)
    {
        scene->setProperty(OgreWorld::PropertyName(), QVariant());
        renderer->ogreWorlds.erase(scene.get());
    }
}

void OgreRenderingModule::SetMaterialAttribute(const QStringList &params)
{
    if (params.size() < 3)
    {
        LogError("OgreRenderingModule::SetMaterialAttribute: Usage: SetMaterialAttribute(asset,attribute,value)");
        return;
    }
    AssetPtr assetPtr = framework_->Asset()->GetAsset(framework_->Asset()->ResolveAssetRef("", params[0]));
    if (!assetPtr || !assetPtr->IsLoaded())
    {
        LogError("OgreRenderingModule::SetMaterialAttribute: No asset found or not loaded");
        return;
    }
    OgreMaterialAsset* matAsset = dynamic_cast<OgreMaterialAsset*>(assetPtr.get());
    if (!matAsset)
    {
        LogError("OgreRenderingModule::SetMaterialAttribute: Not a material asset");
        return;
    }
    matAsset->SetAttribute(params[1], params[2]);
}

} // ~namespace OgreRenderer

using namespace OgreRenderer;

extern "C"
{
DLLEXPORT void TundraPluginMain(Framework *fw)
{
    Framework::SetInstance(fw); // Inside this DLL, remember the pointer to the global framework object.
    fw->RegisterModule(new OgreRenderer::OgreRenderingModule());
}
}
<|endoftext|>


<commit_before>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include "AppSupport.hpp"

#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>

#include <pdal/FileUtils.hpp>
#include <pdal/Utils.hpp>
#include <pdal/PipelineManager.hpp>
#include <pdal/PipelineReader.hpp>
#include <pdal/StageFactory.hpp>

std::string AppSupport::inferReaderDriver(const std::string& filename, pdal::Options& options)
{
    std::string ext = boost::filesystem::extension(filename);

    pdal::Option& fn = options.getOptionByRef("filename");
    fn.setValue<std::string>(filename);

    // maybe this should live in StageFactory?
    std::map<std::string, std::string> drivers;
    drivers["las"] = "drivers.las.reader";
    drivers["laz"] = "drivers.las.reader";
    drivers["bin"] = "drivers.terrasolid.reader";
    drivers["qi"] = "drivers.qfit.reader";
    drivers["xml"] = "drivers.pipeline.reader";
    drivers["nitf"] = "drivers.nitf.reader";
    drivers["ntf"] = "drivers.nitf.reader";

    if (boost::algorithm::iequals(filename, "STDIN"))
    {
        return drivers["xml"];
    }

    if (ext == "") return "";
    ext = ext.substr(1, ext.length()-1);
    if (ext == "") return "";

    boost::to_lower(ext);
    std::string driver = drivers[ext];
    return driver; // will be "" if not found
}

std::string AppSupport::inferWriterDriver(const std::string& filename, pdal::Options& options)
{
    std::string ext = boost::filesystem::extension(filename);

    boost::to_lower(ext);

    if (boost::algorithm::iequals(ext,".laz"))
    {
        options.add("compression", true);
    }

    options.add<std::string>("filename", filename);

    // maybe this should live in StageFactory?
    std::map<std::string, std::string> drivers;
    drivers["las"] = "drivers.las.writer";
    drivers["laz"] = "drivers.las.writer";
    drivers["xyz"] = "drivers.text.writer";
    drivers["txt"] = "drivers.text.writer";
    drivers["pcd"] = "drivers.pcd.writer";

    if (boost::algorithm::iequals(filename, "STDOUT"))
    {
        return drivers["txt"];
    }

    if (ext == "") return drivers["txt"];
    ext = ext.substr(1, ext.length()-1);
    if (ext == "") return drivers["txt"];

    boost::to_lower(ext);
    std::string driver = drivers[ext];
    return driver; // will be "" if not found
}

pdal::Stage* AppSupport::makeReader(pdal::Options& options)
{
    const std::string inputFile = options.getValueOrThrow<std::string>("filename");

    if (!pdal::FileUtils::fileExists(inputFile))
    {
        throw app_runtime_error("file not found: " + inputFile);
    }

    pdal::StageFactory factory;
    std::string driver = factory.inferReaderDriver(inputFile, options);
    if (driver == "")
    {
        throw app_runtime_error("Cannot determine input file type of " + inputFile);
    }

    pdal::Stage* stage = factory.createReader(driver, options);
    if (!stage)
    {
        throw app_runtime_error("reader creation failed");
    }

    return stage;
}

pdal::Writer* AppSupport::makeWriter(pdal::Options& options, pdal::Stage& stage)
{
    const std::string outputFile = options.getValueOrThrow<std::string>("filename");

    pdal::StageFactory factory;
    std::string driver = factory.inferWriterDriver(outputFile, options);
    if (driver == "")
    {
        throw app_runtime_error("Cannot determine output file type of " + outputFile);
    }

    pdal::Writer* writer = factory.createWriter(driver, stage, options);
    if (!writer)
    {
        throw app_runtime_error("writer creation failed");
    }

    return writer;
}

PercentageCallback::PercentageCallback(double major, double minor)
    : m_lastMajorPerc(-1 * major)
    , m_lastMinorPerc(-1 * minor)
    , m_done(false)
{
    return;
}

void PercentageCallback::callback()
{
    if (m_done) return;

    double currPerc = getPercentComplete();

    if (pdal::Utils::compare_distance<double>(currPerc, 100.0))
    {
        std::cerr << "100" << std::endl;
        m_done = true;
    }
    else if (currPerc >= m_lastMajorPerc + 10.0)
    {
        std::cerr << (int)currPerc << std::flush;
        m_lastMajorPerc = currPerc;
        m_lastMinorPerc = currPerc;
    }
    else if (currPerc >= m_lastMinorPerc + 2.0)
    {
        std::cerr << '.' << std::flush;
        m_lastMinorPerc = currPerc;
    }

    return;
}

ShellScriptCallback::ShellScriptCallback(std::vector<std::string> const& command)
{
    double major_tick(10.0);
    double minor_tick(2.0);

    if (!command.size())
    {
        m_command = "";
    }
    else
    {
        m_command = command[0];

        if (command.size() == 3)
        {
            major_tick = boost::lexical_cast<double>(command[1]);
            minor_tick = boost::lexical_cast<double>(command[2]);
        }
        else if (command.size() == 2)
        {
            major_tick = boost::lexical_cast<double>(command[1]);
        }
    }

    PercentageCallback(major_tick, minor_tick);

    return;
}

void ShellScriptCallback::callback()
{
    if (m_done) return;

    double currPerc = getPercentComplete();

    if (pdal::Utils::compare_distance<double>(currPerc, 100.0))
    {
        m_done = true;
    }
    else if (currPerc >= m_lastMajorPerc + 10.0)
    {
        std::string output;
        int stat = pdal::Utils::run_shell_command(m_command + " " + boost::lexical_cast<std::string>(static_cast<int>(currPerc)), output);
    }
    else if (currPerc >= m_lastMinorPerc + 2.0)
    {
        m_lastMinorPerc = currPerc;
    }

    return;
}

HeartbeatCallback::HeartbeatCallback()
{
    return;
}

void HeartbeatCallback::callback()
{
    std::cerr << '.';

    return;
}
<commit_msg>add percentage updates to ShellScriptCallback<commit_after>/******************************************************************************
* Copyright (c) 2011, Michael P. Gerlek (mpg@flaxen.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in
*       the documentation and/or other materials provided
*       with the distribution.
*     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
*       names of its contributors may be used to endorse or promote
*       products derived from this software without specific prior
*       written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
****************************************************************************/

#include "AppSupport.hpp"

#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>

#include <pdal/FileUtils.hpp>
#include <pdal/Utils.hpp>
#include <pdal/PipelineManager.hpp>
#include <pdal/PipelineReader.hpp>
#include <pdal/StageFactory.hpp>

std::string AppSupport::inferReaderDriver(const std::string& filename, pdal::Options& options)
{
    std::string ext = boost::filesystem::extension(filename);

    pdal::Option& fn = options.getOptionByRef("filename");
    fn.setValue<std::string>(filename);

    // maybe this should live in StageFactory?
    std::map<std::string, std::string> drivers;
    drivers["las"] = "drivers.las.reader";
    drivers["laz"] = "drivers.las.reader";
    drivers["bin"] = "drivers.terrasolid.reader";
    drivers["qi"] = "drivers.qfit.reader";
    drivers["xml"] = "drivers.pipeline.reader";
    drivers["nitf"] = "drivers.nitf.reader";
    drivers["ntf"] = "drivers.nitf.reader";

    if (boost::algorithm::iequals(filename, "STDIN"))
    {
        return drivers["xml"];
    }

    if (ext == "") return "";
    ext = ext.substr(1, ext.length()-1);
    if (ext == "") return "";

    boost::to_lower(ext);
    std::string driver = drivers[ext];
    return driver; // will be "" if not found
}

std::string AppSupport::inferWriterDriver(const std::string& filename, pdal::Options& options)
{
    std::string ext = boost::filesystem::extension(filename);

    boost::to_lower(ext);

    if (boost::algorithm::iequals(ext,".laz"))
    {
        options.add("compression", true);
    }

    options.add<std::string>("filename", filename);

    // maybe this should live in StageFactory?
    std::map<std::string, std::string> drivers;
    drivers["las"] = "drivers.las.writer";
    drivers["laz"] = "drivers.las.writer";
    drivers["xyz"] = "drivers.text.writer";
    drivers["txt"] = "drivers.text.writer";
    drivers["pcd"] = "drivers.pcd.writer";

    if (boost::algorithm::iequals(filename, "STDOUT"))
    {
        return drivers["txt"];
    }

    if (ext == "") return drivers["txt"];
    ext = ext.substr(1, ext.length()-1);
    if (ext == "") return drivers["txt"];

    boost::to_lower(ext);
    std::string driver = drivers[ext];
    return driver; // will be "" if not found
}

pdal::Stage* AppSupport::makeReader(pdal::Options& options)
{
    const std::string inputFile = options.getValueOrThrow<std::string>("filename");

    if (!pdal::FileUtils::fileExists(inputFile))
    {
        throw app_runtime_error("file not found: " + inputFile);
    }

    pdal::StageFactory factory;
    std::string driver = factory.inferReaderDriver(inputFile, options);
    if (driver == "")
    {
        throw app_runtime_error("Cannot determine input file type of " + inputFile);
    }

    pdal::Stage* stage = factory.createReader(driver, options);
    if (!stage)
    {
        throw app_runtime_error("reader creation failed");
    }

    return stage;
}

pdal::Writer* AppSupport::makeWriter(pdal::Options& options, pdal::Stage& stage)
{
    const std::string outputFile = options.getValueOrThrow<std::string>("filename");

    pdal::StageFactory factory;
    std::string driver = factory.inferWriterDriver(outputFile, options);
    if (driver == "")
    {
        throw app_runtime_error("Cannot determine output file type of " + outputFile);
    }

    pdal::Writer* writer = factory.createWriter(driver, stage, options);
    if (!writer)
    {
        throw app_runtime_error("writer creation failed");
    }

    return writer;
}

PercentageCallback::PercentageCallback(double major, double minor)
    : m_lastMajorPerc(-1 * major)
    , m_lastMinorPerc(-1 * minor)
    , m_done(false)
{
    return;
}

void PercentageCallback::callback()
{
    if (m_done) return;

    double currPerc = getPercentComplete();

    if (pdal::Utils::compare_distance<double>(currPerc, 100.0))
    {
        std::cerr << "100" << std::endl;
        m_done = true;
    }
    else if (currPerc >= m_lastMajorPerc + 10.0)
    {
        std::cerr << (int)currPerc << std::flush;
        m_lastMajorPerc = currPerc;
        m_lastMinorPerc = currPerc;
    }
    else if (currPerc >= m_lastMinorPerc + 2.0)
    {
        std::cerr << '.' << std::flush;
        m_lastMinorPerc = currPerc;
    }

    return;
}

ShellScriptCallback::ShellScriptCallback(std::vector<std::string> const& command)
{
    double major_tick(10.0);
    double minor_tick(2.0);

    if (!command.size())
    {
        m_command = "";
    }
    else
    {
        m_command = command[0];

        if (command.size() == 3)
        {
            major_tick = boost::lexical_cast<double>(command[1]);
            minor_tick = boost::lexical_cast<double>(command[2]);
        }
        else if (command.size() == 2)
        {
            major_tick = boost::lexical_cast<double>(command[1]);
        }
    }

    PercentageCallback(major_tick, minor_tick);

    return;
}

void ShellScriptCallback::callback()
{
    if (m_done) return;

    double currPerc = getPercentComplete();

    if (pdal::Utils::compare_distance<double>(currPerc, 100.0))
    {
        m_done = true;
    }
    else if (currPerc >= m_lastMajorPerc + 10.0)
    {
        std::string output;
        int stat = pdal::Utils::run_shell_command(m_command + " " + boost::lexical_cast<std::string>(static_cast<int>(currPerc)), output);
        m_lastMajorPerc = currPerc;
        m_lastMinorPerc = currPerc;
    }
    else if (currPerc >= m_lastMinorPerc + 2.0)
    {
        m_lastMinorPerc = currPerc;
    }

    return;
}

HeartbeatCallback::HeartbeatCallback()
{
    return;
}

void HeartbeatCallback::callback()
{
    std::cerr << '.';

    return;
}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/ozone/platform/egl/egl_surface_factory.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "ui/ozone/public/surface_ozone_egl.h"
#include "ui/ozone/public/surface_ozone_canvas.h"
#include "ui/ozone/public/surface_factory_ozone.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/vsync_provider.h"
#include "base/logging.h"

#include "egl_wrapper.h"

#ifndef GL_BGRA_EXT
 #define GL_BGRA_EXT 0x80E1
#endif

#include <fcntl.h>    /* For O_RDWR */
#include <unistd.h>   /* For open(), creat() */
#include <linux/fb.h>
#include <sys/ioctl.h>

#define OZONE_EGL_WINDOW_WIDTH 1024
#define OZONE_EGL_WINDOW_HEIGTH 768

namespace ui {

class EglOzoneCanvas: public ui::SurfaceOzoneCanvas {
 public:
  EglOzoneCanvas();
  virtual ~EglOzoneCanvas();
  // SurfaceOzoneCanvas overrides:
  virtual void ResizeCanvas(const gfx::Size& viewport_size) override;
  //virtual skia::RefPtr<SkCanvas> GetCanvas() override {
  //  return skia::SharePtr<SkCanvas>(surface_->getCanvas());
  //}
  virtual void PresentCanvas(const gfx::Rect& damage) override;

  virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override {
    return scoped_ptr<gfx::VSyncProvider>();
  }

 private:
  skia::RefPtr<SkSurface> surface_;
  ozone_egl_UserData userDate_;
};

EglOzoneCanvas::EglOzoneCanvas()
{
    memset(&userDate_,0,sizeof(userDate_));
}
EglOzoneCanvas::~EglOzoneCanvas()
{
    ozone_egl_textureShutDown (&userDate_);
}

void EglOzoneCanvas::ResizeCanvas(const gfx::Size& viewport_size)
{
  if(userDate_.width == viewport_size.width() && userDate_.height==viewport_size.height())
  {
      return;
  }
  else if(userDate_.width != 0 && userDate_.height !=0)
  {
      ozone_egl_textureShutDown (&userDate_);
  }
  surface_ = skia::AdoptRef(SkSurface::NewRaster(
        SkImageInfo::Make(viewport_size.width(),
                                   viewport_size.height(),
                                   kN32_SkColorType,
                                   kPremul_SkAlphaType)));
  userDate_.width = viewport_size.width();
  userDate_.height = viewport_size.height();
  userDate_.colorType = GL_BGRA_EXT;
  ozone_egl_textureInit ( &userDate_);
}

void EglOzoneCanvas::PresentCanvas(const gfx::Rect& damage)
{
    SkImageInfo info;
    size_t row_bytes;
    userDate_.data = (char *) surface_->peekPixels(&info, &row_bytes);
    ozone_egl_textureDraw(&userDate_);
    ozone_egl_swap();
}

class OzoneEgl : public ui::SurfaceOzoneEGL {
 public:
  OzoneEgl(gfx::AcceleratedWidget window_id){
     native_window_ = window_id;
  }
  virtual ~OzoneEgl() {
     native_window_=0;
  }

  virtual intptr_t GetNativeWindow() override
  {
    return native_window_;
  }

  virtual bool OnSwapBuffers() override
  {
    return true;
  }

  virtual bool ResizeNativeWindow(const gfx::Size& viewport_size) override {
    return true;
  }

  virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override {
    return scoped_ptr<gfx::VSyncProvider>();
  }

 private:
  intptr_t native_window_;
};

SurfaceFactoryEgl::SurfaceFactoryEgl():init_(false)
{

}

SurfaceFactoryEgl::~SurfaceFactoryEgl()
{
    DestroySingleWindow();
}

EGLint g_width;
EGLint g_height;
bool SurfaceFactoryEgl::CreateSingleWindow()
{
  struct fb_var_screeninfo fb_var;

  int fb_fd =  open("/dev/fb0", O_RDWR);

  if(init_)
  {
     return true;
  }

  if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &fb_var)) {
        LOG(FATAL) << "failed to get fb var info errno: " << errno;
        g_width = 640;
	g_height = 480;
  } else {
    g_width = fb_var.xres;
    g_height = fb_var.yres;
  }

 close(fb_fd);

 if(!ozone_egl_setup(0, 0, g_width, g_height))
  {
      LOG(FATAL) << "CreateSingleWindow";
      return false;
  }
  init_ = true;
  return true;
}

void SurfaceFactoryEgl::DestroySingleWindow() {
  ozone_egl_destroy();
  init_ = false;
}

intptr_t SurfaceFactoryEgl::GetNativeDisplay() {
  return (intptr_t)ozone_egl_getNativedisp();
}

//gfx::AcceleratedWidget SurfaceFactoryEgl::GetAcceleratedWidget() {
//  if (!CreateSingleWindow())
//    LOG(FATAL) << "failed to create window";
//  return (gfx::AcceleratedWidget)GetNativeDisplay();
//}

scoped_ptr<ui::SurfaceOzoneEGL>
SurfaceFactoryEgl::CreateEGLSurfaceForWidget(
    gfx::AcceleratedWidget widget) {
  return make_scoped_ptr<ui::SurfaceOzoneEGL>(
      new OzoneEgl(widget));
}

bool SurfaceFactoryEgl::LoadEGLGLES2Bindings(
    AddGLLibraryCallback add_gl_library,
    SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
  return false;
}

const int32* SurfaceFactoryEgl::GetEGLSurfaceProperties(
    const int32* desired_list) {
  return ozone_egl_getConfigAttribs();
}

scoped_ptr<ui::SurfaceOzoneCanvas> SurfaceFactoryEgl::CreateCanvasForWidget(
      gfx::AcceleratedWidget widget){
    LOG(ERROR) << "-CreateCanvasForWidget-";
  scoped_ptr<EglOzoneCanvas> canvas(new EglOzoneCanvas());
  return canvas.PassAs<ui::SurfaceOzoneCanvas>();
}

}  // namespace ui
<commit_msg>overriding OnSwapBuffersAsync<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/ozone/platform/egl/egl_surface_factory.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "ui/ozone/public/surface_ozone_egl.h"
#include "ui/ozone/public/surface_ozone_canvas.h"
#include "ui/ozone/public/surface_factory_ozone.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/vsync_provider.h"
#include "base/logging.h"

#include "egl_wrapper.h"

#ifndef GL_BGRA_EXT
 #define GL_BGRA_EXT 0x80E1
#endif

#include <fcntl.h>    /* For O_RDWR */
#include <unistd.h>   /* For open(), creat() */
#include <linux/fb.h>
#include <sys/ioctl.h>

#define OZONE_EGL_WINDOW_WIDTH 1024
#define OZONE_EGL_WINDOW_HEIGTH 768

namespace ui {

class EglOzoneCanvas: public ui::SurfaceOzoneCanvas {
 public:
  EglOzoneCanvas();
  virtual ~EglOzoneCanvas();
  // SurfaceOzoneCanvas overrides:
  virtual void ResizeCanvas(const gfx::Size& viewport_size) override;
  //virtual skia::RefPtr<SkCanvas> GetCanvas() override {
  //  return skia::SharePtr<SkCanvas>(surface_->getCanvas());
  //}
  virtual void PresentCanvas(const gfx::Rect& damage) override;

  virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override {
    return scoped_ptr<gfx::VSyncProvider>();
  }

 private:
  skia::RefPtr<SkSurface> surface_;
  ozone_egl_UserData userDate_;
};

EglOzoneCanvas::EglOzoneCanvas()
{
    memset(&userDate_,0,sizeof(userDate_));
}
EglOzoneCanvas::~EglOzoneCanvas()
{
    ozone_egl_textureShutDown (&userDate_);
}

void EglOzoneCanvas::ResizeCanvas(const gfx::Size& viewport_size)
{
  if(userDate_.width == viewport_size.width() && userDate_.height==viewport_size.height())
  {
      return;
  }
  else if(userDate_.width != 0 && userDate_.height !=0)
  {
      ozone_egl_textureShutDown (&userDate_);
  }
  surface_ = skia::AdoptRef(SkSurface::NewRaster(
        SkImageInfo::Make(viewport_size.width(),
                                   viewport_size.height(),
                                   kN32_SkColorType,
                                   kPremul_SkAlphaType)));
  userDate_.width = viewport_size.width();
  userDate_.height = viewport_size.height();
  userDate_.colorType = GL_BGRA_EXT;
  ozone_egl_textureInit ( &userDate_);
}

void EglOzoneCanvas::PresentCanvas(const gfx::Rect& damage)
{
    SkImageInfo info;
    size_t row_bytes;
    userDate_.data = (char *) surface_->peekPixels(&info, &row_bytes);
    ozone_egl_textureDraw(&userDate_);
    ozone_egl_swap();
}

class OzoneEgl : public ui::SurfaceOzoneEGL {
 public:
  OzoneEgl(gfx::AcceleratedWidget window_id){
     native_window_ = window_id;
  }
  virtual ~OzoneEgl() {
     native_window_=0;
  }

  virtual intptr_t GetNativeWindow() override
  {
    return native_window_;
  }

  virtual bool OnSwapBuffers() override
  {
    return true;
  }

  virtual bool OnSwapBuffersAsync(const SwapCompletionCallback& callback) override
  {
    return true;
  }

  virtual bool ResizeNativeWindow(const gfx::Size& viewport_size) override {
    return true;
  }

  virtual scoped_ptr<gfx::VSyncProvider> CreateVSyncProvider() override {
    return scoped_ptr<gfx::VSyncProvider>();
  }

 private:
  intptr_t native_window_;
};

SurfaceFactoryEgl::SurfaceFactoryEgl():init_(false)
{

}

SurfaceFactoryEgl::~SurfaceFactoryEgl()
{
    DestroySingleWindow();
}

EGLint g_width;
EGLint g_height;
bool SurfaceFactoryEgl::CreateSingleWindow()
{
  struct fb_var_screeninfo fb_var;

  int fb_fd =  open("/dev/fb0", O_RDWR);

  if(init_)
  {
     return true;
  }

  if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &fb_var)) {
        LOG(FATAL) << "failed to get fb var info errno: " << errno;
        g_width = 640;
	g_height = 480;
  } else {
    g_width = fb_var.xres;
    g_height = fb_var.yres;
  }

 close(fb_fd);

 if(!ozone_egl_setup(0, 0, g_width, g_height))
  {
      LOG(FATAL) << "CreateSingleWindow";
      return false;
  }
  init_ = true;
  return true;
}

void SurfaceFactoryEgl::DestroySingleWindow() {
  ozone_egl_destroy();
  init_ = false;
}

intptr_t SurfaceFactoryEgl::GetNativeDisplay() {
  return (intptr_t)ozone_egl_getNativedisp();
}

//gfx::AcceleratedWidget SurfaceFactoryEgl::GetAcceleratedWidget() {
//  if (!CreateSingleWindow())
//    LOG(FATAL) << "failed to create window";
//  return (gfx::AcceleratedWidget)GetNativeDisplay();
//}

scoped_ptr<ui::SurfaceOzoneEGL>
SurfaceFactoryEgl::CreateEGLSurfaceForWidget(
    gfx::AcceleratedWidget widget) {
  return make_scoped_ptr<ui::SurfaceOzoneEGL>(
      new OzoneEgl(widget));
}

bool SurfaceFactoryEgl::LoadEGLGLES2Bindings(
    AddGLLibraryCallback add_gl_library,
    SetGLGetProcAddressProcCallback set_gl_get_proc_address) {
  return false;
}

const int32* SurfaceFactoryEgl::GetEGLSurfaceProperties(
    const int32* desired_list) {
  return ozone_egl_getConfigAttribs();
}

scoped_ptr<ui::SurfaceOzoneCanvas> SurfaceFactoryEgl::CreateCanvasForWidget(
      gfx::AcceleratedWidget widget){
    LOG(ERROR) << "-CreateCanvasForWidget-";
  scoped_ptr<EglOzoneCanvas> canvas(new EglOzoneCanvas());
  return canvas.PassAs<ui::SurfaceOzoneCanvas>();
}

}  // namespace ui
<|endoftext|>


<commit_before>#include <iostream>

#include <bw/channelselector.h>
#include <bw/thresholding.h>
#include <bw/connectedcomponents.h>
#include <bw/regionfeatures.h>

#include <bw/extern_templates.h>

int main(int argc, char** argv) {
    using namespace vigra;
    using namespace BW;

    if(argc != 3) {
        std::cout << "usage: ./ccpipeline hdf5file hdf5group" << std::endl;
        return 0;
    }
    std::string hdf5file(argv[1]);
    std::string hdf5group(argv[2]);

    typedef TinyVector<int, 3> V;

    V blockShape(100,100,100);

    //extract channel 0
    {
        SourceHDF5<4, float> source(hdf5file, hdf5group);
        SinkHDF5<3, float> sink("01_channel0.h5", "channel0");
        sink.setBlockShape(blockShape);
        ChannelSelector<4, float> cs(&source, blockShape);
        cs.run(0, 0, &sink);
    }

    //threshold
    {
        SourceHDF5<3, float> source("01_channel0.h5", "channel0");
        SinkHDF5<3, vigra::UInt8> sink("02_thresh.h5", "thresh");
        sink.setBlockShape(blockShape);
        Thresholding<3, float> bs(&source, blockShape);
        bs.run(0.5, 0, 1, &sink);
    }

    //connected components
    {
        SourceHDF5<3, UInt8> source("02_thresh.h5", "thresh");
        ConnectedComponents<3> bs(&source, blockShape);
        bs.writeResult("03_cc.h5", "cc", 1);
    }

    //region features
    {
        SourceHDF5<3, float> sourceData("02_thresh.h5", "thresh");
        SourceHDF5<3, uint32_t> sourceLabels("02_thresh.h5", "thresh");
        RegionFeatures<3, float, uint32_t> rf(&sourceData, &sourceLabels, blockShape);
        vigra::MultiArray<2, float> out;
        rf.run("test_result.h5");
    }

}

<commit_msg>example: add license<commit_after>/************************************************************************/
/*                                                                      */
/*    Copyright 2013 by Thorben Kroeger                                 */
/*    thorben.kroeger@iwr.uni-heidelberg.de                             */
/*                                                                      */
/*    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.                                   */
/*                                                                      */
/************************************************************************/

#include <iostream>

#include <bw/channelselector.h>
#include <bw/thresholding.h>
#include <bw/connectedcomponents.h>
#include <bw/regionfeatures.h>

#include <bw/extern_templates.h>

int main(int argc, char** argv) {
    using namespace vigra;
    using namespace BW;

    if(argc != 3) {
        std::cout << "usage: ./ccpipeline hdf5file hdf5group" << std::endl;
        return 0;
    }
    std::string hdf5file(argv[1]);
    std::string hdf5group(argv[2]);

    typedef TinyVector<int, 3> V;

    V blockShape(100,100,100);

    //extract channel 0
    {
        SourceHDF5<4, float> source(hdf5file, hdf5group);
        SinkHDF5<3, float> sink("01_channel0.h5", "channel0");
        sink.setBlockShape(blockShape);
        ChannelSelector<4, float> cs(&source, blockShape);
        cs.run(0, 0, &sink);
    }

    //threshold
    {
        SourceHDF5<3, float> source("01_channel0.h5", "channel0");
        SinkHDF5<3, vigra::UInt8> sink("02_thresh.h5", "thresh");
        sink.setBlockShape(blockShape);
        Thresholding<3, float> bs(&source, blockShape);
        bs.run(0.5, 0, 1, &sink);
    }

    //connected components
    {
        SourceHDF5<3, UInt8> source("02_thresh.h5", "thresh");
        ConnectedComponents<3> bs(&source, blockShape);
        bs.writeResult("03_cc.h5", "cc", 1);
    }

    //region features
    {
        SourceHDF5<3, float> sourceData("02_thresh.h5", "thresh");
        SourceHDF5<3, uint32_t> sourceLabels("02_thresh.h5", "thresh");
        RegionFeatures<3, float, uint32_t> rf(&sourceData, &sourceLabels, blockShape);
        vigra::MultiArray<2, float> out;
        rf.run("test_result.h5");
    }

}

<|endoftext|>


<commit_before>/* mockturtle: C++ logic network library
 * Copyright (C) 2018-2019  EPFL
 *
 * 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 balancing.hpp
  \brief Cut-based depth-optimization

  \author Mathias Soeken
*/

#pragma once

#include <cstdint>
#include <functional>
#include <limits>
#include <optional>
#include <utility>
#include <vector>

#include <fmt/format.h>
#include <kitty/dynamic_truth_table.hpp>

#include "../utils/node_map.hpp"
#include "../utils/progress_bar.hpp"
#include "../utils/stopwatch.hpp"
#include "../views/topo_view.hpp"
#include "cleanup.hpp"
#include "cut_enumeration.hpp"

namespace mockturtle
{

/*! \brief Parameters for balancing.
 */
struct balancing_params
{
  /*! \brief Cut enumeration params. */
  cut_enumeration_params cut_enumeration_ps;

  /*! \brief Show progress. */
  bool progress{false};

  /*! \brief Be verbose. */
  bool verbose{false};
};

/*! \brief Statistics for balancing.
 */
struct balancing_stats
{
  /*! \brief Total run-time. */
  stopwatch<>::duration time_total{};

  /*! \brief Cut enumeration run-time. */
  cut_enumeration_stats cut_enumeration_st;

  /*! \brief Prints report. */
  void report() const
  {
    fmt::print( "[i] total time             = {:>5.2f} secs\n", to_seconds( time_total ) );
    fmt::print( "[i] Cut enumeration stats\n" );
    cut_enumeration_st.report();
  }
};

template<class Ntk>
struct arrival_time_pair
{
  signal<Ntk> f;
  uint32_t level;
};

/*! \brief Callback function for `rebalancing_function_t`.
 *
 * This callback is used in the rebalancing function to announce a new candidate that
 * could be used for replacement in the main balancing algorithm.  Using a callback
 * makes it possible to account for situations in which none, a single, or multiple
 * candidates are generated.
 *
 * The callback returns a pair composed of the output signal of the replacement
 * candidate and the level of the new candidate.  Ideally, the rebalancing function
 * should not call the callback with candidates that a worse level.
 */
template<class Ntk>
using rebalancing_function_callback_t = std::function<void(arrival_time_pair<Ntk> const&, uint32_t)>;

template<class Ntk>
using rebalancing_function_t = std::function<void(Ntk&, kitty::dynamic_truth_table const&, std::vector<arrival_time_pair<Ntk>> const&, uint32_t, uint32_t, rebalancing_function_callback_t<Ntk> const&)>;

namespace detail
{

template<class Ntk>
struct balancing_impl
{
  balancing_impl( Ntk const& ntk, rebalancing_function_t<Ntk> const& rebalancing_fn, balancing_params const& ps, balancing_stats& st )
      : ntk_( ntk ),
        rebalancing_fn_( rebalancing_fn ),
        ps_( ps ),
        st_( st )
  {
  }

  Ntk run()
  {
    Ntk dest;
    node_map<arrival_time_pair<Ntk>, Ntk> old_to_new( ntk_ );

    /* input arrival times and mapping */
    old_to_new[ntk_.get_constant( false )] = {dest.get_constant( false ), 0u};
    if ( ntk_.get_node( ntk_.get_constant( false ) ) != ntk_.get_node( ntk_.get_constant( true ) ) )
    {
      old_to_new[ntk_.get_constant( true )] = {dest.get_constant( true ), 0u};
    }
    ntk_.foreach_pi( [&]( auto const& n ) {
      old_to_new[n] = {dest.create_pi(), 0u};
    } );

    stopwatch<> t( st_.time_total );
    const auto cuts = cut_enumeration<Ntk, true>( ntk_, ps_.cut_enumeration_ps, &st_.cut_enumeration_st );

    uint32_t current_level{};
    const auto size = ntk_.size();
    progress_bar pbar{ntk_.size(), "balancing |{0}| node = {1:>4} / " + std::to_string( size ) + "   current level = {2}", ps_.progress};
    topo_view<Ntk>{ntk_}.foreach_node( [&]( auto const& n, auto index ) {
      pbar( index, index, current_level );

      if ( ntk_.is_constant( n ) || ntk_.is_pi( n ) )
      {
        return;
      }

      arrival_time_pair<Ntk> best{{}, std::numeric_limits<uint32_t>::max()};
      uint32_t best_size{};
      for ( auto& cut : cuts.cuts( ntk_.node_to_index( n ) ) )
      {
        if ( cut->size() == 1u || kitty::is_const0( cuts.truth_table( *cut ) ) )
        {
          continue;
        }

        std::vector<arrival_time_pair<Ntk>> arrival_times( cut->size() );
        std::transform( cut->begin(), cut->end(), arrival_times.begin(), [&]( auto leaf ) { return old_to_new[ntk_.index_to_node( leaf )]; });

        rebalancing_fn_( dest, cuts.truth_table( *cut ), arrival_times, best.level, best_size, [&]( arrival_time_pair<Ntk> const& cand, uint32_t cand_size ) {
          if ( cand.level < best.level || ( cand.level == best.level && cand_size < best_size ) )
          {
            best = cand;
            best_size = cand_size;
          }
        });
      }
      old_to_new[n] = best;
      current_level = std::max( current_level, best.level );
    } );

    ntk_.foreach_po( [&]( auto const& f ) {
      const auto s = old_to_new[f].f;
      dest.create_po( ntk_.is_complemented( f ) ? dest.create_not( s ) : s );
    } );

    return cleanup_dangling( dest );
  }

private:
  Ntk const& ntk_;
  rebalancing_function_t<Ntk> const& rebalancing_fn_;
  balancing_params const& ps_;
  balancing_stats& st_;
};

} // namespace detail

/*! Balancing of a logic network
 *
 * This function implements a dynamic-programming and cut-enumeration based
 * balancing algorithm.  It returns a new network of the same type and performs
 * generic balancing by providing a rebalancing function.
 *
   \verbatim embed:rst

   Example

   .. code-block:: c++

      const auto aig = ...;

      sop_balancing<aig_network> balance_fn;
      balance_params ps;
      ps.cut_enumeration_ps.cut_size = 6u;
      const auto balanced_aig = balance( aig, {balance_fn}, ps );
   \endverbatim
 */
template<class Ntk>
Ntk balancing( Ntk const& ntk, rebalancing_function_t<Ntk> const& rebalancing_fn = {}, balancing_params const& ps = {}, balancing_stats* pst = nullptr )
{
  static_assert( is_network_type_v<Ntk>, "Ntk is not a network type" );
  static_assert( has_create_not_v<Ntk>, "Ntk does not implement the create_not method" );
  static_assert( has_create_pi_v<Ntk>, "Ntk does not implement the create_pi method" );
  static_assert( has_create_po_v<Ntk>, "Ntk does not implement the create_po method" );
  static_assert( has_foreach_pi_v<Ntk>, "Ntk does not implement the foreach_pi method" );
  static_assert( has_foreach_po_v<Ntk>, "Ntk does not implement the foreach_po method" );
  static_assert( has_get_constant_v<Ntk>, "Ntk does not implement the get_constant method" );
  static_assert( has_get_node_v<Ntk>, "Ntk does not implement the get_node method" );
  static_assert( has_is_complemented_v<Ntk>, "Ntk does not implement the is_complemented method" );
  static_assert( has_is_constant_v<Ntk>, "Ntk does not implement the is_constant method" );
  static_assert( has_is_pi_v<Ntk>, "Ntk does not implement the is_pi method" );
  static_assert( has_node_to_index_v<Ntk>, "Ntk does not implement the node_to_index method" );
  static_assert( has_size_v<Ntk>, "Ntk does not implement the size method" );

  balancing_stats st;
  const auto dest = detail::balancing_impl<Ntk>{ntk, rebalancing_fn, ps, st}.run();

  if ( pst )
  {
    *pst = st;
  }
  if ( ps.verbose )
  {
    st.report();
  }

  return dest;
}

} // namespace mockturtle
<commit_msg>Only rewrite along critical path in balancing. (#353)<commit_after>/* mockturtle: C++ logic network library
 * Copyright (C) 2018-2019  EPFL
 *
 * 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 balancing.hpp
  \brief Cut-based depth-optimization

  \author Mathias Soeken
*/

#pragma once

#include <cstdint>
#include <functional>
#include <limits>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include <fmt/format.h>
#include <kitty/dynamic_truth_table.hpp>

#include "../utils/cost_functions.hpp"
#include "../utils/node_map.hpp"
#include "../utils/progress_bar.hpp"
#include "../utils/stopwatch.hpp"
#include "../views/depth_view.hpp"
#include "../views/topo_view.hpp"
#include "cleanup.hpp"
#include "cut_enumeration.hpp"

namespace mockturtle
{

/*! \brief Parameters for balancing.
 */
struct balancing_params
{
  /*! \brief Cut enumeration params. */
  cut_enumeration_params cut_enumeration_ps;

  /*! \brief Optimize only on critical path. */
  bool only_on_critical_path{false};

  /*! \brief Show progress. */
  bool progress{false};

  /*! \brief Be verbose. */
  bool verbose{false};
};

/*! \brief Statistics for balancing.
 */
struct balancing_stats
{
  /*! \brief Total run-time. */
  stopwatch<>::duration time_total{};

  /*! \brief Cut enumeration run-time. */
  cut_enumeration_stats cut_enumeration_st;

  /*! \brief Prints report. */
  void report() const
  {
    fmt::print( "[i] total time             = {:>5.2f} secs\n", to_seconds( time_total ) );
    fmt::print( "[i] Cut enumeration stats\n" );
    cut_enumeration_st.report();
  }
};

template<class Ntk>
struct arrival_time_pair
{
  signal<Ntk> f;
  uint32_t level;
};

/*! \brief Callback function for `rebalancing_function_t`.
 *
 * This callback is used in the rebalancing function to announce a new candidate that
 * could be used for replacement in the main balancing algorithm.  Using a callback
 * makes it possible to account for situations in which none, a single, or multiple
 * candidates are generated.
 *
 * The callback returns a pair composed of the output signal of the replacement
 * candidate and the level of the new candidate.  Ideally, the rebalancing function
 * should not call the callback with candidates that a worse level.
 */
template<class Ntk>
using rebalancing_function_callback_t = std::function<void(arrival_time_pair<Ntk> const&, uint32_t)>;

template<class Ntk>
using rebalancing_function_t = std::function<void(Ntk&, kitty::dynamic_truth_table const&, std::vector<arrival_time_pair<Ntk>> const&, uint32_t, uint32_t, rebalancing_function_callback_t<Ntk> const&)>;

namespace detail
{

template<class Ntk, class CostFn>
struct balancing_impl
{
  balancing_impl( Ntk const& ntk, rebalancing_function_t<Ntk> const& rebalancing_fn, balancing_params const& ps, balancing_stats& st )
      : ntk_( ntk ),
        rebalancing_fn_( rebalancing_fn ),
        ps_( ps ),
        st_( st )
  {
  }

  Ntk run()
  {
    Ntk dest;
    node_map<arrival_time_pair<Ntk>, Ntk> old_to_new( ntk_ );

    /* input arrival times and mapping */
    old_to_new[ntk_.get_constant( false )] = {dest.get_constant( false ), 0u};
    if ( ntk_.get_node( ntk_.get_constant( false ) ) != ntk_.get_node( ntk_.get_constant( true ) ) )
    {
      old_to_new[ntk_.get_constant( true )] = {dest.get_constant( true ), 0u};
    }
    ntk_.foreach_pi( [&]( auto const& n ) {
      old_to_new[n] = {dest.create_pi(), 0u};
    } );

    std::shared_ptr<depth_view<Ntk, CostFn>> depth_ntk;
    if ( ps_.only_on_critical_path )
    {
      depth_ntk = std::make_shared<depth_view<Ntk, CostFn>>( ntk_ );
    }

    stopwatch<> t( st_.time_total );
    const auto cuts = cut_enumeration<Ntk, true>( ntk_, ps_.cut_enumeration_ps, &st_.cut_enumeration_st );

    uint32_t current_level{};
    const auto size = ntk_.size();
    progress_bar pbar{ntk_.size(), "balancing |{0}| node = {1:>4} / " + std::to_string( size ) + "   current level = {2}", ps_.progress};
    topo_view<Ntk>{ntk_}.foreach_node( [&]( auto const& n, auto index ) {
      pbar( index, index, current_level );

      if ( ntk_.is_constant( n ) || ntk_.is_pi( n ) )
      {
        return;
      }

      if ( ps_.only_on_critical_path && !depth_ntk->is_on_critical_path( n ) )
      {
        std::vector<signal<Ntk>> children;
        ntk_.foreach_fanin( n, [&]( auto const& f ) {
          const auto f_best = old_to_new[f].f;
          children.push_back( ntk_.is_complemented( f ) ? dest.create_not( f_best ) : f_best );
        });
        old_to_new[n] = {dest.clone_node( ntk_, n, children ), depth_ntk->level( n )};
        return;
      }

      arrival_time_pair<Ntk> best{{}, std::numeric_limits<uint32_t>::max()};
      uint32_t best_size{};
      for ( auto& cut : cuts.cuts( ntk_.node_to_index( n ) ) )
      {
        if ( cut->size() == 1u || kitty::is_const0( cuts.truth_table( *cut ) ) )
        {
          continue;
        }

        std::vector<arrival_time_pair<Ntk>> arrival_times( cut->size() );
        std::transform( cut->begin(), cut->end(), arrival_times.begin(), [&]( auto leaf ) { return old_to_new[ntk_.index_to_node( leaf )]; });

        rebalancing_fn_( dest, cuts.truth_table( *cut ), arrival_times, best.level, best_size, [&]( arrival_time_pair<Ntk> const& cand, uint32_t cand_size ) {
          if ( cand.level < best.level || ( cand.level == best.level && cand_size < best_size ) )
          {
            best = cand;
            best_size = cand_size;
          }
        });
      }
      old_to_new[n] = best;
      current_level = std::max( current_level, best.level );
    } );

    ntk_.foreach_po( [&]( auto const& f ) {
      const auto s = old_to_new[f].f;
      dest.create_po( ntk_.is_complemented( f ) ? dest.create_not( s ) : s );
    } );

    return cleanup_dangling( dest );
  }

private:
  Ntk const& ntk_;
  rebalancing_function_t<Ntk> const& rebalancing_fn_;
  balancing_params const& ps_;
  balancing_stats& st_;
};

} // namespace detail

/*! Balancing of a logic network
 *
 * This function implements a dynamic-programming and cut-enumeration based
 * balancing algorithm.  It returns a new network of the same type and performs
 * generic balancing by providing a rebalancing function.
 *
 * The template parameter `CostFn` is only used to compute the critical paths,
 * when the `only_on_critical_path` parameter is assigned true.  Note that the
 * size for rewriting candidates is computed by the rebalancing function and
 * may not correspond to the cost given by CostFn.
 *
   \verbatim embed:rst

   Example

   .. code-block:: c++

      const auto aig = ...;

      sop_balancing<aig_network> balance_fn;
      balance_params ps;
      ps.cut_enumeration_ps.cut_size = 6u;
      const auto balanced_aig = balance( aig, {balance_fn}, ps );
   \endverbatim
 */
template<class Ntk, class CostFn = unit_cost<Ntk>>
Ntk balancing( Ntk const& ntk, rebalancing_function_t<Ntk> const& rebalancing_fn = {}, balancing_params const& ps = {}, balancing_stats* pst = nullptr )
{
  static_assert( is_network_type_v<Ntk>, "Ntk is not a network type" );
  static_assert( has_create_not_v<Ntk>, "Ntk does not implement the create_not method" );
  static_assert( has_create_pi_v<Ntk>, "Ntk does not implement the create_pi method" );
  static_assert( has_create_po_v<Ntk>, "Ntk does not implement the create_po method" );
  static_assert( has_foreach_pi_v<Ntk>, "Ntk does not implement the foreach_pi method" );
  static_assert( has_foreach_po_v<Ntk>, "Ntk does not implement the foreach_po method" );
  static_assert( has_get_constant_v<Ntk>, "Ntk does not implement the get_constant method" );
  static_assert( has_get_node_v<Ntk>, "Ntk does not implement the get_node method" );
  static_assert( has_is_complemented_v<Ntk>, "Ntk does not implement the is_complemented method" );
  static_assert( has_is_constant_v<Ntk>, "Ntk does not implement the is_constant method" );
  static_assert( has_is_pi_v<Ntk>, "Ntk does not implement the is_pi method" );
  static_assert( has_node_to_index_v<Ntk>, "Ntk does not implement the node_to_index method" );
  static_assert( has_size_v<Ntk>, "Ntk does not implement the size method" );

  balancing_stats st;
  const auto dest = detail::balancing_impl<Ntk, CostFn>{ntk, rebalancing_fn, ps, st}.run();

  if ( pst )
  {
    *pst = st;
  }
  if ( ps.verbose )
  {
    st.report();
  }

  return dest;
}

} // namespace mockturtle
<|endoftext|>


<commit_before>#include "common.h"
#include "World.h"
#include "PositionComponent.h"
#include "PlayerCameraComponent.h"

void World::Init() {

}

void World::Update(DeltaTicks &, std::vector<Object *> &) {
	chunks.With([] (ChunksType &chunks) {
		//INFO(chunks.size());
	});

	if(cameraObj == nullptr) { return; }
	auto camera = cameraObj->Get<PlayerCameraComponent>();
	if(camera != nullptr) {
		auto pos = cameraObj->Get<PositionComponent>();
		if(pos != nullptr) {
			const unsigned char distance = 6;
			auto chunkSizeF = glm::fvec3(chunkSize);
			auto keyBase = glm::ivec3(glm::floor(pos->position.To<glm::fvec3>()) / chunkSizeF);
			auto jobM = engine->systems.Get<JobManager>();

			/* clean up chunks outside distance */
			chunks.With([this, distance, &keyBase] (ChunksType &chunks) {
				for(auto it = chunks.begin(); it != chunks.end();) {
					auto &keyTuple = it->first;
					auto obj = std::get<1>(it->second);

					if(abs(std::get<0>(keyTuple) -keyBase.x) > distance ||
					   abs(std::get<1>(keyTuple) -keyBase.y) > distance ||
					   abs(std::get<2>(keyTuple) -keyBase.z) > distance) {
						auto &status = std::get<0>(it->second);
						switch(status) {
						case ChunkStatus::Generating:
							status = ChunkStatus::Dying;
							break;
						case ChunkStatus::Alive:
						case ChunkStatus::Dead:
							if(obj != nullptr) {
								engine->RemoveObject(obj, false);
								obj->Pool();
							}
							chunks.erase(it++);
							continue;
						}
					}
					++it;
				}
			});

			for(int d = 0; d <= distance; ++d) {
				for(int x = -d; x <= d; ++x) {
					for(int y = -d; y <= d; ++y) {
						for(int z = -d; z <= d; ++z) {
							auto key = keyBase + glm::ivec3(x, y, z);
							auto keyTuple = std::make_tuple(key.x, key.y, key.z);

							if(chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
								return chunks.find(keyTuple) == chunks.end();
							})) {
								chunks.With([&keyTuple] (ChunksType &chunks) {
									chunks.emplace(keyTuple, std::make_tuple(ChunkStatus::Generating, nullptr));
								});
								jobM->Do([this, jobM, key, keyTuple, chunkSizeF] () {
									auto dead = chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
										auto &status = std::get<0>(chunks.at(keyTuple));
										if(status == ChunkStatus::Dying) {
											status = ChunkStatus::Dead;
											return true;
										} else { return false; }
									});
									if(dead) { return; }

									auto data = Generate(keyTuple);
									auto chunkObj = Chunk::New(chunkSize.x, chunkSize.y, chunkSize.z, std::move(data));
									auto pos = chunkObj->Get<PositionComponent>();
									auto chunkPos = glm::fvec3(key) * chunkSizeF;
									pos->position = Point(chunkPos.x, chunkPos.y, chunkPos.z + chunkSize.z, 1);

									jobM->Do([this, keyTuple, key, chunkSizeF, chunkObj] () {
										engine->AddObject(chunkObj);
										chunks.With([&keyTuple, chunkObj] (ChunksType &chunks) {
											chunks.at(keyTuple) = std::make_tuple(ChunkStatus::Alive, chunkObj);
										});
									}, JobPriority::High, JobThread::Main);
								}, JobPriority::Normal, JobThread::Worker);
							}
						}
					}
				}
			}
		}
	}
}

void World::Destroy() {

}

void World::ObjectAdded(Object *obj) {
	auto camera = obj->Get<PlayerCameraComponent>();
	if(camera != nullptr) {
		cameraObj = obj;
	}
}

std::vector<bool> World::Generate(const ChunkKeyType &keyTuple) const {
	/*const float start = -0.5, end = -0;
	static double factor = 1.0f;
	factor /= 1.0001f;
	auto r = factor * (start - end) + end;*/

	const float scale = 0.5f;
	const float scaleX = scale, scaleY = scale * 2, scaleZ = scale;

	std::vector<bool> blocks;
	blocks.resize(chunkSize.x * chunkSize.y * chunkSize.z);

	float xIncr = 1.0f / chunkSize.x, yIncr = 1.0f / chunkSize.y, zIncr = 1.0f / chunkSize.z;
	int i = 0;
	for(float z = 0; z < 1; z += zIncr) {
		for(float x = 0; x < 1; x += xIncr) {
			for(float y = 0; y < 1; y += yIncr) {
				double random = noise.eval(
					( std::get<0>(keyTuple) + x) * scaleX,
					( std::get<1>(keyTuple) + y) * scaleY,
					(-std::get<2>(keyTuple) + z) * scaleZ
				);
				blocks.at(i++) = random > 0.25f;
			}
		}
	}
	return blocks;
}
<commit_msg>Tweaked world generation cave factor<commit_after>#include "common.h"
#include "World.h"
#include "PositionComponent.h"
#include "PlayerCameraComponent.h"

void World::Init() {

}

void World::Update(DeltaTicks &, std::vector<Object *> &) {
	chunks.With([] (ChunksType &chunks) {
		//INFO(chunks.size());
	});

	if(cameraObj == nullptr) { return; }
	auto camera = cameraObj->Get<PlayerCameraComponent>();
	if(camera != nullptr) {
		auto pos = cameraObj->Get<PositionComponent>();
		if(pos != nullptr) {
			const unsigned char distance = 6;

			auto chunkSizeF = glm::fvec3(chunkSize);
			auto keyBase = glm::ivec3(glm::floor(pos->position.To<glm::fvec3>()) / chunkSizeF);
			auto jobM = engine->systems.Get<JobManager>();

			/* clean up chunks outside distance */
			chunks.With([this, distance, &keyBase] (ChunksType &chunks) {
				for(auto it = chunks.begin(); it != chunks.end();) {
					auto &keyTuple = it->first;
					auto obj = std::get<1>(it->second);

					if(abs(std::get<0>(keyTuple) -keyBase.x) > distance ||
					   abs(std::get<1>(keyTuple) -keyBase.y) > distance ||
					   abs(std::get<2>(keyTuple) -keyBase.z) > distance) {
						auto &status = std::get<0>(it->second);
						switch(status) {
						case ChunkStatus::Generating:
							status = ChunkStatus::Dying;
							break;
						case ChunkStatus::Alive:
						case ChunkStatus::Dead:
							if(obj != nullptr) {
								engine->RemoveObject(obj, false);
								obj->Pool();
							}
							chunks.erase(it++);
							continue;
						}
					}
					++it;
				}
			});

			for(int d = 0; d <= distance; ++d) {
				for(int x = -d; x <= d; ++x) {
					for(int y = -d; y <= d; ++y) {
						for(int z = -d; z <= d; ++z) {
							auto key = keyBase + glm::ivec3(x, y, z);
							auto keyTuple = std::make_tuple(key.x, key.y, key.z);

							if(chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
								return chunks.find(keyTuple) == chunks.end();
							})) {
								chunks.With([&keyTuple] (ChunksType &chunks) {
									chunks.emplace(keyTuple, std::make_tuple(ChunkStatus::Generating, nullptr));
								});
								jobM->Do([this, jobM, key, keyTuple, chunkSizeF] () {
									auto dead = chunks.With<bool>([&keyTuple] (ChunksType &chunks) {
										auto &status = std::get<0>(chunks.at(keyTuple));
										if(status == ChunkStatus::Dying) {
											status = ChunkStatus::Dead;
											return true;
										} else { return false; }
									});
									if(dead) { return; }

									auto data = Generate(keyTuple);
									auto chunkObj = Chunk::New(chunkSize.x, chunkSize.y, chunkSize.z, std::move(data));
									auto pos = chunkObj->Get<PositionComponent>();
									auto chunkPos = glm::fvec3(key) * chunkSizeF;
									pos->position = Point(chunkPos.x, chunkPos.y, chunkPos.z + chunkSize.z, 1);

									jobM->Do([this, keyTuple, key, chunkSizeF, chunkObj] () {
										engine->AddObject(chunkObj);
										chunks.With([&keyTuple, chunkObj] (ChunksType &chunks) {
											chunks.at(keyTuple) = std::make_tuple(ChunkStatus::Alive, chunkObj);
										});
									}, JobPriority::High, JobThread::Main);
								}, JobPriority::Normal, JobThread::Worker);
							}
						}
					}
				}
			}
		}
	}
}

void World::Destroy() {

}

void World::ObjectAdded(Object *obj) {
	auto camera = obj->Get<PlayerCameraComponent>();
	if(camera != nullptr) {
		cameraObj = obj;
	}
}

std::vector<bool> World::Generate(const ChunkKeyType &keyTuple) const {
	/*const float start = -0.5, end = -0;
	static double factor = 1.0f;
	factor /= 1.0001f;
	auto r = factor * (start - end) + end;*/

	const float scale = 0.5f;
	const float scaleX = scale, scaleY = scale * 2, scaleZ = scale;

	std::vector<bool> blocks;
	blocks.resize(chunkSize.x * chunkSize.y * chunkSize.z);

	float xIncr = 1.0f / chunkSize.x, yIncr = 1.0f / chunkSize.y, zIncr = 1.0f / chunkSize.z;
	int i = 0;
	for(float z = 0; z < 1; z += zIncr) {
		for(float x = 0; x < 1; x += xIncr) {
			for(float y = 0; y < 1; y += yIncr) {
				double random = noise.eval(
					( std::get<0>(keyTuple) + x) * scaleX,
					( std::get<1>(keyTuple) + y) * scaleY,
					(-std::get<2>(keyTuple) + z) * scaleZ
				);
				blocks.at(i++) = random > 0.45f;
			}
		}
	}
	return blocks;
}
<|endoftext|>


<commit_before>// ----------------------------------------------------------------------------
// Callbacks.cpp
//
//
// Authors:
// Peter Polidoro polidorop@janelia.hhmi.org
// ----------------------------------------------------------------------------
#include "Callbacks.h"

namespace callbacks
{
// Callbacks must be non-blocking (avoid 'delay')
//
// modular_device.getParameterValue must be cast to either:
// const char*
// long
// double
// bool
// ArduinoJson::JsonArray&
// ArduinoJson::JsonObject&
//
// For more info read about ArduinoJson parsing https://github.com/janelia-arduino/ArduinoJson
//
// modular_device.getSavedVariableValue type must match the saved variable default type
// modular_device.setSavedVariableValue type must match the saved variable default type

void executeStandaloneCallbackCallback()
{
  controller.executeStandaloneCallback();
}

void getDspVar1Callback()
{
  int value = controller.getDspVar1();
  modular_device.addResultToResponse(value);
}

void setDspVar1Callback()
{
  long value = modular_device.getParameterValue(constants::dsp_var1_parameter_name);
  controller.setDspVar1(value);
}

void getIntVar1Callback()
{
  uint8_t value = controller.getIntVar1();
  modular_device.addResultToResponse(value);
}

void setIntVar1Callback()
{
  long value = modular_device.getParameterValue(constants::int_var1_parameter_name);
  controller.setIntVar1(value);
}

void getIntVar2Callback()
{
  uint8_t value = controller.getIntVar2();
  modular_device.addResultToResponse(value);
}

void setIntVar2Callback()
{
  long value = modular_device.getParameterValue(constants::int_var2_parameter_name);
  controller.setIntVar2(value);
}

// Standalone Callbacks
void addIntVar1ToDspVar1Callback()
{
  int dis_var1 = controller.getDspVar1();
  int int_var1 = controller.getIntVar1();
  controller.setDspVar1(dis_var1+int_var1);
}

void subIntVar2FromDspVar1Callback()
{
  int dis_var1 = controller.getDspVar1();
  int int_var2 = controller.getIntVar2();
  controller.setDspVar1(dis_var1-int_var2);
}
}
<commit_msg>addToResponse -> writeToResponse.<commit_after>// ----------------------------------------------------------------------------
// Callbacks.cpp
//
//
// Authors:
// Peter Polidoro polidorop@janelia.hhmi.org
// ----------------------------------------------------------------------------
#include "Callbacks.h"

namespace callbacks
{
// Callbacks must be non-blocking (avoid 'delay')
//
// modular_device.getParameterValue must be cast to either:
// const char*
// long
// double
// bool
// ArduinoJson::JsonArray&
// ArduinoJson::JsonObject&
//
// For more info read about ArduinoJson parsing https://github.com/janelia-arduino/ArduinoJson
//
// modular_device.getSavedVariableValue type must match the saved variable default type
// modular_device.setSavedVariableValue type must match the saved variable default type

void executeStandaloneCallbackCallback()
{
  controller.executeStandaloneCallback();
}

void getDspVar1Callback()
{
  int value = controller.getDspVar1();
  modular_device.writeResultToResponse(value);
}

void setDspVar1Callback()
{
  long value = modular_device.getParameterValue(constants::dsp_var1_parameter_name);
  controller.setDspVar1(value);
}

void getIntVar1Callback()
{
  uint8_t value = controller.getIntVar1();
  modular_device.writeResultToResponse(value);
}

void setIntVar1Callback()
{
  long value = modular_device.getParameterValue(constants::int_var1_parameter_name);
  controller.setIntVar1(value);
}

void getIntVar2Callback()
{
  uint8_t value = controller.getIntVar2();
  modular_device.writeResultToResponse(value);
}

void setIntVar2Callback()
{
  long value = modular_device.getParameterValue(constants::int_var2_parameter_name);
  controller.setIntVar2(value);
}

// Standalone Callbacks
void addIntVar1ToDspVar1Callback()
{
  int dis_var1 = controller.getDspVar1();
  int int_var1 = controller.getIntVar1();
  controller.setDspVar1(dis_var1+int_var1);
}

void subIntVar2FromDspVar1Callback()
{
  int dis_var1 = controller.getDspVar1();
  int int_var2 = controller.getIntVar2();
  controller.setDspVar1(dis_var1-int_var2);
}
}
<|endoftext|>