<commit_before>#include "routine_tracer_funcstats.h"
#include "simulator.h"
#include "core_manager.h"
#include "thread.h"
#include "core.h"
#include "performance_model.h"
#include "log.h"
#include "stats.h"
#include "cache_efficiency_tracker.h"
#include "utils.h"

#include <sstream>

RoutineTracerFunctionStats::RtnThread::RtnThread(RoutineTracerFunctionStats::RtnMaster *master, Thread *thread)
   : RoutineTracerThread(thread)
   , m_master(master)
   , m_current_eip(0)
{
}

void RoutineTracerFunctionStats::RtnThread::functionEnter(IntPtr eip)
{
   functionBegin(eip);
}

void RoutineTracerFunctionStats::RtnThread::functionExit(IntPtr eip)
{
   functionEnd(eip, true);
}

void RoutineTracerFunctionStats::RtnThread::functionChildEnter(IntPtr eip, IntPtr eip_child)
{
   functionEnd(eip, false);
}

void RoutineTracerFunctionStats::RtnThread::functionChildExit(IntPtr eip, IntPtr eip_child)
{
   functionBegin(eip);
}

void RoutineTracerFunctionStats::RtnThread::functionBeginHelper(IntPtr eip, RtnValues& values_start)
{
   m_current_eip = eip;
   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();
   for(ThreadStatsManager::ThreadStatTypeList::const_iterator it = types.begin(); it != types.end(); ++it)
   {
      values_start[*it] = getThreadStat(*it);
   }
}

void RoutineTracerFunctionStats::RtnThread::functionEndHelper(IntPtr eip, UInt64 count)
{
   RtnValues values;
   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();
   for(ThreadStatsManager::ThreadStatTypeList::const_iterator it = types.begin(); it != types.end(); ++it)
   {
      values[*it] = getThreadStat(*it) - m_values_start[*it];
   }
   m_master->updateRoutine(eip, count, values);
}

void RoutineTracerFunctionStats::RtnThread::functionEndFullHelper(const std::deque<IntPtr> &stack, UInt64 count)
{
   RtnValues values;
   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();
   for(auto it = types.begin(); it != types.end(); ++it)
   {
      values[*it] = getThreadStat(*it) - m_values_start_full[stack][*it];
   }
   m_master->updateRoutineFull(stack, count, values);
}

void RoutineTracerFunctionStats::RtnThread::functionBegin(IntPtr eip)
{
   Sim()->getThreadStatsManager()->update(m_thread->getId());

   functionBeginHelper(eip, m_values_start);
   functionBeginHelper(eip, m_values_start_full[m_stack]);

}

void RoutineTracerFunctionStats::RtnThread::functionEnd(IntPtr eip, bool is_function_start)
{
   Sim()->getThreadStatsManager()->update(m_thread->getId());

   functionEndHelper(eip, is_function_start ? 1 : 0);
   functionEndFullHelper(m_stack, is_function_start ? 1 : 0);
}

UInt64 RoutineTracerFunctionStats::RtnThread::getThreadStat(ThreadStatsManager::ThreadStatType type)
{
   return Sim()->getThreadStatsManager()->getThreadStatistic(m_thread->getId(), type);
}

UInt64 RoutineTracerFunctionStats::RtnThread::getCurrentRoutineId()
{
   return m_current_eip;
}

RoutineTracerFunctionStats::RtnMaster::RtnMaster()
{
   ThreadStatNamedStat::registerStat("fp_addsub", "interval_timer", "uop_fp_addsub");
   ThreadStatNamedStat::registerStat("fp_muldiv", "interval_timer", "uop_fp_muldiv");
   ThreadStatNamedStat::registerStat("l2miss", "L2", "load-misses");
   ThreadStatNamedStat::registerStat("l3miss", "L3", "load-misses");
   ThreadStatAggregates::registerStats();
   ThreadStatNamedStat::registerStat("cpiBase", "interval_timer", "cpiBase");
   ThreadStatNamedStat::registerStat("cpiBranchPredictor", "interval_timer", "cpiBranchPredictor");
   ThreadStatCpiMem::registerStat();
   Sim()->getConfig()->setCacheEfficiencyCallbacks(__ce_get_owner, __ce_notify, (UInt64)this);
}

RoutineTracerFunctionStats::RtnMaster::~RtnMaster()
{
   writeResults(Sim()->getConfig()->formatOutputFileName("sim.rtntrace").c_str());
   writeResultsFull(Sim()->getConfig()->formatOutputFileName("sim.rtntracefull").c_str());
}

UInt64 RoutineTracerFunctionStats::RtnMaster::ce_get_owner(core_id_t core_id)
{
   Thread *thread = Sim()->getCoreManager()->getCoreFromID(core_id)->getThread();
   if (thread && m_threads.count(thread->getId()))
      return m_threads[thread->getId()]->getCurrentRoutineId();
   else
      return 0;
}

void RoutineTracerFunctionStats::RtnMaster::ce_notify(bool on_roi_end, UInt64 owner, CacheBlockInfo::BitsUsedType bits_used, UInt32 bits_total)
{
   ScopedLock sl(m_lock);

   IntPtr eip = owner;
   if (m_routines.count(eip))
   {
      m_routines[eip]->m_bits_used += countBits(bits_used);
      m_routines[eip]->m_bits_total += bits_total;
   }
}

RoutineTracerThread* RoutineTracerFunctionStats::RtnMaster::getThreadHandler(Thread *thread)
{
   RtnThread* thread_handler = new RtnThread(this, thread);
   m_threads[thread->getId()] = thread_handler;
   return thread_handler;
}

void RoutineTracerFunctionStats::RtnMaster::addRoutine(IntPtr eip, const char *name, const char *imgname, IntPtr offset, int column, int line, const char *filename)
{
   ScopedLock sl(m_lock);

   if (m_routines.count(eip) == 0)
   {
      m_routines[eip] = new RoutineTracerFunctionStats::Routine(eip, name, imgname, offset, column, line, filename);
   }
}

bool RoutineTracerFunctionStats::RtnMaster::hasRoutine(IntPtr eip)
{
   ScopedLock sl(m_lock);

   return m_routines.count(eip) > 0;
}

void RoutineTracerFunctionStats::RtnMaster::updateRoutine(IntPtr eip, UInt64 calls, RtnValues values)
{
   ScopedLock sl(m_lock);

   if (m_routines.count(eip) == 0)
   {
      m_routines[eip] = new RoutineTracerFunctionStats::Routine(eip, "(unknown)", "(unknown)", 0, 0, 0, "");
   }

   LOG_ASSERT_ERROR(m_routines.count(eip), "Routine %lx not found", eip);

   m_routines[eip]->m_calls += calls;
   for(RtnValues::iterator it = values.begin(); it != values.end(); ++it)
   {
      m_routines[eip]->m_values[it->first] += it->second;
   }
}

void RoutineTracerFunctionStats::RtnMaster::updateRoutineFull(const std::deque<UInt64>& stack, UInt64 calls, RtnValues values)
{
   ScopedLock sl(m_lock);

   LOG_ASSERT_ERROR(m_routines.count(stack.back()), "Routine %lx not found", stack.back());

   if (m_callstack_routines.count(stack) == 0)
   {
      m_callstack_routines[stack] = new RoutineTracerFunctionStats::Routine(*m_routines[stack.back()]);
   }

   m_callstack_routines[stack]->m_calls += calls;
   for(auto it = values.begin(); it != values.end(); ++it)
   {
      m_callstack_routines[stack]->m_values[it->first] += it->second;
   }
}

void RoutineTracerFunctionStats::RtnMaster::writeResults(const char *filename)
{
   FILE *fp = fopen(filename, "w");

   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();

   fprintf(fp, "eip\tname\tsource\tcalls\tbits_used\tbits_total");
   for(ThreadStatsManager::ThreadStatTypeList::const_iterator it = types.begin(); it != types.end(); ++it)
      fprintf(fp, "\t%s", Sim()->getThreadStatsManager()->getThreadStatName(*it));
   fprintf(fp, "\n");

   for(RoutineMap::iterator it = m_routines.begin(); it != m_routines.end(); ++it)
   {
      fprintf(fp, "%" PRIxPTR "\t%s\t%s\t%" PRId64 "\t%" PRId64 "\t%" PRId64,
         it->second->m_eip, it->second->m_name, it->second->m_location,
         it->second->m_calls, it->second->m_bits_used, it->second->m_bits_total);
      for(ThreadStatsManager::ThreadStatTypeList::const_iterator jt = types.begin(); jt != types.end(); ++jt)
         fprintf(fp, "\t%" PRId64, it->second->m_values[*jt]);
      fprintf(fp, "\n");
   }
   fclose(fp);
}

void RoutineTracerFunctionStats::RtnMaster::writeResultsFull(const char *filename)
{
   FILE *fp = fopen(filename, "w");

   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();

   // header line
   fprintf(fp, "stack\tcalls\tbits_used\tbits_total");
   for(ThreadStatsManager::ThreadStatTypeList::const_iterator it = types.begin(); it != types.end(); ++it)
      fprintf(fp, "\t%s", Sim()->getThreadStatsManager()->getThreadStatName(*it));
   fprintf(fp, "\n");

   // first print all routine names
   for(RoutineMap::iterator it = m_routines.begin(); it != m_routines.end(); ++it)
   {
      fprintf(fp, ":%" PRIxPTR "\t%s\t%s\n", it->second->m_eip, it->second->m_name, it->second->m_location);
   }

   // now print context-aware statistics
   for(auto it = m_callstack_routines.begin(); it != m_callstack_routines.end(); ++it)
   {
      std::ostringstream s;
      s << std::hex << it->first.front();
      for (auto kt = ++it->first.begin(); kt != it->first.end(); ++kt)
      {
         s << ":" << std::hex << *kt << std::dec;
      }
      fprintf(fp, "%s\t%" PRId64 "\t%" PRId64 "\t%" PRId64,
         s.str().c_str(), it->second->m_calls, it->second->m_bits_used, it->second->m_bits_total);
      for(ThreadStatsManager::ThreadStatTypeList::const_iterator jt = types.begin(); jt != types.end(); ++jt)
         fprintf(fp, "\t%" PRId64, it->second->m_values[*jt]);
      fprintf(fp, "\n");
   }
   fclose(fp);
}

// Helper class to provide global icount/time statistics

class ThreadStatAggregates
{
   public:
      static void registerStats();
   private:
      static UInt64 callback(ThreadStatsManager::ThreadStatType type, thread_id_t thread_id, Core *core, UInt64 user);
};

void RoutineTracerFunctionStats::ThreadStatAggregates::registerStats()
{
   Sim()->getThreadStatsManager()->registerThreadStatMetric(ThreadStatsManager::DYNAMIC, "global_instructions", callback, (UInt64)GLOBAL_INSTRUCTIONS);
   Sim()->getThreadStatsManager()->registerThreadStatMetric(ThreadStatsManager::DYNAMIC, "global_nonidle_elapsed_time", callback, (UInt64)GLOBAL_NONIDLE_ELAPSED_TIME);
}

UInt64 RoutineTracerFunctionStats::ThreadStatAggregates::callback(ThreadStatsManager::ThreadStatType type, thread_id_t thread_id, Core *core, UInt64 user)
{
   UInt64 result = 0;

   switch(user)
   {
      case GLOBAL_INSTRUCTIONS:
         for(core_id_t core_id = 0; core_id < (core_id_t)Sim()->getConfig()->getApplicationCores(); ++core_id)
            result += Sim()->getCoreManager()->getCoreFromID(core_id)->getPerformanceModel()->getInstructionCount();
         return result;

      case GLOBAL_NONIDLE_ELAPSED_TIME:
         for(core_id_t core_id = 0; core_id < (core_id_t)Sim()->getConfig()->getApplicationCores(); ++core_id)
            result += Sim()->getCoreManager()->getCoreFromID(core_id)->getPerformanceModel()->getNonIdleElapsedTime().getFS();
         return result;

      default:
         LOG_PRINT_ERROR("Unexpected user value %d", user);
   }
}

// Helper class to provide simplified cpiMem component

ThreadStatsManager::ThreadStatType RoutineTracerFunctionStats::ThreadStatCpiMem::registerStat()
{
   ThreadStatCpiMem *tsns = new ThreadStatCpiMem();
   return Sim()->getThreadStatsManager()->registerThreadStatMetric(ThreadStatsManager::DYNAMIC, "cpiMem", callback, (UInt64)tsns);
}

RoutineTracerFunctionStats::ThreadStatCpiMem::ThreadStatCpiMem()
   : m_stats(Sim()->getConfig()->getApplicationCores())
{
   for(core_id_t core_id = 0; core_id < (core_id_t)Sim()->getConfig()->getApplicationCores(); ++core_id)
   {
      for (int h = HitWhere::WHERE_FIRST ; h < HitWhere::NUM_HITWHERES ; h++)
      {
         String metricName = "cpiDataCache" + String(HitWhereString((HitWhere::where_t)h));
         StatsMetricBase *m = Sim()->getStatsManager()->getMetricObject("interval_timer", core_id, metricName);
         LOG_ASSERT_ERROR(m != NULL, "Invalid statistic %s.%d.%s", "interval_timer", core_id, metricName.c_str());
         m_stats[core_id].push_back(m);
      }
   }
}

UInt64 RoutineTracerFunctionStats::ThreadStatCpiMem::callback(ThreadStatsManager::ThreadStatType type, thread_id_t thread_id, Core *core, UInt64 user)
{
   ThreadStatCpiMem* tsns = (ThreadStatCpiMem*)user;
   std::vector<StatsMetricBase*>& stats = tsns->m_stats[core->getId()];

   UInt64 result = 0;
   for(std::vector<StatsMetricBase*>::iterator it = stats.begin(); it != stats.end(); ++it)
      result += (*it)->recordMetric();
   return result;
}
<commit_msg>[rtntracer] Stack-based funcstats output: write location data only for functions that have been called at least once to reduce output file size, ignore extra calls to functionEndFullHelper at ROI-end which have an out-of-date m_stack<commit_after>#include "routine_tracer_funcstats.h"
#include "simulator.h"
#include "core_manager.h"
#include "thread.h"
#include "core.h"
#include "performance_model.h"
#include "log.h"
#include "stats.h"
#include "cache_efficiency_tracker.h"
#include "utils.h"

#include <sstream>

RoutineTracerFunctionStats::RtnThread::RtnThread(RoutineTracerFunctionStats::RtnMaster *master, Thread *thread)
   : RoutineTracerThread(thread)
   , m_master(master)
   , m_current_eip(0)
{
}

void RoutineTracerFunctionStats::RtnThread::functionEnter(IntPtr eip)
{
   functionBegin(eip);
}

void RoutineTracerFunctionStats::RtnThread::functionExit(IntPtr eip)
{
   functionEnd(eip, true);
}

void RoutineTracerFunctionStats::RtnThread::functionChildEnter(IntPtr eip, IntPtr eip_child)
{
   functionEnd(eip, false);
}

void RoutineTracerFunctionStats::RtnThread::functionChildExit(IntPtr eip, IntPtr eip_child)
{
   functionBegin(eip);
}

void RoutineTracerFunctionStats::RtnThread::functionBeginHelper(IntPtr eip, RtnValues& values_start)
{
   m_current_eip = eip;
   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();
   for(ThreadStatsManager::ThreadStatTypeList::const_iterator it = types.begin(); it != types.end(); ++it)
   {
      values_start[*it] = getThreadStat(*it);
   }
}

void RoutineTracerFunctionStats::RtnThread::functionEndHelper(IntPtr eip, UInt64 count)
{
   RtnValues values;
   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();
   for(ThreadStatsManager::ThreadStatTypeList::const_iterator it = types.begin(); it != types.end(); ++it)
   {
      values[*it] = getThreadStat(*it) - m_values_start[*it];
   }
   m_master->updateRoutine(eip, count, values);
}

void RoutineTracerFunctionStats::RtnThread::functionEndFullHelper(const std::deque<IntPtr> &stack, UInt64 count)
{
   RtnValues values;
   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();
   for(auto it = types.begin(); it != types.end(); ++it)
   {
      values[*it] = getThreadStat(*it) - m_values_start_full[stack][*it];
   }
   m_master->updateRoutineFull(stack, count, values);
}

void RoutineTracerFunctionStats::RtnThread::functionBegin(IntPtr eip)
{
   Sim()->getThreadStatsManager()->update(m_thread->getId());

   functionBeginHelper(eip, m_values_start);
   functionBeginHelper(eip, m_values_start_full[m_stack]);

}

void RoutineTracerFunctionStats::RtnThread::functionEnd(IntPtr eip, bool is_function_start)
{
   Sim()->getThreadStatsManager()->update(m_thread->getId());

   functionEndHelper(eip, is_function_start ? 1 : 0);
   // Ignore simulated stack unwind at end of ROI (m_stack isn't kept up-to-date during this)
   if (eip == m_stack.back())
      functionEndFullHelper(m_stack, is_function_start ? 1 : 0);
}

UInt64 RoutineTracerFunctionStats::RtnThread::getThreadStat(ThreadStatsManager::ThreadStatType type)
{
   return Sim()->getThreadStatsManager()->getThreadStatistic(m_thread->getId(), type);
}

UInt64 RoutineTracerFunctionStats::RtnThread::getCurrentRoutineId()
{
   return m_current_eip;
}

RoutineTracerFunctionStats::RtnMaster::RtnMaster()
{
   ThreadStatNamedStat::registerStat("fp_addsub", "interval_timer", "uop_fp_addsub");
   ThreadStatNamedStat::registerStat("fp_muldiv", "interval_timer", "uop_fp_muldiv");
   ThreadStatNamedStat::registerStat("l2miss", "L2", "load-misses");
   ThreadStatNamedStat::registerStat("l3miss", "L3", "load-misses");
   ThreadStatAggregates::registerStats();
   ThreadStatNamedStat::registerStat("cpiBase", "interval_timer", "cpiBase");
   ThreadStatNamedStat::registerStat("cpiBranchPredictor", "interval_timer", "cpiBranchPredictor");
   ThreadStatCpiMem::registerStat();
   Sim()->getConfig()->setCacheEfficiencyCallbacks(__ce_get_owner, __ce_notify, (UInt64)this);
}

RoutineTracerFunctionStats::RtnMaster::~RtnMaster()
{
   writeResults(Sim()->getConfig()->formatOutputFileName("sim.rtntrace").c_str());
   writeResultsFull(Sim()->getConfig()->formatOutputFileName("sim.rtntracefull").c_str());
}

UInt64 RoutineTracerFunctionStats::RtnMaster::ce_get_owner(core_id_t core_id)
{
   Thread *thread = Sim()->getCoreManager()->getCoreFromID(core_id)->getThread();
   if (thread && m_threads.count(thread->getId()))
      return m_threads[thread->getId()]->getCurrentRoutineId();
   else
      return 0;
}

void RoutineTracerFunctionStats::RtnMaster::ce_notify(bool on_roi_end, UInt64 owner, CacheBlockInfo::BitsUsedType bits_used, UInt32 bits_total)
{
   ScopedLock sl(m_lock);

   IntPtr eip = owner;
   if (m_routines.count(eip))
   {
      m_routines[eip]->m_bits_used += countBits(bits_used);
      m_routines[eip]->m_bits_total += bits_total;
   }
}

RoutineTracerThread* RoutineTracerFunctionStats::RtnMaster::getThreadHandler(Thread *thread)
{
   RtnThread* thread_handler = new RtnThread(this, thread);
   m_threads[thread->getId()] = thread_handler;
   return thread_handler;
}

void RoutineTracerFunctionStats::RtnMaster::addRoutine(IntPtr eip, const char *name, const char *imgname, IntPtr offset, int column, int line, const char *filename)
{
   ScopedLock sl(m_lock);

   if (m_routines.count(eip) == 0)
   {
      m_routines[eip] = new RoutineTracerFunctionStats::Routine(eip, name, imgname, offset, column, line, filename);
   }
}

bool RoutineTracerFunctionStats::RtnMaster::hasRoutine(IntPtr eip)
{
   ScopedLock sl(m_lock);

   return m_routines.count(eip) > 0;
}

void RoutineTracerFunctionStats::RtnMaster::updateRoutine(IntPtr eip, UInt64 calls, RtnValues values)
{
   ScopedLock sl(m_lock);

   if (m_routines.count(eip) == 0)
   {
      m_routines[eip] = new RoutineTracerFunctionStats::Routine(eip, "(unknown)", "(unknown)", 0, 0, 0, "");
   }

   LOG_ASSERT_ERROR(m_routines.count(eip), "Routine %lx not found", eip);

   m_routines[eip]->m_calls += calls;
   for(RtnValues::iterator it = values.begin(); it != values.end(); ++it)
   {
      m_routines[eip]->m_values[it->first] += it->second;
   }
}

void RoutineTracerFunctionStats::RtnMaster::updateRoutineFull(const std::deque<UInt64>& stack, UInt64 calls, RtnValues values)
{
   ScopedLock sl(m_lock);

   LOG_ASSERT_ERROR(m_routines.count(stack.back()), "Routine %lx not found", stack.back());

   if (m_callstack_routines.count(stack) == 0)
   {
      m_callstack_routines[stack] = new RoutineTracerFunctionStats::Routine(*m_routines[stack.back()]);
   }

   m_callstack_routines[stack]->m_calls += calls;
   for(auto it = values.begin(); it != values.end(); ++it)
   {
      m_callstack_routines[stack]->m_values[it->first] += it->second;
   }
}

void RoutineTracerFunctionStats::RtnMaster::writeResults(const char *filename)
{
   FILE *fp = fopen(filename, "w");

   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();

   fprintf(fp, "eip\tname\tsource\tcalls\tbits_used\tbits_total");
   for(ThreadStatsManager::ThreadStatTypeList::const_iterator it = types.begin(); it != types.end(); ++it)
      fprintf(fp, "\t%s", Sim()->getThreadStatsManager()->getThreadStatName(*it));
   fprintf(fp, "\n");

   for(RoutineMap::iterator it = m_routines.begin(); it != m_routines.end(); ++it)
   {
      fprintf(fp, "%" PRIxPTR "\t%s\t%s\t%" PRId64 "\t%" PRId64 "\t%" PRId64,
         it->second->m_eip, it->second->m_name, it->second->m_location,
         it->second->m_calls, it->second->m_bits_used, it->second->m_bits_total);
      for(ThreadStatsManager::ThreadStatTypeList::const_iterator jt = types.begin(); jt != types.end(); ++jt)
         fprintf(fp, "\t%" PRId64, it->second->m_values[*jt]);
      fprintf(fp, "\n");
   }
   fclose(fp);
}

void RoutineTracerFunctionStats::RtnMaster::writeResultsFull(const char *filename)
{
   FILE *fp = fopen(filename, "w");

   const ThreadStatsManager::ThreadStatTypeList& types = Sim()->getThreadStatsManager()->getThreadStatTypes();

   // header line
   fprintf(fp, "stack\tcalls\tbits_used\tbits_total");
   for(ThreadStatsManager::ThreadStatTypeList::const_iterator it = types.begin(); it != types.end(); ++it)
      fprintf(fp, "\t%s", Sim()->getThreadStatsManager()->getThreadStatName(*it));
   fprintf(fp, "\n");

   // first print all routine names
   for(RoutineMap::iterator it = m_routines.begin(); it != m_routines.end(); ++it)
   {
      if (it->second->m_calls)
         fprintf(fp, ":%" PRIxPTR "\t%s\t%s\n", it->second->m_eip, it->second->m_name, it->second->m_location);
   }

   // now print context-aware statistics
   for(auto it = m_callstack_routines.begin(); it != m_callstack_routines.end(); ++it)
   {
      std::ostringstream s;
      s << std::hex << it->first.front();
      for (auto kt = ++it->first.begin(); kt != it->first.end(); ++kt)
      {
         s << ":" << std::hex << *kt << std::dec;
      }
      fprintf(fp, "%s\t%" PRId64 "\t%" PRId64 "\t%" PRId64,
         s.str().c_str(), it->second->m_calls, it->second->m_bits_used, it->second->m_bits_total);
      for(ThreadStatsManager::ThreadStatTypeList::const_iterator jt = types.begin(); jt != types.end(); ++jt)
         fprintf(fp, "\t%" PRId64, it->second->m_values[*jt]);
      fprintf(fp, "\n");
   }
   fclose(fp);
}

// Helper class to provide global icount/time statistics

class ThreadStatAggregates
{
   public:
      static void registerStats();
   private:
      static UInt64 callback(ThreadStatsManager::ThreadStatType type, thread_id_t thread_id, Core *core, UInt64 user);
};

void RoutineTracerFunctionStats::ThreadStatAggregates::registerStats()
{
   Sim()->getThreadStatsManager()->registerThreadStatMetric(ThreadStatsManager::DYNAMIC, "global_instructions", callback, (UInt64)GLOBAL_INSTRUCTIONS);
   Sim()->getThreadStatsManager()->registerThreadStatMetric(ThreadStatsManager::DYNAMIC, "global_nonidle_elapsed_time", callback, (UInt64)GLOBAL_NONIDLE_ELAPSED_TIME);
}

UInt64 RoutineTracerFunctionStats::ThreadStatAggregates::callback(ThreadStatsManager::ThreadStatType type, thread_id_t thread_id, Core *core, UInt64 user)
{
   UInt64 result = 0;

   switch(user)
   {
      case GLOBAL_INSTRUCTIONS:
         for(core_id_t core_id = 0; core_id < (core_id_t)Sim()->getConfig()->getApplicationCores(); ++core_id)
            result += Sim()->getCoreManager()->getCoreFromID(core_id)->getPerformanceModel()->getInstructionCount();
         return result;

      case GLOBAL_NONIDLE_ELAPSED_TIME:
         for(core_id_t core_id = 0; core_id < (core_id_t)Sim()->getConfig()->getApplicationCores(); ++core_id)
            result += Sim()->getCoreManager()->getCoreFromID(core_id)->getPerformanceModel()->getNonIdleElapsedTime().getFS();
         return result;

      default:
         LOG_PRINT_ERROR("Unexpected user value %d", user);
   }
}

// Helper class to provide simplified cpiMem component

ThreadStatsManager::ThreadStatType RoutineTracerFunctionStats::ThreadStatCpiMem::registerStat()
{
   ThreadStatCpiMem *tsns = new ThreadStatCpiMem();
   return Sim()->getThreadStatsManager()->registerThreadStatMetric(ThreadStatsManager::DYNAMIC, "cpiMem", callback, (UInt64)tsns);
}

RoutineTracerFunctionStats::ThreadStatCpiMem::ThreadStatCpiMem()
   : m_stats(Sim()->getConfig()->getApplicationCores())
{
   for(core_id_t core_id = 0; core_id < (core_id_t)Sim()->getConfig()->getApplicationCores(); ++core_id)
   {
      for (int h = HitWhere::WHERE_FIRST ; h < HitWhere::NUM_HITWHERES ; h++)
      {
         String metricName = "cpiDataCache" + String(HitWhereString((HitWhere::where_t)h));
         StatsMetricBase *m = Sim()->getStatsManager()->getMetricObject("interval_timer", core_id, metricName);
         LOG_ASSERT_ERROR(m != NULL, "Invalid statistic %s.%d.%s", "interval_timer", core_id, metricName.c_str());
         m_stats[core_id].push_back(m);
      }
   }
}

UInt64 RoutineTracerFunctionStats::ThreadStatCpiMem::callback(ThreadStatsManager::ThreadStatType type, thread_id_t thread_id, Core *core, UInt64 user)
{
   ThreadStatCpiMem* tsns = (ThreadStatCpiMem*)user;
   std::vector<StatsMetricBase*>& stats = tsns->m_stats[core->getId()];

   UInt64 result = 0;
   for(std::vector<StatsMetricBase*>::iterator it = stats.begin(); it != stats.end(); ++it)
      result += (*it)->recordMetric();
   return result;
}
<|endoftext|>


<commit_before><commit_msg>Ensure that SyncWaiter (base/waitable_event_posix.cc) condition variables cannot be destroyed (pthread_cond_destroy) during a broadcast (pthread_cond_broadcast).  SyncWaiter::Fire now holds the lock until the broadcast is complete.  Given the lock ordering, this guarantees that the condition variable cannot be destroyed until it is safe to do so.  Holding the lock through the broadcast is harmless, as pthread_cond_wait and pthread_cond_timedwait will simply block (if needed) until able to take the lock prior to returning.<commit_after><|endoftext|>


<commit_before>#include "QmitkRenderWindow.h"
#include "mitkOpenGLRenderer.h"
#include "mitkRenderWindow.h"
#include <qcursor.h>
#include "mitkDisplayPositionEvent.h"
//##ModelId=3E1EB4410304
mitk::QmitkRenderWindow::QmitkRenderWindow(mitk::BaseRenderer* renderer, QGLFormat glf, QWidget *parent, const char *name)
  : QGLWidget(glf, parent, name), mitk::RenderWindow(name, renderer)
{
  InitRenderer();
  setFocusPolicy(QWidget::StrongFocus);
  setMouseTracking(true);
}

//##ModelId=3E1EB4410318
mitk::QmitkRenderWindow::QmitkRenderWindow(mitk::BaseRenderer* renderer, QWidget *parent, const char *name)
  : QGLWidget(parent, name), mitk::RenderWindow(name, renderer)
{
  InitRenderer();
  setFocusPolicy(QWidget::StrongFocus);
  setMouseTracking(true);
}

//##ModelId=3E1EB441032C
mitk::QmitkRenderWindow::~QmitkRenderWindow()
{

}

void mitk::QmitkRenderWindow::InitRenderer()
{
  m_InitNeeded = true;
  m_ResizeNeeded = true;

  if(m_Renderer.IsNull())
    m_Renderer = mitk::OpenGLRenderer::New();

  m_Renderer->InitRenderer(this);

  this->setAutoBufferSwap( false );
}

/*!
\brief Initialize the OpenGL Window
*/
//##ModelId=3E33145903C8
void mitk::QmitkRenderWindow::initializeGL()
{
  m_Renderer->Initialize();
}

/*!
\brief Resize the OpenGL Window
*/
//##ModelId=3E33145A001C
void mitk::QmitkRenderWindow::resizeGL( int w, int h )
{
  if(QGLWidget::isVisible())
  {
    m_Renderer->Resize(w, h);
    updateGL();
  }
}

/*!
\brief Render the scene
*/
//##ModelId=3E3314590396
void mitk::QmitkRenderWindow::paintGL( )
{
  // Get the native window ID and pass it
  // to the m_Renderer
  // before we render for the first time...
  if(m_InitNeeded)
  {
    WId nId = winId();
    m_Renderer->SetWindowId( (void*) nId );
    m_InitNeeded = false;
  }
  else
    // rendering when not visible might cause serious problems (program may hang)
    if(QGLWidget::isVisible())
    {
      m_Renderer->Paint();
    }
}

void mitk::QmitkRenderWindow::showEvent ( QShowEvent * )
{
  // when the widget becomes visible the first time, we need to tell vtk the window size
  if(m_ResizeNeeded)
  {
    m_ResizeNeeded=false;
    m_Renderer->InitSize(width(),height());
    //m_Renderer->SetSize(width(),height());
    //    resizeGL(width(),height());
  }
}

//##ModelId=3E3D1D4A00A5
void mitk::QmitkRenderWindow::MakeCurrent()
{
  makeCurrent();
}

void mitk::QmitkRenderWindow::SwapBuffers()
{
  swapBuffers();
};

bool mitk::QmitkRenderWindow::IsSharing () const
{
  return isSharing();
}

//##ModelId=3E6D5DD40306
void mitk::QmitkRenderWindow::mousePressEvent(QMouseEvent *me)
{
  QGLWidget::mousePressEvent(me);
  if (m_Renderer)
  {
    Point2D p(me->x(), me->y());
    mitk::MouseEvent event(NULL, me->type(), me->button(), me->state(), Qt::Key_unknown, p);
    m_Renderer->MousePressEvent(&event);
  }
}

//##ModelId=3E6D5DD4032E
void mitk::QmitkRenderWindow::mouseReleaseEvent(QMouseEvent *me)
{
  QGLWidget::mouseReleaseEvent(me);
  if (m_Renderer) {
    Point2D p(me->x(), me->y());
    mitk::MouseEvent event(NULL, me->type(), me->button(), me->state(), Qt::Key_unknown, p);
    m_Renderer->MouseReleaseEvent(&event);
  }
}

//##ModelId=3E6D5DD40356
void mitk::QmitkRenderWindow::mouseMoveEvent(QMouseEvent *me)
{
  QGLWidget::mouseMoveEvent(me);
  if (m_Renderer) {
    Point2D p(me->x(), me->y());
    mitk::MouseEvent event(NULL, me->type(), me->button(), me->state(), Qt::Key_unknown, p);
    m_Renderer->MouseMoveEvent(&event);
}
}

void mitk::QmitkRenderWindow::wheelEvent(QWheelEvent *we)
{
/*  QGLWidget::wheelEvent(we);
  if (m_Renderer)
    m_Renderer->WheelEvent(we); */
}

//##ModelId=3E6D5DD40388
void mitk::QmitkRenderWindow::keyPressEvent(QKeyEvent *ke)
{
  if (m_Renderer)
  {
    QPoint cp = mapFromGlobal(QCursor::pos());
    mitk::KeyEvent mke(ke->type(), ke->key(), ke->ascii(), ke->state(), ke->text(), ke->isAutoRepeat(), ke->count(), cp.x(), cp.y(), QCursor::pos().x(), QCursor::pos().y());
    m_Renderer->KeyPressEvent(&mke);
    if(mke.isAccepted())
      ke->accept();
  }
}

//##ModelId=3EF59AD202B7
void mitk::QmitkRenderWindow::Update()
{
  update();
};

void mitk::QmitkRenderWindow::Repaint()
{
  updateGL();
};

//##ModelId=3E6D5DD403B0
void mitk::QmitkRenderWindow::focusInEvent(QFocusEvent*)  {};
//##ModelId=3E6D5DD403E2
void mitk::QmitkRenderWindow::focusOutEvent(QFocusEvent*) {};
<commit_msg>fixing bug: string-conversion    ke->text.latin1()<commit_after>#include "QmitkRenderWindow.h"
#include "mitkOpenGLRenderer.h"
#include "mitkRenderWindow.h"
#include <qcursor.h>
#include "mitkDisplayPositionEvent.h"
//##ModelId=3E1EB4410304
mitk::QmitkRenderWindow::QmitkRenderWindow(mitk::BaseRenderer* renderer, QGLFormat glf, QWidget *parent, const char *name)
  : QGLWidget(glf, parent, name), mitk::RenderWindow(name, renderer)
{
  InitRenderer();
  setFocusPolicy(QWidget::StrongFocus);
  setMouseTracking(true);
}

//##ModelId=3E1EB4410318
mitk::QmitkRenderWindow::QmitkRenderWindow(mitk::BaseRenderer* renderer, QWidget *parent, const char *name)
  : QGLWidget(parent, name), mitk::RenderWindow(name, renderer)
{
  InitRenderer();
  setFocusPolicy(QWidget::StrongFocus);
  setMouseTracking(true);
}

//##ModelId=3E1EB441032C
mitk::QmitkRenderWindow::~QmitkRenderWindow()
{

}

void mitk::QmitkRenderWindow::InitRenderer()
{
  m_InitNeeded = true;
  m_ResizeNeeded = true;

  if(m_Renderer.IsNull())
    m_Renderer = mitk::OpenGLRenderer::New();

  m_Renderer->InitRenderer(this);

  this->setAutoBufferSwap( false );
}

/*!
\brief Initialize the OpenGL Window
*/
//##ModelId=3E33145903C8
void mitk::QmitkRenderWindow::initializeGL()
{
  m_Renderer->Initialize();
}

/*!
\brief Resize the OpenGL Window
*/
//##ModelId=3E33145A001C
void mitk::QmitkRenderWindow::resizeGL( int w, int h )
{
  if(QGLWidget::isVisible())
  {
    m_Renderer->Resize(w, h);
    updateGL();
  }
}

/*!
\brief Render the scene
*/
//##ModelId=3E3314590396
void mitk::QmitkRenderWindow::paintGL( )
{
  // Get the native window ID and pass it
  // to the m_Renderer
  // before we render for the first time...
  if(m_InitNeeded)
  {
    WId nId = winId();
    m_Renderer->SetWindowId( (void*) nId );
    m_InitNeeded = false;
  }
  else
    // rendering when not visible might cause serious problems (program may hang)
    if(QGLWidget::isVisible())
    {
      m_Renderer->Paint();
    }
}

void mitk::QmitkRenderWindow::showEvent ( QShowEvent * )
{
  // when the widget becomes visible the first time, we need to tell vtk the window size
  if(m_ResizeNeeded)
  {
    m_ResizeNeeded=false;
    m_Renderer->InitSize(width(),height());
    //m_Renderer->SetSize(width(),height());
    //    resizeGL(width(),height());
  }
}

//##ModelId=3E3D1D4A00A5
void mitk::QmitkRenderWindow::MakeCurrent()
{
  makeCurrent();
}

void mitk::QmitkRenderWindow::SwapBuffers()
{
  swapBuffers();
};

bool mitk::QmitkRenderWindow::IsSharing () const
{
  return isSharing();
}

//##ModelId=3E6D5DD40306
void mitk::QmitkRenderWindow::mousePressEvent(QMouseEvent *me)
{
  QGLWidget::mousePressEvent(me);
  if (m_Renderer)
  {
    Point2D p(me->x(), me->y());
    mitk::MouseEvent event(NULL, me->type(), me->button(), me->state(), Qt::Key_unknown, p);
    m_Renderer->MousePressEvent(&event);
  }
}

//##ModelId=3E6D5DD4032E
void mitk::QmitkRenderWindow::mouseReleaseEvent(QMouseEvent *me)
{
  QGLWidget::mouseReleaseEvent(me);
  if (m_Renderer) {
    Point2D p(me->x(), me->y());
    mitk::MouseEvent event(NULL, me->type(), me->button(), me->state(), Qt::Key_unknown, p);
    m_Renderer->MouseReleaseEvent(&event);
  }
}

//##ModelId=3E6D5DD40356
void mitk::QmitkRenderWindow::mouseMoveEvent(QMouseEvent *me)
{
  QGLWidget::mouseMoveEvent(me);
  if (m_Renderer) {
    Point2D p(me->x(), me->y());
    mitk::MouseEvent event(NULL, me->type(), me->button(), me->state(), Qt::Key_unknown, p);
    m_Renderer->MouseMoveEvent(&event);
}
}

void mitk::QmitkRenderWindow::wheelEvent(QWheelEvent *we)
{
/*  QGLWidget::wheelEvent(we);
  if (m_Renderer)
    m_Renderer->WheelEvent(we); */
}

//##ModelId=3E6D5DD40388
void mitk::QmitkRenderWindow::keyPressEvent(QKeyEvent *ke)
{
  if (m_Renderer)
  {
    QPoint cp = mapFromGlobal(QCursor::pos());
		mitk::KeyEvent mke(ke->type(), ke->key(), ke->ascii(), ke->state(), ke->text().latin1(), ke->isAutoRepeat(), ke->count(), cp.x(), cp.y(), QCursor::pos().x(), QCursor::pos().y());
    m_Renderer->KeyPressEvent(&mke);
    if(mke.isAccepted())
      ke->accept();
  }
}

//##ModelId=3EF59AD202B7
void mitk::QmitkRenderWindow::Update()
{
  update();
};

void mitk::QmitkRenderWindow::Repaint()
{
  updateGL();
};

//##ModelId=3E6D5DD403B0
void mitk::QmitkRenderWindow::focusInEvent(QFocusEvent*)  {};
//##ModelId=3E6D5DD403E2
void mitk::QmitkRenderWindow::focusOutEvent(QFocusEvent*) {};
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: filefmt.hxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: vg $ $Date: 2006-11-01 16:15:28 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SB_FILEFMT_HXX
#define _SB_FILEFMT_HXX

#ifndef _SOLAR_H
#include <tools/solar.h>
#endif

class SvStream;

// Version  2: Datentyp des Returnwerts fuer Publics
// Version  3: neue Opcodes
// Version  4: neue Opcodes
// Version  5: Bug (Ansprung von STATIC-Variablen im Init-Code)
// Version  6: Neue Opcodes und Bug (Globals anlegen, ohne BASIC zu beenden)
// Version  7: Korrektur im WITH-Parsing
// Version  8: Korrektur im IF-Parsing
// Version  9: Init-Code auch mit LEAVE beenden, wenn keine SUB/FUNCTION folgt
// Version  A: #36374 Bei DIM AS NEW... auch Variablen anlegen
// Version  B: #40689 Static umgestellt
// Version  C: #41606 Bug bei Static
// Version  D: #42678 Bug bei RTL-Function spc
// Version  E: #56204 DCREATE, um auch bei DIM AS NEW Arrays anzulegen
// Version  F: #57844 Einfuehrung von SvNumberformat::StringToDouble
// Version 10: #29955 For-Schleifen-Level in Statement-PCodes generieren
// Version 11: #29955 Wegen Build-Inkonsistenzen Neu-Compilieren erzwingen

#define B_LEGACYVERSION 0x00000011L
#define B_CURVERSION 0x00000012L
#define B_EXT_IMG_VERSION 0x00000012L

// Eine Datei enthaelt entweder einen Modul- oder einen Library-Record.
// Diese Records enthalten wiederum weitere Records. Jeder Record hat
// den folgenden Header:

//  UINT16 Kennung
//  UINT32 Laenge des Records ohne Header
//  UINT16 Anzahl Unterelemente

// Alle Datei-Offsets in Records sind relativ zum Start des Moduls!

#define B_LIBRARY       0x4C42      // BL Library Record
#define B_MODULE        0x4D42      // BM Module Record
#define B_NAME          0x4E4D      // MN module name
#define B_COMMENT       0x434D      // MC comment
#define B_SOURCE        0x4353      // SC source code
#define B_PCODE         0x4350      // PC p-code
#define B_OLDPUBLICS    0x7550      // Pu publics
#define B_PUBLICS       0x5550      // PU publics
#define B_POOLDIR       0x4450      // PD symbol pool directory
#define B_SYMPOOL       0x5953      // SY symbol pool
#define B_STRINGPOOL    0x5453      // ST symbol pool
#define B_LINERANGES    0x524C      // LR line ranges for publics
#define B_MODEND        0x454D      // ME module end
#define B_SBXOBJECTS    0x5853      // SX SBX objects

#define EXTENDED_BINARY_MODULES
#ifdef  EXTENDED_BINARY_MODULES
#define B_EXTSOURCE     0x5345      // ES extended source
#endif

// Ein Library Record enthaelt nur Module Records
//  UINT16 Kennung BL
//  UINT32 Laenge des Records
//  UINT16 Anzahl Module

// Ein Modul-Record enthaelt alle anderen Recordtypen
//  UINT16 Kennung BM
//  UINT32 Laenge des Records
//  UINT16 1
// Daten:
//  UINT32 Versionsnummer
//  UINT32 Zeichensatz
//  UINT32 Startadresse Initialisierungscode
//  UINT32 Startadresse Sub Main
//  UINT32 Reserviert
//  UINT32 Reserviert

// Modulname, Kommentar und Quellcode:
//  UINT16 Kennung MN, MC oder SC
//  UINT32 Laenge des Records
//  UINT16 1
// Daten:
//  String-Instanz

// P-Code:
//  UINT16 Kennung PC
//  UINT32 Laenge des Records
//  UINT16 1
// Daten:
//  Der P-Code als Bytesack

// Alle Symbole und Strings werden in einem String-Pool gehalten.
// Verweise auf diese Strings sind in Form eines Indexes in diesen Pool.

// Liste aller Publics:
//  UINT16 Kennung PU oder Pu
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Publics
// Daten fuer jeden Public-Eintrag:
//  UINT16 String-Index
//  UINT32 Startadresse im P-Code-Image (UINT16 fuer alte Publics)
//  UINT16 Datentyp des Returnwertes (ab Version 2)

// Verzeichnis der Symbol-Tabellen:
//  UINT16 Kennung SP
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Symboltabellen
// Daten fuer jede Symboltabelle:
//  UINT16 Stringindex des Namens
//  UINT16 Anzahl Symbole
//  UINT16 Scope-Kennung

// Symboltabelle:
//  UINT16 Kennung SY
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Symbole
// Daten:
//  UINT16 Stringindex des Namens
//  UINT16 Anzahl Symbole
// Daten fuer jedes Symbol:
//  UINT16 Stringindex des Namens
//  UINT16 Datentyp
//  UINT16 Laenge bei STRING*n-Symbolen (0x8000: STATIC-Variable)

// Stringpool:
//  UINT16 Kennung ST
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Strings
// Daten fuer jeden String:
//  UINT32 Offset in den Block aller Strings
// Danach folgt der Block aller Strings, die dort als ASCIIZ-Strings liegen.

// Line Ranges:
//  UINT16 Kennung LR
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Strings
// Daten fuer jedes Public:
//  UINT16 1. Zeile (Sub XXX)
//  UINT16 2. Zeile (End Sub)

// SBX-Objekte:
// UINT16 Anzahl Objekte
// ....   Objektdaten

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

// Service-Routinen (in IMAGE.CXX)

BOOL  SbGood( SvStream& r );
ULONG SbOpenRecord( SvStream&, UINT16 nSignature, UINT16 nElem );
void  SbCloseRecord( SvStream&, ULONG );

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.6.148); FILE MERGED 2008/04/01 15:01:52 thb 1.6.148.2: #i85898# Stripping all external header guards 2008/03/28 16:07:26 rt 1.6.148.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: filefmt.hxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SB_FILEFMT_HXX
#define _SB_FILEFMT_HXX

#include <tools/solar.h>

class SvStream;

// Version  2: Datentyp des Returnwerts fuer Publics
// Version  3: neue Opcodes
// Version  4: neue Opcodes
// Version  5: Bug (Ansprung von STATIC-Variablen im Init-Code)
// Version  6: Neue Opcodes und Bug (Globals anlegen, ohne BASIC zu beenden)
// Version  7: Korrektur im WITH-Parsing
// Version  8: Korrektur im IF-Parsing
// Version  9: Init-Code auch mit LEAVE beenden, wenn keine SUB/FUNCTION folgt
// Version  A: #36374 Bei DIM AS NEW... auch Variablen anlegen
// Version  B: #40689 Static umgestellt
// Version  C: #41606 Bug bei Static
// Version  D: #42678 Bug bei RTL-Function spc
// Version  E: #56204 DCREATE, um auch bei DIM AS NEW Arrays anzulegen
// Version  F: #57844 Einfuehrung von SvNumberformat::StringToDouble
// Version 10: #29955 For-Schleifen-Level in Statement-PCodes generieren
// Version 11: #29955 Wegen Build-Inkonsistenzen Neu-Compilieren erzwingen

#define B_LEGACYVERSION 0x00000011L
#define B_CURVERSION 0x00000012L
#define B_EXT_IMG_VERSION 0x00000012L

// Eine Datei enthaelt entweder einen Modul- oder einen Library-Record.
// Diese Records enthalten wiederum weitere Records. Jeder Record hat
// den folgenden Header:

//  UINT16 Kennung
//  UINT32 Laenge des Records ohne Header
//  UINT16 Anzahl Unterelemente

// Alle Datei-Offsets in Records sind relativ zum Start des Moduls!

#define B_LIBRARY       0x4C42      // BL Library Record
#define B_MODULE        0x4D42      // BM Module Record
#define B_NAME          0x4E4D      // MN module name
#define B_COMMENT       0x434D      // MC comment
#define B_SOURCE        0x4353      // SC source code
#define B_PCODE         0x4350      // PC p-code
#define B_OLDPUBLICS    0x7550      // Pu publics
#define B_PUBLICS       0x5550      // PU publics
#define B_POOLDIR       0x4450      // PD symbol pool directory
#define B_SYMPOOL       0x5953      // SY symbol pool
#define B_STRINGPOOL    0x5453      // ST symbol pool
#define B_LINERANGES    0x524C      // LR line ranges for publics
#define B_MODEND        0x454D      // ME module end
#define B_SBXOBJECTS    0x5853      // SX SBX objects

#define EXTENDED_BINARY_MODULES
#ifdef  EXTENDED_BINARY_MODULES
#define B_EXTSOURCE     0x5345      // ES extended source
#endif

// Ein Library Record enthaelt nur Module Records
//  UINT16 Kennung BL
//  UINT32 Laenge des Records
//  UINT16 Anzahl Module

// Ein Modul-Record enthaelt alle anderen Recordtypen
//  UINT16 Kennung BM
//  UINT32 Laenge des Records
//  UINT16 1
// Daten:
//  UINT32 Versionsnummer
//  UINT32 Zeichensatz
//  UINT32 Startadresse Initialisierungscode
//  UINT32 Startadresse Sub Main
//  UINT32 Reserviert
//  UINT32 Reserviert

// Modulname, Kommentar und Quellcode:
//  UINT16 Kennung MN, MC oder SC
//  UINT32 Laenge des Records
//  UINT16 1
// Daten:
//  String-Instanz

// P-Code:
//  UINT16 Kennung PC
//  UINT32 Laenge des Records
//  UINT16 1
// Daten:
//  Der P-Code als Bytesack

// Alle Symbole und Strings werden in einem String-Pool gehalten.
// Verweise auf diese Strings sind in Form eines Indexes in diesen Pool.

// Liste aller Publics:
//  UINT16 Kennung PU oder Pu
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Publics
// Daten fuer jeden Public-Eintrag:
//  UINT16 String-Index
//  UINT32 Startadresse im P-Code-Image (UINT16 fuer alte Publics)
//  UINT16 Datentyp des Returnwertes (ab Version 2)

// Verzeichnis der Symbol-Tabellen:
//  UINT16 Kennung SP
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Symboltabellen
// Daten fuer jede Symboltabelle:
//  UINT16 Stringindex des Namens
//  UINT16 Anzahl Symbole
//  UINT16 Scope-Kennung

// Symboltabelle:
//  UINT16 Kennung SY
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Symbole
// Daten:
//  UINT16 Stringindex des Namens
//  UINT16 Anzahl Symbole
// Daten fuer jedes Symbol:
//  UINT16 Stringindex des Namens
//  UINT16 Datentyp
//  UINT16 Laenge bei STRING*n-Symbolen (0x8000: STATIC-Variable)

// Stringpool:
//  UINT16 Kennung ST
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Strings
// Daten fuer jeden String:
//  UINT32 Offset in den Block aller Strings
// Danach folgt der Block aller Strings, die dort als ASCIIZ-Strings liegen.

// Line Ranges:
//  UINT16 Kennung LR
//  UINT32 Laenge des Records
//  UINT16 Anzahl der Strings
// Daten fuer jedes Public:
//  UINT16 1. Zeile (Sub XXX)
//  UINT16 2. Zeile (End Sub)

// SBX-Objekte:
// UINT16 Anzahl Objekte
// ....   Objektdaten

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

// Service-Routinen (in IMAGE.CXX)

BOOL  SbGood( SvStream& r );
ULONG SbOpenRecord( SvStream&, UINT16 nSignature, UINT16 nElem );
void  SbCloseRecord( SvStream&, ULONG );

#endif
<|endoftext|>


<commit_before>#include "perf_precomp.hpp"
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;

typedef std::tr1::tuple<std::string, std::string, int> Cascade_Image_MinSize_t;
typedef perf::TestBaseWithParam<Cascade_Image_MinSize_t> Cascade_Image_MinSize;

PERF_TEST_P( Cascade_Image_MinSize, CascadeClassifier_UMat,
             testing::Combine(
                testing::Values( string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt.xml"),
                                 string("cv/cascadeandhog/cascades/lbpcascade_frontalface.xml") ),
                testing::Values( string("cv/shared/lena.png"),
                                 string("cv/cascadeandhog/images/bttf301.png"),
                                 string("cv/cascadeandhog/images/class57.png") ),
                testing::Values(30, 64, 90) ) )
{
    const string cascasePath = get<0>(GetParam());
    const string imagePath   = get<1>(GetParam());
    int min_size = get<2>(GetParam());
    Size minSize(min_size, min_size);

    CascadeClassifier cc( getDataPath(cascasePath) );
    if (cc.empty())
        FAIL() << "Can't load cascade file: " << getDataPath(cascasePath);

    Mat img = imread(getDataPath(imagePath), IMREAD_GRAYSCALE);
    if (img.empty())
        FAIL() << "Can't load source image: " << getDataPath(imagePath);

    vector<Rect> faces;

    equalizeHist(img, img);
    declare.in(img).time(60);

    UMat uimg = img.getUMat(ACCESS_READ);

    while(next())
    {
        faces.clear();

        startTimer();
        cc.detectMultiScale(uimg, faces, 1.1, 3, 0, minSize);
        stopTimer();
    }

    sort(faces.begin(), faces.end(), comparators::RectLess());
    SANITY_CHECK(faces, min_size/5);
}
<commit_msg>switching to `CL_PERF_TEST_P`, adding `safeFinish()` to flush CL queue<commit_after>#include "perf_precomp.hpp"
#include <opencv2/imgproc.hpp>

#include "opencv2/ts/ocl_perf.hpp"

using namespace std;
using namespace cv;
using namespace perf;
using std::tr1::make_tuple;
using std::tr1::get;

typedef std::tr1::tuple<std::string, std::string, int> Cascade_Image_MinSize_t;
typedef perf::TestBaseWithParam<Cascade_Image_MinSize_t> Cascade_Image_MinSize;

OCL_PERF_TEST_P(Cascade_Image_MinSize, CascadeClassifier,
                 testing::Combine(
                    testing::Values( string("cv/cascadeandhog/cascades/haarcascade_frontalface_alt.xml"),
                                     string("cv/cascadeandhog/cascades/lbpcascade_frontalface.xml") ),
                    testing::Values( string("cv/shared/lena.png"),
                                     string("cv/cascadeandhog/images/bttf301.png"),
                                     string("cv/cascadeandhog/images/class57.png") ),
                    testing::Values(30, 64, 90) ) )
{
    const string cascasePath = get<0>(GetParam());
    const string imagePath   = get<1>(GetParam());
    int min_size = get<2>(GetParam());
    Size minSize(min_size, min_size);

    CascadeClassifier cc( getDataPath(cascasePath) );
    if (cc.empty())
        FAIL() << "Can't load cascade file: " << getDataPath(cascasePath);

    Mat img = imread(getDataPath(imagePath), IMREAD_GRAYSCALE);
    if (img.empty())
        FAIL() << "Can't load source image: " << getDataPath(imagePath);

    vector<Rect> faces;

    equalizeHist(img, img);
    declare.in(img).time(60);

    UMat uimg = img.getUMat(ACCESS_READ);

    while(next())
    {
        faces.clear();
        cvtest::ocl::perf::safeFinish();

        startTimer();
        cc.detectMultiScale(uimg, faces, 1.1, 3, 0, minSize);
        stopTimer();
    }

    sort(faces.begin(), faces.end(), comparators::RectLess());
    SANITY_CHECK(faces, min_size/5);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * 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 <filamentapp/Config.h>
#include <filamentapp/FilamentApp.h>

#include <filament/Camera.h>
#include <filament/ColorGrading.h>
#include <filament/Engine.h>
#include <filament/IndexBuffer.h>
#include <filament/Material.h>
#include <filament/RenderableManager.h>
#include <filament/Renderer.h>
#include <filament/Scene.h>
#include <filament/Skybox.h>
#include <filament/TransformManager.h>
#include <filament/VertexBuffer.h>
#include <filament/View.h>

#include <utils/EntityManager.h>

#include <viewer/ViewerGui.h>

#include <camutils/Manipulator.h>

#include <getopt/getopt.h>

#include <math/half.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <math/mat3.h>
#include <math/norm.h>

#include <imgui.h>

#include <imageio/ImageDecoder.h>

#include <fstream>
#include <iostream>
#include <string>

#include "generated/resources/resources.h"

using namespace filament;
using namespace filament::math;
using namespace filament::viewer;

using namespace image;
using namespace utils;

struct App {
    Engine* engine;
    ViewerGui* viewer;
    Config config;
    Camera* mainCamera;

    struct Scene {
        Entity imageEntity;
        VertexBuffer* imageVertexBuffer = nullptr;
        IndexBuffer* imageIndexBuffer = nullptr;
        Material* imageMaterial = nullptr;
        Texture* imageTexture = nullptr;
        Texture* defaultTexture = nullptr;
        TextureSampler sampler;
    } scene;

    bool showImage = false;
    float3 backgroundColor = float3(0.0f);

    // zero-initialized so that the first time through is always dirty.
    ColorGradingSettings lastColorGradingOptions = { 0 };

    ColorGrading* colorGrading = nullptr;
};

static void printUsage(char* name) {
    std::string exec_name(Path(name).getName());
    std::string usage(
        "IMAGE_VIEWER displays the specified image\n"
        "Usage:\n"
        "    IMAGE_VIEWER [options] <image path>\n"
        "Options:\n"
        "   --help, -h\n"
        "       Prints this message\n\n"
        "   --api, -a\n"
        "       Specify the backend API: opengl (default), vulkan, or metal\n\n"
        "   --camera=<camera mode>, -c <camera mode>\n"
        "       Set the camera mode: orbit (default) or flight\n"
        "       Flight mode uses the following controls:\n"
        "           Click and drag the mouse to pan the camera\n"
        "           Use the scroll weel to adjust movement speed\n"
        "           W / S: forward / backward\n"
        "           A / D: left / right\n"
        "           E / Q: up / down\n\n"
    );
    const std::string from("IMAGE_VIEWER");
    for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) {
        usage.replace(pos, from.length(), exec_name);
    }
    std::cout << usage;
}

static int handleCommandLineArguments(int argc, char* argv[], App* app) {
    static constexpr const char* OPTSTR = "ha:c:";
    static const struct option OPTIONS[] = {
        { "help",         no_argument,       nullptr, 'h' },
        { "api",          required_argument, nullptr, 'a' },
        { "camera",       required_argument, nullptr, 'c' },
        { nullptr, 0, nullptr, 0 }
    };
    int opt;
    int option_index = 0;
    while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
        std::string arg(optarg ? optarg : "");
        switch (opt) {
            default:
            case 'h':
                printUsage(argv[0]);
                exit(0);
            case 'a':
                if (arg == "opengl") {
                    app->config.backend = Engine::Backend::OPENGL;
                } else if (arg == "vulkan") {
                    app->config.backend = Engine::Backend::VULKAN;
                } else if (arg == "metal") {
                    app->config.backend = Engine::Backend::METAL;
                } else {
                    std::cerr << "Unrecognized backend. Must be 'opengl'|'vulkan'|'metal'.\n";
                }
                break;
            case 'c':
                if (arg == "flight") {
                    app->config.cameraMode = camutils::Mode::FREE_FLIGHT;
                } else if (arg == "orbit") {
                    app->config.cameraMode = camutils::Mode::ORBIT;
                } else {
                    std::cerr << "Unrecognized camera mode. Must be 'flight'|'orbit'.\n";
                }
                break;
        }
    }
    return optind;
}

static constexpr float4 sFullScreenTriangleVertices[3] = {
        { -1.0f, -1.0f, 1.0f, 1.0f },
        {  3.0f, -1.0f, 1.0f, 1.0f },
        { -1.0f,  3.0f, 1.0f, 1.0f }
};

static const uint16_t sFullScreenTriangleIndices[3] = { 0, 1, 2 };

static void createImageRenderable(Engine* engine, Scene* scene, App& app) {
    auto& em = EntityManager::get();
    Material* material = Material::Builder()
            .package(RESOURCES_IMAGE_DATA, RESOURCES_IMAGE_SIZE)
            .build(*engine);

    VertexBuffer* vertexBuffer = VertexBuffer::Builder()
            .vertexCount(3)
            .bufferCount(1)
            .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT4, 0)
            .build(*engine);

    vertexBuffer->setBufferAt(
            *engine, 0, { sFullScreenTriangleVertices, sizeof(sFullScreenTriangleVertices) });

    IndexBuffer* indexBuffer = IndexBuffer::Builder()
            .indexCount(3)
            .bufferType(IndexBuffer::IndexType::USHORT)
            .build(*engine);

    indexBuffer->setBuffer(*engine,
            { sFullScreenTriangleIndices, sizeof(sFullScreenTriangleIndices) });

    Entity imageEntity = em.create();
    RenderableManager::Builder(1)
            .boundingBox({{}, {1.0f, 1.0f, 1.0f}})
            .material(0, material->getDefaultInstance())
            .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vertexBuffer, indexBuffer, 0, 3)
            .culling(false)
            .build(*engine, imageEntity);

    scene->addEntity(imageEntity);

    app.scene.imageEntity = imageEntity;
    app.scene.imageVertexBuffer = vertexBuffer;
    app.scene.imageIndexBuffer = indexBuffer;
    app.scene.imageMaterial = material;

    Texture* texture = Texture::Builder()
            .width(1)
            .height(1)
            .levels(1)
            .format(Texture::InternalFormat::RGBA8)
            .sampler(Texture::Sampler::SAMPLER_2D)
            .build(*engine);
    static uint32_t pixel = 0;
    Texture::PixelBufferDescriptor buffer(&pixel, 4, Texture::Format::RGBA, Texture::Type::UBYTE);
    texture->setImage(*engine, 0, std::move(buffer));

    app.scene.defaultTexture = texture;
}

static void loadImage(App& app, Engine* engine, Path filename) {
    if (app.scene.imageTexture) {
        engine->destroy(app.scene.imageTexture);
        app.scene.imageTexture = nullptr;
    }

    if (!filename.exists()) {
        std::cerr << "The input image does not exist: " << filename << std::endl;
        app.showImage = false;
        return;
    }

    std::ifstream inputStream(filename, std::ios::binary);
    LinearImage* image = new LinearImage(ImageDecoder::decode(
            inputStream, filename, ImageDecoder::ColorSpace::SRGB));

    if (!image->isValid()) {
        std::cerr << "The input image is invalid: " << filename << std::endl;
        app.showImage = false;
        return;
    }

    inputStream.close();

    uint32_t channels = image->getChannels();
    uint32_t w = image->getWidth();
    uint32_t h = image->getHeight();
    Texture* texture = Texture::Builder()
            .width(w)
            .height(h)
            .levels(0xff)
            .format(channels == 3 ?
                    Texture::InternalFormat::RGB16F : Texture::InternalFormat::RGBA16F)
            .sampler(Texture::Sampler::SAMPLER_2D)
            .build(*engine);

    Texture::PixelBufferDescriptor::Callback freeCallback = [](void* buf, size_t, void* data) {
        delete reinterpret_cast<LinearImage*>(data);
    };

    Texture::PixelBufferDescriptor buffer(
            image->getPixelRef(),
            size_t(w * h * channels * sizeof(float)),
            channels == 3 ? Texture::Format::RGB : Texture::Format::RGBA,
            Texture::Type::FLOAT,
            freeCallback
    );

    texture->setImage(*engine, 0, std::move(buffer));
    texture->generateMipmaps(*engine);

    app.scene.sampler.setMagFilter(TextureSampler::MagFilter::LINEAR);
    app.scene.sampler.setMinFilter(TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR);
    app.scene.sampler.setWrapModeS(TextureSampler::WrapMode::REPEAT);
    app.scene.sampler.setWrapModeT(TextureSampler::WrapMode::REPEAT);

    app.scene.imageTexture = texture;
    app.showImage = true;
}

int main(int argc, char** argv) {
    App app;

    app.config.title = "Filament Image Viewer";

    int optionIndex = handleCommandLineArguments(argc, argv, &app);

    Path filename;
    int num_args = argc - optionIndex;
    if (num_args >= 1) {
        filename = argv[optionIndex];
    }

    auto setup = [&](Engine* engine, View* view, Scene* scene) {
        app.engine = engine;
        app.viewer = new ViewerGui(engine, scene, view, 410);
        app.viewer->getSettings().viewer.autoScaleEnabled = false;
        app.viewer->getSettings().viewer.autoInstancingEnabled = true;
        app.viewer->getSettings().view.bloom.enabled = false;
        app.viewer->getSettings().view.ssao.enabled = false;
        app.viewer->getSettings().view.dithering = Dithering::NONE;
        app.viewer->getSettings().view.antiAliasing = AntiAliasing::NONE;

        createImageRenderable(engine, scene, app);

        loadImage(app, engine, filename);

        app.viewer->setUiCallback([&app] () {
            if (ImGui::CollapsingHeader("Image", ImGuiTreeNodeFlags_DefaultOpen)) {
                ImGui::ColorEdit3("Background color", &app.backgroundColor.r);
            }
        });
    };

    auto cleanup = [&app](Engine* engine, View*, Scene*) {
        engine->destroy(app.scene.imageEntity);
        engine->destroy(app.scene.imageVertexBuffer);
        engine->destroy(app.scene.imageIndexBuffer);
        engine->destroy(app.scene.imageMaterial);
        engine->destroy(app.scene.imageTexture);
        engine->destroy(app.scene.defaultTexture);
        engine->destroy(app.colorGrading);

        delete app.viewer;
    };

    auto gui = [&app](Engine* engine, View* view) {
        app.viewer->updateUserInterface();

        FilamentApp::get().setSidebarWidth(app.viewer->getSidebarWidth());
    };

    auto preRender = [&app](Engine* engine, View* view, Scene* scene, Renderer* renderer) {
        auto& rcm = engine->getRenderableManager();

        // This applies clear options, the skybox mask, and some camera settings.
        Camera& camera = view->getCamera();
        Skybox* skybox = scene->getSkybox();
        applySettings(engine, app.viewer->getSettings().viewer, &camera, skybox, renderer);

        // Check if color grading has changed.
        ColorGradingSettings& options = app.viewer->getSettings().view.colorGrading;
        if (options.enabled) {
            if (options != app.lastColorGradingOptions) {
                ColorGrading *colorGrading = createColorGrading(options, engine);
                engine->destroy(app.colorGrading);
                app.colorGrading = colorGrading;
                app.lastColorGradingOptions = options;
            }
            view->setColorGrading(app.colorGrading);
        } else {
            view->setColorGrading(nullptr);
        }

        if (app.showImage) {
            Texture *texture = app.scene.imageTexture;
            float srcWidth = texture->getWidth();
            float srcHeight = texture->getHeight();
            float dstWidth = view->getViewport().width;
            float dstHeight = view->getViewport().height;

            float srcRatio = srcWidth / srcHeight;
            float dstRatio = dstWidth / dstHeight;

            bool xMajor = dstWidth / srcWidth > dstHeight / srcHeight;

            float sx = 1.0f;
            float sy = dstRatio / srcRatio;

            float tx = 0.0f;
            float ty = ((1.0f - sy) * 0.5f) / sy;

            if (xMajor) {
                sx = srcRatio / dstRatio;
                sy = 1.0;
                tx = ((1.0f - sx) * 0.5f) / sx;
                ty = 0.0f;
            }

            mat3f transform(
                    1.0f / sx,  0.0f,       0.0f,
                    0.0f,       1.0f / sy,  0.0f,
                    -tx,        -ty,         1.0f
            );

            app.scene.imageMaterial->setDefaultParameter("transform", transform);
            app.scene.imageMaterial->setDefaultParameter(
                    "image", app.scene.imageTexture, app.scene.sampler);
        } else {
            app.scene.imageMaterial->setDefaultParameter(
                    "image", app.scene.defaultTexture, app.scene.sampler);
        }

        app.scene.imageMaterial->setDefaultParameter("showImage", app.showImage ? 1 : 0);
        app.scene.imageMaterial->setDefaultParameter(
                "backgroundColor", RgbType::sRGB, app.backgroundColor);
    };

    FilamentApp& filamentApp = FilamentApp::get();

    filamentApp.setDropHandler([&] (std::string path) {
        loadImage(app, app.engine, Path(path));
    });

    filamentApp.run(app.config, setup, cleanup, gui, preRender);

    return 0;
}
<commit_msg>Fix memory leak (#6056)<commit_after>/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * 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 <filamentapp/Config.h>
#include <filamentapp/FilamentApp.h>

#include <filament/Camera.h>
#include <filament/ColorGrading.h>
#include <filament/Engine.h>
#include <filament/IndexBuffer.h>
#include <filament/Material.h>
#include <filament/RenderableManager.h>
#include <filament/Renderer.h>
#include <filament/Scene.h>
#include <filament/Skybox.h>
#include <filament/TransformManager.h>
#include <filament/VertexBuffer.h>
#include <filament/View.h>

#include <utils/EntityManager.h>

#include <viewer/ViewerGui.h>

#include <camutils/Manipulator.h>

#include <getopt/getopt.h>

#include <math/half.h>
#include <math/vec3.h>
#include <math/vec4.h>
#include <math/mat3.h>
#include <math/norm.h>

#include <imgui.h>

#include <imageio/ImageDecoder.h>

#include <fstream>
#include <iostream>
#include <string>

#include "generated/resources/resources.h"

using namespace filament;
using namespace filament::math;
using namespace filament::viewer;

using namespace image;
using namespace utils;

struct App {
    Engine* engine;
    ViewerGui* viewer;
    Config config;
    Camera* mainCamera;

    struct Scene {
        Entity imageEntity;
        VertexBuffer* imageVertexBuffer = nullptr;
        IndexBuffer* imageIndexBuffer = nullptr;
        Material* imageMaterial = nullptr;
        Texture* imageTexture = nullptr;
        Texture* defaultTexture = nullptr;
        TextureSampler sampler;
    } scene;

    bool showImage = false;
    float3 backgroundColor = float3(0.0f);

    // zero-initialized so that the first time through is always dirty.
    ColorGradingSettings lastColorGradingOptions = { 0 };

    ColorGrading* colorGrading = nullptr;
};

static void printUsage(char* name) {
    std::string exec_name(Path(name).getName());
    std::string usage(
        "IMAGE_VIEWER displays the specified image\n"
        "Usage:\n"
        "    IMAGE_VIEWER [options] <image path>\n"
        "Options:\n"
        "   --help, -h\n"
        "       Prints this message\n\n"
        "   --api, -a\n"
        "       Specify the backend API: opengl (default), vulkan, or metal\n\n"
        "   --camera=<camera mode>, -c <camera mode>\n"
        "       Set the camera mode: orbit (default) or flight\n"
        "       Flight mode uses the following controls:\n"
        "           Click and drag the mouse to pan the camera\n"
        "           Use the scroll weel to adjust movement speed\n"
        "           W / S: forward / backward\n"
        "           A / D: left / right\n"
        "           E / Q: up / down\n\n"
    );
    const std::string from("IMAGE_VIEWER");
    for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) {
        usage.replace(pos, from.length(), exec_name);
    }
    std::cout << usage;
}

static int handleCommandLineArguments(int argc, char* argv[], App* app) {
    static constexpr const char* OPTSTR = "ha:c:";
    static const struct option OPTIONS[] = {
        { "help",         no_argument,       nullptr, 'h' },
        { "api",          required_argument, nullptr, 'a' },
        { "camera",       required_argument, nullptr, 'c' },
        { nullptr, 0, nullptr, 0 }
    };
    int opt;
    int option_index = 0;
    while ((opt = getopt_long(argc, argv, OPTSTR, OPTIONS, &option_index)) >= 0) {
        std::string arg(optarg ? optarg : "");
        switch (opt) {
            default:
            case 'h':
                printUsage(argv[0]);
                exit(0);
            case 'a':
                if (arg == "opengl") {
                    app->config.backend = Engine::Backend::OPENGL;
                } else if (arg == "vulkan") {
                    app->config.backend = Engine::Backend::VULKAN;
                } else if (arg == "metal") {
                    app->config.backend = Engine::Backend::METAL;
                } else {
                    std::cerr << "Unrecognized backend. Must be 'opengl'|'vulkan'|'metal'.\n";
                }
                break;
            case 'c':
                if (arg == "flight") {
                    app->config.cameraMode = camutils::Mode::FREE_FLIGHT;
                } else if (arg == "orbit") {
                    app->config.cameraMode = camutils::Mode::ORBIT;
                } else {
                    std::cerr << "Unrecognized camera mode. Must be 'flight'|'orbit'.\n";
                }
                break;
        }
    }
    return optind;
}

static constexpr float4 sFullScreenTriangleVertices[3] = {
        { -1.0f, -1.0f, 1.0f, 1.0f },
        {  3.0f, -1.0f, 1.0f, 1.0f },
        { -1.0f,  3.0f, 1.0f, 1.0f }
};

static const uint16_t sFullScreenTriangleIndices[3] = { 0, 1, 2 };

static void createImageRenderable(Engine* engine, Scene* scene, App& app) {
    auto& em = EntityManager::get();
    Material* material = Material::Builder()
            .package(RESOURCES_IMAGE_DATA, RESOURCES_IMAGE_SIZE)
            .build(*engine);

    VertexBuffer* vertexBuffer = VertexBuffer::Builder()
            .vertexCount(3)
            .bufferCount(1)
            .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT4, 0)
            .build(*engine);

    vertexBuffer->setBufferAt(
            *engine, 0, { sFullScreenTriangleVertices, sizeof(sFullScreenTriangleVertices) });

    IndexBuffer* indexBuffer = IndexBuffer::Builder()
            .indexCount(3)
            .bufferType(IndexBuffer::IndexType::USHORT)
            .build(*engine);

    indexBuffer->setBuffer(*engine,
            { sFullScreenTriangleIndices, sizeof(sFullScreenTriangleIndices) });

    Entity imageEntity = em.create();
    RenderableManager::Builder(1)
            .boundingBox({{}, {1.0f, 1.0f, 1.0f}})
            .material(0, material->getDefaultInstance())
            .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, vertexBuffer, indexBuffer, 0, 3)
            .culling(false)
            .build(*engine, imageEntity);

    scene->addEntity(imageEntity);

    app.scene.imageEntity = imageEntity;
    app.scene.imageVertexBuffer = vertexBuffer;
    app.scene.imageIndexBuffer = indexBuffer;
    app.scene.imageMaterial = material;

    Texture* texture = Texture::Builder()
            .width(1)
            .height(1)
            .levels(1)
            .format(Texture::InternalFormat::RGBA8)
            .sampler(Texture::Sampler::SAMPLER_2D)
            .build(*engine);
    static uint32_t pixel = 0;
    Texture::PixelBufferDescriptor buffer(&pixel, 4, Texture::Format::RGBA, Texture::Type::UBYTE);
    texture->setImage(*engine, 0, std::move(buffer));

    app.scene.defaultTexture = texture;
}

static void loadImage(App& app, Engine* engine, const Path& filename) {
    if (app.scene.imageTexture) {
        engine->destroy(app.scene.imageTexture);
        app.scene.imageTexture = nullptr;
    }

    if (!filename.exists()) {
        std::cerr << "The input image does not exist: " << filename << std::endl;
        app.showImage = false;
        return;
    }

    std::ifstream inputStream(filename, std::ios::binary);
    LinearImage* image = new LinearImage(ImageDecoder::decode(
            inputStream, filename, ImageDecoder::ColorSpace::SRGB));

    if (!image->isValid()) {
        std::cerr << "The input image is invalid: " << filename << std::endl;
        app.showImage = false;
        return;
    }

    inputStream.close();

    uint32_t channels = image->getChannels();
    uint32_t w = image->getWidth();
    uint32_t h = image->getHeight();
    Texture* texture = Texture::Builder()
            .width(w)
            .height(h)
            .levels(0xff)
            .format(channels == 3 ?
                    Texture::InternalFormat::RGB16F : Texture::InternalFormat::RGBA16F)
            .sampler(Texture::Sampler::SAMPLER_2D)
            .build(*engine);

    Texture::PixelBufferDescriptor::Callback freeCallback = [](void* buf, size_t, void* data) {
        delete reinterpret_cast<LinearImage*>(data);
    };

    Texture::PixelBufferDescriptor buffer(
            image->getPixelRef(),
            size_t(w * h * channels * sizeof(float)),
            channels == 3 ? Texture::Format::RGB : Texture::Format::RGBA,
            Texture::Type::FLOAT,
            freeCallback,
            image
    );

    texture->setImage(*engine, 0, std::move(buffer));
    texture->generateMipmaps(*engine);

    app.scene.sampler.setMagFilter(TextureSampler::MagFilter::LINEAR);
    app.scene.sampler.setMinFilter(TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR);
    app.scene.sampler.setWrapModeS(TextureSampler::WrapMode::REPEAT);
    app.scene.sampler.setWrapModeT(TextureSampler::WrapMode::REPEAT);

    app.scene.imageTexture = texture;
    app.showImage = true;
}

int main(int argc, char** argv) {
    App app;

    app.config.title = "Filament Image Viewer";

    int optionIndex = handleCommandLineArguments(argc, argv, &app);

    Path filename;
    int num_args = argc - optionIndex;
    if (num_args >= 1) {
        filename = argv[optionIndex];
    }

    auto setup = [&](Engine* engine, View* view, Scene* scene) {
        app.engine = engine;
        app.viewer = new ViewerGui(engine, scene, view, 410);
        app.viewer->getSettings().viewer.autoScaleEnabled = false;
        app.viewer->getSettings().viewer.autoInstancingEnabled = true;
        app.viewer->getSettings().view.bloom.enabled = false;
        app.viewer->getSettings().view.ssao.enabled = false;
        app.viewer->getSettings().view.dithering = Dithering::NONE;
        app.viewer->getSettings().view.antiAliasing = AntiAliasing::NONE;

        createImageRenderable(engine, scene, app);

        loadImage(app, engine, filename);

        app.viewer->setUiCallback([&app] () {
            if (ImGui::CollapsingHeader("Image", ImGuiTreeNodeFlags_DefaultOpen)) {
                ImGui::ColorEdit3("Background color", &app.backgroundColor.r);
            }
        });
    };

    auto cleanup = [&app](Engine* engine, View*, Scene*) {
        engine->destroy(app.scene.imageEntity);
        engine->destroy(app.scene.imageVertexBuffer);
        engine->destroy(app.scene.imageIndexBuffer);
        engine->destroy(app.scene.imageMaterial);
        engine->destroy(app.scene.imageTexture);
        engine->destroy(app.scene.defaultTexture);
        engine->destroy(app.colorGrading);

        delete app.viewer;
    };

    auto gui = [&app](Engine* engine, View* view) {
        app.viewer->updateUserInterface();

        FilamentApp::get().setSidebarWidth(app.viewer->getSidebarWidth());
    };

    auto preRender = [&app](Engine* engine, View* view, Scene* scene, Renderer* renderer) {
        auto& rcm = engine->getRenderableManager();

        // This applies clear options, the skybox mask, and some camera settings.
        Camera& camera = view->getCamera();
        Skybox* skybox = scene->getSkybox();
        applySettings(engine, app.viewer->getSettings().viewer, &camera, skybox, renderer);

        // Check if color grading has changed.
        ColorGradingSettings& options = app.viewer->getSettings().view.colorGrading;
        if (options.enabled) {
            if (options != app.lastColorGradingOptions) {
                ColorGrading *colorGrading = createColorGrading(options, engine);
                engine->destroy(app.colorGrading);
                app.colorGrading = colorGrading;
                app.lastColorGradingOptions = options;
            }
            view->setColorGrading(app.colorGrading);
        } else {
            view->setColorGrading(nullptr);
        }

        if (app.showImage) {
            Texture *texture = app.scene.imageTexture;
            float srcWidth = (float) texture->getWidth();
            float srcHeight = (float) texture->getHeight();
            float dstWidth = (float) view->getViewport().width;
            float dstHeight = (float) view->getViewport().height;

            float srcRatio = srcWidth / srcHeight;
            float dstRatio = dstWidth / dstHeight;

            bool xMajor = dstWidth / srcWidth > dstHeight / srcHeight;

            float sx = 1.0f;
            float sy = dstRatio / srcRatio;

            float tx = 0.0f;
            float ty = ((1.0f - sy) * 0.5f) / sy;

            if (xMajor) {
                sx = srcRatio / dstRatio;
                sy = 1.0;
                tx = ((1.0f - sx) * 0.5f) / sx;
                ty = 0.0f;
            }

            mat3f transform(
                    1.0f / sx,  0.0f,       0.0f,
                    0.0f,       1.0f / sy,  0.0f,
                    -tx,        -ty,         1.0f
            );

            app.scene.imageMaterial->setDefaultParameter("transform", transform);
            app.scene.imageMaterial->setDefaultParameter(
                    "image", app.scene.imageTexture, app.scene.sampler);
        } else {
            app.scene.imageMaterial->setDefaultParameter(
                    "image", app.scene.defaultTexture, app.scene.sampler);
        }

        app.scene.imageMaterial->setDefaultParameter("showImage", app.showImage ? 1 : 0);
        app.scene.imageMaterial->setDefaultParameter(
                "backgroundColor", RgbType::sRGB, app.backgroundColor);
    };

    FilamentApp& filamentApp = FilamentApp::get();

    filamentApp.setDropHandler([&] (std::string path) {
        loadImage(app, app.engine, Path(path));
    });

    filamentApp.run(app.config, setup, cleanup, gui, preRender);

    return 0;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file constraint_checker.cc
 **/

#include "modules/planning/constraint_checker/constraint_checker.h"

#include "modules/common/log.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

namespace {
template <typename T>
bool WithinRange(const T v, const T lower, const T upper) {
  return lower <= v && v <= upper;
}
}

bool ConstraintChecker::ValidTrajectory(
    const DiscretizedTrajectory& trajectory) {
  for (const auto& p : trajectory.trajectory_points()) {
    double t = p.relative_time();
    double lon_v = p.v();
    if (!WithinRange(lon_v, FLAGS_speed_lower_bound, FLAGS_speed_upper_bound)) {
      AERROR << "Velocity at relative time " << t
             << " exceeds bound, value: " << lon_v << ", bound ["
             << FLAGS_speed_lower_bound << ", " << FLAGS_speed_upper_bound
             << "].";
      return false;
    }

    double lon_a = p.a();
    if (!WithinRange(lon_a, FLAGS_longitudinal_acceleration_lower_bound,
                     FLAGS_longitudinal_acceleration_upper_bound)) {
      AERROR << "Longitudinal acceleration at relative time " << t
             << " exceeds bound, value: " << lon_a << ", bound ["
             << FLAGS_longitudinal_acceleration_lower_bound << ", "
             << FLAGS_longitudinal_acceleration_upper_bound << "].";
      return false;
    }

    double kappa = p.path_point().kappa();
    if (!WithinRange(kappa, -FLAGS_kappa_bound, FLAGS_kappa_bound)) {
      AERROR << "Kappa at relative time " << t
             << " exceeds bound, value: " << kappa << ", bound ["
             << -FLAGS_kappa_bound << ", " << FLAGS_kappa_bound << "].";
      return false;
    }
  }

  return true;
}

}  // namespace planning
}  // namespace apollo
<commit_msg>planning: remove kappa check in trajectory checker.<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file constraint_checker.cc
 **/

#include "modules/planning/constraint_checker/constraint_checker.h"

#include "modules/common/log.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

namespace {
template <typename T>
bool WithinRange(const T v, const T lower, const T upper) {
  return lower <= v && v <= upper;
}
}

bool ConstraintChecker::ValidTrajectory(
    const DiscretizedTrajectory& trajectory) {
  for (const auto& p : trajectory.trajectory_points()) {
    double t = p.relative_time();
    double lon_v = p.v();
    if (!WithinRange(lon_v, FLAGS_speed_lower_bound, FLAGS_speed_upper_bound)) {
      AERROR << "Velocity at relative time " << t
             << " exceeds bound, value: " << lon_v << ", bound ["
             << FLAGS_speed_lower_bound << ", " << FLAGS_speed_upper_bound
             << "].";
      return false;
    }

    double lon_a = p.a();
    if (!WithinRange(lon_a, FLAGS_longitudinal_acceleration_lower_bound,
                     FLAGS_longitudinal_acceleration_upper_bound)) {
      AERROR << "Longitudinal acceleration at relative time " << t
             << " exceeds bound, value: " << lon_a << ", bound ["
             << FLAGS_longitudinal_acceleration_lower_bound << ", "
             << FLAGS_longitudinal_acceleration_upper_bound << "].";
      return false;
    }
  }
  return true;
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>


<commit_before>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/

#include "HeatConduction.h"
#include "MooseMesh.h"

template<>
InputParameters validParams<HeatConductionKernel>()
{
  InputParameters params = validParams<Diffusion>();
  params.addClassDescription("Compute thermal conductivity");
  params.addParam<MaterialPropertyName>("diffusion_coefficient_name",
                                        "thermal_conductivity",
                                        "Property name of the diffusivity (Default: thermal_conductivity)");
  params.addParam<MaterialPropertyName>("diffusion_coefficient_dT_name",
                                        "thermal_conductivity_dT",
                                        "Property name of the derivative of the diffusivity with respect "
                                        "to the variable (Default: thermal_conductivity_dT)");
  params.set<bool>("use_displaced_mesh") = true;
  return params;
}

HeatConductionKernel::HeatConductionKernel(const InputParameters & parameters) :
    Diffusion(parameters),
    _diffusion_coefficient(getMaterialProperty<Real>("diffusion_coefficient_name")),
    _diffusion_coefficient_dT(hasMaterialProperty<Real>("diffusion_coefficient_dT_name") ?
                              &getMaterialProperty<Real>("diffusion_coefficient_dT_name") : NULL)
{
}

Real
HeatConductionKernel::computeQpResidual()
{
  return _diffusion_coefficient[_qp] * Diffusion::computeQpResidual();
}

Real
HeatConductionKernel::computeQpJacobian()
{
  Real jac = _diffusion_coefficient[_qp] * Diffusion::computeQpJacobian();
  if (_diffusion_coefficient_dT)
    jac += (*_diffusion_coefficient_dT)[_qp] * _phi[_j][_qp] * Diffusion::computeQpResidual();
  return jac;
}
<commit_msg>Fix class description of HeatConductionKernel.<commit_after>/****************************************************************/
/* MOOSE - Multiphysics Object Oriented Simulation Environment  */
/*                                                              */
/*          All contents are licensed under LGPL V2.1           */
/*             See LICENSE for full restrictions                */
/****************************************************************/

#include "HeatConduction.h"
#include "MooseMesh.h"

template<>
InputParameters validParams<HeatConductionKernel>()
{
  InputParameters params = validParams<Diffusion>();
  params.addClassDescription("Computes residual/Jacobian contribution for $(k \\nabla T, \\nabla \\psi)$ term.");
  params.addParam<MaterialPropertyName>("diffusion_coefficient_name",
                                        "thermal_conductivity",
                                        "Property name of the diffusivity (Default: thermal_conductivity)");
  params.addParam<MaterialPropertyName>("diffusion_coefficient_dT_name",
                                        "thermal_conductivity_dT",
                                        "Property name of the derivative of the diffusivity with respect "
                                        "to the variable (Default: thermal_conductivity_dT)");
  params.set<bool>("use_displaced_mesh") = true;
  return params;
}

HeatConductionKernel::HeatConductionKernel(const InputParameters & parameters) :
    Diffusion(parameters),
    _diffusion_coefficient(getMaterialProperty<Real>("diffusion_coefficient_name")),
    _diffusion_coefficient_dT(hasMaterialProperty<Real>("diffusion_coefficient_dT_name") ?
                              &getMaterialProperty<Real>("diffusion_coefficient_dT_name") : NULL)
{
}

Real
HeatConductionKernel::computeQpResidual()
{
  return _diffusion_coefficient[_qp] * Diffusion::computeQpResidual();
}

Real
HeatConductionKernel::computeQpJacobian()
{
  Real jac = _diffusion_coefficient[_qp] * Diffusion::computeQpJacobian();
  if (_diffusion_coefficient_dT)
    jac += (*_diffusion_coefficient_dT)[_qp] * _phi[_j][_qp] * Diffusion::computeQpResidual();
  return jac;
}
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/behavior/feasible_region.h"

#include <cmath>

#include "glog/logging.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

FeasibleRegion::FeasibleRegion(const std::array<double, 3>& init_s,
                               const double speed_limit) {
  Setup(init_s, speed_limit);
}

void FeasibleRegion::Setup(const std::array<double, 3>& init_s,
                           const double speed_limit) {
  init_s_ = init_s;
  speed_limit_ = speed_limit;

  double v = init_s[1];
  CHECK(v >= 0.0);

  const double max_deceleration = -FLAGS_longitudinal_acceleration_lower_bound;
  t_at_zero_speed_ = v / max_deceleration;
  s_at_zero_speed_ = init_s[0] + v * v / (2.0 * max_deceleration);

  double delta_v = speed_limit - v;
  if (delta_v < 0.0) {
    t_at_speed_limit_ = delta_v / FLAGS_longitudinal_acceleration_lower_bound;
    s_at_speed_limit_ = init_s_[0] + v * t_at_speed_limit_ +
                        0.5 * FLAGS_longitudinal_acceleration_lower_bound *
                            t_at_speed_limit_ * t_at_speed_limit_;
  } else {
    t_at_speed_limit_ = delta_v / FLAGS_longitudinal_acceleration_upper_bound;
    s_at_speed_limit_ = init_s_[0] + v * t_at_speed_limit_ +
                        0.5 * FLAGS_longitudinal_acceleration_upper_bound *
                            t_at_speed_limit_ * t_at_speed_limit_;
  }
}

double FeasibleRegion::SUpper(const double t) const {
  CHECK(t >= 0.0);

  if (init_s_[1] < speed_limit_) {
    if (t < t_at_speed_limit_) {
      return init_s_[0] + init_s_[1] * t +
             0.5 * FLAGS_longitudinal_acceleration_upper_bound * t * t;
    } else {
      return s_at_speed_limit_ + speed_limit_ * (t - t_at_speed_limit_);
    }
  } else {
    return init_s_[0] + init_s_[1] * t;
  }
}

double FeasibleRegion::SLower(const double t) const {
  if (t < t_at_zero_speed_) {
    return init_s_[0] + init_s_[1] * t +
           0.5 * FLAGS_longitudinal_acceleration_lower_bound * t * t;
  }
  return s_at_zero_speed_;
}

double FeasibleRegion::VUpper(const double t) const {
  return std::max(
      init_s_[1],
      std::min(init_s_[1] + FLAGS_longitudinal_acceleration_upper_bound * t,
               speed_limit_));
}

double FeasibleRegion::VLower(const double t) const {
  return t < t_at_zero_speed_
             ? init_s_[1] + FLAGS_longitudinal_acceleration_lower_bound * t
             : 0.0;
}

double FeasibleRegion::TLower(const double s) const {
  CHECK(s >= init_s_[0]);

  if (init_s_[1] < speed_limit_) {
    if (s < s_at_speed_limit_) {
      double delta =
          init_s_[1] * init_s_[1] -
          2.0 * FLAGS_longitudinal_acceleration_upper_bound * (init_s_[0] - s);
      return (std::sqrt(delta) - init_s_[1]) /
             FLAGS_longitudinal_acceleration_upper_bound;
    } else {
      return t_at_speed_limit_ + (s - s_at_speed_limit_) / speed_limit_;
    }
  } else {
    return (s - init_s_[0]) / init_s_[1];
  }
}

}  // namespace planning
}  // namespace apollo
<commit_msg>Planning: modify check greater equal format<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * 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.
 *****************************************************************************/

/**
 * @file
 **/

#include "modules/planning/lattice/behavior/feasible_region.h"

#include <cmath>

#include "glog/logging.h"
#include "modules/planning/common/planning_gflags.h"

namespace apollo {
namespace planning {

FeasibleRegion::FeasibleRegion(const std::array<double, 3>& init_s,
                               const double speed_limit) {
  Setup(init_s, speed_limit);
}

void FeasibleRegion::Setup(const std::array<double, 3>& init_s,
                           const double speed_limit) {
  init_s_ = init_s;
  speed_limit_ = speed_limit;

  double v = init_s[1];
  CHECK_GE(v, 0.0);

  const double max_deceleration = -FLAGS_longitudinal_acceleration_lower_bound;
  t_at_zero_speed_ = v / max_deceleration;
  s_at_zero_speed_ = init_s[0] + v * v / (2.0 * max_deceleration);

  double delta_v = speed_limit - v;
  if (delta_v < 0.0) {
    t_at_speed_limit_ = delta_v / FLAGS_longitudinal_acceleration_lower_bound;
    s_at_speed_limit_ = init_s_[0] + v * t_at_speed_limit_ +
                        0.5 * FLAGS_longitudinal_acceleration_lower_bound *
                            t_at_speed_limit_ * t_at_speed_limit_;
  } else {
    t_at_speed_limit_ = delta_v / FLAGS_longitudinal_acceleration_upper_bound;
    s_at_speed_limit_ = init_s_[0] + v * t_at_speed_limit_ +
                        0.5 * FLAGS_longitudinal_acceleration_upper_bound *
                            t_at_speed_limit_ * t_at_speed_limit_;
  }
}

double FeasibleRegion::SUpper(const double t) const {
  CHECK(t >= 0.0);

  if (init_s_[1] < speed_limit_) {
    if (t < t_at_speed_limit_) {
      return init_s_[0] + init_s_[1] * t +
             0.5 * FLAGS_longitudinal_acceleration_upper_bound * t * t;
    } else {
      return s_at_speed_limit_ + speed_limit_ * (t - t_at_speed_limit_);
    }
  } else {
    return init_s_[0] + init_s_[1] * t;
  }
}

double FeasibleRegion::SLower(const double t) const {
  if (t < t_at_zero_speed_) {
    return init_s_[0] + init_s_[1] * t +
           0.5 * FLAGS_longitudinal_acceleration_lower_bound * t * t;
  }
  return s_at_zero_speed_;
}

double FeasibleRegion::VUpper(const double t) const {
  return std::max(
      init_s_[1],
      std::min(init_s_[1] + FLAGS_longitudinal_acceleration_upper_bound * t,
               speed_limit_));
}

double FeasibleRegion::VLower(const double t) const {
  return t < t_at_zero_speed_
             ? init_s_[1] + FLAGS_longitudinal_acceleration_lower_bound * t
             : 0.0;
}

double FeasibleRegion::TLower(const double s) const {
  CHECK(s >= init_s_[0]);

  if (init_s_[1] < speed_limit_) {
    if (s < s_at_speed_limit_) {
      double delta =
          init_s_[1] * init_s_[1] -
          2.0 * FLAGS_longitudinal_acceleration_upper_bound * (init_s_[0] - s);
      return (std::sqrt(delta) - init_s_[1]) /
             FLAGS_longitudinal_acceleration_upper_bound;
    } else {
      return t_at_speed_limit_ + (s - s_at_speed_limit_) / speed_limit_;
    }
  } else {
    return (s - init_s_[0]) / init_s_[1];
  }
}

}  // namespace planning
}  // namespace apollo
<|endoftext|>