<commit_before>#ifndef NFL_ALGOS_HPP
#define NFL_ALGOS_HPP

#include <nfl/arch/common.hpp>

namespace nfl {

namespace ops {

template <class SIMD, class poly, class T=typename poly::value_type>
struct ntt_loop_body;

template <class SIMD, class poly, class T=typename poly::value_type>
struct ntt_loop;

template <class poly, class T>
struct ntt_loop_body<simd::serial, poly, T>
{
  using value_type = typename poly::value_type;
  using greater_value_type = typename poly::greater_value_type;
  using simd_type = simd::serial;

  ntt_loop_body(value_type const p){
    _p = p;
  }

  inline void operator()(value_type* x0, value_type* x1, value_type const* winvtab, value_type const* wtab) const
  {
    value_type u0 = *x0;
    value_type u1 = *x1;

    value_type t1 = u0 - u1 + 2*_p;

    value_type q = ((greater_value_type) t1 * (*winvtab)) >> params<T>::kModulusRepresentationBitsize;
    value_type t2 = t1 * (*wtab) - q * _p;

    value_type t0 = u0 + u1;
    t0 -= ((t0 >= 2*_p) ? (2*_p) : 0);

    *x0 = t0;
    *x1 = t2;
  }

  value_type _p;
};

template <class poly, class T>
struct ntt_loop<simd::serial, poly, T>
{
  using value_type = typename poly::value_type;
  using greater_value_type = typename poly::greater_value_type;

  static constexpr size_t J = static_log2<poly::degree>::value-2;

  static size_t run(value_type* x, const value_type* &wtab,
                  const value_type* &winvtab, const value_type p) {
    ntt_loop_body<simd::serial, poly, T> body(p);
    for (size_t w = 0; w < J; w++) {
      const size_t M = 1 << w;
      const size_t N = poly::degree >> w;
      for (size_t r = 0; r < M; r++) {
        for (size_t i = 0; i < N/2; i += 2) {
          body(&x[N * r + i + 0], &x[N * r + i + 0 + N/2], &winvtab[i + 0], &wtab[i + 0]);
          body(&x[N * r + i + 1], &x[N * r + i + 1 + N/2], &winvtab[i + 1], &wtab[i + 1]);
        }
      }
      wtab += N / 2;
      winvtab += N / 2;
    }

    return 1<<J;
  }
};

} // ops

} // nfl

#endif
<commit_msg>Faster serial NTT. (#40)<commit_after>#ifndef NFL_ALGOS_HPP
#define NFL_ALGOS_HPP

#include <nfl/arch/common.hpp>

namespace nfl {

namespace ops {

template <class SIMD, class poly, class T=typename poly::value_type>
struct ntt_loop_body;

template <class SIMD, class poly, class T=typename poly::value_type>
struct ntt_loop;

template <class poly, class T>
struct ntt_loop_body<simd::serial, poly, T>
{
  using value_type = typename poly::value_type;
  using greater_value_type = typename poly::greater_value_type;
  using simd_type = simd::serial;

  ntt_loop_body(value_type const p){
    _p = p;
  }

  inline void operator()(value_type* x0, value_type* x1, value_type const* winvtab, value_type const* wtab) const
  {
    value_type u0 = *x0;
    value_type u1 = *x1;

    value_type t0 = u0 + u1;
    t0 -= ((t0 >= 2*_p) ? (2*_p) : 0);

    value_type t1 = u0 - u1 + 2*_p;

    value_type q = ((greater_value_type) t1 * (*winvtab)) >> params<T>::kModulusRepresentationBitsize;
    value_type t2 = t1 * (*wtab) - q * _p;

    *x0 = t0;
    *x1 = t2;
  }

  value_type _p;
};

template <class poly, class T>
struct ntt_loop<simd::serial, poly, T>
{
  using value_type = typename poly::value_type;
  using greater_value_type = typename poly::greater_value_type;

  static constexpr size_t J = static_log2<poly::degree>::value-2;

  static size_t run(value_type* x, const value_type* &wtab,
                  const value_type* &winvtab, const value_type p) {
    ntt_loop_body<simd::serial, poly, T> body(p);
    for (size_t w = 0; w < J; w++) {
      const size_t M = 1 << w;
      const size_t N = poly::degree >> w;
      for (size_t r = 0; r < M; r++) {
        for (size_t i = 0; i < N/2; i += 2) {
          body(&x[N * r + i + 0], &x[N * r + i + 0 + N/2], &winvtab[i + 0], &wtab[i + 0]);
          body(&x[N * r + i + 1], &x[N * r + i + 1 + N/2], &winvtab[i + 1], &wtab[i + 1]);
        }
      }
      wtab += N / 2;
      winvtab += N / 2;
    }

    return 1<<J;
  }
};

} // ops

} // nfl

#endif
<|endoftext|>


<commit_before>#ifndef LIBTEN_IOPROC_HH
#define LIBTEN_IOPROC_HH

#include "task.hh"
#include "channel.hh"
#include <stdarg.h>
#include <memory>
#include <boost/any.hpp>
#include "shared_pool.hh"
#include <fcntl.h>
#include <cassert>
#include <exception>

namespace ten {

struct pcall;
typedef channel<std::unique_ptr<pcall> > iochannel;

//! remote call in another thread
struct pcall {
    iochannel ch;
    std::function<void ()> vop;
    std::function<boost::any ()> op;
    std::exception_ptr exception;
    boost::any ret;

    pcall(const std::function<void ()> &vop_, iochannel &ch_) : ch(ch_), vop(vop_) {}
    pcall(const std::function<boost::any ()> &op_, iochannel &ch_) : ch(ch_), op(op_) {}
};

void ioproctask(iochannel &);

//! a pool of threads for making blocking calls
struct ioproc {
    iochannel ch;
    std::vector<uint64_t> tids;

    ioproc(
            size_t stacksize = default_stacksize,
            unsigned nprocs = 1,
            unsigned chanbuf = 0,
            void (*proctask)(iochannel &) = ioproctask)
        : ch(chanbuf ? chanbuf : nprocs)
    {
        for (unsigned i=0; i<nprocs; ++i) {
            tids.push_back(procspawn(std::bind(proctask, ch), stacksize));
        }
    }

    ~ioproc() {
        DVLOG(5) << "closing ioproc channel: " << this;
        ch.close();
        DVLOG(5) << "freeing ioproc: " << this;
    }
};

//! wait on an iochannel for a call to complete
inline void iowait(iochannel &reply_chan) {
    // TODO: maybe this close logic needs to be in channel itself?
    // is there ever a case where you'd want a channel to stay open
    // after a task using it has been interrupted? i can't think of one
    try {
        std::unique_ptr<pcall> reply(reply_chan.recv());
        if (reply->exception != 0) {
            std::rethrow_exception(reply->exception);
        }
    } catch (task_interrupted &e) {
        reply_chan.close();
        throw;
    }
}

//! wait on an iochannel for a call to complete with a result
template <typename ReturnT>
ReturnT iowait(iochannel &reply_chan) {
    try {
        std::unique_ptr<pcall> reply(reply_chan.recv());
        if (reply->exception != 0) {
            std::rethrow_exception(reply->exception);
        }
        return boost::any_cast<ReturnT>(reply->ret);
    } catch (task_interrupted &e) {
        reply_chan.close();
        throw;
    }
}

//! make an iocall, but dont wait for it to complete
template <typename Func>
void iocallasync(
        ioproc &io,
        Func &&f,
        iochannel reply_chan = iochannel())
{
    std::unique_ptr<pcall> call;
    if (std::is_void<decltype(f())>::value) {
        // void op
        std::function<void ()> vop(f);
        call.reset(new pcall(vop, reply_chan));
    } else {
        // has return type
        std::function<boost::any ()> op(f);
        call.reset(new pcall(op, reply_chan));
    }
    io.ch.send(std::move(call));
}

//! make an iocall and wait for the result
template <typename Func>
auto iocall(
        ioproc &io,
        Func &&f,
        iochannel reply_chan = iochannel())
    -> typename std::enable_if<
         !std::is_void<decltype(f())>::value,
         decltype(f())
       >::type
{
    std::function<boost::any ()> op(f);
    std::unique_ptr<pcall> call(new pcall(op, reply_chan));
    io.ch.send(std::move(call));
    return iowait<decltype(f())>(reply_chan);
}

//! make an iocall and wait it to complete
template <typename Func>
auto iocall(
        ioproc &io,
        Func &&f,
        iochannel reply_chan = iochannel())
    -> typename std::enable_if<
         std::is_void<decltype(f())>::value,
         void
       >::type
{
    std::function<void ()> vop(f);
    std::unique_ptr<pcall> call(new pcall(vop, reply_chan));
    io.ch.send(std::move(call));
    iowait(reply_chan);
}

////// iorw /////

template <typename ProcT> int ioopen(ProcT &io, char *path, int mode) {
    return iocall(io, std::bind((int (*)(char *, int))::open, path, mode));
}

template <typename ProcT>  int ioclose(ProcT &io, int fd) {
    return iocall(io, std::bind(::close, fd));
}

template <typename ProcT> ssize_t ioread(ProcT &io, int fd, void *buf, size_t n) {
    return iocall(io, std::bind(::read, fd, buf, n));
}

template <typename ProcT> ssize_t iowrite(ProcT &io, int fd, void *buf, size_t n) {
    return iocall(io, std::bind(::write, fd, buf, n));
}

} // end namespace ten

#endif // LIBTEN_IOPROC_HH
<commit_msg>fix iocallasync<commit_after>#ifndef LIBTEN_IOPROC_HH
#define LIBTEN_IOPROC_HH

#include "task.hh"
#include "channel.hh"
#include <stdarg.h>
#include <memory>
#include <boost/any.hpp>
#include "shared_pool.hh"
#include <fcntl.h>
#include <cassert>
#include <exception>

namespace ten {

struct pcall;
typedef channel<std::unique_ptr<pcall> > iochannel;

//! remote call in another thread
struct pcall {
    iochannel ch;
    std::function<void ()> vop;
    std::function<boost::any ()> op;
    std::exception_ptr exception;
    boost::any ret;

    pcall(const std::function<void ()> &vop_, iochannel &ch_) : ch(ch_), vop(vop_) {}
    pcall(const std::function<boost::any ()> &op_, iochannel &ch_) : ch(ch_), op(op_) {}
};

void ioproctask(iochannel &);

//! a pool of threads for making blocking calls
struct ioproc {
    iochannel ch;
    std::vector<uint64_t> tids;

    ioproc(
            size_t stacksize = default_stacksize,
            unsigned nprocs = 1,
            unsigned chanbuf = 0,
            void (*proctask)(iochannel &) = ioproctask)
        : ch(chanbuf ? chanbuf : nprocs)
    {
        for (unsigned i=0; i<nprocs; ++i) {
            tids.push_back(procspawn(std::bind(proctask, ch), stacksize));
        }
    }

    ~ioproc() {
        DVLOG(5) << "closing ioproc channel: " << this;
        ch.close();
        DVLOG(5) << "freeing ioproc: " << this;
    }
};

//! wait on an iochannel for a call to complete
inline void iowait(iochannel &reply_chan) {
    // TODO: maybe this close logic needs to be in channel itself?
    // is there ever a case where you'd want a channel to stay open
    // after a task using it has been interrupted? i can't think of one
    try {
        std::unique_ptr<pcall> reply(reply_chan.recv());
        if (reply->exception != 0) {
            std::rethrow_exception(reply->exception);
        }
    } catch (task_interrupted &e) {
        reply_chan.close();
        throw;
    }
}

//! wait on an iochannel for a call to complete with a result
template <typename ReturnT>
ReturnT iowait(iochannel &reply_chan) {
    try {
        std::unique_ptr<pcall> reply(reply_chan.recv());
        if (reply->exception != 0) {
            std::rethrow_exception(reply->exception);
        }
        return boost::any_cast<ReturnT>(reply->ret);
    } catch (task_interrupted &e) {
        reply_chan.close();
        throw;
    }
}

//! make an iocall, but dont wait for it to complete
template <typename Func>
auto iocallasync(
        ioproc &io,
        Func &&f,
        iochannel reply_chan = iochannel())
    -> typename std::enable_if<
         !std::is_void<decltype(f())>::value,
         void
       >::type
{
    // has return type
    std::function<boost::any ()> op(f);
    std::unique_ptr<pcall> call(new pcall(op, reply_chan));
    io.ch.send(std::move(call));
}

//! make an iocall, but dont wait for it to complete
template <typename Func>
auto iocallasync(
        ioproc &io,
        Func &&f,
        iochannel reply_chan = iochannel())
    -> typename std::enable_if<
         std::is_void<decltype(f())>::value,
         void
       >::type
{
    // void op
    std::function<void ()> vop(f);
    std::unique_ptr<pcall> call(new pcall(vop, reply_chan));
    io.ch.send(std::move(call));
}

//! make an iocall and wait for the result
template <typename Func>
auto iocall(
        ioproc &io,
        Func &&f,
        iochannel reply_chan = iochannel())
    -> typename std::enable_if<
         !std::is_void<decltype(f())>::value,
         decltype(f())
       >::type
{
    std::function<boost::any ()> op(f);
    std::unique_ptr<pcall> call(new pcall(op, reply_chan));
    io.ch.send(std::move(call));
    return iowait<decltype(f())>(reply_chan);
}

//! make an iocall and wait it to complete
template <typename Func>
auto iocall(
        ioproc &io,
        Func &&f,
        iochannel reply_chan = iochannel())
    -> typename std::enable_if<
         std::is_void<decltype(f())>::value,
         void
       >::type
{
    std::function<void ()> vop(f);
    std::unique_ptr<pcall> call(new pcall(vop, reply_chan));
    io.ch.send(std::move(call));
    iowait(reply_chan);
}

////// iorw /////

template <typename ProcT> int ioopen(ProcT &io, char *path, int mode) {
    return iocall(io, std::bind((int (*)(char *, int))::open, path, mode));
}

template <typename ProcT>  int ioclose(ProcT &io, int fd) {
    return iocall(io, std::bind(::close, fd));
}

template <typename ProcT> ssize_t ioread(ProcT &io, int fd, void *buf, size_t n) {
    return iocall(io, std::bind(::read, fd, buf, n));
}

template <typename ProcT> ssize_t iowrite(ProcT &io, int fd, void *buf, size_t n) {
    return iocall(io, std::bind(::write, fd, buf, n));
}

} // end namespace ten

#endif // LIBTEN_IOPROC_HH
<|endoftext|>


<commit_before><commit_msg>Added standard.net.tlse module (preparing to drop libssl)<commit_after><|endoftext|>


<commit_before><commit_msg>#i105649#: OOXMLDocPropHandler::AddCustomProperty():  add properties as REMOVEABLE, not TRANSIENT!<commit_after><|endoftext|>


<commit_before>// $Id: string_to_enum.C,v 1.2 2005-06-21 21:53:58 benkirk Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// 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

// C++ includes
#include <map>

// Local includes
#include "libmesh_common.h"
#include "string_to_enum.h"
#include "enum_elem_type.h"
#include "enum_order.h"
#include "enum_fe_family.h"
#include "enum_inf_map_type.h"

// ------------------------------------------------------------
// Anonymous namespace to hold local data & methods
namespace {

  //----------------------------------------------------
  std::map<std::string, ElemType> elem_type_to_enum;

  // Initialize elem_type_to_enum on first call
  void init_elem_type_to_enum ()
  {
    if (elem_type_to_enum.empty())
      {
	elem_type_to_enum["EDGE2"     ]=EDGE2;
	elem_type_to_enum["EDGE3"     ]=EDGE3;
	elem_type_to_enum["EDGE4"     ]=EDGE4;

	elem_type_to_enum["TRI3"      ]=TRI3;
	elem_type_to_enum["TRI6"      ]=TRI6;

	elem_type_to_enum["QUAD4"     ]=QUAD4;
	elem_type_to_enum["QUAD8"     ]=QUAD8;
	elem_type_to_enum["QUAD9"     ]=QUAD9;

	elem_type_to_enum["TET4"      ]=TET4;
	elem_type_to_enum["TET10"     ]=TET10;

	elem_type_to_enum["HEX8"      ]=HEX8;
	elem_type_to_enum["HEX20"     ]=HEX20;
	elem_type_to_enum["HEX27"     ]=HEX27;

	elem_type_to_enum["PRISM6"    ]=PRISM6;
	elem_type_to_enum["PRISM15"   ]=PRISM15;
	elem_type_to_enum["PRISM18"   ]=PRISM18;

	elem_type_to_enum["PYRAMID5"  ]=PYRAMID5;

	elem_type_to_enum["INFEDGE2"  ]=INFEDGE2;

	elem_type_to_enum["INFQUAD4"  ]=INFQUAD4;
	elem_type_to_enum["INFQUAD6"  ]=INFQUAD6;

	elem_type_to_enum["INFHEX8"   ]=INFHEX8;
	elem_type_to_enum["INFHEX16"  ]=INFHEX16;
	elem_type_to_enum["INFHEX18"  ]=INFHEX18;

	elem_type_to_enum["INFPRISM6" ]=INFPRISM6;
	elem_type_to_enum["INFPRISM12"]=INFPRISM12;
      }
  }

  std::map<ElemType, std::string> enum_to_elem_type;

  // Initialize the enum_to_elem_type on first call
  void init_enum_to_elem_type ()
  {
    // Build reverse map
    if (enum_to_elem_type.empty())
      {
	// Initialize elem_type_to_enum on first call
	init_elem_type_to_enum();

	std::map<std::string, ElemType>::iterator it =
	  elem_type_to_enum.begin();

	for  (; it != elem_type_to_enum.end(); ++it)
	  enum_to_elem_type.insert (std::make_pair(it->second, it->first));

	assert (elem_type_to_enum.size() ==
		enum_to_elem_type.size());
      }
  }

  //---------------------------------------------
  std::map<std::string, Order> order_to_enum;

  // Initialize order_to_enum on first call
  void init_order_to_enum ()
  {
    if (order_to_enum.empty())
      {
	order_to_enum["CONSTANT"     ]=CONSTANT;
	order_to_enum["FIRST"        ]=FIRST;
	order_to_enum["SECOND"       ]=SECOND;
	order_to_enum["THIRD"        ]=THIRD;
	order_to_enum["FOURTH"       ]=FOURTH;
	order_to_enum["FIFTH"        ]=FIFTH;
	order_to_enum["SIXTH"        ]=SIXTH;
	order_to_enum["SEVENTH"      ]=SEVENTH;
	order_to_enum["EIGHTH"       ]=EIGHTH;
	order_to_enum["NINTH"        ]=NINTH;
	order_to_enum["TENTH"        ]=TENTH;

	order_to_enum["ELEVENTH"     ]=ELEVENTH;
	order_to_enum["TWELFTH"      ]=TWELFTH;
	order_to_enum["THIRTEENTH"   ]=THIRTEENTH;
	order_to_enum["FOURTEENTH"   ]=FOURTEENTH;
	order_to_enum["FIFTEENTH"    ]=FIFTEENTH;
	order_to_enum["SIXTEENTH"    ]=SIXTEENTH;
	order_to_enum["SEVENTEENTH"  ]=SEVENTEENTH;
	order_to_enum["EIGHTTEENTH"  ]=EIGHTTEENTH;
	order_to_enum["NINTEENTH"    ]=NINTEENTH;
	order_to_enum["TWENTIETH"    ]=TWENTIETH;

	order_to_enum["TWENTYFIRST"  ]=TWENTYFIRST;
	order_to_enum["TWENTYSECOND" ]=TWENTYSECOND;
	order_to_enum["TWENTYTHIRD"  ]=TWENTYTHIRD;
	order_to_enum["TWENTYFOURTH" ]=TWENTYFOURTH;
	order_to_enum["TWENTYFIFTH"  ]=TWENTYFIFTH;
	order_to_enum["TWENTYSIXTH"  ]=TWENTYSIXTH;
	order_to_enum["TWENTYSEVENTH"]=TWENTYSEVENTH;
	order_to_enum["TWENTYEIGHTH" ]=TWENTYEIGHTH;
	order_to_enum["TWENTYNINTH"  ]=TWENTYNINTH;
	order_to_enum["THIRTIETH"    ]=THIRTIETH;

	order_to_enum["THIRTYFIRST"  ]=THIRTYFIRST;
	order_to_enum["THIRTYSECOND" ]=THIRTYSECOND;
	order_to_enum["THIRTYTHIRD"  ]=THIRTYTHIRD;
	order_to_enum["THIRTYFOURTH" ]=THIRTYFOURTH;
	order_to_enum["THIRTYFIFTH"  ]=THIRTYFIFTH;
	order_to_enum["THIRTYSIXTH"  ]=THIRTYSIXTH;
	order_to_enum["THIRTYSEVENTH"]=THIRTYSEVENTH;
	order_to_enum["THIRTYEIGHTH" ]=THIRTYEIGHTH;
	order_to_enum["THIRTYNINTH"  ]=THIRTYNINTH;
	order_to_enum["FOURTIETH"    ]=FOURTIETH;

	order_to_enum["FOURTYFIRST"  ]=FOURTYFIRST;
	order_to_enum["FOURTYSECOND" ]=FOURTYSECOND;
	order_to_enum["FOURTYTHIRD"  ]=FOURTYTHIRD;
      }
  }

  std::map<Order, std::string> enum_to_order;

  // Initialize the enum_to_order on first call
  void init_enum_to_order ()
  {
    // Build reverse map
    if (enum_to_order.empty())
      {
	// Initialize order_to_enum on first call
	init_order_to_enum();

	std::map<std::string, Order>::iterator it =
	  order_to_enum.begin();

	for  (; it != order_to_enum.end(); ++it)
	  enum_to_order.insert (std::make_pair(it->second, it->first));

	assert (order_to_enum.size() ==
		enum_to_order.size());
      }
  }

  //---------------------------------------------------
  std::map<std::string, FEFamily> fefamily_to_enum;

  // Initialize fefamily_to_enum on first call
  void init_fefamily_to_enum ()
  {
    if (fefamily_to_enum.empty())
      {
	fefamily_to_enum["LAGRANGE"    ]=LAGRANGE;
	fefamily_to_enum["HIERARCHIC"  ]=HIERARCHIC;
	fefamily_to_enum["MONOMIAL"    ]=MONOMIAL;
	fefamily_to_enum["XYZ"         ]=XYZ;
	fefamily_to_enum["BERNSTEIN"   ]=BERNSTEIN;
	fefamily_to_enum["SZABAB"      ]=SZABAB;
	fefamily_to_enum["INFINITE_MAP"]=INFINITE_MAP;
	fefamily_to_enum["JACOBI_20_00"]=JACOBI_20_00;
	fefamily_to_enum["JACOBI_30_00"]=JACOBI_30_00;
	fefamily_to_enum["LEGENDRE"    ]=LEGENDRE;
	fefamily_to_enum["CLOUGH"      ]=CLOUGH;
      }

  }

  std::map<FEFamily, std::string> enum_to_fefamily;

  // Initialize the enum_to_fefamily on first call
  void init_enum_to_fefamily ()
  {
    // Build reverse map
    if (enum_to_fefamily.empty())
      {
	// Initialize fefamily_to_enum on first call
	init_fefamily_to_enum();

	std::map<std::string, FEFamily>::iterator it =
	  fefamily_to_enum.begin();

	for  (; it != fefamily_to_enum.end(); ++it)
	  enum_to_fefamily.insert (std::make_pair(it->second, it->first));

	assert (fefamily_to_enum.size() ==
		enum_to_fefamily.size());
      }
  }

#ifdef ENABLE_INFINITE_ELEMENTS
  //---------------------------------------------------
  std::map<std::string, InfMapType> inf_map_type_to_enum;

  // Initialize inf_map_type_to_enum on first call
  void init_inf_map_type_to_enum ()
  {
    if (inf_map_type_to_enum.empty())
      {
	inf_map_type_to_enum["CARTESIAN"  ]=CARTESIAN;
	inf_map_type_to_enum["SPHERICAL"  ]=SPHERICAL;
	inf_map_type_to_enum["ELLIPSOIDAL"]=ELLIPSOIDAL;
      }
  }

  std::map<InfMapType, std::string> enum_to_inf_map_type;

  // Initialize the enum_to_inf_map_type on first call
  void init_enum_to_inf_map_type ()
  {
    // Build reverse map
    if (enum_to_inf_map_type.empty())
      {
	// Initialize inf_map_type_to_enum on first call
	init_inf_map_type_to_enum();

	std::map<std::string, InfMapType>::iterator it =
	  inf_map_type_to_enum.begin();

	for  (; it != inf_map_type_to_enum.end(); ++it)
	  enum_to_inf_map_type.insert (std::make_pair(it->second, it->first));

	assert (inf_map_type_to_enum.size() ==
		enum_to_inf_map_type.size());
      }
  }
#endif // #ifdef ENABLE_INFINITE_ELEMENTS
} // end anonymous namespace

// ------------------------------------------------------
// Utility::string_to_enum<> & Utility::enum_to_string<>
// full specializations
namespace Utility {

  //------------------------------------------------------
  // ElemType specialization
  template <>
  ElemType string_to_enum<ElemType> (const std::string& s)
  {
    init_elem_type_to_enum();

    if (!elem_type_to_enum.count(s))
      error();

    return elem_type_to_enum[s];
  }

  template <>
  std::string enum_to_string<ElemType> (const ElemType e)
  {
    init_enum_to_elem_type();

    if (!enum_to_elem_type.count(e))
      error();

    return enum_to_elem_type[e];
  }

  //------------------------------------------------
  // Order specialization
  template <>
  Order string_to_enum<Order> (const std::string& s)
  {
    init_order_to_enum();

    if (!order_to_enum.count(s))
      error();

    return order_to_enum[s];
  }

  template <>
  std::string enum_to_string<Order> (const Order o)
  {
    init_enum_to_order();

    if (!enum_to_order.count(o))
      error();

    return enum_to_order[o];
  }

  //------------------------------------------------------
  // FEFamily specialization
  template <>
  FEFamily string_to_enum<FEFamily> (const std::string& s)
  {
    init_fefamily_to_enum();

    if (!fefamily_to_enum.count(s))
      error();

    return fefamily_to_enum[s];
  }

  template <>
  std::string enum_to_string<FEFamily> (const FEFamily f)
  {
    init_enum_to_fefamily();

    if (!enum_to_fefamily.count(f))
      error();

    return enum_to_fefamily[f];
  }

  //------------------------------------------------------
  // InfMapType specialization
  template <>
  InfMapType string_to_enum<InfMapType> (const std::string& s)
  {
    init_inf_map_type_to_enum();

    if (!inf_map_type_to_enum.count(s))
      error();

    return inf_map_type_to_enum[s];
  }

  template <>
  std::string enum_to_string<InfMapType> (const InfMapType i)
  {
    init_enum_to_inf_map_type();

    if (!enum_to_inf_map_type.count(i))
      error();

    return enum_to_inf_map_type[i];
  }
}

<commit_msg>removed #ifdef for --disable-ifem<commit_after>// $Id: string_to_enum.C,v 1.3 2005-06-22 14:04:47 benkirk Exp $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2005  Benjamin S. Kirk, John W. Peterson

// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.

// 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

// C++ includes
#include <map>

// Local includes
#include "libmesh_common.h"
#include "string_to_enum.h"
#include "enum_elem_type.h"
#include "enum_order.h"
#include "enum_fe_family.h"
#include "enum_inf_map_type.h"

// ------------------------------------------------------------
// Anonymous namespace to hold local data & methods
namespace {

  //----------------------------------------------------
  std::map<std::string, ElemType> elem_type_to_enum;

  // Initialize elem_type_to_enum on first call
  void init_elem_type_to_enum ()
  {
    if (elem_type_to_enum.empty())
      {
	elem_type_to_enum["EDGE2"     ]=EDGE2;
	elem_type_to_enum["EDGE3"     ]=EDGE3;
	elem_type_to_enum["EDGE4"     ]=EDGE4;

	elem_type_to_enum["TRI3"      ]=TRI3;
	elem_type_to_enum["TRI6"      ]=TRI6;

	elem_type_to_enum["QUAD4"     ]=QUAD4;
	elem_type_to_enum["QUAD8"     ]=QUAD8;
	elem_type_to_enum["QUAD9"     ]=QUAD9;

	elem_type_to_enum["TET4"      ]=TET4;
	elem_type_to_enum["TET10"     ]=TET10;

	elem_type_to_enum["HEX8"      ]=HEX8;
	elem_type_to_enum["HEX20"     ]=HEX20;
	elem_type_to_enum["HEX27"     ]=HEX27;

	elem_type_to_enum["PRISM6"    ]=PRISM6;
	elem_type_to_enum["PRISM15"   ]=PRISM15;
	elem_type_to_enum["PRISM18"   ]=PRISM18;

	elem_type_to_enum["PYRAMID5"  ]=PYRAMID5;

	elem_type_to_enum["INFEDGE2"  ]=INFEDGE2;

	elem_type_to_enum["INFQUAD4"  ]=INFQUAD4;
	elem_type_to_enum["INFQUAD6"  ]=INFQUAD6;

	elem_type_to_enum["INFHEX8"   ]=INFHEX8;
	elem_type_to_enum["INFHEX16"  ]=INFHEX16;
	elem_type_to_enum["INFHEX18"  ]=INFHEX18;

	elem_type_to_enum["INFPRISM6" ]=INFPRISM6;
	elem_type_to_enum["INFPRISM12"]=INFPRISM12;
      }
  }

  std::map<ElemType, std::string> enum_to_elem_type;

  // Initialize the enum_to_elem_type on first call
  void init_enum_to_elem_type ()
  {
    // Build reverse map
    if (enum_to_elem_type.empty())
      {
	// Initialize elem_type_to_enum on first call
	init_elem_type_to_enum();

	std::map<std::string, ElemType>::iterator it =
	  elem_type_to_enum.begin();

	for  (; it != elem_type_to_enum.end(); ++it)
	  enum_to_elem_type.insert (std::make_pair(it->second, it->first));

	assert (elem_type_to_enum.size() ==
		enum_to_elem_type.size());
      }
  }

  //---------------------------------------------
  std::map<std::string, Order> order_to_enum;

  // Initialize order_to_enum on first call
  void init_order_to_enum ()
  {
    if (order_to_enum.empty())
      {
	order_to_enum["CONSTANT"     ]=CONSTANT;
	order_to_enum["FIRST"        ]=FIRST;
	order_to_enum["SECOND"       ]=SECOND;
	order_to_enum["THIRD"        ]=THIRD;
	order_to_enum["FOURTH"       ]=FOURTH;
	order_to_enum["FIFTH"        ]=FIFTH;
	order_to_enum["SIXTH"        ]=SIXTH;
	order_to_enum["SEVENTH"      ]=SEVENTH;
	order_to_enum["EIGHTH"       ]=EIGHTH;
	order_to_enum["NINTH"        ]=NINTH;
	order_to_enum["TENTH"        ]=TENTH;

	order_to_enum["ELEVENTH"     ]=ELEVENTH;
	order_to_enum["TWELFTH"      ]=TWELFTH;
	order_to_enum["THIRTEENTH"   ]=THIRTEENTH;
	order_to_enum["FOURTEENTH"   ]=FOURTEENTH;
	order_to_enum["FIFTEENTH"    ]=FIFTEENTH;
	order_to_enum["SIXTEENTH"    ]=SIXTEENTH;
	order_to_enum["SEVENTEENTH"  ]=SEVENTEENTH;
	order_to_enum["EIGHTTEENTH"  ]=EIGHTTEENTH;
	order_to_enum["NINTEENTH"    ]=NINTEENTH;
	order_to_enum["TWENTIETH"    ]=TWENTIETH;

	order_to_enum["TWENTYFIRST"  ]=TWENTYFIRST;
	order_to_enum["TWENTYSECOND" ]=TWENTYSECOND;
	order_to_enum["TWENTYTHIRD"  ]=TWENTYTHIRD;
	order_to_enum["TWENTYFOURTH" ]=TWENTYFOURTH;
	order_to_enum["TWENTYFIFTH"  ]=TWENTYFIFTH;
	order_to_enum["TWENTYSIXTH"  ]=TWENTYSIXTH;
	order_to_enum["TWENTYSEVENTH"]=TWENTYSEVENTH;
	order_to_enum["TWENTYEIGHTH" ]=TWENTYEIGHTH;
	order_to_enum["TWENTYNINTH"  ]=TWENTYNINTH;
	order_to_enum["THIRTIETH"    ]=THIRTIETH;

	order_to_enum["THIRTYFIRST"  ]=THIRTYFIRST;
	order_to_enum["THIRTYSECOND" ]=THIRTYSECOND;
	order_to_enum["THIRTYTHIRD"  ]=THIRTYTHIRD;
	order_to_enum["THIRTYFOURTH" ]=THIRTYFOURTH;
	order_to_enum["THIRTYFIFTH"  ]=THIRTYFIFTH;
	order_to_enum["THIRTYSIXTH"  ]=THIRTYSIXTH;
	order_to_enum["THIRTYSEVENTH"]=THIRTYSEVENTH;
	order_to_enum["THIRTYEIGHTH" ]=THIRTYEIGHTH;
	order_to_enum["THIRTYNINTH"  ]=THIRTYNINTH;
	order_to_enum["FOURTIETH"    ]=FOURTIETH;

	order_to_enum["FOURTYFIRST"  ]=FOURTYFIRST;
	order_to_enum["FOURTYSECOND" ]=FOURTYSECOND;
	order_to_enum["FOURTYTHIRD"  ]=FOURTYTHIRD;
      }
  }

  std::map<Order, std::string> enum_to_order;

  // Initialize the enum_to_order on first call
  void init_enum_to_order ()
  {
    // Build reverse map
    if (enum_to_order.empty())
      {
	// Initialize order_to_enum on first call
	init_order_to_enum();

	std::map<std::string, Order>::iterator it =
	  order_to_enum.begin();

	for  (; it != order_to_enum.end(); ++it)
	  enum_to_order.insert (std::make_pair(it->second, it->first));

	assert (order_to_enum.size() ==
		enum_to_order.size());
      }
  }

  //---------------------------------------------------
  std::map<std::string, FEFamily> fefamily_to_enum;

  // Initialize fefamily_to_enum on first call
  void init_fefamily_to_enum ()
  {
    if (fefamily_to_enum.empty())
      {
	fefamily_to_enum["LAGRANGE"    ]=LAGRANGE;
	fefamily_to_enum["HIERARCHIC"  ]=HIERARCHIC;
	fefamily_to_enum["MONOMIAL"    ]=MONOMIAL;
	fefamily_to_enum["XYZ"         ]=XYZ;
	fefamily_to_enum["BERNSTEIN"   ]=BERNSTEIN;
	fefamily_to_enum["SZABAB"      ]=SZABAB;
	fefamily_to_enum["INFINITE_MAP"]=INFINITE_MAP;
	fefamily_to_enum["JACOBI_20_00"]=JACOBI_20_00;
	fefamily_to_enum["JACOBI_30_00"]=JACOBI_30_00;
	fefamily_to_enum["LEGENDRE"    ]=LEGENDRE;
	fefamily_to_enum["CLOUGH"      ]=CLOUGH;
      }

  }

  std::map<FEFamily, std::string> enum_to_fefamily;

  // Initialize the enum_to_fefamily on first call
  void init_enum_to_fefamily ()
  {
    // Build reverse map
    if (enum_to_fefamily.empty())
      {
	// Initialize fefamily_to_enum on first call
	init_fefamily_to_enum();

	std::map<std::string, FEFamily>::iterator it =
	  fefamily_to_enum.begin();

	for  (; it != fefamily_to_enum.end(); ++it)
	  enum_to_fefamily.insert (std::make_pair(it->second, it->first));

	assert (fefamily_to_enum.size() ==
		enum_to_fefamily.size());
      }
  }

  //---------------------------------------------------
  std::map<std::string, InfMapType> inf_map_type_to_enum;

  // Initialize inf_map_type_to_enum on first call
  void init_inf_map_type_to_enum ()
  {
    if (inf_map_type_to_enum.empty())
      {
	inf_map_type_to_enum["CARTESIAN"  ]=CARTESIAN;
	inf_map_type_to_enum["SPHERICAL"  ]=SPHERICAL;
	inf_map_type_to_enum["ELLIPSOIDAL"]=ELLIPSOIDAL;
      }
  }

  std::map<InfMapType, std::string> enum_to_inf_map_type;

  // Initialize the enum_to_inf_map_type on first call
  void init_enum_to_inf_map_type ()
  {
    // Build reverse map
    if (enum_to_inf_map_type.empty())
      {
	// Initialize inf_map_type_to_enum on first call
	init_inf_map_type_to_enum();

	std::map<std::string, InfMapType>::iterator it =
	  inf_map_type_to_enum.begin();

	for  (; it != inf_map_type_to_enum.end(); ++it)
	  enum_to_inf_map_type.insert (std::make_pair(it->second, it->first));

	assert (inf_map_type_to_enum.size() ==
		enum_to_inf_map_type.size());
      }
  }
} // end anonymous namespace

// ------------------------------------------------------
// Utility::string_to_enum<> & Utility::enum_to_string<>
// full specializations
namespace Utility {

  //------------------------------------------------------
  // ElemType specialization
  template <>
  ElemType string_to_enum<ElemType> (const std::string& s)
  {
    init_elem_type_to_enum();

    if (!elem_type_to_enum.count(s))
      error();

    return elem_type_to_enum[s];
  }

  template <>
  std::string enum_to_string<ElemType> (const ElemType e)
  {
    init_enum_to_elem_type();

    if (!enum_to_elem_type.count(e))
      error();

    return enum_to_elem_type[e];
  }

  //------------------------------------------------
  // Order specialization
  template <>
  Order string_to_enum<Order> (const std::string& s)
  {
    init_order_to_enum();

    if (!order_to_enum.count(s))
      error();

    return order_to_enum[s];
  }

  template <>
  std::string enum_to_string<Order> (const Order o)
  {
    init_enum_to_order();

    if (!enum_to_order.count(o))
      error();

    return enum_to_order[o];
  }

  //------------------------------------------------------
  // FEFamily specialization
  template <>
  FEFamily string_to_enum<FEFamily> (const std::string& s)
  {
    init_fefamily_to_enum();

    if (!fefamily_to_enum.count(s))
      error();

    return fefamily_to_enum[s];
  }

  template <>
  std::string enum_to_string<FEFamily> (const FEFamily f)
  {
    init_enum_to_fefamily();

    if (!enum_to_fefamily.count(f))
      error();

    return enum_to_fefamily[f];
  }

  //------------------------------------------------------
  // InfMapType specialization
  template <>
  InfMapType string_to_enum<InfMapType> (const std::string& s)
  {
    init_inf_map_type_to_enum();

    if (!inf_map_type_to_enum.count(s))
      error();

    return inf_map_type_to_enum[s];
  }

  template <>
  std::string enum_to_string<InfMapType> (const InfMapType i)
  {
    init_enum_to_inf_map_type();

    if (!enum_to_inf_map_type.count(i))
      error();

    return enum_to_inf_map_type[i];
  }
}

<|endoftext|>


<commit_before>
#include <iostream>
#include <Eigen/Geometry>
#include <bench/BenchTimer.h>

using namespace std;
using namespace Eigen;

#ifndef SCALAR
#define SCALAR float
#endif

typedef SCALAR Scalar;
typedef NumTraits<Scalar>::Real RealScalar;
typedef Matrix<RealScalar,Dynamic,Dynamic> A;
typedef Matrix</*Real*/Scalar,Dynamic,Dynamic> B;
typedef Matrix<Scalar,Dynamic,Dynamic> C;
typedef Matrix<RealScalar,Dynamic,Dynamic> M;

template<typename Transformation, typename Data>
EIGEN_DONT_INLINE void transform(const Transformation& t, Data& data)
{
  EIGEN_ASM_COMMENT("begin");
  data = t * data;
  EIGEN_ASM_COMMENT("end");
}

template<typename Scalar, typename Data>
EIGEN_DONT_INLINE void transform(const Quaternion<Scalar>& t, Data& data)
{
  EIGEN_ASM_COMMENT("begin quat");
  for(int i=0;i<data.cols();++i)
    data.col(i) = t * data.col(i);
  EIGEN_ASM_COMMENT("end quat");
}

template<typename T> struct ToRotationMatrixWrapper
{
  enum {Dim = T::Dim};
  typedef typename T::Scalar Scalar;
  ToRotationMatrixWrapper(const T& o) : object(o) {}
  T object;
};

template<typename QType, typename Data>
EIGEN_DONT_INLINE void transform(const ToRotationMatrixWrapper<QType>& t, Data& data)
{
  EIGEN_ASM_COMMENT("begin quat via mat");
  data = t.object.toRotationMatrix() * data;
  EIGEN_ASM_COMMENT("end quat via mat");
}

template<typename Scalar, int Dim, typename Data>
EIGEN_DONT_INLINE void transform(const Transform<Scalar,Dim,Projective>& t, Data& data)
{
  data = (t * data.colwise().homogeneous()).template block<Dim,Data::ColsAtCompileTime>(0,0);
}

template<typename T> struct get_dim { enum { Dim = T::Dim }; };
template<typename S, int R, int C, int O, int MR, int MC>
struct get_dim<Matrix<S,R,C,O,MR,MC> > { enum { Dim = R }; };

template<typename Transformation, int N>
struct bench_impl
{
  static EIGEN_DONT_INLINE void run(const Transformation& t)
  {
    Matrix<typename Transformation::Scalar,get_dim<Transformation>::Dim,N> data;
    data.setRandom();
    bench_impl<Transformation,N-1>::run(t);
    BenchTimer timer;
    BENCH(timer,4,100000,transform(t,data));
    cout.width(9);
    cout << timer.best() << " ";
  }
};

template<typename Transformation>
struct bench_impl<Transformation,0>
{
  static EIGEN_DONT_INLINE void run(const Transformation&) {}
};

template<typename Transformation>
EIGEN_DONT_INLINE void bench(const std::string& msg, const Transformation& t)
{
  cout << msg << " ";
  bench_impl<Transformation,8>::run(t);
  std::cout << "\n";
}

int main(int argc, char ** argv)
{
  Matrix<Scalar,3,4> mat34; mat34.setRandom();
  Transform<Scalar,3,Isometry> iso3(mat34);
  Transform<Scalar,3,Affine> aff3(mat34);
  Transform<Scalar,3,AffineCompact> caff3(mat34);
  Transform<Scalar,3,Projective> proj3(mat34);
  Quaternion<Scalar> quat;
  ToRotationMatrixWrapper<Quaternion<Scalar> > quatmat(quat);
  Matrix<Scalar,3,3> mat33; mat33.setRandom();

  cout.precision(4);
  std::cout
     << "N          ";
  for(int i=0;i<8;++i)
  {
    cout.width(9);
    cout << i+1 << " ";
  }
  cout << "\n";
  bench("matrix 3x3", mat33);
  bench("quaternion", quat);
  bench("quat-mat  ", quatmat);
  bench("isometry3 ", iso3);
  bench("affine3   ", aff3);
  bench("c affine3 ", caff3);
  bench("proj3     ", proj3);
}

<commit_msg>fix unitialized quaternion<commit_after>
#include <iostream>
#include <Eigen/Geometry>
#include <bench/BenchTimer.h>

using namespace std;
using namespace Eigen;

#ifndef SCALAR
#define SCALAR float
#endif

#ifndef SIZE
#define SIZE 8
#endif

typedef SCALAR Scalar;
typedef NumTraits<Scalar>::Real RealScalar;
typedef Matrix<RealScalar,Dynamic,Dynamic> A;
typedef Matrix</*Real*/Scalar,Dynamic,Dynamic> B;
typedef Matrix<Scalar,Dynamic,Dynamic> C;
typedef Matrix<RealScalar,Dynamic,Dynamic> M;

template<typename Transformation, typename Data>
EIGEN_DONT_INLINE void transform(const Transformation& t, Data& data)
{
  EIGEN_ASM_COMMENT("begin");
  data = t * data;
  EIGEN_ASM_COMMENT("end");
}

template<typename Scalar, typename Data>
EIGEN_DONT_INLINE void transform(const Quaternion<Scalar>& t, Data& data)
{
  EIGEN_ASM_COMMENT("begin quat");
  for(int i=0;i<data.cols();++i)
    data.col(i) = t * data.col(i);
  EIGEN_ASM_COMMENT("end quat");
}

template<typename T> struct ToRotationMatrixWrapper
{
  enum {Dim = T::Dim};
  typedef typename T::Scalar Scalar;
  ToRotationMatrixWrapper(const T& o) : object(o) {}
  T object;
};

template<typename QType, typename Data>
EIGEN_DONT_INLINE void transform(const ToRotationMatrixWrapper<QType>& t, Data& data)
{
  EIGEN_ASM_COMMENT("begin quat via mat");
  data = t.object.toRotationMatrix() * data;
  EIGEN_ASM_COMMENT("end quat via mat");
}

template<typename Scalar, int Dim, typename Data>
EIGEN_DONT_INLINE void transform(const Transform<Scalar,Dim,Projective>& t, Data& data)
{
  data = (t * data.colwise().homogeneous()).template block<Dim,Data::ColsAtCompileTime>(0,0);
}

template<typename T> struct get_dim { enum { Dim = T::Dim }; };
template<typename S, int R, int C, int O, int MR, int MC>
struct get_dim<Matrix<S,R,C,O,MR,MC> > { enum { Dim = R }; };

template<typename Transformation, int N>
struct bench_impl
{
  static EIGEN_DONT_INLINE void run(const Transformation& t)
  {
    Matrix<typename Transformation::Scalar,get_dim<Transformation>::Dim,N> data;
    data.setRandom();
    bench_impl<Transformation,N-1>::run(t);
    BenchTimer timer;
    BENCH(timer,10,100000,transform(t,data));
    cout.width(9);
    cout << timer.best() << " ";
  }
};

template<typename Transformation>
struct bench_impl<Transformation,0>
{
  static EIGEN_DONT_INLINE void run(const Transformation&) {}
};

template<typename Transformation>
EIGEN_DONT_INLINE void bench(const std::string& msg, const Transformation& t)
{
  cout << msg << " ";
  bench_impl<Transformation,SIZE>::run(t);
  std::cout << "\n";
}

int main(int argc, char ** argv)
{
  Matrix<Scalar,3,4> mat34; mat34.setRandom();
  Transform<Scalar,3,Isometry> iso3(mat34);
  Transform<Scalar,3,Affine> aff3(mat34);
  Transform<Scalar,3,AffineCompact> caff3(mat34);
  Transform<Scalar,3,Projective> proj3(mat34);
  Quaternion<Scalar> quat;quat.setIdentity();
  ToRotationMatrixWrapper<Quaternion<Scalar> > quatmat(quat);
  Matrix<Scalar,3,3> mat33; mat33.setRandom();

  cout.precision(4);
  std::cout
     << "N          ";
  for(int i=0;i<SIZE;++i)
  {
    cout.width(9);
    cout << i+1 << " ";
  }
  cout << "\n";

  bench("matrix 3x3", mat33);
  bench("quaternion", quat);
  bench("quat-mat  ", quatmat);
  bench("isometry3 ", iso3);
  bench("affine3   ", aff3);
  bench("c affine3 ", caff3);
  bench("proj3     ", proj3);
}

<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2018 Intel Corporation                                         //
//                                                                          //
// 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 <memory>
#include <random>
#include "GLFWOSPRayWindow.h"

struct Sphere
{
  // initial (maximum) height of the sphere, at which it has 0 velocity
  float maxHeight;

  ospcommon::vec3f center;
  float radius;
  ospcommon::vec4f color;
};

// track the spheres data, geometry, and model globally so we can update them
// every frame
static std::vector<Sphere> g_spheres;
static OSPGeometry g_spheresGeometry;
static OSPModel g_model;

std::vector<Sphere> generateRandomSpheres(size_t numSpheres)
{
  // create random number distributions for sphere center, radius, and color
  std::random_device rd;
  std::mt19937 gen(rd());

  std::uniform_real_distribution<float> centerDistribution(-1.f, 1.f);
  std::uniform_real_distribution<float> radiusDistribution(0.05f, 0.15f);
  std::uniform_real_distribution<float> colorDistribution(0.5f, 1.f);

  // populate the spheres
  std::vector<Sphere> spheres(numSpheres);

  for (auto &s : spheres) {
    s.maxHeight = centerDistribution(gen);

    s.center.x = centerDistribution(gen);
    s.center.y = s.maxHeight;
    s.center.z = centerDistribution(gen);

    s.radius = radiusDistribution(gen);

    s.color.x = colorDistribution(gen);
    s.color.y = colorDistribution(gen);
    s.color.z = colorDistribution(gen);
    s.color.w = colorDistribution(gen);
  }

  return spheres;
}

OSPGeometry createGroundPlaneGeometry()
{
  OSPGeometry planeGeometry = ospNewGeometry("quads");

  struct Vertex
  {
    ospcommon::vec3f position;
    ospcommon::vec3f normal;
    ospcommon::vec4f color;
  };

  struct QuadIndex
  {
    int x;
    int y;
    int z;
    int w;
  };

  std::vector<Vertex> vertices;
  std::vector<QuadIndex> quadIndices;

  // ground plane
  int startingIndex = vertices.size();

  // extent of plane in the (x, z) directions
  const float planeExtent = 1.5f;

  const ospcommon::vec3f up   = ospcommon::vec3f{0.f, 1.f, 0.f};
  const ospcommon::vec4f gray = ospcommon::vec4f{0.9f, 0.9f, 0.9f, 0.75f};

  vertices.push_back(
      Vertex{ospcommon::vec3f{-planeExtent, -1.f, -planeExtent}, up, gray});
  vertices.push_back(
      Vertex{ospcommon::vec3f{planeExtent, -1.f, -planeExtent}, up, gray});
  vertices.push_back(
      Vertex{ospcommon::vec3f{planeExtent, -1.f, planeExtent}, up, gray});
  vertices.push_back(
      Vertex{ospcommon::vec3f{-planeExtent, -1.f, planeExtent}, up, gray});

  quadIndices.push_back(QuadIndex{startingIndex,
                                  startingIndex + 1,
                                  startingIndex + 2,
                                  startingIndex + 3});

  // stripes on ground plane
  const float stripeWidth  = 0.025f;
  const float paddedExtent = planeExtent + stripeWidth;
  const size_t numStripes  = 10;

  const ospcommon::vec4f stripeColor =
      ospcommon::vec4f{1.0f, 0.1f, 0.1f, 1.f};

  for (size_t i = 0; i < numStripes; i++) {
    // the center coordinate of the stripe, either in the x or z direction
    const float coord =
        -planeExtent + float(i) / float(numStripes - 1) * 2.f * planeExtent;

    // offset the stripes by an epsilon above the ground plane
    const float yLevel = -1.f + 1e-3f;

    // x-direction stripes
    startingIndex = vertices.size();

    vertices.push_back(
        Vertex{ospcommon::vec3f{-paddedExtent, yLevel, coord - stripeWidth},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{paddedExtent, yLevel, coord - stripeWidth},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{paddedExtent, yLevel, coord + stripeWidth},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{-paddedExtent, yLevel, coord + stripeWidth},
               up,
               stripeColor});

    quadIndices.push_back(QuadIndex{startingIndex,
                                    startingIndex + 1,
                                    startingIndex + 2,
                                    startingIndex + 3});

    // z-direction stripes
    startingIndex = vertices.size();

    vertices.push_back(
        Vertex{ospcommon::vec3f{coord - stripeWidth, yLevel, -paddedExtent},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{coord + stripeWidth, yLevel, -paddedExtent},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{coord + stripeWidth, yLevel, paddedExtent},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{coord - stripeWidth, yLevel, paddedExtent},
               up,
               stripeColor});

    quadIndices.push_back(QuadIndex{startingIndex,
                                    startingIndex + 1,
                                    startingIndex + 2,
                                    startingIndex + 3});
  }

  // create OSPRay data objects
  std::vector<ospcommon::vec3f> positionVector;
  std::vector<ospcommon::vec3f> normalVector;
  std::vector<ospcommon::vec4f> colorVector;

  std::transform(vertices.begin(),
                 vertices.end(),
                 std::back_inserter(positionVector),
                 [](Vertex const &v) { return v.position; });
  std::transform(vertices.begin(),
                 vertices.end(),
                 std::back_inserter(normalVector),
                 [](Vertex const &v) { return v.normal; });
  std::transform(vertices.begin(),
                 vertices.end(),
                 std::back_inserter(colorVector),
                 [](Vertex const &v) { return v.color; });

  OSPData positionData =
      ospNewData(vertices.size(), OSP_FLOAT3, positionVector.data());
  OSPData normalData =
      ospNewData(vertices.size(), OSP_FLOAT3, normalVector.data());
  OSPData colorData =
      ospNewData(vertices.size(), OSP_FLOAT4, colorVector.data());
  OSPData indexData =
      ospNewData(quadIndices.size(), OSP_INT4, quadIndices.data());

  // set vertex / index data on the geometry
  ospSetData(planeGeometry, "vertex", positionData);
  ospSetData(planeGeometry, "vertex.normal", normalData);
  ospSetData(planeGeometry, "vertex.color", colorData);
  ospSetData(planeGeometry, "index", indexData);

  // create and assign a material to the geometry
  OSPMaterial material = ospNewMaterial2("pathtracer", "OBJMaterial");
  ospCommit(material);

  ospSetMaterial(planeGeometry, material);

  // finally, commit the geometry
  ospCommit(planeGeometry);

  // release handles we no longer need
  ospRelease(positionData);
  ospRelease(normalData);
  ospRelease(colorData);
  ospRelease(indexData);
  ospRelease(material);

  return planeGeometry;
}

OSPGeometry createRandomSpheresGeometry(size_t numSpheres)
{
  g_spheres = generateRandomSpheres(numSpheres);

  // create a data object with all the sphere information
  OSPData spheresData =
      ospNewData(numSpheres * sizeof(Sphere), OSP_UCHAR, g_spheres.data());

  // create the sphere geometry, and assign attributes
  g_spheresGeometry = ospNewGeometry("spheres");

  ospSetData(g_spheresGeometry, "spheres", spheresData);
  ospSet1i(g_spheresGeometry, "bytes_per_sphere", int(sizeof(Sphere)));
  ospSet1i(g_spheresGeometry, "offset_center", int(offsetof(Sphere, center)));
  ospSet1i(g_spheresGeometry, "offset_radius", int(offsetof(Sphere, radius)));

  ospSetData(g_spheresGeometry, "color", spheresData);
  ospSet1i(g_spheresGeometry, "color_offset", int(offsetof(Sphere, color)));
  ospSet1i(g_spheresGeometry, "color_format", int(OSP_FLOAT4));
  ospSet1i(g_spheresGeometry, "color_stride", int(sizeof(Sphere)));

  // create glass material and assign to geometry
  OSPMaterial glassMaterial = ospNewMaterial2("pathtracer", "ThinGlass");
  ospSet1f(glassMaterial, "attenuationDistance", 0.2f);
  ospCommit(glassMaterial);

  ospSetMaterial(g_spheresGeometry, glassMaterial);

  // commit the spheres geometry
  ospCommit(g_spheresGeometry);

  // release handles we no longer need
  ospRelease(spheresData);
  ospRelease(glassMaterial);

  return g_spheresGeometry;
}

OSPModel createModel()
{
  // create the "world" model which will contain all of our geometries
  OSPModel world = ospNewModel();

  // add in spheres geometry (100 of them)
  ospAddGeometry(world, createRandomSpheresGeometry(100));

  // add in a ground plane geometry
  ospAddGeometry(world, createGroundPlaneGeometry());

  // commit the world model
  ospCommit(world);

  return world;
}

OSPRenderer createRenderer()
{
  // create OSPRay renderer
  OSPRenderer renderer = ospNewRenderer("pathtracer");

  // create an ambient light
  OSPLight ambientLight = ospNewLight3("ambient");
  ospCommit(ambientLight);

  // create lights data containing all lights
  OSPLight lights[]  = {ambientLight};
  OSPData lightsData = ospNewData(1, OSP_LIGHT, lights, 0);
  ospCommit(lightsData);

  // set the lights to the renderer
  ospSetData(renderer, "lights", lightsData);

  // increase the samples per pixel
  ospSet1i(renderer, "spp", 4);

  // commit the renderer
  ospCommit(renderer);

  // release handles we no longer need
  ospRelease(lightsData);

  return renderer;
}

// updates the bouncing spheres coordinates based on simple gravity model
void updateSpheresCoordinates()
{
  // update the current spheres' heights based on current "time"
  static float t = 0.f;

  for (auto &s : g_spheres) {
    const float g = 9.81f;
    const float T = sqrtf(2.f*s.maxHeight/g);
    const float Vmax = sqrtf(2.f*s.maxHeight*g);

    float tRemainder = fmod(T+t, 2.f*T);

    s.center.y = -1.f + 0.5f*s.radius + -g*tRemainder*tRemainder*0.5f + Vmax*tRemainder;
  }

  // increment by fixed time interval, rather than actual elapsed time
  t += 0.01f;
}

void updateSpheresGeometry()
{
  // create new spheres data for the updated center coordinates, and assign to geometry
  OSPData spheresData =
      ospNewData(g_spheres.size() * sizeof(Sphere), OSP_UCHAR, g_spheres.data());

  ospSetData(g_spheresGeometry, "spheres", spheresData);

  // commit the updated spheres geometry
  ospCommit(g_spheresGeometry);

  // release handles we no longer need
  ospRelease(spheresData);
}

// updates the bouncing spheres' coordinates, geometry, and model
void displayCallback(GLFWOSPRayWindow * glfwOSPRayWindow)
{
  // update the spheres coordinates and geometry
  updateSpheresCoordinates();
  updateSpheresGeometry();

  // commit the model since the spheres geometry changed
  ospCommit(g_model);

  // update the model on the GLFW window
  glfwOSPRayWindow->setModel(g_model);
}

int main(int argc, const char **argv)
{
  // initialize OSPRay; OSPRay parses (and removes) its commandline parameters,
  // e.g. "--osp:debug"
  OSPError initError = ospInit(&argc, argv);

  if (initError != OSP_NO_ERROR)
    return initError;

  // set an error callback to catch any OSPRay errors and exit the application
  ospDeviceSetErrorFunc(
      ospGetCurrentDevice(), [](OSPError error, const char *errorDetails) {
        std::cerr << "OSPRay error: " << errorDetails << std::endl;
        exit(error);
      });

  // create OSPRay model
  g_model = createModel();

  // create OSPRay renderer
  OSPRenderer renderer = createRenderer();

  // create a GLFW OSPRay window: this object will create and manage the OSPRay
  // frame buffer and camera directly
  auto glfwOSPRayWindow =
      std::unique_ptr<GLFWOSPRayWindow>(new GLFWOSPRayWindow(
          ospcommon::vec2i{1024, 768},
          ospcommon::box3f(ospcommon::vec3f(-1.f), ospcommon::vec3f(1.f)),
          g_model,
          renderer));

  // register a callback with the GLFW OSPRay window to update the model every frame
  glfwOSPRayWindow->registerDisplayCallback(
      std::function<void(GLFWOSPRayWindow *)>(displayCallback));

  // start the GLFW main loop, which will continuously render
  glfwOSPRayWindow->mainLoop();

  // cleanly shut OSPRay down
  ospShutdown();

  return 0;
}
<commit_msg>minor physics correction.<commit_after>// ======================================================================== //
// Copyright 2018 Intel Corporation                                         //
//                                                                          //
// 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 <memory>
#include <random>
#include "GLFWOSPRayWindow.h"

struct Sphere
{
  // initial (maximum) height of the sphere, at which it has 0 velocity
  float maxHeight;

  ospcommon::vec3f center;
  float radius;
  ospcommon::vec4f color;
};

// track the spheres data, geometry, and model globally so we can update them
// every frame
static std::vector<Sphere> g_spheres;
static OSPGeometry g_spheresGeometry;
static OSPModel g_model;

std::vector<Sphere> generateRandomSpheres(size_t numSpheres)
{
  // create random number distributions for sphere center, radius, and color
  std::random_device rd;
  std::mt19937 gen(rd());

  std::uniform_real_distribution<float> centerDistribution(-1.f, 1.f);
  std::uniform_real_distribution<float> radiusDistribution(0.05f, 0.15f);
  std::uniform_real_distribution<float> colorDistribution(0.5f, 1.f);

  // populate the spheres
  std::vector<Sphere> spheres(numSpheres);

  for (auto &s : spheres) {
    // maximum height above y=-1 ground plane
    s.maxHeight = 1.f + centerDistribution(gen);

    s.center.x = centerDistribution(gen);
    s.center.y = s.maxHeight;
    s.center.z = centerDistribution(gen);

    s.radius = radiusDistribution(gen);

    s.color.x = colorDistribution(gen);
    s.color.y = colorDistribution(gen);
    s.color.z = colorDistribution(gen);
    s.color.w = colorDistribution(gen);
  }

  return spheres;
}

OSPGeometry createGroundPlaneGeometry()
{
  OSPGeometry planeGeometry = ospNewGeometry("quads");

  struct Vertex
  {
    ospcommon::vec3f position;
    ospcommon::vec3f normal;
    ospcommon::vec4f color;
  };

  struct QuadIndex
  {
    int x;
    int y;
    int z;
    int w;
  };

  std::vector<Vertex> vertices;
  std::vector<QuadIndex> quadIndices;

  // ground plane
  int startingIndex = vertices.size();

  // extent of plane in the (x, z) directions
  const float planeExtent = 1.5f;

  const ospcommon::vec3f up   = ospcommon::vec3f{0.f, 1.f, 0.f};
  const ospcommon::vec4f gray = ospcommon::vec4f{0.9f, 0.9f, 0.9f, 0.75f};

  vertices.push_back(
      Vertex{ospcommon::vec3f{-planeExtent, -1.f, -planeExtent}, up, gray});
  vertices.push_back(
      Vertex{ospcommon::vec3f{planeExtent, -1.f, -planeExtent}, up, gray});
  vertices.push_back(
      Vertex{ospcommon::vec3f{planeExtent, -1.f, planeExtent}, up, gray});
  vertices.push_back(
      Vertex{ospcommon::vec3f{-planeExtent, -1.f, planeExtent}, up, gray});

  quadIndices.push_back(QuadIndex{startingIndex,
                                  startingIndex + 1,
                                  startingIndex + 2,
                                  startingIndex + 3});

  // stripes on ground plane
  const float stripeWidth  = 0.025f;
  const float paddedExtent = planeExtent + stripeWidth;
  const size_t numStripes  = 10;

  const ospcommon::vec4f stripeColor =
      ospcommon::vec4f{1.0f, 0.1f, 0.1f, 1.f};

  for (size_t i = 0; i < numStripes; i++) {
    // the center coordinate of the stripe, either in the x or z direction
    const float coord =
        -planeExtent + float(i) / float(numStripes - 1) * 2.f * planeExtent;

    // offset the stripes by an epsilon above the ground plane
    const float yLevel = -1.f + 1e-3f;

    // x-direction stripes
    startingIndex = vertices.size();

    vertices.push_back(
        Vertex{ospcommon::vec3f{-paddedExtent, yLevel, coord - stripeWidth},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{paddedExtent, yLevel, coord - stripeWidth},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{paddedExtent, yLevel, coord + stripeWidth},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{-paddedExtent, yLevel, coord + stripeWidth},
               up,
               stripeColor});

    quadIndices.push_back(QuadIndex{startingIndex,
                                    startingIndex + 1,
                                    startingIndex + 2,
                                    startingIndex + 3});

    // z-direction stripes
    startingIndex = vertices.size();

    vertices.push_back(
        Vertex{ospcommon::vec3f{coord - stripeWidth, yLevel, -paddedExtent},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{coord + stripeWidth, yLevel, -paddedExtent},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{coord + stripeWidth, yLevel, paddedExtent},
               up,
               stripeColor});
    vertices.push_back(
        Vertex{ospcommon::vec3f{coord - stripeWidth, yLevel, paddedExtent},
               up,
               stripeColor});

    quadIndices.push_back(QuadIndex{startingIndex,
                                    startingIndex + 1,
                                    startingIndex + 2,
                                    startingIndex + 3});
  }

  // create OSPRay data objects
  std::vector<ospcommon::vec3f> positionVector;
  std::vector<ospcommon::vec3f> normalVector;
  std::vector<ospcommon::vec4f> colorVector;

  std::transform(vertices.begin(),
                 vertices.end(),
                 std::back_inserter(positionVector),
                 [](Vertex const &v) { return v.position; });
  std::transform(vertices.begin(),
                 vertices.end(),
                 std::back_inserter(normalVector),
                 [](Vertex const &v) { return v.normal; });
  std::transform(vertices.begin(),
                 vertices.end(),
                 std::back_inserter(colorVector),
                 [](Vertex const &v) { return v.color; });

  OSPData positionData =
      ospNewData(vertices.size(), OSP_FLOAT3, positionVector.data());
  OSPData normalData =
      ospNewData(vertices.size(), OSP_FLOAT3, normalVector.data());
  OSPData colorData =
      ospNewData(vertices.size(), OSP_FLOAT4, colorVector.data());
  OSPData indexData =
      ospNewData(quadIndices.size(), OSP_INT4, quadIndices.data());

  // set vertex / index data on the geometry
  ospSetData(planeGeometry, "vertex", positionData);
  ospSetData(planeGeometry, "vertex.normal", normalData);
  ospSetData(planeGeometry, "vertex.color", colorData);
  ospSetData(planeGeometry, "index", indexData);

  // create and assign a material to the geometry
  OSPMaterial material = ospNewMaterial2("pathtracer", "OBJMaterial");
  ospCommit(material);

  ospSetMaterial(planeGeometry, material);

  // finally, commit the geometry
  ospCommit(planeGeometry);

  // release handles we no longer need
  ospRelease(positionData);
  ospRelease(normalData);
  ospRelease(colorData);
  ospRelease(indexData);
  ospRelease(material);

  return planeGeometry;
}

OSPGeometry createRandomSpheresGeometry(size_t numSpheres)
{
  g_spheres = generateRandomSpheres(numSpheres);

  // create a data object with all the sphere information
  OSPData spheresData =
      ospNewData(numSpheres * sizeof(Sphere), OSP_UCHAR, g_spheres.data());

  // create the sphere geometry, and assign attributes
  g_spheresGeometry = ospNewGeometry("spheres");

  ospSetData(g_spheresGeometry, "spheres", spheresData);
  ospSet1i(g_spheresGeometry, "bytes_per_sphere", int(sizeof(Sphere)));
  ospSet1i(g_spheresGeometry, "offset_center", int(offsetof(Sphere, center)));
  ospSet1i(g_spheresGeometry, "offset_radius", int(offsetof(Sphere, radius)));

  ospSetData(g_spheresGeometry, "color", spheresData);
  ospSet1i(g_spheresGeometry, "color_offset", int(offsetof(Sphere, color)));
  ospSet1i(g_spheresGeometry, "color_format", int(OSP_FLOAT4));
  ospSet1i(g_spheresGeometry, "color_stride", int(sizeof(Sphere)));

  // create glass material and assign to geometry
  OSPMaterial glassMaterial = ospNewMaterial2("pathtracer", "ThinGlass");
  ospSet1f(glassMaterial, "attenuationDistance", 0.2f);
  ospCommit(glassMaterial);

  ospSetMaterial(g_spheresGeometry, glassMaterial);

  // commit the spheres geometry
  ospCommit(g_spheresGeometry);

  // release handles we no longer need
  ospRelease(spheresData);
  ospRelease(glassMaterial);

  return g_spheresGeometry;
}

OSPModel createModel()
{
  // create the "world" model which will contain all of our geometries
  OSPModel world = ospNewModel();

  // add in spheres geometry (100 of them)
  ospAddGeometry(world, createRandomSpheresGeometry(100));

  // add in a ground plane geometry
  ospAddGeometry(world, createGroundPlaneGeometry());

  // commit the world model
  ospCommit(world);

  return world;
}

OSPRenderer createRenderer()
{
  // create OSPRay renderer
  OSPRenderer renderer = ospNewRenderer("pathtracer");

  // create an ambient light
  OSPLight ambientLight = ospNewLight3("ambient");
  ospCommit(ambientLight);

  // create lights data containing all lights
  OSPLight lights[]  = {ambientLight};
  OSPData lightsData = ospNewData(1, OSP_LIGHT, lights, 0);
  ospCommit(lightsData);

  // set the lights to the renderer
  ospSetData(renderer, "lights", lightsData);

  // increase the samples per pixel
  ospSet1i(renderer, "spp", 4);

  // commit the renderer
  ospCommit(renderer);

  // release handles we no longer need
  ospRelease(lightsData);

  return renderer;
}

// updates the bouncing spheres coordinates based on simple gravity model
void updateSpheresCoordinates()
{
  // update the current spheres' heights based on current "time"
  static float t = 0.f;

  for (auto &s : g_spheres) {
    const float g = 9.81f;
    const float T = sqrtf(8.f*s.maxHeight/g);
    const float Vmax = sqrtf(2.f*s.maxHeight*g);

    float tRemainder = fmod(0.5f*T+t, T);

    s.center.y = -1.f + s.radius - 0.5f*g*tRemainder*tRemainder + Vmax*tRemainder;
  }

  // increment by fixed time interval, rather than actual elapsed time
  t += 0.01f;
}

void updateSpheresGeometry()
{
  // create new spheres data for the updated center coordinates, and assign to geometry
  OSPData spheresData =
      ospNewData(g_spheres.size() * sizeof(Sphere), OSP_UCHAR, g_spheres.data());

  ospSetData(g_spheresGeometry, "spheres", spheresData);

  // commit the updated spheres geometry
  ospCommit(g_spheresGeometry);

  // release handles we no longer need
  ospRelease(spheresData);
}

// updates the bouncing spheres' coordinates, geometry, and model
void displayCallback(GLFWOSPRayWindow * glfwOSPRayWindow)
{
  // update the spheres coordinates and geometry
  updateSpheresCoordinates();
  updateSpheresGeometry();

  // commit the model since the spheres geometry changed
  ospCommit(g_model);

  // update the model on the GLFW window
  glfwOSPRayWindow->setModel(g_model);
}

int main(int argc, const char **argv)
{
  // initialize OSPRay; OSPRay parses (and removes) its commandline parameters,
  // e.g. "--osp:debug"
  OSPError initError = ospInit(&argc, argv);

  if (initError != OSP_NO_ERROR)
    return initError;

  // set an error callback to catch any OSPRay errors and exit the application
  ospDeviceSetErrorFunc(
      ospGetCurrentDevice(), [](OSPError error, const char *errorDetails) {
        std::cerr << "OSPRay error: " << errorDetails << std::endl;
        exit(error);
      });

  // create OSPRay model
  g_model = createModel();

  // create OSPRay renderer
  OSPRenderer renderer = createRenderer();

  // create a GLFW OSPRay window: this object will create and manage the OSPRay
  // frame buffer and camera directly
  auto glfwOSPRayWindow =
      std::unique_ptr<GLFWOSPRayWindow>(new GLFWOSPRayWindow(
          ospcommon::vec2i{1024, 768},
          ospcommon::box3f(ospcommon::vec3f(-1.f), ospcommon::vec3f(1.f)),
          g_model,
          renderer));

  // register a callback with the GLFW OSPRay window to update the model every frame
  glfwOSPRayWindow->registerDisplayCallback(
      std::function<void(GLFWOSPRayWindow *)>(displayCallback));

  // start the GLFW main loop, which will continuously render
  glfwOSPRayWindow->mainLoop();

  // cleanly shut OSPRay down
  ospShutdown();

  return 0;
}
<|endoftext|>


<commit_before>#include <Eigen/StdVector>
#include <unsupported/Eigen/BVH>
#include <iostream>

using namespace Eigen;
typedef AlignedBox<double, 2> Box2d;

Box2d internal::bounding_box(const Vector2d &v) { return Box2d(v, v); } //compute the bounding box of a single point

struct PointPointMinimizer //how to compute squared distances between points and rectangles
{
  PointPointMinimizer() : calls(0) {}
  typedef double Scalar;

  double minimumOnVolumeVolume(const Box2d &r1, const Box2d &r2) { ++calls; return r1.squaredExteriorDistance(r2); }
  double minimumOnVolumeObject(const Box2d &r, const Vector2d &v) { ++calls; return r.squaredExteriorDistance(v); }
  double minimumOnObjectVolume(const Vector2d &v, const Box2d &r) { ++calls; return r.squaredExteriorDistance(v); }
  double minimumOnObjectObject(const Vector2d &v1, const Vector2d &v2) { ++calls; return (v1 - v2).squaredNorm(); }

  int calls;
};

int main()
{
  typedef std::vector<Vector2d, aligned_allocator<Vector2d> > StdVectorOfVector2d;
  StdVectorOfVector2d redPoints, bluePoints;
  for(int i = 0; i < 100; ++i) { //initialize random set of red points and blue points
    redPoints.push_back(Vector2d::Random());
    bluePoints.push_back(Vector2d::Random());
  }

  PointPointMinimizer minimizer;
  double minDistSq = std::numeric_limits<double>::max();

  //brute force to find closest red-blue pair
  for(int i = 0; i < (int)redPoints.size(); ++i)
    for(int j = 0; j < (int)bluePoints.size(); ++j)
      minDistSq = std::min(minDistSq, minimizer.minimumOnObjectObject(redPoints[i], bluePoints[j]));
  std::cout << "Brute force distance = " << sqrt(minDistSq) << ", calls = " << minimizer.calls << std::endl;

  //using BVH to find closest red-blue pair
  minimizer.calls = 0;
  KdBVH<double, 2, Vector2d> redTree(redPoints.begin(), redPoints.end()), blueTree(bluePoints.begin(), bluePoints.end()); //construct the trees
  minDistSq = BVMinimize(redTree, blueTree, minimizer); //actual BVH minimization call
  std::cout << "BVH distance         = " << sqrt(minDistSq) << ", calls = " << minimizer.calls << std::endl;

  return 0;
}
<commit_msg>fix doc compilation<commit_after>#include <Eigen/StdVector>
#include <unsupported/Eigen/BVH>
#include <iostream>

using namespace Eigen;
typedef AlignedBox<double, 2> Box2d;

namespace Eigen {
    namespace internal {
        Box2d bounding_box(const Vector2d &v) { return Box2d(v, v); } //compute the bounding box of a single point
    }
}

struct PointPointMinimizer //how to compute squared distances between points and rectangles
{
  PointPointMinimizer() : calls(0) {}
  typedef double Scalar;

  double minimumOnVolumeVolume(const Box2d &r1, const Box2d &r2) { ++calls; return r1.squaredExteriorDistance(r2); }
  double minimumOnVolumeObject(const Box2d &r, const Vector2d &v) { ++calls; return r.squaredExteriorDistance(v); }
  double minimumOnObjectVolume(const Vector2d &v, const Box2d &r) { ++calls; return r.squaredExteriorDistance(v); }
  double minimumOnObjectObject(const Vector2d &v1, const Vector2d &v2) { ++calls; return (v1 - v2).squaredNorm(); }

  int calls;
};

int main()
{
  typedef std::vector<Vector2d, aligned_allocator<Vector2d> > StdVectorOfVector2d;
  StdVectorOfVector2d redPoints, bluePoints;
  for(int i = 0; i < 100; ++i) { //initialize random set of red points and blue points
    redPoints.push_back(Vector2d::Random());
    bluePoints.push_back(Vector2d::Random());
  }

  PointPointMinimizer minimizer;
  double minDistSq = std::numeric_limits<double>::max();

  //brute force to find closest red-blue pair
  for(int i = 0; i < (int)redPoints.size(); ++i)
    for(int j = 0; j < (int)bluePoints.size(); ++j)
      minDistSq = std::min(minDistSq, minimizer.minimumOnObjectObject(redPoints[i], bluePoints[j]));
  std::cout << "Brute force distance = " << sqrt(minDistSq) << ", calls = " << minimizer.calls << std::endl;

  //using BVH to find closest red-blue pair
  minimizer.calls = 0;
  KdBVH<double, 2, Vector2d> redTree(redPoints.begin(), redPoints.end()), blueTree(bluePoints.begin(), bluePoints.end()); //construct the trees
  minDistSq = BVMinimize(redTree, blueTree, minimizer); //actual BVH minimization call
  std::cout << "BVH distance         = " << sqrt(minDistSq) << ", calls = " << minimizer.calls << std::endl;

  return 0;
}
<|endoftext|>


<commit_before>#include "Loop.h"

Loop* Loop::loopInstance = nullptr;
int CallbackData::idCount = 0;

void Loop::process()
{
	for(auto timeout : timeouts)
	{
		if( millis() - timeout->started() > timeout->delay() )
		{
			// call the timeout
			timeout->callback()();
			timeout->reset();
		}
	}
}

int Loop::addTimeout(unsigned long delay, CallbackData::Callback cb)
{
	CallbackData* cbd = new CallbackData(delay, cb);

	timeouts.push_back(cbd);

	return cbd->id();
}

void Loop::removeTimeout(int hnld)
{
	for(auto timeout : timeouts)
	{
		if(timeout->id() == hndl)
		{
			timeouts->erase(timeout);
			delete timeout;
		}
	}
}<commit_msg>more fixes<commit_after>#include "Loop.h"

Loop* Loop::loopInstance = nullptr;
int CallbackData::idCount = 0;

void Loop::process()
{
	for(auto timeout : timeouts)
	{
		if( millis() - timeout->started() > timeout->delay() )
		{
			// call the timeout
			timeout->callback()();
			timeout->reset();
		}
	}
}

int Loop::addTimeout(unsigned long delay, CallbackData::Callback cb)
{
	CallbackData* cbd = new CallbackData(delay, cb);

	timeouts.push_back(cbd);

	return cbd->id();
}

void Loop::removeTimeout(int hndl)
{
	for(auto timeout : timeouts)
	{
		if(timeout->id() == hndl)
		{
			timeouts.erase(timeout);
			delete timeout;
		}
	}
}<|endoftext|>


<commit_before>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "vk_test.h"

// only support on 64-bit, just because it's easier to share CPU & GPU structs if pointer size is
// identical

#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || \
    defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)

struct VK_Buffer_Address : VulkanGraphicsTest
{
  static constexpr const char *Description = "Test capture and replay of VK_EXT_buffer_reference";

  // should match definition below in GLSL
  struct DrawData
  {
    DefaultA2V *vert_data;
    // no alignment on Vec4f, use scalar block layout
    Vec4f tint;
    Vec2f offset;
    Vec2f scale;
    // padding to make the struct size 16 to make aligning the buffer easier.
    Vec2f padding;
  };

  std::string common = R"EOSHADER(

#version 460 core

#extension GL_EXT_buffer_reference : require
#extension GL_EXT_scalar_block_layout : require

struct v2f
{
	vec4 pos;
	vec4 col;
	vec4 uv;
};

struct DefaultA2V {
  vec3 pos;
  vec4 col;
  vec2 uv;
};

layout(bufferreference, scalar, bufferreferencealign = 16) buffer TriangleData {
  DefaultA2V verts[3];
};

layout(bufferreference, scalar, bufferreferencealign = 16) buffer DrawData {
  TriangleData tri;
  vec4 tint;
  vec2 offset;
  vec2 scale;
};

layout(push_constant) uniform PushData {
  DrawData data_ptr;
} push;

)EOSHADER";

  const std::string vertex = R"EOSHADER(

layout(location = 0) out v2f vertOut;

void main()
{
  DrawData draw = push.data_ptr;
  DefaultA2V vert = draw.tri.verts[gl_VertexIndex];

	gl_Position = vertOut.pos = vec4(vert.pos*vec3(draw.scale,1) + vec3(draw.offset, 0), 1);
	vertOut.col = vert.col;
	vertOut.uv = vec4(vert.uv, 0, 1);
}

)EOSHADER";

  const std::string pixel = R"EOSHADER(

layout(location = 0) in v2f vertIn;

layout(location = 0, index = 0) out vec4 Color;

void main()
{
  DrawData draw = push.data_ptr;

	Color = vertIn.col * draw.tint;
}

)EOSHADER";

  void Prepare(int argc, char **argv)
  {
    devExts.push_back(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    devExts.push_back(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);

    VulkanGraphicsTest::Prepare(argc, argv);

    if(!Avail.empty())
      return;

    static VkPhysicalDeviceBufferAddressFeaturesEXT bufaddrFeatures = {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT,
    };

    getPhysFeatures2(&bufaddrFeatures);

    if(!bufaddrFeatures.bufferDeviceAddress)
      Avail = "Buffer device address feature 'bufferDeviceAddress' not available";

    devInfoNext = &bufaddrFeatures;
  }

  int main()
  {
    // initialise, create window, create context, etc
    if(!Init())
      return 3;

    VkPipelineLayout layout = createPipelineLayout(
        vkh::PipelineLayoutCreateInfo({}, {vkh::PushConstantRange(VK_SHADER_STAGE_ALL, 0, 8)}));

    vkh::GraphicsPipelineCreateInfo pipeCreateInfo;

    pipeCreateInfo.layout = layout;
    pipeCreateInfo.renderPass = swapRenderPass;

    pipeCreateInfo.stages = {
        CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
        CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
    };

    VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);

    vkh::BufferCreateInfo bufinfo(0x100000, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT);

    AllocatedBuffer databuf(allocator, bufinfo,
                            VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    // north-facing primary colours triangle
    const DefaultA2V tri1[3] = {
        {Vec3f(-0.5f, -0.5f, 0.0f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(0.0f, 0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)},
        {Vec3f(0.5f, -0.5f, 0.0f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
    };

    // north-west-facing triangle
    const DefaultA2V tri2[3] = {
        {Vec3f(-0.5f, 0.5f, 0.0f), Vec4f(1.0f, 0.2f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(0.5f, 0.5f, 0.0f), Vec4f(0.7f, 0.85f, 1.0f, 1.0f), Vec2f(0.0f, 1.0f)},
        {Vec3f(-0.5f, -0.5f, 0.0f), Vec4f(1.0f, 1.0f, 0.4f, 1.0f), Vec2f(1.0f, 0.0f)},
    };

    VkBufferDeviceAddressInfoEXT info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT};
    info.buffer = databuf.buffer;

    VkDeviceAddress baseAddr = vkGetBufferDeviceAddressEXT(device, &info);
    byte *gpuptr = (byte *)baseAddr;    // not a valid cpu pointer but useful for avoiding casting

    byte *cpuptr = databuf.map();

    // put triangle data first
    memcpy(cpuptr, tri1, sizeof(tri1));
    DefaultA2V *gputri1 = (DefaultA2V *)gpuptr;
    cpuptr += sizeof(tri1);
    gpuptr += sizeof(tri1);

    // align to 16 bytes
    cpuptr = AlignUpPtr(cpuptr, 16);
    gpuptr = AlignUpPtr(gpuptr, 16);

    memcpy(cpuptr, tri2, sizeof(tri2));
    DefaultA2V *gputri2 = (DefaultA2V *)gpuptr;
    cpuptr += sizeof(tri2);
    gpuptr += sizeof(tri2);

    // align to 16 bytes
    cpuptr = AlignUpPtr(cpuptr, 16);
    gpuptr = AlignUpPtr(gpuptr, 16);

    DrawData *drawscpu = (DrawData *)cpuptr;
    DrawData *drawsgpu = (DrawData *)gpuptr;

    drawscpu[0].vert_data = gputri1;
    drawscpu[0].offset = Vec2f(-0.5f, 0.0f);
    drawscpu[0].scale = Vec2f(0.5f, 0.5f);
    drawscpu[0].tint = Vec4f(1.0f, 0.5f, 0.5f, 1.0f);    // tint red

    drawscpu[1].vert_data = gputri1;
    drawscpu[1].offset = Vec2f(0.0f, 0.0f);
    drawscpu[1].scale = Vec2f(0.5f, -0.5f);              // flip vertically
    drawscpu[1].tint = Vec4f(0.2f, 0.5f, 1.0f, 1.0f);    // tint blue

    drawscpu[2].vert_data = gputri2;    // use second triangle
    drawscpu[2].offset = Vec2f(0.6f, 0.0f);
    drawscpu[2].scale = Vec2f(0.5f, 0.5f);
    drawscpu[2].tint = Vec4f(1.0f, 1.0f, 1.0f, 1.0f);

    float time = 0.0f;

    while(Running())
    {
      VkCommandBuffer cmd = GetCommandBuffer();

      vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());

      VkImage swapimg =
          StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
                           vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
                           vkh::ImageSubresourceRange());

      vkCmdBeginRenderPass(
          cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
          VK_SUBPASS_CONTENTS_INLINE);

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
      vkCmdSetViewport(cmd, 0, 1, &viewport);
      vkCmdSetScissor(cmd, 0, 1, &scissor);

      // look ma, no binds
      DrawData *bindptr = drawsgpu;
      drawscpu[0].scale.x = (abs(sinf(time)) + 0.1f) * 0.5f;
      vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_ALL, 0, 8, &bindptr);
      vkCmdDraw(cmd, 3, 1, 0, 0);

      bindptr++;
      drawscpu[1].scale.y = (abs(cosf(time)) + 0.1f) * 0.5f;
      vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_ALL, 0, 8, &bindptr);
      vkCmdDraw(cmd, 3, 1, 0, 0);

      bindptr++;
      drawscpu[2].tint = Vec4f(cosf(time) * 0.5f + 0.5f, sinf(time) * 0.5f + 0.5f,
                               cosf(time + 3.14f) * 0.5f + 0.5f, 1.0f);
      vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_ALL, 0, 8, &bindptr);
      vkCmdDraw(cmd, 3, 1, 0, 0);

      vkCmdEndRenderPass(cmd);

      FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkEndCommandBuffer(cmd);

      Submit(0, 1, {cmd});

      Present();

      time += 0.1f;
    }

    databuf.unmap();

    return 0;
  }
};

REGISTER_TEST(VK_Buffer_Address);

#endif    // if 64-bit<commit_msg>Fix VK_Buffer_Address shader compilation<commit_after>/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2018 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "vk_test.h"

// only support on 64-bit, just because it's easier to share CPU & GPU structs if pointer size is
// identical

#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || \
    defined(__ia64) || defined(_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)

struct VK_Buffer_Address : VulkanGraphicsTest
{
  static constexpr const char *Description = "Test capture and replay of VK_EXT_buffer_reference";

  // should match definition below in GLSL
  struct DrawData
  {
    DefaultA2V *vert_data;
    // no alignment on Vec4f, use scalar block layout
    Vec4f tint;
    Vec2f offset;
    Vec2f scale;
    // padding to make the struct size 16 to make aligning the buffer easier.
    Vec2f padding;
  };

  std::string common = R"EOSHADER(

#version 460 core

#extension GL_EXT_buffer_reference : require
#extension GL_EXT_scalar_block_layout : require

struct v2f
{
	vec4 pos;
	vec4 col;
	vec4 uv;
};

struct DefaultA2V {
  vec3 pos;
  vec4 col;
  vec2 uv;
};

layout(buffer_reference, scalar, buffer_reference_align = 16) buffer TriangleData {
  DefaultA2V verts[3];
};

layout(buffer_reference, scalar, buffer_reference_align = 16) buffer DrawData {
  TriangleData tri;
  vec4 tint;
  vec2 offset;
  vec2 scale;
};

layout(push_constant) uniform PushData {
  DrawData data_ptr;
} push;

)EOSHADER";

  const std::string vertex = R"EOSHADER(

layout(location = 0) out v2f vertOut;

void main()
{
  DrawData draw = push.data_ptr;
  DefaultA2V vert = draw.tri.verts[gl_VertexIndex];

	gl_Position = vertOut.pos = vec4(vert.pos*vec3(draw.scale,1) + vec3(draw.offset, 0), 1);
	vertOut.col = vert.col;
	vertOut.uv = vec4(vert.uv, 0, 1);
}

)EOSHADER";

  const std::string pixel = R"EOSHADER(

layout(location = 0) in v2f vertIn;

layout(location = 0, index = 0) out vec4 Color;

void main()
{
  DrawData draw = push.data_ptr;

	Color = vertIn.col * draw.tint;
}

)EOSHADER";

  void Prepare(int argc, char **argv)
  {
    devExts.push_back(VK_EXT_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME);
    devExts.push_back(VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME);

    VulkanGraphicsTest::Prepare(argc, argv);

    if(!Avail.empty())
      return;

    static VkPhysicalDeviceBufferAddressFeaturesEXT bufaddrFeatures = {
        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT,
    };

    getPhysFeatures2(&bufaddrFeatures);

    if(!bufaddrFeatures.bufferDeviceAddress)
      Avail = "Buffer device address feature 'bufferDeviceAddress' not available";

    devInfoNext = &bufaddrFeatures;
  }

  int main()
  {
    // initialise, create window, create context, etc
    if(!Init())
      return 3;

    VkPipelineLayout layout = createPipelineLayout(
        vkh::PipelineLayoutCreateInfo({}, {vkh::PushConstantRange(VK_SHADER_STAGE_ALL, 0, 8)}));

    vkh::GraphicsPipelineCreateInfo pipeCreateInfo;

    pipeCreateInfo.layout = layout;
    pipeCreateInfo.renderPass = swapRenderPass;

    pipeCreateInfo.stages = {
        CompileShaderModule(common + vertex, ShaderLang::glsl, ShaderStage::vert, "main"),
        CompileShaderModule(common + pixel, ShaderLang::glsl, ShaderStage::frag, "main"),
    };

    VkPipeline pipe = createGraphicsPipeline(pipeCreateInfo);

    vkh::BufferCreateInfo bufinfo(0x100000, VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT_EXT);

    AllocatedBuffer databuf(allocator, bufinfo,
                            VmaAllocationCreateInfo({0, VMA_MEMORY_USAGE_CPU_TO_GPU}));

    // north-facing primary colours triangle
    const DefaultA2V tri1[3] = {
        {Vec3f(-0.5f, -0.5f, 0.0f), Vec4f(1.0f, 0.0f, 0.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(0.0f, 0.5f, 0.0f), Vec4f(0.0f, 1.0f, 0.0f, 1.0f), Vec2f(0.0f, 1.0f)},
        {Vec3f(0.5f, -0.5f, 0.0f), Vec4f(0.0f, 0.0f, 1.0f, 1.0f), Vec2f(1.0f, 0.0f)},
    };

    // north-west-facing triangle
    const DefaultA2V tri2[3] = {
        {Vec3f(-0.5f, 0.5f, 0.0f), Vec4f(1.0f, 0.2f, 1.0f, 1.0f), Vec2f(0.0f, 0.0f)},
        {Vec3f(0.5f, 0.5f, 0.0f), Vec4f(0.7f, 0.85f, 1.0f, 1.0f), Vec2f(0.0f, 1.0f)},
        {Vec3f(-0.5f, -0.5f, 0.0f), Vec4f(1.0f, 1.0f, 0.4f, 1.0f), Vec2f(1.0f, 0.0f)},
    };

    VkBufferDeviceAddressInfoEXT info = {VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT};
    info.buffer = databuf.buffer;

    VkDeviceAddress baseAddr = vkGetBufferDeviceAddressEXT(device, &info);
    byte *gpuptr = (byte *)baseAddr;    // not a valid cpu pointer but useful for avoiding casting

    byte *cpuptr = databuf.map();

    // put triangle data first
    memcpy(cpuptr, tri1, sizeof(tri1));
    DefaultA2V *gputri1 = (DefaultA2V *)gpuptr;
    cpuptr += sizeof(tri1);
    gpuptr += sizeof(tri1);

    // align to 16 bytes
    cpuptr = AlignUpPtr(cpuptr, 16);
    gpuptr = AlignUpPtr(gpuptr, 16);

    memcpy(cpuptr, tri2, sizeof(tri2));
    DefaultA2V *gputri2 = (DefaultA2V *)gpuptr;
    cpuptr += sizeof(tri2);
    gpuptr += sizeof(tri2);

    // align to 16 bytes
    cpuptr = AlignUpPtr(cpuptr, 16);
    gpuptr = AlignUpPtr(gpuptr, 16);

    DrawData *drawscpu = (DrawData *)cpuptr;
    DrawData *drawsgpu = (DrawData *)gpuptr;

    drawscpu[0].vert_data = gputri1;
    drawscpu[0].offset = Vec2f(-0.5f, 0.0f);
    drawscpu[0].scale = Vec2f(0.5f, 0.5f);
    drawscpu[0].tint = Vec4f(1.0f, 0.5f, 0.5f, 1.0f);    // tint red

    drawscpu[1].vert_data = gputri1;
    drawscpu[1].offset = Vec2f(0.0f, 0.0f);
    drawscpu[1].scale = Vec2f(0.5f, -0.5f);              // flip vertically
    drawscpu[1].tint = Vec4f(0.2f, 0.5f, 1.0f, 1.0f);    // tint blue

    drawscpu[2].vert_data = gputri2;    // use second triangle
    drawscpu[2].offset = Vec2f(0.6f, 0.0f);
    drawscpu[2].scale = Vec2f(0.5f, 0.5f);
    drawscpu[2].tint = Vec4f(1.0f, 1.0f, 1.0f, 1.0f);

    float time = 0.0f;

    while(Running())
    {
      VkCommandBuffer cmd = GetCommandBuffer();

      vkBeginCommandBuffer(cmd, vkh::CommandBufferBeginInfo());

      VkImage swapimg =
          StartUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkCmdClearColorImage(cmd, swapimg, VK_IMAGE_LAYOUT_GENERAL,
                           vkh::ClearColorValue(0.4f, 0.5f, 0.6f, 1.0f), 1,
                           vkh::ImageSubresourceRange());

      vkCmdBeginRenderPass(
          cmd, vkh::RenderPassBeginInfo(swapRenderPass, swapFramebuffers[swapIndex], scissor),
          VK_SUBPASS_CONTENTS_INLINE);

      vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipe);
      vkCmdSetViewport(cmd, 0, 1, &viewport);
      vkCmdSetScissor(cmd, 0, 1, &scissor);

      // look ma, no binds
      DrawData *bindptr = drawsgpu;
      drawscpu[0].scale.x = (abs(sinf(time)) + 0.1f) * 0.5f;
      vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_ALL, 0, 8, &bindptr);
      vkCmdDraw(cmd, 3, 1, 0, 0);

      bindptr++;
      drawscpu[1].scale.y = (abs(cosf(time)) + 0.1f) * 0.5f;
      vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_ALL, 0, 8, &bindptr);
      vkCmdDraw(cmd, 3, 1, 0, 0);

      bindptr++;
      drawscpu[2].tint = Vec4f(cosf(time) * 0.5f + 0.5f, sinf(time) * 0.5f + 0.5f,
                               cosf(time + 3.14f) * 0.5f + 0.5f, 1.0f);
      vkCmdPushConstants(cmd, layout, VK_SHADER_STAGE_ALL, 0, 8, &bindptr);
      vkCmdDraw(cmd, 3, 1, 0, 0);

      vkCmdEndRenderPass(cmd);

      FinishUsingBackbuffer(cmd, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);

      vkEndCommandBuffer(cmd);

      Submit(0, 1, {cmd});

      Present();

      time += 0.1f;
    }

    databuf.unmap();

    return 0;
  }
};

REGISTER_TEST(VK_Buffer_Address);

#endif    // if 64-bit<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/ui/ui_test.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/automation_proxy.h"
#include "net/base/net_util.h"

typedef UITest ChromeMainTest;

#if !defined(OS_MACOSX)
// These tests don't apply to the Mac version; see
// LaunchAnotherBrowserBlockUntilClosed for details.

// Make sure that the second invocation creates a new window.
TEST_F(ChromeMainTest, SecondLaunch) {
  include_testing_id_ = false;

  ASSERT_TRUE(LaunchAnotherBrowserBlockUntilClosed(
                  CommandLine(CommandLine::NO_PROGRAM)));

  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2));
}

TEST_F(ChromeMainTest, ReuseBrowserInstanceWhenOpeningFile) {
  include_testing_id_ = false;

  FilePath test_file = test_data_directory_.AppendASCII("empty.html");

  CommandLine command_line(CommandLine::NO_PROGRAM);
  command_line.AppendArgPath(test_file);
  ASSERT_TRUE(LaunchAnotherBrowserBlockUntilClosed(command_line));

  ASSERT_TRUE(automation()->IsURLDisplayed(net::FilePathToFileURL(test_file)));
}

TEST_F(ChromeMainTest, SecondLaunchWithIncognitoUrl) {
  include_testing_id_ = false;
  int num_normal_windows;
  // We should start with one normal window.
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);

  // Run with --incognito switch and an URL specified.
  FilePath test_file = test_data_directory_.AppendASCII("empty.html");
  CommandLine command_line(CommandLine::NO_PROGRAM);
  command_line.AppendSwitch(switches::kIncognito);
  command_line.AppendArgPath(test_file);
  ASSERT_TRUE(LaunchAnotherBrowserBlockUntilClosed(command_line));

  // There should be one normal and one incognito window now.
  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2));
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);
}

TEST_F(ChromeMainTest, SecondLaunchFromIncognitoWithNormalUrl) {
  include_testing_id_ = false;
  int num_normal_windows;
  // We should start with one normal window.
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);

  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser_proxy.get());

  // Create an incognito window.
  ASSERT_TRUE(browser_proxy->RunCommand(IDC_NEW_INCOGNITO_WINDOW));
  int window_count;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(2, window_count);
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);

  // Close the first window.
  ASSERT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW));
  browser_proxy = NULL;

  // There should only be the incognito window open now.
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(1, window_count);
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(0, num_normal_windows);

  // Run with just an URL specified, no --incognito switch.
  FilePath test_file = test_data_directory_.AppendASCII("empty.html");
  CommandLine command_line(CommandLine::NO_PROGRAM);
  command_line.AppendArgPath(test_file);
  ASSERT_TRUE(LaunchAnotherBrowserBlockUntilClosed(command_line));

  // There should be one normal and one incognito window now.
  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2));
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);
}

#endif  // !OS_MACOSX
<commit_msg>Disable ChromeMainTest.ReuseBrowserInstanceWhenOpeningFile which sometimes asserts. BUG=110629 TBR=apatrick@chromium.org Review URL: https://chromiumcodereview.appspot.com/9252023<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/test/ui/ui_test.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/automation/automation_proxy.h"
#include "net/base/net_util.h"

typedef UITest ChromeMainTest;

#if !defined(OS_MACOSX)
// These tests don't apply to the Mac version; see
// LaunchAnotherBrowserBlockUntilClosed for details.

// Make sure that the second invocation creates a new window.
TEST_F(ChromeMainTest, SecondLaunch) {
  include_testing_id_ = false;

  ASSERT_TRUE(LaunchAnotherBrowserBlockUntilClosed(
                  CommandLine(CommandLine::NO_PROGRAM)));

  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2));
}

TEST_F(ChromeMainTest, DISABLED_ReuseBrowserInstanceWhenOpeningFile) {
  include_testing_id_ = false;

  FilePath test_file = test_data_directory_.AppendASCII("empty.html");

  CommandLine command_line(CommandLine::NO_PROGRAM);
  command_line.AppendArgPath(test_file);
  ASSERT_TRUE(LaunchAnotherBrowserBlockUntilClosed(command_line));

  ASSERT_TRUE(automation()->IsURLDisplayed(net::FilePathToFileURL(test_file)));
}

TEST_F(ChromeMainTest, SecondLaunchWithIncognitoUrl) {
  include_testing_id_ = false;
  int num_normal_windows;
  // We should start with one normal window.
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);

  // Run with --incognito switch and an URL specified.
  FilePath test_file = test_data_directory_.AppendASCII("empty.html");
  CommandLine command_line(CommandLine::NO_PROGRAM);
  command_line.AppendSwitch(switches::kIncognito);
  command_line.AppendArgPath(test_file);
  ASSERT_TRUE(LaunchAnotherBrowserBlockUntilClosed(command_line));

  // There should be one normal and one incognito window now.
  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2));
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);
}

TEST_F(ChromeMainTest, SecondLaunchFromIncognitoWithNormalUrl) {
  include_testing_id_ = false;
  int num_normal_windows;
  // We should start with one normal window.
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);

  scoped_refptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser_proxy.get());

  // Create an incognito window.
  ASSERT_TRUE(browser_proxy->RunCommand(IDC_NEW_INCOGNITO_WINDOW));
  int window_count;
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(2, window_count);
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);

  // Close the first window.
  ASSERT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW));
  browser_proxy = NULL;

  // There should only be the incognito window open now.
  ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count));
  ASSERT_EQ(1, window_count);
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(0, num_normal_windows);

  // Run with just an URL specified, no --incognito switch.
  FilePath test_file = test_data_directory_.AppendASCII("empty.html");
  CommandLine command_line(CommandLine::NO_PROGRAM);
  command_line.AppendArgPath(test_file);
  ASSERT_TRUE(LaunchAnotherBrowserBlockUntilClosed(command_line));

  // There should be one normal and one incognito window now.
  ASSERT_TRUE(automation()->WaitForWindowCountToBecome(2));
  ASSERT_TRUE(automation()->GetNormalBrowserWindowCount(&num_normal_windows));
  ASSERT_EQ(1, num_normal_windows);
}

#endif  // !OS_MACOSX
<|endoftext|>