<commit_before>    #include "Pipeline.h"
#include "Processor.h"
#include <cassert>
using namespace std;

namespace Simulator
{

Pipeline::PipeAction Pipeline::MemoryStage::OnCycle()
{
    PipeValue rcv = m_input.Rcv;

    if (m_input.size > 0)
    {
        // It's a new memory operation!
        assert(m_input.size <= sizeof(uint64_t));

        Result result = SUCCESS;
        if (rcv.m_state == RST_FULL)
        {
            // Memory write

            // Serialize and store data
            char data[MAX_MEMORY_OPERATION_SIZE];

            uint64_t value = 0;
            switch (m_input.Rc.type) {
                case RT_INTEGER: value = m_input.Rcv.m_integer.get(m_input.Rcv.m_size); break;
                case RT_FLOAT:   value = m_input.Rcv.m_float.toint(m_input.Rcv.m_size); break;
                default: assert(0);
            }

            SerializeRegister(m_input.Rc.type, value, data, (size_t)m_input.size);

            if ((result = m_dcache.Write(m_input.address, data, m_input.size, m_input.fid, m_input.tid)) == FAILED)
            {
                // Stall
                return PIPE_STALL;
            }

            // Clear the register state so it won't get written to the register file
            rcv.m_state = RST_INVALID;
        }
        // Memory read
        else if (m_input.address > numeric_limits<MemAddr>::max() - 31)
        {
            // Invalid address; don't send request, just clear register
            rcv = MAKE_EMPTY_PIPEVALUE(rcv.m_size);
        }
        else if (m_input.address > numeric_limits<MemAddr>::max() - 255)
        {
            // Special range for obtaining profiling information. Rather hackish.
            MemAddr i = (m_input.address - (numeric_limits<MemAddr>::max() - 255)) / sizeof(Integer);
            rcv.m_state = RST_FULL;
            rcv.m_size  = m_input.Rcv.m_size;
            rcv.m_integer.set( m_parent.GetProcessor().GetProfileWord(i), rcv.m_size);
        }
        else if (m_input.Rc.valid())
        {
            // Memory read
            char data[MAX_MEMORY_OPERATION_SIZE];
			RegAddr reg = m_input.Rc;
            if ((result = m_dcache.Read(m_input.address, data, m_input.size, m_input.fid, &reg)) == FAILED)
            {
                // Stall
                return PIPE_STALL;
            }

            rcv.m_size = m_input.Rcv.m_size;
            if (result == SUCCESS)
            {
                // Unserialize and store data
                uint64_t value = UnserializeRegister(m_input.Rc.type, data, (size_t)m_input.size);

                if (m_input.sign_extend)
                {
                    // Sign-extend the value
                    size_t shift = (sizeof(value) - (size_t)m_input.size) * 8;
                    value = (int64_t)(value << shift) >> shift;
                }

                rcv.m_state = RST_FULL;
                switch (m_input.Rc.type)
                {
                case RT_INTEGER: rcv.m_integer.set(value, rcv.m_size); break;
                case RT_FLOAT:   rcv.m_float.fromint(value, rcv.m_size); break;
                default:         assert(0);
                }
            }
			else
			{
				// Remember request data
	            rcv = MAKE_PENDING_PIPEVALUE(rcv.m_size);
				rcv.m_memory.fid         = m_input.fid;
				rcv.m_memory.next        = reg;
				rcv.m_memory.offset      = (unsigned int)(m_input.address % m_dcache.GetLineSize());
				rcv.m_memory.size        = (size_t)m_input.size;
				rcv.m_memory.sign_extend = m_input.sign_extend;
				rcv.m_remote             = m_input.Rrc;
			}
        }

        if (result == DELAYED)
        {
            // Increase the outstanding memory count for the family
            if (m_input.Rcv.m_state == RST_FULL)
            {
                if (!m_allocator.IncreaseThreadDependency(m_input.tid, THREADDEP_OUTSTANDING_WRITES))
                {
                    return PIPE_STALL;
                }
            }
            else if (!m_allocator.OnMemoryRead(m_input.fid))
            {
                return PIPE_STALL;
            }
        }
    }

    COMMIT
    {
        // Copy common latch data
        (CommonData&)m_output = m_input;

        m_output.suspend = m_input.suspend;
        m_output.Rc      = m_input.Rc;
        m_output.Rrc     = m_input.Rrc;
        m_output.Rcv     = rcv;
    }
    return PIPE_CONTINUE;
}

Pipeline::MemoryStage::MemoryStage(Pipeline& parent, const ExecuteMemoryLatch& input, MemoryWritebackLatch& output, DCache& dcache, Allocator& alloc, const Config& /*config*/)
  : Stage(parent, "memory"),
    m_input(input),
    m_output(output),
    m_allocator(alloc),
    m_dcache(dcache)
{
}

}
<commit_msg>mgsim: fixed runtime profiling bug<commit_after>    #include "Pipeline.h"
#include "Processor.h"
#include <cassert>
using namespace std;

namespace Simulator
{

Pipeline::PipeAction Pipeline::MemoryStage::OnCycle()
{
    PipeValue rcv = m_input.Rcv;

    if (m_input.size > 0)
    {
        // It's a new memory operation!
        assert(m_input.size <= sizeof(uint64_t));

        Result result = SUCCESS;
        if (rcv.m_state == RST_FULL)
        {
            // Memory write

            // Serialize and store data
            char data[MAX_MEMORY_OPERATION_SIZE];

            uint64_t value = 0;
            switch (m_input.Rc.type) {
                case RT_INTEGER: value = m_input.Rcv.m_integer.get(m_input.Rcv.m_size); break;
                case RT_FLOAT:   value = m_input.Rcv.m_float.toint(m_input.Rcv.m_size); break;
                default: assert(0);
            }

            SerializeRegister(m_input.Rc.type, value, data, (size_t)m_input.size);

            if ((result = m_dcache.Write(m_input.address, data, m_input.size, m_input.fid, m_input.tid)) == FAILED)
            {
                // Stall
                return PIPE_STALL;
            }

            // Clear the register state so it won't get written to the register file
            rcv.m_state = RST_INVALID;
        }
        // Memory read
        else if (m_input.address >= numeric_limits<MemAddr>::max() - 31)
        {
            // Invalid address; don't send request, just clear register
            rcv = MAKE_EMPTY_PIPEVALUE(rcv.m_size);
        }
        else if (m_input.address >= numeric_limits<MemAddr>::max() - 255)
        {
            // Special range for obtaining profiling information. Rather hackish.
            MemAddr i = (m_input.address - (numeric_limits<MemAddr>::max() - 255)) / sizeof(Integer);
            rcv.m_state = RST_FULL;
            rcv.m_size  = m_input.Rcv.m_size;
            rcv.m_integer.set( m_parent.GetProcessor().GetProfileWord(i), rcv.m_size);
        }
        else if (m_input.Rc.valid())
        {
            // Memory read
            char data[MAX_MEMORY_OPERATION_SIZE];
			RegAddr reg = m_input.Rc;
            if ((result = m_dcache.Read(m_input.address, data, m_input.size, m_input.fid, &reg)) == FAILED)
            {
                // Stall
                return PIPE_STALL;
            }

            rcv.m_size = m_input.Rcv.m_size;
            if (result == SUCCESS)
            {
                // Unserialize and store data
                uint64_t value = UnserializeRegister(m_input.Rc.type, data, (size_t)m_input.size);

                if (m_input.sign_extend)
                {
                    // Sign-extend the value
                    size_t shift = (sizeof(value) - (size_t)m_input.size) * 8;
                    value = (int64_t)(value << shift) >> shift;
                }

                rcv.m_state = RST_FULL;
                switch (m_input.Rc.type)
                {
                case RT_INTEGER: rcv.m_integer.set(value, rcv.m_size); break;
                case RT_FLOAT:   rcv.m_float.fromint(value, rcv.m_size); break;
                default:         assert(0);
                }
            }
			else
			{
				// Remember request data
	            rcv = MAKE_PENDING_PIPEVALUE(rcv.m_size);
				rcv.m_memory.fid         = m_input.fid;
				rcv.m_memory.next        = reg;
				rcv.m_memory.offset      = (unsigned int)(m_input.address % m_dcache.GetLineSize());
				rcv.m_memory.size        = (size_t)m_input.size;
				rcv.m_memory.sign_extend = m_input.sign_extend;
				rcv.m_remote             = m_input.Rrc;
			}
        }

        if (result == DELAYED)
        {
            // Increase the outstanding memory count for the family
            if (m_input.Rcv.m_state == RST_FULL)
            {
                if (!m_allocator.IncreaseThreadDependency(m_input.tid, THREADDEP_OUTSTANDING_WRITES))
                {
                    return PIPE_STALL;
                }
            }
            else if (!m_allocator.OnMemoryRead(m_input.fid))
            {
                return PIPE_STALL;
            }
        }
    }

    COMMIT
    {
        // Copy common latch data
        (CommonData&)m_output = m_input;

        m_output.suspend = m_input.suspend;
        m_output.Rc      = m_input.Rc;
        m_output.Rrc     = m_input.Rrc;
        m_output.Rcv     = rcv;
    }
    return PIPE_CONTINUE;
}

Pipeline::MemoryStage::MemoryStage(Pipeline& parent, const ExecuteMemoryLatch& input, MemoryWritebackLatch& output, DCache& dcache, Allocator& alloc, const Config& /*config*/)
  : Stage(parent, "memory"),
    m_input(input),
    m_output(output),
    m_allocator(alloc),
    m_dcache(dcache)
{
}

}
<|endoftext|>


<commit_before>#include "PicoBorgRev.hpp"
#include <errno.h>
#include <fcntl.h>
#include "I2CCommunicator.hpp"
#include "I2CException.hpp"
#include <inttypes.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include "PicoBorgRevException.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

PicoBorgRev::PicoBorgRev(I2CCommunicator *communicator, uint8_t pbrAddress)
{
	if (PicoBorgRev::checkId(communicator, pbrAddress)) {
		printf("PBR board found\n");
		this->communicator = communicator;
		this->pbrAddress = pbrAddress;

		//clear buffers
		for (int i = 0; i < BUFFER_MAX; i++) {
			bufIn[i] = 0x0;
			bufOut[i] = 0x0;
		}

	} else {
		char message[70];
		snprintf(message, sizeof(message) - 1, "Board on address %d on bus %d is not a pbr!", pbrAddress, communicator->getBusnumber());
		throw PicoBorgRevException(message);
	}
}

uint8_t PicoBorgRev::scanForAddress(uint8_t index, I2CCommunicator *communicator)
{
	uint8_t found = 0;
	uint8_t pbrAddress;
	for (pbrAddress = PBR_MINIMUM_I2C_ADDRESS; pbrAddress <= PBR_MAXIMUM_I2C_ADDRESS; pbrAddress++) {
		if (PicoBorgRev::checkId(communicator, pbrAddress)) {
			if (index <= 0) {
				found = pbrAddress;
				break;
			} else {
				index--;
			}
		}
	}
	return found;
}

bool PicoBorgRev::checkId(I2CCommunicator *communicator, uint8_t pbrAddress)
{
	communicator->setTarget(pbrAddress);
	uint8_t bufOut[BUFFER_MAX];
	uint8_t bufIn[BUFFER_MAX];
	bufOut[0] = PBR_COMMAND_GET_ID;
	try {
		if (communicator->send(bufOut, 1)  == I2C_ERROR_OK) {
			printf("Send to address 0x%02x\n", pbrAddress);
			if (communicator->rec(bufIn, 2) == I2C_ERROR_OK) {
				printf("Recieved message: 0x%02x\n", bufIn[1]);
				return (bufIn[1] == PBR_I2C_ID_PICOBORG_REV);
		      }
		}
	} catch (const I2CException& e) {

	}
	printf("Board not a pbr\n");
	return false;

}

int main(int argc, char **argv)
{
	//printf("PicoBorgRev found on: 0x%02x \n", PicoBorgRevInitialise(true));
	I2CCommunicator * com = new I2CCommunicator();
	uint8_t address = PicoBorgRev::scanForAddress(1, com);
	PicoBorgRev *pbr = new PicoBorgRev(com, address);
	delete pbr;
	delete com;
}
<commit_msg>bug fix<commit_after>#include "PicoBorgRev.hpp"
#include <errno.h>
#include <fcntl.h>
#include "I2CCommunicator.hpp"
#include "I2CException.hpp"
#include <inttypes.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include "PicoBorgRevException.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

PicoBorgRev::PicoBorgRev(I2CCommunicator *communicator, uint8_t pbrAddress)
{
	if (PicoBorgRev::checkId(communicator, pbrAddress)) {
		printf("PBR board found on 0x%02x\n", pbrAddress);
		this->communicator = communicator;
		this->pbrAddress = pbrAddress;

		//clear buffers
		for (int i = 0; i < BUFFER_MAX; i++) {
			bufIn[i] = 0x0;
			bufOut[i] = 0x0;
		}

	} else {
		char message[70];
		snprintf(message, sizeof(message) - 1, "Board on address 0x%02x on bus %d is not a pbr!", pbrAddress, communicator->getBusnumber());
		throw PicoBorgRevException(message);
	}
}

uint8_t PicoBorgRev::scanForAddress(uint8_t index, I2CCommunicator *communicator)
{
	uint8_t found = 0;
	uint8_t pbrAddress;
	for (pbrAddress = PBR_MINIMUM_I2C_ADDRESS; pbrAddress <= PBR_MAXIMUM_I2C_ADDRESS; pbrAddress++) {
		if (PicoBorgRev::checkId(communicator, pbrAddress)) {
			if (index <= 0) {
				found = pbrAddress;
				break;
			} else {
				index--;
			}
		}
	}
	return found;
}

bool PicoBorgRev::checkId(I2CCommunicator *communicator, uint8_t pbrAddress)
{
	communicator->setTarget(pbrAddress);
	uint8_t bufOut[BUFFER_MAX];
	uint8_t bufIn[BUFFER_MAX];
	bufOut[0] = PBR_COMMAND_GET_ID;
	try {
		if (communicator->send(bufOut, 1)  == I2C_ERROR_OK) {
			printf("Send to address 0x%02x\n", pbrAddress);
			if (communicator->rec(bufIn, 2) == I2C_ERROR_OK) {
				printf("Recieved message: 0x%02x\n", bufIn[1]);
				return (bufIn[1] == PBR_I2C_ID_PICOBORG_REV);
		      }
		}
	} catch (const I2CException& e) {

	}
	printf("No pbr on 0x%02x\n", pbrAddress);
	return false;

}

int main(int argc, char **argv)
{
	//printf("PicoBorgRev found on: 0x%02x \n", PicoBorgRevInitialise(true));
	I2CCommunicator * com = new I2CCommunicator();
	uint8_t address = PicoBorgRev::scanForAddress(0, com);
	printf("Found 0x%02x", address);
	PicoBorgRev *pbr = new PicoBorgRev(com, address);
	delete pbr;
	delete com;
}
<|endoftext|>


<commit_before>#include <sh/sh.hpp>
#include <sh/shutil.hpp>
#include <iostream>
#include "Shader.hpp"
#include "Globals.hpp"

using namespace SH;
using namespace ShUtil;

class SimplePhong : public Shader {
public:
  SimplePhong();
  ~SimplePhong();

  bool init();

  ShProgram vertex() { return vsh;}
  ShProgram fragment() { return fsh;}

  ShProgram vsh, fsh;

  static SimplePhong instance;
};

SimplePhong::SimplePhong()
  : Shader("Basic Lighting Models: Phong: Classic Phong")
{
}

SimplePhong::~SimplePhong()
{
}

bool SimplePhong::init()
{
  vsh = SH_BEGIN_PROGRAM("gpu:vertex") {
    ShInputPosition4f ipos;
    ShInputNormal3f inorm;

    ShOutputPosition4f opos; // Position in NDC
    ShOutputNormal3f onorm;
    ShInOutTexCoord2f tc; // pass through tex coords
    ShOutputVector3f view;
    ShOutputVector3f halfv;
    ShOutputVector3f lightv; // direction to light

    opos = Globals::mvp | ipos; // Compute NDC position
    onorm = Globals::mv | inorm; // Compute view-space normal

    ShPoint3f posv = (Globals::mv | ipos)(0,1,2); // Compute view-space position
    lightv = normalize(Globals::lightPos - posv); // Compute light direction

    ShPoint3f viewv = -normalize(posv); // Compute view vector
    view = normalize(viewv - posv);
    halfv = normalize(viewv + lightv); // Compute half vector
  } SH_END;

  ShColor3f SH_DECL(specular) = ShColor3f(0.5, 1.0, 1.0);
  ShColor3f SH_DECL(diffuse) = ShColor3f(1.0, 0.0, 0.0);
  ShAttrib1f SH_DECL(exponent) = ShAttrib1f(35.0);
  exponent.range(5.0f, 500.0f);

  fsh = SH_BEGIN_PROGRAM("gpu:fragment") {
    ShInputNormal3f normal;
    ShInputTexCoord2f tc; // ignore texcoords
    ShInputVector3f view;
    ShInputVector3f half;
    ShInputVector3f light;
    ShInputPosition4f posh;

    ShOutputColor3f result;
    normal = normalize(normal);
    half = normalize(half);
    light = normalize(light);

    // Compute phong lighting.
    ShMatrix3x3f identity = ShMatrix3x3f();
    ShMatrix3x1f normalmat; // to transpose the normal
    normalmat[0] = sqrt(2) * normal[0]; // need to multiply the matrix by 2
    normalmat[1] = sqrt(2) * normal[1];
    normalmat[2] = sqrt(2) * normal[2];
    ShMatrix3x3f Householder = (normalmat | transpose(normalmat));
    Householder -= identity; // Compuse Householder transformation matrix
    ShMatrix1x3f viewtranspose; // to transpose the view vector
    viewtranspose[0][0] = view[0];
    viewtranspose[0][1] = view[1];
    viewtranspose[0][2] = view[2];
    ShAttrib1f irrad = pos(normal | light);
    result = diffuse * irrad + specular * pow(pos(viewtranspose | Householder | light), exponent) / (normal | light);
  } SH_END;
  return true;
}

SimplePhong SimplePhong::instance = SimplePhong();

// the modified Phong model
class ModifiedPhong : public Shader {
public:
  ModifiedPhong();
  ~ModifiedPhong();

  bool init();

  ShProgram vertex() { return vsh;}
  ShProgram fragment() { return fsh;}

  ShProgram vsh, fsh;

  static ModifiedPhong instance;
};

ModifiedPhong::ModifiedPhong()
  : Shader("Basic Lighting Models: Phong: Modified Phong")
{
}

ModifiedPhong::~ModifiedPhong()
{
}

bool ModifiedPhong::init()
{
  vsh = SH_BEGIN_PROGRAM("gpu:vertex") {
    ShInputPosition4f ipos;
    ShInputNormal3f inorm;

    ShOutputPosition4f opos; // Position in NDC
    ShOutputNormal3f onorm;
    ShInOutTexCoord2f tc; // pass through tex coords
    ShOutputVector3f view;
    ShOutputVector3f halfv;
    ShOutputVector3f lightv; // direction to light

    opos = Globals::mvp | ipos; // Compute NDC position
    onorm = Globals::mv | inorm; // Compute view-space normal

    ShPoint3f posv = (Globals::mv | ipos)(0,1,2); // Compute view-space position
    lightv = normalize(Globals::lightPos - posv); // Compute light direction

    ShPoint3f viewv = -normalize(posv); // Compute view vector
    view = normalize(viewv - posv);
    halfv = normalize(viewv + lightv); // Compute half vector
  } SH_END;

  ShAttrib1f SH_DECL(kd) = 1.0f;
  kd.range(0.0f, 10.0f);
  ShColor3f SH_DECL(specular) = ShColor3f(0.5, 1.0, 1.0);
  ShColor3f SH_DECL(diffuse) = ShColor3f(1.0, 0.0, 0.0);
  ShAttrib1f SH_DECL(exponent) = ShAttrib1f(35.0);
  exponent.range(5.0f, 500.0f);

  fsh = SH_BEGIN_PROGRAM("gpu:fragment") {
    ShInputNormal3f normal;
    ShInputTexCoord2f tc; // ignore texcoords
    ShInputVector3f view;
    ShInputVector3f half;
    ShInputVector3f light;
    ShInputPosition4f posh;

    ShOutputColor3f result;

    normal = normalize(normal);
    half = normalize(half);
    light = normalize(light);

    // Compute phong lighting.
    ShAttrib1f irrad = pos(normal | light);
    ShMatrix3x3f identity = ShMatrix3x3f();
    ShMatrix3x1f normalmat; // to transpose the normal
    normalmat[0] = sqrt(2) * normal[0]; // need to multiply the matrix by 2
    normalmat[1] = sqrt(2) * normal[1];
    normalmat[2] = sqrt(2) * normal[2];
    ShMatrix3x3f Householder = (normalmat | transpose(normalmat));
    Householder -= identity; // Compuse Householder transformation matrix
    ShMatrix1x3f viewtranspose; // to transpose the view vector
    viewtranspose[0][0] = view[0];
    viewtranspose[0][1] = view[1];
    viewtranspose[0][2] = view[2];
    result = kd * diffuse * irrad / M_PI  +
	    specular * (exponent+2)/(2*M_PI) * pow(pos(viewtranspose | Householder | light), exponent);
  } SH_END;
  return true;
}

ModifiedPhong ModifiedPhong::instance = ModifiedPhong();

// the Blinn-Phong model
class BlinnPhong : public Shader {
public:
  BlinnPhong();
  ~BlinnPhong();

  bool init();

  ShProgram vertex() { return vsh;}
  ShProgram fragment() { return fsh;}

  ShProgram vsh, fsh;

  static BlinnPhong instance;
};

BlinnPhong::BlinnPhong()
  : Shader("Basic Lighting Models: Phong: Blinn-Phong")
{
}

BlinnPhong::~BlinnPhong()
{
}

bool BlinnPhong::init()
{
  vsh = SH_BEGIN_PROGRAM("gpu:vertex") {
    ShInputPosition4f ipos;
    ShInputNormal3f inorm;

    ShOutputPosition4f opos; // Position in NDC
    ShOutputNormal3f onorm;
    ShInOutTexCoord2f tc; // pass through tex coords
    ShOutputVector3f halfv;
    ShOutputVector3f lightv; // direction to light

    opos = Globals::mvp | ipos; // Compute NDC position
    onorm = Globals::mv | inorm; // Compute view-space normal

    ShPoint3f posv = (Globals::mv | ipos)(0,1,2); // Compute view-space position
    lightv = normalize(Globals::lightPos - posv); // Compute light direction

    ShPoint3f viewv = -normalize(posv); // Compute view vector
    halfv = normalize(viewv + lightv); // Compute half vector
  } SH_END;

  ShColor3f SH_DECL(specular) = ShColor3f(0.5, 1.0, 1.0);
  ShColor3f SH_DECL(diffuse) = ShColor3f(1.0, 0.0, 0.0);
  ShAttrib1f SH_DECL(exponent) = ShAttrib1f(35.0);
  exponent.range(5.0f, 500.0f);

  fsh = SH_BEGIN_PROGRAM("gpu:fragment") {
    ShInputNormal3f normal;
    ShInputTexCoord2f tc; // ignore texcoords
    ShInputVector3f half;
    ShInputVector3f light;
    ShInputPosition4f posh;

    ShOutputColor3f result;

    normal = normalize(normal);
    half = normalize(half);
    light = normalize(light);

    // Compute phong lighting.
    ShAttrib1f irrad = pos(normal | light);
    result = diffuse * irrad + specular * pow(pos(normal | half), exponent) / (normal | light);
  } SH_END;
  return true;
}

BlinnPhong BlinnPhong::instance = BlinnPhong();

<commit_msg>change modified phong<commit_after>#include <sh/sh.hpp>
#include <sh/shutil.hpp>
#include <iostream>
#include "Shader.hpp"
#include "Globals.hpp"

using namespace SH;
using namespace ShUtil;

class SimplePhong : public Shader {
public:
  SimplePhong();
  ~SimplePhong();

  bool init();

  ShProgram vertex() { return vsh;}
  ShProgram fragment() { return fsh;}

  ShProgram vsh, fsh;

  static SimplePhong instance;
};

SimplePhong::SimplePhong()
  : Shader("Basic Lighting Models: Phong: Classic Phong")
{
}

SimplePhong::~SimplePhong()
{
}

bool SimplePhong::init()
{
  vsh = SH_BEGIN_PROGRAM("gpu:vertex") {
    ShInputPosition4f ipos;
    ShInputNormal3f inorm;

    ShOutputPosition4f opos; // Position in NDC
    ShOutputNormal3f onorm;
    ShInOutTexCoord2f tc; // pass through tex coords
    ShOutputVector3f view;
    ShOutputVector3f halfv;
    ShOutputVector3f lightv; // direction to light

    opos = Globals::mvp | ipos; // Compute NDC position
    onorm = Globals::mv | inorm; // Compute view-space normal

    ShPoint3f posv = (Globals::mv | ipos)(0,1,2); // Compute view-space position
    lightv = normalize(Globals::lightPos - posv); // Compute light direction

    ShPoint3f viewv = -normalize(posv); // Compute view vector
    view = normalize(viewv - posv);
    halfv = normalize(viewv + lightv); // Compute half vector
  } SH_END;

  ShColor3f SH_DECL(specular) = ShColor3f(0.5, 1.0, 1.0);
  ShColor3f SH_DECL(diffuse) = ShColor3f(1.0, 0.0, 0.0);
  ShAttrib1f SH_DECL(exponent) = ShAttrib1f(35.0);
  exponent.range(5.0f, 500.0f);

  fsh = SH_BEGIN_PROGRAM("gpu:fragment") {
    ShInputNormal3f normal;
    ShInputTexCoord2f tc; // ignore texcoords
    ShInputVector3f view;
    ShInputVector3f half;
    ShInputVector3f light;
    ShInputPosition4f posh;

    ShOutputColor3f result;
    normal = normalize(normal);
    half = normalize(half);
    light = normalize(light);

    // Compute phong lighting.
    ShMatrix3x3f identity = ShMatrix3x3f();
    ShMatrix3x1f normalmat; // to transpose the normal
    normalmat[0] = sqrt(2) * normal[0]; // need to multiply the matrix by 2
    normalmat[1] = sqrt(2) * normal[1];
    normalmat[2] = sqrt(2) * normal[2];
    ShMatrix3x3f Householder = (normalmat | transpose(normalmat));
    Householder -= identity; // Compuse Householder transformation matrix
    ShMatrix1x3f viewtranspose; // to transpose the view vector
    viewtranspose[0][0] = view[0];
    viewtranspose[0][1] = view[1];
    viewtranspose[0][2] = view[2];
    ShAttrib1f irrad = pos(normal | light);
    result = diffuse * irrad + specular * pow(pos(viewtranspose | Householder | light), exponent) / (normal | light);
  } SH_END;
  return true;
}

SimplePhong SimplePhong::instance = SimplePhong();

// the modified Phong model
class ModifiedPhong : public Shader {
public:
  ModifiedPhong();
  ~ModifiedPhong();

  bool init();

  ShProgram vertex() { return vsh;}
  ShProgram fragment() { return fsh;}

  ShProgram vsh, fsh;

  static ModifiedPhong instance;
};

ModifiedPhong::ModifiedPhong()
  : Shader("Basic Lighting Models: Phong: Modified Phong")
{
}

ModifiedPhong::~ModifiedPhong()
{
}

bool ModifiedPhong::init()
{
  vsh = SH_BEGIN_PROGRAM("gpu:vertex") {
    ShInputPosition4f ipos;
    ShInputNormal3f inorm;

    ShOutputPosition4f opos; // Position in NDC
    ShOutputNormal3f onorm;
    ShInOutTexCoord2f tc; // pass through tex coords
    ShOutputVector3f view;
    ShOutputVector3f halfv;
    ShOutputVector3f lightv; // direction to light

    opos = Globals::mvp | ipos; // Compute NDC position
    onorm = Globals::mv | inorm; // Compute view-space normal

    ShPoint3f posv = (Globals::mv | ipos)(0,1,2); // Compute view-space position
    lightv = normalize(Globals::lightPos - posv); // Compute light direction

    ShPoint3f viewv = -normalize(posv); // Compute view vector
    view = normalize(viewv - posv);
    halfv = normalize(viewv + lightv); // Compute half vector
  } SH_END;

  ShColor3f SH_DECL(specular) = ShColor3f(0.5, 1.0, 1.0);
  ShColor3f SH_DECL(diffuse) = ShColor3f(1.0, 0.0, 0.0);
  ShAttrib1f SH_DECL(exponent) = ShAttrib1f(35.0);
  exponent.range(5.0f, 500.0f);

  fsh = SH_BEGIN_PROGRAM("gpu:fragment") {
    ShInputNormal3f normal;
    ShInputTexCoord2f tc; // ignore texcoords
    ShInputVector3f view;
    ShInputVector3f half;
    ShInputVector3f light;
    ShInputPosition4f posh;

    ShOutputColor3f result;

    normal = normalize(normal);
    half = normalize(half);
    light = normalize(light);

    // Compute phong lighting.
    ShAttrib1f irrad = pos(normal | light);
    ShMatrix3x3f identity = ShMatrix3x3f();
    ShMatrix3x1f normalmat; // to transpose the normal
    normalmat[0] = sqrt(2) * normal[0]; // need to multiply the matrix by 2
    normalmat[1] = sqrt(2) * normal[1];
    normalmat[2] = sqrt(2) * normal[2];
    ShMatrix3x3f Householder = (normalmat | transpose(normalmat));
    Householder -= identity; // Compuse Householder transformation matrix
    ShMatrix1x3f viewtranspose; // to transpose the view vector
    viewtranspose[0][0] = view[0];
    viewtranspose[0][1] = view[1];
    viewtranspose[0][2] = view[2];
    result = diffuse * irrad / M_PI  +
	    specular * (exponent+2)/(2*M_PI) * pow(pos(viewtranspose | Householder | light), exponent);
  } SH_END;
  return true;
}

ModifiedPhong ModifiedPhong::instance = ModifiedPhong();

// the Blinn-Phong model
class BlinnPhong : public Shader {
public:
  BlinnPhong();
  ~BlinnPhong();

  bool init();

  ShProgram vertex() { return vsh;}
  ShProgram fragment() { return fsh;}

  ShProgram vsh, fsh;

  static BlinnPhong instance;
};

BlinnPhong::BlinnPhong()
  : Shader("Basic Lighting Models: Phong: Blinn-Phong")
{
}

BlinnPhong::~BlinnPhong()
{
}

bool BlinnPhong::init()
{
  vsh = SH_BEGIN_PROGRAM("gpu:vertex") {
    ShInputPosition4f ipos;
    ShInputNormal3f inorm;

    ShOutputPosition4f opos; // Position in NDC
    ShOutputNormal3f onorm;
    ShInOutTexCoord2f tc; // pass through tex coords
    ShOutputVector3f halfv;
    ShOutputVector3f lightv; // direction to light

    opos = Globals::mvp | ipos; // Compute NDC position
    onorm = Globals::mv | inorm; // Compute view-space normal

    ShPoint3f posv = (Globals::mv | ipos)(0,1,2); // Compute view-space position
    lightv = normalize(Globals::lightPos - posv); // Compute light direction

    ShPoint3f viewv = -normalize(posv); // Compute view vector
    halfv = normalize(viewv + lightv); // Compute half vector
  } SH_END;

  ShColor3f SH_DECL(specular) = ShColor3f(0.5, 1.0, 1.0);
  ShColor3f SH_DECL(diffuse) = ShColor3f(1.0, 0.0, 0.0);
  ShAttrib1f SH_DECL(exponent) = ShAttrib1f(35.0);
  exponent.range(5.0f, 500.0f);

  fsh = SH_BEGIN_PROGRAM("gpu:fragment") {
    ShInputNormal3f normal;
    ShInputTexCoord2f tc; // ignore texcoords
    ShInputVector3f half;
    ShInputVector3f light;
    ShInputPosition4f posh;

    ShOutputColor3f result;

    normal = normalize(normal);
    half = normalize(half);
    light = normalize(light);

    // Compute phong lighting.
    ShAttrib1f irrad = pos(normal | light);
    result = diffuse * irrad + specular * pow(pos(normal | half), exponent) / (normal | light);
  } SH_END;
  return true;
}

BlinnPhong BlinnPhong::instance = BlinnPhong();

<|endoftext|>


<commit_before>/* Copyright (C) 2012,2013 IBM Corp.
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include <cassert>
#include <cstdio>

#include "FHE.h"
#include "timing.h"
#include "EncryptedArray.h"

#define pSize (NTL_SP_NBITS/2) /* The size of levels in the chain */

long rotationAmount(const EncryptedArray& ea, const FHEPubKey& publicKey,
	       bool withMatrix=false);
void timeOps(const EncryptedArray& ea, const FHEPubKey& publicKey,
	     Ctxt& c0, Ctxt& c1, Ctxt& c2, Ctxt& c3, ZZX& p, long nTests,
	     long nPrimes=0);

// Returns either a random automorphism amount or an amount
// for which we have a key-switching matrix s^k -> s.
long rotationAmount(const EncryptedArray& ea, const FHEPubKey& publicKey,
	       bool onlyWithMatrix)
{
  const PAlgebra& pa = ea.getContext().zMStar;
  long nSlots = pa.getNSlots();
  long r = RandomBnd(nSlots);
  long k = pa.ith_rep(r);
  if (onlyWithMatrix) { // return the 1st step in the path to k
    const KeySwitch& matrix = publicKey.getNextKSWmatrix(k,0);
    k = matrix.fromKey.getPowerOfX();
  }
  return k;
}

void timeOps(const EncryptedArray& ea, const FHEPubKey& publicKey,
	     Ctxt& c0, Ctxt& c1, Ctxt& c2, Ctxt& c3, ZZX& p, long nTests,
	     long nPrimes)
{
  if (nPrimes>0) {  // perform operations at a lower level
    c0.modDownToLevel(nPrimes);
    c1.modDownToLevel(nPrimes);
    c2.modDownToLevel(nPrimes);
  }

  // Multiplication with 2,3 arguments
  cerr << "." << std::flush;
  for (long i=0; i<nTests; i++) {
    Ctxt cc1 = c1;
    startFHEtimer("multiplyBy");
    cc1.multiplyBy(c0);
    stopFHEtimer("multiplyBy");
    c3 += cc1; // Just so the compiler doesn't optimize it away
  }

  cerr << "." << std::flush;
  for (long i=0; i<nTests; i++) {
    Ctxt cc2 = c2;
    startFHEtimer("multiplyBy2");
    cc2.multiplyBy2(c0,c1);
    stopFHEtimer("multiplyBy2");
    c3 += cc2; // Just so the compiler doesn't optimize it away
  }

  // Multiply by constant
  cerr << "." << std::flush;
  for (long i=0; i<3*nTests; i++) {
    Ctxt cc0 = c0;
    startFHEtimer("multByConstant");
    cc0.multByConstant(p);
    stopFHEtimer("multByConstant");
    c3 -= cc0; // Just so the compiler doesn't optimize it away
  }

  // Add constant
  cerr << "." << std::flush;
  for (long i=0; i<10*nTests; i++) {
    Ctxt cc0 = c0;
    startFHEtimer("addConstant");
    cc0.addConstant(p);
    stopFHEtimer("addConstant");
    c3 += cc0; // Just so the compiler doesn't optimize it away
  }

  // Rotation by an amount k for which we have a key-switching matrix
  cerr << "." << std::flush;
  for (long i=0; i<nTests; i++) {
    Ctxt cc0 = c0;
    long k = rotationAmount(ea,publicKey,/*withMatrix=*/true);
    startFHEtimer("automorph-with-matrix");
    cc0.smartAutomorph(k);
    stopFHEtimer("automorph-with-matrix");
    c3 += cc0; // Just so the compiler doesn't optimize it away
  }
  // Rotation by a random amount k
  cerr << "." << std::flush;
  for (long i=0; i<nTests; i++) {
    Ctxt cc0 = c0;
    long k = rotationAmount(ea,publicKey,/*withMatrix=*/false);
    startFHEtimer("automorph");
    cc0.smartAutomorph(k);
    stopFHEtimer("automorph");
    c3 += cc0; // Just so the compiler doesn't optimize it away
  }
}

void  TimeIt(long m, long p, long r, bool d_eq_1)
{
  cerr << "\n\n******** TimeIt: m=" << m
       << ", p=" << p
       << ", r=" << r
       << ", d=" << d_eq_1
       << endl;
  resetAllTimers();

  // Build the context, with as many primes as possible wrt to secparam=80
  startFHEtimer("Initialize context");
  FHEcontext context(m, p, r);
  stopFHEtimer("Initialize context");

  long phim = context.zMStar.getPhiM();
  long L = floor((7.2*phim)/(pSize* /*cc*/1.33* (110+/*k*/80))) -1;
  assert(L>1); // Make sure we have at least a few primes

  startFHEtimer("buildModChain");
  buildModChain(context, L, /*c=*/3);
  stopFHEtimer("buildModChain");

  startFHEtimer("keyGen");
  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(64); // A Hamming-weight-64 secret key
  addSome1DMatrices(secretKey); // compute key-switching matrices that we need
  stopFHEtimer("keyGen");

  ZZX G;
  if (d_eq_1)
    SetX(G); // set G(X)=X
  else
    G = context.alMod.getFactorsOverZZ()[0];

  startFHEtimer("Initialize EncryptedArray");
  EncryptedArray ea(context, G);
  stopFHEtimer("Initialize EncryptedArray");

  PlaintextArray p0(ea);
  PlaintextArray p1(ea);
  PlaintextArray p2(ea);
  Ctxt c0(publicKey), c1(publicKey), c2(publicKey), c3(publicKey);

  p0.random();
  p1.random();
  p2.random();

  ZZX pp;
  startFHEtimer("encode");
  ea.encode(pp, p0);
  stopFHEtimer("encode");
  startFHEtimer("SK-encrypt");
  secretKey.Encrypt(c0, pp);
  startFHEtimer("SK-encrypt");
  startFHEtimer("PK-encrypt");
  publicKey.Encrypt(c0, pp);
  startFHEtimer("PK-encrypt");

  startFHEtimer("encode");
  ea.encode(pp, p1);
  stopFHEtimer("encode");
  startFHEtimer("SK-encrypt");
  secretKey.Encrypt(c1, pp);
  startFHEtimer("SK-encrypt");
  startFHEtimer("PK-encrypt");
  publicKey.Encrypt(c1, pp);
  startFHEtimer("PK-encrypt");

  startFHEtimer("encode");
  ea.encode(pp, p2);
  stopFHEtimer("encode");
  startFHEtimer("SK-encrypt");
  secretKey.Encrypt(c2, pp);
  startFHEtimer("SK-encrypt");
  startFHEtimer("PK-encrypt");
  publicKey.Encrypt(c2, pp);
  startFHEtimer("PK-encrypt");

  cerr << "Initialization time:\n";
  printAllTimers();
  cerr << endl;

  long nTests = 3*(53261/m); // more tests for smaller values of m
  resetAllTimers();
  cerr << "Operations with "<<L<<" primes in the chain: ";
  timeOps(ea, publicKey, c0,c1,c2,c3, pp, nTests);// timing with all primes in the chain
  cerr << endl;
  printAllTimers();
  cerr << endl;

  if (L >= 14) {
    L -= (L-2)/3;
    resetAllTimers();
    cerr << "Operations with "<<L<<" primes in the chain: ";
    timeOps(ea, publicKey, c0,c1,c2,c3, pp, nTests, L); // timing with 2/3 of the primes
    cerr << endl;
    printAllTimers();
    cerr << endl;
  }
  if (L >= 8) {
    L -= (L-2)/2;
    resetAllTimers();
    cerr << "Operations with "<<L<<" primes in the chain: ";
    timeOps(ea, publicKey, c0,c1,c2,c3, pp, nTests, L); // timing with 1/3 of the primes
    cerr << endl;
    printAllTimers();
    cerr << endl;
  }
  if (L >= 4) {
    resetAllTimers();
    cerr << "Operations with 2 primes in the chain: ";
    timeOps(ea, publicKey, c0,c1,c2,c3, pp, nTests, 2); // timing with only two primes
    cerr << endl;
    printAllTimers();
    cerr << endl;
  }
  resetAllTimers();

  startFHEtimer("decrypt");
  secretKey.Decrypt(pp, c0);
  startFHEtimer("decrypt");
  startFHEtimer("decode");
  ea.decode(p0, pp);
  stopFHEtimer("decode");

  startFHEtimer("decrypt");
  secretKey.Decrypt(pp, c1);
  startFHEtimer("decrypt");
  startFHEtimer("decode");
  ea.decode(p1, pp);
  stopFHEtimer("decode");

  startFHEtimer("decrypt");
  secretKey.Decrypt(pp, c2);
  startFHEtimer("decrypt");
  startFHEtimer("decode");
  ea.decode(p2, pp);
  stopFHEtimer("decode");

  cerr << "Decoding/decryption time:\n";
  printAllTimers();
}

void usage(char *prog)
{
  cerr << "Usage: "<<prog<<" [ optional parameters ]...\n";
  cerr << "  optional parameters have the form 'attr1=val1 attr2=val2 ...'\n";
  cerr << "  e.g, 'm=11441 p=2 r=1'\n\n";
  cerr << "  m determines the cyclotomic ring, defaults to all the set\n";
  cerr << "    m in { 4051, 4369, 4859, 10261,11023,11441,\n";
  cerr << "          18631,20485,21845, 49981,53261       }\n";
  cerr << "  p is the plaintext base [default=2]" << endl;
  cerr << "  r is the lifting [default=1]" << endl;
  cerr << "  d is the degree of the field extension [default==1]\n";
  cerr << "    (d == 0 => factors[0] defined the extension)\n";
  exit(0);
}

int main(int argc, char *argv[])
{
  argmap_t argmap;
  argmap["p"] = "2";
  argmap["r"] = "1";
  argmap["m"] = "0";
  argmap["d"] = "1";

  // get parameters from the command line
  if (!parseArgs(argc, argv, argmap)) usage(argv[0]);

  long p = atoi(argmap["p"]);
  long r = atoi(argmap["r"]);
  long m = atoi(argmap["m"]);
  long d = atoi(argmap["d"]);

  long ms[11] = { 4051, 4369, 4859, 10261,11023,11441,
		 18631,20485,21845, 49981,53261};
  if (m>0)
    TimeIt(m, p, r, (d==1));
  else for (long i=0; i<11; i++)
      TimeIt(ms[i], p, r, (d==1));
}
<commit_msg>typos<commit_after>/* Copyright (C) 2012,2013 IBM Corp.
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
#include <cassert>
#include <cstdio>

#include "FHE.h"
#include "timing.h"
#include "EncryptedArray.h"

#define pSize (NTL_SP_NBITS/2) /* The size of levels in the chain */

long rotationAmount(const EncryptedArray& ea, const FHEPubKey& publicKey,
	       bool withMatrix=false);
void timeOps(const EncryptedArray& ea, const FHEPubKey& publicKey,
	     Ctxt& c0, Ctxt& c1, Ctxt& c2, Ctxt& c3, ZZX& p, long nTests,
	     long nPrimes=0);

// Returns either a random automorphism amount or an amount
// for which we have a key-switching matrix s^k -> s.
long rotationAmount(const EncryptedArray& ea, const FHEPubKey& publicKey,
	       bool onlyWithMatrix)
{
  const PAlgebra& pa = ea.getContext().zMStar;
  long nSlots = pa.getNSlots();
  long r = RandomBnd(nSlots);
  long k = pa.ith_rep(r);
  if (onlyWithMatrix) { // return the 1st step in the path to k
    const KeySwitch& matrix = publicKey.getNextKSWmatrix(k,0);
    k = matrix.fromKey.getPowerOfX();
  }
  return k;
}

void timeOps(const EncryptedArray& ea, const FHEPubKey& publicKey,
	     Ctxt& c0, Ctxt& c1, Ctxt& c2, Ctxt& c3, ZZX& p, long nTests,
	     long nPrimes)
{
  if (nPrimes>0) {  // perform operations at a lower level
    c0.modDownToLevel(nPrimes);
    c1.modDownToLevel(nPrimes);
    c2.modDownToLevel(nPrimes);
  }

  // Multiplication with 2,3 arguments
  cerr << "." << std::flush;
  for (long i=0; i<nTests; i++) {
    Ctxt cc1 = c1;
    startFHEtimer("multiplyBy");
    cc1.multiplyBy(c0);
    stopFHEtimer("multiplyBy");
    c3 += cc1; // Just so the compiler doesn't optimize it away
  }

  cerr << "." << std::flush;
  for (long i=0; i<nTests; i++) {
    Ctxt cc2 = c2;
    startFHEtimer("multiplyBy2");
    cc2.multiplyBy2(c0,c1);
    stopFHEtimer("multiplyBy2");
    c3 += cc2; // Just so the compiler doesn't optimize it away
  }

  // Multiply by constant
  cerr << "." << std::flush;
  for (long i=0; i<3*nTests; i++) {
    Ctxt cc0 = c0;
    startFHEtimer("multByConstant");
    cc0.multByConstant(p);
    stopFHEtimer("multByConstant");
    c3 -= cc0; // Just so the compiler doesn't optimize it away
  }

  // Add constant
  cerr << "." << std::flush;
  for (long i=0; i<10*nTests; i++) {
    Ctxt cc0 = c0;
    startFHEtimer("addConstant");
    cc0.addConstant(p);
    stopFHEtimer("addConstant");
    c3 += cc0; // Just so the compiler doesn't optimize it away
  }

  // Rotation by an amount k for which we have a key-switching matrix
  cerr << "." << std::flush;
  for (long i=0; i<nTests; i++) {
    Ctxt cc0 = c0;
    long k = rotationAmount(ea,publicKey,/*withMatrix=*/true);
    startFHEtimer("automorph-with-matrix");
    cc0.smartAutomorph(k);
    stopFHEtimer("automorph-with-matrix");
    c3 += cc0; // Just so the compiler doesn't optimize it away
  }
  // Rotation by a random amount k
  cerr << "." << std::flush;
  for (long i=0; i<nTests; i++) {
    Ctxt cc0 = c0;
    long k = rotationAmount(ea,publicKey,/*withMatrix=*/false);
    startFHEtimer("automorph");
    cc0.smartAutomorph(k);
    stopFHEtimer("automorph");
    c3 += cc0; // Just so the compiler doesn't optimize it away
  }
}

void  TimeIt(long m, long p, long r, bool d_eq_1)
{
  cerr << "\n\n******** TimeIt: m=" << m
       << ", p=" << p
       << ", r=" << r
       << ", d=" << d_eq_1
       << endl;
  resetAllTimers();

  // Build the context, with as many primes as possible wrt to secparam=80
  startFHEtimer("Initialize context");
  FHEcontext context(m, p, r);
  stopFHEtimer("Initialize context");

  long phim = context.zMStar.getPhiM();
  long L = floor((7.2*phim)/(pSize* /*cc*/1.33* (110+/*k*/80))) -1;
  assert(L>1); // Make sure we have at least a few primes

  startFHEtimer("buildModChain");
  buildModChain(context, L, /*c=*/3);
  stopFHEtimer("buildModChain");

  startFHEtimer("keyGen");
  FHESecKey secretKey(context);
  const FHEPubKey& publicKey = secretKey;
  secretKey.GenSecKey(64); // A Hamming-weight-64 secret key
  addSome1DMatrices(secretKey); // compute key-switching matrices that we need
  stopFHEtimer("keyGen");

  ZZX G;
  if (d_eq_1)
    SetX(G); // set G(X)=X
  else
    G = context.alMod.getFactorsOverZZ()[0];

  startFHEtimer("Initialize EncryptedArray");
  EncryptedArray ea(context, G);
  stopFHEtimer("Initialize EncryptedArray");

  PlaintextArray p0(ea);
  PlaintextArray p1(ea);
  PlaintextArray p2(ea);
  Ctxt c0(publicKey), c1(publicKey), c2(publicKey), c3(publicKey);

  p0.random();
  p1.random();
  p2.random();

  ZZX pp;
  startFHEtimer("encode");
  ea.encode(pp, p0);
  stopFHEtimer("encode");
  startFHEtimer("SK-encrypt");
  secretKey.Encrypt(c0, pp);
  stopFHEtimer("SK-encrypt");
  startFHEtimer("PK-encrypt");
  publicKey.Encrypt(c0, pp);
  stopFHEtimer("PK-encrypt");

  startFHEtimer("encode");
  ea.encode(pp, p1);
  stopFHEtimer("encode");
  startFHEtimer("SK-encrypt");
  secretKey.Encrypt(c1, pp);
  stopFHEtimer("SK-encrypt");
  startFHEtimer("PK-encrypt");
  publicKey.Encrypt(c1, pp);
  stopFHEtimer("PK-encrypt");

  startFHEtimer("encode");
  ea.encode(pp, p2);
  stopFHEtimer("encode");
  startFHEtimer("SK-encrypt");
  secretKey.Encrypt(c2, pp);
  stopFHEtimer("SK-encrypt");
  startFHEtimer("PK-encrypt");
  publicKey.Encrypt(c2, pp);
  stopFHEtimer("PK-encrypt");

  cerr << "Initialization time:\n";
  printAllTimers();
  cerr << endl;

  long nTests = 3*(53261/m); // more tests for smaller values of m
  resetAllTimers();
  cerr << "Operations with "<<L<<" primes in the chain: ";
  timeOps(ea, publicKey, c0,c1,c2,c3, pp, nTests);// timing with all primes in the chain
  cerr << endl;
  printAllTimers();
  cerr << endl;

  if (L >= 14) {
    L -= (L-2)/3;
    resetAllTimers();
    cerr << "Operations with "<<L<<" primes in the chain: ";
    timeOps(ea, publicKey, c0,c1,c2,c3, pp, nTests, L); // timing with 2/3 of the primes
    cerr << endl;
    printAllTimers();
    cerr << endl;
  }
  if (L >= 8) {
    L -= (L-2)/2;
    resetAllTimers();
    cerr << "Operations with "<<L<<" primes in the chain: ";
    timeOps(ea, publicKey, c0,c1,c2,c3, pp, nTests, L); // timing with 1/3 of the primes
    cerr << endl;
    printAllTimers();
    cerr << endl;
  }
  if (L >= 4) {
    resetAllTimers();
    cerr << "Operations with 2 primes in the chain: ";
    timeOps(ea, publicKey, c0,c1,c2,c3, pp, nTests, 2); // timing with only two primes
    cerr << endl;
    printAllTimers();
    cerr << endl;
  }
  resetAllTimers();

  startFHEtimer("decrypt");
  secretKey.Decrypt(pp, c0);
  stopFHEtimer("decrypt");
  startFHEtimer("decode");
  ea.decode(p0, pp);
  stopFHEtimer("decode");

  startFHEtimer("decrypt");
  secretKey.Decrypt(pp, c1);
  stopFHEtimer("decrypt");
  startFHEtimer("decode");
  ea.decode(p1, pp);
  stopFHEtimer("decode");

  startFHEtimer("decrypt");
  secretKey.Decrypt(pp, c2);
  stopFHEtimer("decrypt");
  startFHEtimer("decode");
  ea.decode(p2, pp);
  stopFHEtimer("decode");

  cerr << "Decoding/decryption time:\n";
  printAllTimers();
}

void usage(char *prog)
{
  cerr << "Usage: "<<prog<<" [ optional parameters ]...\n";
  cerr << "  optional parameters have the form 'attr1=val1 attr2=val2 ...'\n";
  cerr << "  e.g, 'm=11441 p=2 r=1'\n\n";
  cerr << "  m determines the cyclotomic ring, defaults to all the set\n";
  cerr << "    m in { 4051, 4369, 4859, 10261,11023,11441,\n";
  cerr << "          18631,20485,21845, 49981,53261       }\n";
  cerr << "  p is the plaintext base [default=2]" << endl;
  cerr << "  r is the lifting [default=1]" << endl;
  cerr << "  d is the degree of the field extension [default==1]\n";
  cerr << "    (d == 0 => factors[0] defined the extension)\n";
  exit(0);
}

int main(int argc, char *argv[])
{
  argmap_t argmap;
  argmap["p"] = "2";
  argmap["r"] = "1";
  argmap["m"] = "0";
  argmap["d"] = "1";

  // get parameters from the command line
  if (!parseArgs(argc, argv, argmap)) usage(argv[0]);

  long p = atoi(argmap["p"]);
  long r = atoi(argmap["r"]);
  long m = atoi(argmap["m"]);
  long d = atoi(argmap["d"]);

  long ms[11] = { 4051, 4369, 4859, 10261,11023,11441,
		 18631,20485,21845, 49981,53261};
  if (m>0)
    TimeIt(m, p, r, (d==1));
  else for (long i=0; i<11; i++)
      TimeIt(ms[i], p, r, (d==1));
}
<|endoftext|>


<commit_before>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#include <eosio/txn_test_gen_plugin/txn_test_gen_plugin.hpp>
#include <eosio/chain_plugin/chain_plugin.hpp>
#include <eos/utilities/key_conversion.hpp>

#include <fc/variant.hpp>
#include <fc/io/json.hpp>
#include <fc/exception/exception.hpp>
#include <fc/reflect/variant.hpp>

#include <boost/asio/high_resolution_timer.hpp>
#include <boost/algorithm/clamp.hpp>

namespace eosio { namespace detail {
  struct txn_test_gen_empty {};
}}

FC_REFLECT(eosio::detail::txn_test_gen_empty, );

namespace eosio {

using namespace eosio::chain;

#define CALL(api_name, api_handle, call_name, INVOKE, http_response_code) \
{std::string("/v1/" #api_name "/" #call_name), \
   [this](string, string body, url_response_callback cb) mutable { \
          try { \
             if (body.empty()) body = "{}"; \
             INVOKE \
             cb(http_response_code, fc::json::to_string(result)); \
          } catch (fc::eof_exception& e) { \
             error_results results{400, "Bad Request", e.to_string()}; \
             cb(400, fc::json::to_string(results)); \
             elog("Unable to parse arguments: ${args}", ("args", body)); \
          } catch (fc::exception& e) { \
             error_results results{500, "Internal Service Error", e.to_detail_string()}; \
             cb(500, fc::json::to_string(results)); \
             elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \
          } \
       }}

#define INVOKE_V_R_R(api_handle, call_name, in_param0, in_param1) \
     const auto& vs = fc::json::json::from_string(body).as<fc::variants>(); \
     api_handle->call_name(vs.at(0).as<in_param0>(), vs.at(1).as<in_param1>()); \
     eosio::detail::txn_test_gen_empty result;

#define INVOKE_V_V(api_handle, call_name) \
     api_handle->call_name(); \
     eosio::detail::txn_test_gen_empty result;

struct txn_test_gen_plugin_impl {
   void create_test_accounts(const std::string& init_name, const std::string& init_priv_key) {
      name newaccountA("txn.test.a");
      name newaccountB("txn.test.b");
      name creator(init_name);

      chain_controller& cc = app().get_plugin<chain_plugin>().chain();
      chain::chain_id_type chainid;
      app().get_plugin<chain_plugin>().get_chain_id(chainid);
      uint64_t stake = 10000;

      fc::crypto::private_key txn_test_receiver_A_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, 'a')));
      fc::crypto::private_key txn_test_receiver_B_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, 'b')));
      fc::crypto::public_key  txn_text_receiver_A_pub_key = txn_test_receiver_A_priv_key.get_public_key();
      fc::crypto::public_key  txn_text_receiver_B_pub_key = txn_test_receiver_B_priv_key.get_public_key();
      fc::crypto::private_key creator_priv_key = fc::crypto::private_key(init_priv_key);

      //stake some currency; and then create some test accounts
      auto memo = fc::variant(fc::time_point::now()).as_string() + " " + fc::variant(fc::time_point::now().time_since_epoch()).as_string();
      signed_transaction trx;
      trx.expiration = cc.head_block_time() + fc::seconds(30);
      trx.set_reference_block(cc.head_block_id());
      trx.write_scope = {creator, config::system_account_name, config::eosio_auth_scope};
      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::lock{creator, creator, 300});

      //create "A" account
      {
      auto owner_auth   = eosio::chain::authority{1, {{txn_text_receiver_A_pub_key, 1}}, {}};
      auto active_auth  = eosio::chain::authority{1, {{txn_text_receiver_A_pub_key, 1}}, {}};
      auto recovery_auth = eosio::chain::authority{1, {}, {{{creator, "active"}, 1}}};
      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::newaccount{creator, newaccountA, owner_auth, active_auth, recovery_auth, stake});
      }
      //create "B" account
      {
      auto owner_auth   = eosio::chain::authority{1, {{txn_text_receiver_B_pub_key, 1}}, {}};
      auto active_auth  = eosio::chain::authority{1, {{txn_text_receiver_B_pub_key, 1}}, {}};
      auto recovery_auth = eosio::chain::authority{1, {}, {{{creator, "active"}, 1}}};

      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::newaccount{creator, newaccountB, owner_auth, active_auth, recovery_auth, stake});
      }
      trx.sign(creator_priv_key, chainid);
      cc.push_transaction(trx);

      //now, transfer some balance to new accounts
      {
      uint64_t balance = 10000;
      signed_transaction trx;
      trx.write_scope = sort_names({creator,newaccountA,newaccountB});
      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::transfer{creator, newaccountA, balance, memo});
      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::transfer{creator, newaccountB, balance, memo});
      trx.expiration = cc.head_block_time() + fc::seconds(30);
      trx.set_reference_block(cc.head_block_id());
      trx.sign(creator_priv_key, chainid);
      cc.push_transaction(trx);
      }
   }

   void start_generation(const std::string& salt, const uint64_t& persecond) {
      if(running)
         throw fc::exception(fc::invalid_operation_exception_code);
      running = true;
      memo_salt = salt;

      timer_timeout = 1000/boost::algorithm::clamp(persecond/2, 1, 200);

      ilog("Started transaction test plugin; performing ${p} transactions/second", ("p", 1000/timer_timeout*2));

      arm_timer(boost::asio::high_resolution_timer::clock_type::now());
   }

   void arm_timer(boost::asio::high_resolution_timer::time_point s) {
      timer.expires_at(s + std::chrono::milliseconds(timer_timeout));
      timer.async_wait([this](const boost::system::error_code& ec) {
         if(ec)
            return;
         try {
            this->send_transaction();
         }
         catch(fc::exception e) {
            elog("pushing transaction failed: ${e}", ("e", e.to_detail_string()));
            this->stop_generation();
            return;
         }
         this->arm_timer(timer.expires_at());
      });
   }

   void send_transaction() {
      chain_controller& cc = app().get_plugin<chain_plugin>().chain();
      chain::chain_id_type chainid;
      app().get_plugin<chain_plugin>().get_chain_id(chainid);

      name sender("txn.test.a");
      name recipient("txn.test.b");

      std::string memo = memo_salt + fc::variant(fc::time_point::now()).as_string() + " " + fc::variant(fc::time_point::now().time_since_epoch()).as_string();
      //make transaction a->b
      {
      signed_transaction trx;
      trx.write_scope = sort_names({sender,recipient});
      trx.actions.emplace_back(vector<chain::permission_level>{{sender,"active"}}, contracts::transfer{sender, recipient, 1, memo});
      trx.expiration = cc.head_block_time() + fc::seconds(30);
      trx.set_reference_block(cc.head_block_id());

      fc::crypto::private_key creator_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, 'a')));
      trx.sign(creator_priv_key, chainid);
      cc.push_transaction(trx);
      }

      //make transaction b->a
      {
      signed_transaction trx;
      trx.write_scope = sort_names({sender,recipient});
      trx.actions.emplace_back(vector<chain::permission_level>{{recipient,"active"}}, contracts::transfer{recipient, sender, 1, memo});
      trx.expiration = cc.head_block_time() + fc::seconds(30);
      trx.set_reference_block(cc.head_block_id());

      fc::crypto::private_key b_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, 'b')));
      trx.sign(b_priv_key, chainid);
      cc.push_transaction(trx);
      }
   }

   void stop_generation() {
      if(!running)
         throw fc::exception(fc::invalid_operation_exception_code);
      timer.cancel();
      running = false;
      ilog("Stopping transaction generation test");
   }

   boost::asio::high_resolution_timer timer{app().get_io_service()};
   bool running{false};

   unsigned timer_timeout;

   std::string memo_salt;
};

txn_test_gen_plugin::txn_test_gen_plugin() {}
txn_test_gen_plugin::~txn_test_gen_plugin() {}

void txn_test_gen_plugin::set_program_options(options_description&, options_description& cfg) {
}

void txn_test_gen_plugin::plugin_initialize(const variables_map& options) {
}

void txn_test_gen_plugin::plugin_startup() {
   app().get_plugin<http_plugin>().add_api({
      CALL(txn_test_gen, my, create_test_accounts, INVOKE_V_R_R(my, create_test_accounts, std::string, std::string), 200),
      CALL(txn_test_gen, my, stop_generation, INVOKE_V_V(my, stop_generation), 200),
      CALL(txn_test_gen, my, start_generation, INVOKE_V_R_R(my, start_generation, std::string, uint64_t), 200)
   });
   my.reset(new txn_test_gen_plugin_impl);
}

void txn_test_gen_plugin::plugin_shutdown() {
   try {
      my->stop_generation();
   }
   catch(fc::exception e) {
   }
}

}
<commit_msg>Revert "Add explicit this-> to lambda.  gcc 5.4 went strange."<commit_after>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#include <eosio/txn_test_gen_plugin/txn_test_gen_plugin.hpp>
#include <eosio/chain_plugin/chain_plugin.hpp>
#include <eos/utilities/key_conversion.hpp>

#include <fc/variant.hpp>
#include <fc/io/json.hpp>
#include <fc/exception/exception.hpp>
#include <fc/reflect/variant.hpp>

#include <boost/asio/high_resolution_timer.hpp>
#include <boost/algorithm/clamp.hpp>

namespace eosio { namespace detail {
  struct txn_test_gen_empty {};
}}

FC_REFLECT(eosio::detail::txn_test_gen_empty, );

namespace eosio {

using namespace eosio::chain;

#define CALL(api_name, api_handle, call_name, INVOKE, http_response_code) \
{std::string("/v1/" #api_name "/" #call_name), \
   [this](string, string body, url_response_callback cb) mutable { \
          try { \
             if (body.empty()) body = "{}"; \
             INVOKE \
             cb(http_response_code, fc::json::to_string(result)); \
          } catch (fc::eof_exception& e) { \
             error_results results{400, "Bad Request", e.to_string()}; \
             cb(400, fc::json::to_string(results)); \
             elog("Unable to parse arguments: ${args}", ("args", body)); \
          } catch (fc::exception& e) { \
             error_results results{500, "Internal Service Error", e.to_detail_string()}; \
             cb(500, fc::json::to_string(results)); \
             elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \
          } \
       }}

#define INVOKE_V_R_R(api_handle, call_name, in_param0, in_param1) \
     const auto& vs = fc::json::json::from_string(body).as<fc::variants>(); \
     api_handle->call_name(vs.at(0).as<in_param0>(), vs.at(1).as<in_param1>()); \
     eosio::detail::txn_test_gen_empty result;

#define INVOKE_V_V(api_handle, call_name) \
     api_handle->call_name(); \
     eosio::detail::txn_test_gen_empty result;

struct txn_test_gen_plugin_impl {
   void create_test_accounts(const std::string& init_name, const std::string& init_priv_key) {
      name newaccountA("txn.test.a");
      name newaccountB("txn.test.b");
      name creator(init_name);

      chain_controller& cc = app().get_plugin<chain_plugin>().chain();
      chain::chain_id_type chainid;
      app().get_plugin<chain_plugin>().get_chain_id(chainid);
      uint64_t stake = 10000;

      fc::crypto::private_key txn_test_receiver_A_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, 'a')));
      fc::crypto::private_key txn_test_receiver_B_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, 'b')));
      fc::crypto::public_key  txn_text_receiver_A_pub_key = txn_test_receiver_A_priv_key.get_public_key();
      fc::crypto::public_key  txn_text_receiver_B_pub_key = txn_test_receiver_B_priv_key.get_public_key();
      fc::crypto::private_key creator_priv_key = fc::crypto::private_key(init_priv_key);

      //stake some currency; and then create some test accounts
      auto memo = fc::variant(fc::time_point::now()).as_string() + " " + fc::variant(fc::time_point::now().time_since_epoch()).as_string();
      signed_transaction trx;
      trx.expiration = cc.head_block_time() + fc::seconds(30);
      trx.set_reference_block(cc.head_block_id());
      trx.write_scope = {creator, config::system_account_name, config::eosio_auth_scope};
      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::lock{creator, creator, 300});

      //create "A" account
      {
      auto owner_auth   = eosio::chain::authority{1, {{txn_text_receiver_A_pub_key, 1}}, {}};
      auto active_auth  = eosio::chain::authority{1, {{txn_text_receiver_A_pub_key, 1}}, {}};
      auto recovery_auth = eosio::chain::authority{1, {}, {{{creator, "active"}, 1}}};
      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::newaccount{creator, newaccountA, owner_auth, active_auth, recovery_auth, stake});
      }
      //create "B" account
      {
      auto owner_auth   = eosio::chain::authority{1, {{txn_text_receiver_B_pub_key, 1}}, {}};
      auto active_auth  = eosio::chain::authority{1, {{txn_text_receiver_B_pub_key, 1}}, {}};
      auto recovery_auth = eosio::chain::authority{1, {}, {{{creator, "active"}, 1}}};

      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::newaccount{creator, newaccountB, owner_auth, active_auth, recovery_auth, stake});
      }
      trx.sign(creator_priv_key, chainid);
      cc.push_transaction(trx);

      //now, transfer some balance to new accounts
      {
      uint64_t balance = 10000;
      signed_transaction trx;
      trx.write_scope = sort_names({creator,newaccountA,newaccountB});
      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::transfer{creator, newaccountA, balance, memo});
      trx.actions.emplace_back(vector<chain::permission_level>{{creator,"active"}}, contracts::transfer{creator, newaccountB, balance, memo});
      trx.expiration = cc.head_block_time() + fc::seconds(30);
      trx.set_reference_block(cc.head_block_id());
      trx.sign(creator_priv_key, chainid);
      cc.push_transaction(trx);
      }
   }

   void start_generation(const std::string& salt, const uint64_t& persecond) {
      if(running)
         throw fc::exception(fc::invalid_operation_exception_code);
      running = true;
      memo_salt = salt;

      timer_timeout = 1000/boost::algorithm::clamp(persecond/2, 1, 200);

      ilog("Started transaction test plugin; performing ${p} transactions/second", ("p", 1000/timer_timeout*2));

      arm_timer(boost::asio::high_resolution_timer::clock_type::now());
   }

   void arm_timer(boost::asio::high_resolution_timer::time_point s) {
      timer.expires_at(s + std::chrono::milliseconds(timer_timeout));
      timer.async_wait([this](const boost::system::error_code& ec) {
         if(ec)
            return;
         try {
            send_transaction();
         }
         catch(fc::exception e) {
            elog("pushing transaction failed: ${e}", ("e", e.to_detail_string()));
            stop_generation();
            return;
         }
         arm_timer(timer.expires_at());
      });
   }

   void send_transaction() {
      chain_controller& cc = app().get_plugin<chain_plugin>().chain();
      chain::chain_id_type chainid;
      app().get_plugin<chain_plugin>().get_chain_id(chainid);

      name sender("txn.test.a");
      name recipient("txn.test.b");

      std::string memo = memo_salt + fc::variant(fc::time_point::now()).as_string() + " " + fc::variant(fc::time_point::now().time_since_epoch()).as_string();
      //make transaction a->b
      {
      signed_transaction trx;
      trx.write_scope = sort_names({sender,recipient});
      trx.actions.emplace_back(vector<chain::permission_level>{{sender,"active"}}, contracts::transfer{sender, recipient, 1, memo});
      trx.expiration = cc.head_block_time() + fc::seconds(30);
      trx.set_reference_block(cc.head_block_id());

      fc::crypto::private_key creator_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, 'a')));
      trx.sign(creator_priv_key, chainid);
      cc.push_transaction(trx);
      }

      //make transaction b->a
      {
      signed_transaction trx;
      trx.write_scope = sort_names({sender,recipient});
      trx.actions.emplace_back(vector<chain::permission_level>{{recipient,"active"}}, contracts::transfer{recipient, sender, 1, memo});
      trx.expiration = cc.head_block_time() + fc::seconds(30);
      trx.set_reference_block(cc.head_block_id());

      fc::crypto::private_key b_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, 'b')));
      trx.sign(b_priv_key, chainid);
      cc.push_transaction(trx);
      }
   }

   void stop_generation() {
      if(!running)
         throw fc::exception(fc::invalid_operation_exception_code);
      timer.cancel();
      running = false;
      ilog("Stopping transaction generation test");
   }

   boost::asio::high_resolution_timer timer{app().get_io_service()};
   bool running{false};

   unsigned timer_timeout;

   std::string memo_salt;
};

txn_test_gen_plugin::txn_test_gen_plugin() {}
txn_test_gen_plugin::~txn_test_gen_plugin() {}

void txn_test_gen_plugin::set_program_options(options_description&, options_description& cfg) {
}

void txn_test_gen_plugin::plugin_initialize(const variables_map& options) {
}

void txn_test_gen_plugin::plugin_startup() {
   app().get_plugin<http_plugin>().add_api({
      CALL(txn_test_gen, my, create_test_accounts, INVOKE_V_R_R(my, create_test_accounts, std::string, std::string), 200),
      CALL(txn_test_gen, my, stop_generation, INVOKE_V_V(my, stop_generation), 200),
      CALL(txn_test_gen, my, start_generation, INVOKE_V_R_R(my, start_generation, std::string, uint64_t), 200)
   });
   my.reset(new txn_test_gen_plugin_impl);
}

void txn_test_gen_plugin::plugin_shutdown() {
   try {
      my->stop_generation();
   }
   catch(fc::exception e) {
   }
}

}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <osquery/enroll.h>
#include <osquery/filesystem.h>
#include <osquery/system.h>

#include "osquery/remote/requests.h"
#include "osquery/remote/serializers/json.h"
#include "osquery/remote/transports/tls.h"

// Ordering is messed up because of tls.h
#include "osquery/core/process.h"

namespace osquery {

DECLARE_string(enroll_secret_path);
DECLARE_bool(disable_enrollment);

/// Enrollment TLS endpoint (path) using TLS hostname.
CLI_FLAG(string,
         enroll_tls_endpoint,
         "",
         "TLS/HTTPS endpoint for client enrollment");

/// Undocumented feature for TLS access token passing.
HIDDEN_FLAG(bool,
            tls_secret_always,
            false,
            "Include TLS enroll secret in every request");

/// Undocumented feature to override TLS enrollment key name.
HIDDEN_FLAG(string,
            tls_enroll_override,
            "enroll_secret",
            "Override the TLS enroll secret key name");

DECLARE_uint64(config_tls_max_attempts);

class TLSEnrollPlugin : public EnrollPlugin {
 private:
  /// Enroll called, return cached key or if no key cached, call requestKey.
  std::string enroll() override;

 private:
  /// Request an enrollment key response from the TLS endpoint.
  Status requestKey(const std::string& uri, std::string& node_key);
};

REGISTER(TLSEnrollPlugin, "enroll", "tls");

std::string TLSEnrollPlugin::enroll() {
  // If no node secret has been negotiated, try a TLS request.
  auto uri = "https://" + FLAGS_tls_hostname + FLAGS_enroll_tls_endpoint;
  if (FLAGS_tls_secret_always) {
    uri += ((uri.find('?') != std::string::npos) ? "&" : "?") +
           FLAGS_tls_enroll_override + "=" + getEnrollSecret();
  }

  std::string node_key;
  VLOG(1) << "TLSEnrollPlugin requesting a node enroll key from: " << uri;
  for (size_t i = 1; i <= FLAGS_config_tls_max_attempts; i++) {
    auto status = requestKey(uri, node_key);
    if (status.ok() || i == FLAGS_config_tls_max_attempts) {
      break;
    }

    LOG(WARNING) << "Failed enrollment request to " << uri << " ("
                 << status.what() << ") retrying...";
    sleepFor(i * i * 1000);
  }

  return node_key;
}

Status TLSEnrollPlugin::requestKey(const std::string& uri,
                                   std::string& node_key) {
  // Read the optional enrollment secret data (sent with an enrollment request).
  boost::property_tree::ptree params;
  params.put<std::string>(FLAGS_tls_enroll_override, getEnrollSecret());
  params.put<std::string>("host_identifier", getHostIdentifier());

  auto request = Request<TLSTransport, JSONSerializer>(uri);
  request.setOption("hostname", FLAGS_tls_hostname);
  auto status = request.call(params);
  if (!status.ok()) {
    return status;
  }

  // The call succeeded, store the node secret key (the enrollment response).
  boost::property_tree::ptree recv;
  status = request.getResponse(recv);
  if (!status.ok()) {
    return status;
  }

  // Support multiple response keys as a node key (identifier).
  if (recv.count("node_key") > 0) {
    node_key = recv.get("node_key", "");
  } else if (recv.count("id") > 0) {
    node_key = recv.get("id", "");
  }

  if (node_key.size() == 0) {
    return Status(1, "No node key returned from TLS enroll plugin");
  }
  return Status(0, "OK");
}
}
<commit_msg>Adds platform_type to enrollment request (#3375)<commit_after>/*
 *  Copyright (c) 2014-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */

#include <osquery/enroll.h>
#include <osquery/filesystem.h>
#include <osquery/system.h>

#include "osquery/remote/requests.h"
#include "osquery/remote/serializers/json.h"
#include "osquery/remote/transports/tls.h"

// Ordering is messed up because of tls.h
#include "osquery/core/process.h"

namespace osquery {

DECLARE_string(enroll_secret_path);
DECLARE_bool(disable_enrollment);

/// Enrollment TLS endpoint (path) using TLS hostname.
CLI_FLAG(string,
         enroll_tls_endpoint,
         "",
         "TLS/HTTPS endpoint for client enrollment");

/// Undocumented feature for TLS access token passing.
HIDDEN_FLAG(bool,
            tls_secret_always,
            false,
            "Include TLS enroll secret in every request");

/// Undocumented feature to override TLS enrollment key name.
HIDDEN_FLAG(string,
            tls_enroll_override,
            "enroll_secret",
            "Override the TLS enroll secret key name");

DECLARE_uint64(config_tls_max_attempts);

class TLSEnrollPlugin : public EnrollPlugin {
 private:
  /// Enroll called, return cached key or if no key cached, call requestKey.
  std::string enroll() override;

 private:
  /// Request an enrollment key response from the TLS endpoint.
  Status requestKey(const std::string& uri, std::string& node_key);
};

REGISTER(TLSEnrollPlugin, "enroll", "tls");

std::string TLSEnrollPlugin::enroll() {
  // If no node secret has been negotiated, try a TLS request.
  auto uri = "https://" + FLAGS_tls_hostname + FLAGS_enroll_tls_endpoint;
  if (FLAGS_tls_secret_always) {
    uri += ((uri.find('?') != std::string::npos) ? "&" : "?") +
           FLAGS_tls_enroll_override + "=" + getEnrollSecret();
  }

  std::string node_key;
  VLOG(1) << "TLSEnrollPlugin requesting a node enroll key from: " << uri;
  for (size_t i = 1; i <= FLAGS_config_tls_max_attempts; i++) {
    auto status = requestKey(uri, node_key);
    if (status.ok() || i == FLAGS_config_tls_max_attempts) {
      break;
    }

    LOG(WARNING) << "Failed enrollment request to " << uri << " ("
                 << status.what() << ") retrying...";
    sleepFor(i * i * 1000);
  }

  return node_key;
}

Status TLSEnrollPlugin::requestKey(const std::string& uri,
                                   std::string& node_key) {
  // Read the optional enrollment secret data (sent with an enrollment request).
  boost::property_tree::ptree params;
  params.put<std::string>(FLAGS_tls_enroll_override, getEnrollSecret());
  params.put<std::string>("host_identifier", getHostIdentifier());
  params.put<std::string>("platform_type",
      boost::lexical_cast<std::string>(static_cast<uint64_t>(kPlatformType)));

  auto request = Request<TLSTransport, JSONSerializer>(uri);
  request.setOption("hostname", FLAGS_tls_hostname);
  auto status = request.call(params);
  if (!status.ok()) {
    return status;
  }

  // The call succeeded, store the node secret key (the enrollment response).
  boost::property_tree::ptree recv;
  status = request.getResponse(recv);
  if (!status.ok()) {
    return status;
  }

  // Support multiple response keys as a node key (identifier).
  if (recv.count("node_key") > 0) {
    node_key = recv.get("node_key", "");
  } else if (recv.count("id") > 0) {
    node_key = recv.get("id", "");
  }

  if (node_key.size() == 0) {
    return Status(1, "No node key returned from TLS enroll plugin");
  }
  return Status(0, "OK");
}
}
<|endoftext|>


<commit_before>/*!
	@file
	@author		Albert Semenov
	@date		04/2008
	@module
*/
/*
	This file is part of MyGUI.

	MyGUI 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 3 of the License, or
	(at your option) any later version.

	MyGUI 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 MyGUI.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_OgreRenderManager.h"
#include "MyGUI_OgreTexture.h"
#include "MyGUI_OgreVertexBuffer.h"
#include "MyGUI_LogManager.h"
#include "MyGUI_Gui.h"

namespace MyGUI
{

	MYGUI_INSTANCE_IMPLEMENT(OgreRenderManager);

	void OgreRenderManager::initialise(Ogre::RenderWindow* _window)
	{
		//MYGUI_ASSERT(false == mIsInitialise, INSTANCE_TYPE_NAME << " initialised twice");
		//MYGUI_LOG(Info, "* Initialise: " << INSTANCE_TYPE_NAME);

		//
		mSceneManager = nullptr;
		mUpdate = false;
		//mMaximumDepth = 0;
		mListener = nullptr;
		mRenderSystem = nullptr;

		mColorBlendMode.blendType	= Ogre::LBT_COLOUR;
		mColorBlendMode.source1		= Ogre::LBS_TEXTURE;
		mColorBlendMode.source2		= Ogre::LBS_DIFFUSE;
		mColorBlendMode.operation	= Ogre::LBX_MODULATE;

		mAlphaBlendMode.blendType	= Ogre::LBT_ALPHA;
		mAlphaBlendMode.source1		= Ogre::LBS_TEXTURE;
		mAlphaBlendMode.source2		= Ogre::LBS_DIFFUSE;
		mAlphaBlendMode.operation	= Ogre::LBX_MODULATE;

		mTextureAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP;
		mTextureAddressMode.v = Ogre::TextureUnitState::TAM_CLAMP;
		mTextureAddressMode.w = Ogre::TextureUnitState::TAM_CLAMP;

		Ogre::Root * root = Ogre::Root::getSingletonPtr();
		if (root != nullptr)
		{
			//
			Ogre::VertexElementType vertext_type = root->getRenderSystem()->getColourVertexElementType();
			if (vertext_type == Ogre::VET_COLOUR_ARGB) mVertexFormat = VertexColourType::ColourARGB;
			else if (vertext_type == Ogre::VET_COLOUR_ABGR) mVertexFormat = VertexColourType::ColourABGR;

			Ogre::SceneManagerEnumerator::SceneManagerIterator iter = root->getSceneManagerIterator();
			if (iter.hasMoreElements())
			{
				mSceneManager = iter.getNext();
				mSceneManager->addRenderQueueListener(this);
			}

			//
			mRenderSystem = root->getRenderSystem();
			if (mRenderSystem != nullptr)
			{
				mRenderSystem->addListener(this);

				//mMaximumDepth = mRenderSystem->getMaximumDepthInputValue();
				//mTexelOffset.set(mRenderSystem->getHorizontalTexelOffset(), mRenderSystem->getVerticalTexelOffset());
			}
		}

		//
		mActiveViewport = 0;
		//
		mWindow = _window;
		if (mWindow != nullptr)
		{
			//MYGUI_ASSERT(mWindow->getNumViewports(), "You must have viewport for MyGUI initialisation.");
			//mViewSize.set(mWindow->getViewport(mActiveViewport)->getActualWidth(), mWindow->getViewport(mActiveViewport)->getActualHeight());
			Ogre::Viewport* port = mWindow->getViewport(mActiveViewport);
			mViewSize.set(port->getActualWidth(), port->getActualHeight());

			if (mRenderSystem != nullptr)
			{
				mRenderTargetInfo.maximumDepth = mRenderSystem->getMaximumDepthInputValue();
				mRenderTargetInfo.hOffset = mRenderSystem->getHorizontalTexelOffset() / float(mViewSize.width);
				mRenderTargetInfo.vOffset = mRenderSystem->getVerticalTexelOffset() / float(mViewSize.height);
				mRenderTargetInfo.aspectCoef = float(mViewSize.height) / float(mViewSize.width);
				mRenderTargetInfo.pixScaleX = 1.0 / float(mViewSize.width);
				mRenderTargetInfo.pixScaleY = 1.0 / float(mViewSize.height);
			}
		}

		mRenderTargetInfo.rttFlipY = Ogre::Root::getSingleton().getRenderSystem()->getName( ) == "OpenGL Rendering Subsystem";

		//
		if (mWindow != nullptr)
		{
			Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
			windowResized(mWindow);
		}

		//MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully initialized");
		mIsInitialise = true;
	}

	void OgreRenderManager::shutdown()
	{
		if (false == mIsInitialise) return;
		//MYGUI_LOG(Info, "* Shutdown: " << INSTANCE_TYPE_NAME);

		clearTextures();

		//
		if (mWindow != nullptr)
		{
			Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
		}

		//
		Ogre::Root * root = Ogre::Root::getSingletonPtr();
		if (root != nullptr)
		{
			root->getRenderSystem()->removeListener(this);
		}

		setSceneManager(nullptr);

		//MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully shutdown");
		mIsInitialise = false;
	}

	void OgreRenderManager::renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation)
	{
		if (Ogre::RENDER_QUEUE_OVERLAY != queueGroupId) return;

		Ogre::Viewport * vp = mSceneManager->getCurrentViewport();
		if (nullptr == vp || !vp->getOverlaysEnabled()) return;

		if (mListener != nullptr)
		{
			begin();
			mListener->doRender(mUpdate);
			end();
		}

		//
		mUpdate = false;
	}

	void OgreRenderManager::renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation)
	{
	}

	void OgreRenderManager::setSceneManager(Ogre::SceneManager * _scene)
	{
		if (nullptr != mSceneManager) mSceneManager->removeRenderQueueListener(this);
		mSceneManager = _scene;
		if (nullptr != mSceneManager) mSceneManager->addRenderQueueListener(this);
	}

	void OgreRenderManager::eventOccurred(const Ogre::String& eventName, const Ogre::NameValuePairList* parameters)
	{
		if(eventName == "DeviceLost")
		{
		}
		else if(eventName == "DeviceRestored")
		{
			//
			mUpdate = true;
		}
	}

	void OgreRenderManager::setRenderQueueListener(IRenderQueueListener* _listener)
	{
		mListener = _listener;
		mUpdate = true;
	}

	ITexture* OgreRenderManager::createTexture(const std::string& _name, const std::string& _group)
	{
		MapTexture::const_iterator item = mTextures.find(_name);
		MYGUI_ASSERT(item==mTextures.end(), "Resource '" << _name << "' already exist");

		OgreTexture* texture = new OgreTexture(_name, _group);
		mTextures[_name] = texture;

		return texture;
	}

	void OgreRenderManager::destroyTexture(ITexture* _texture)
	{
		for (MapTexture::iterator item=mTextures.begin(); item!=mTextures.end(); ++item)
		{
			if (item->second == _texture)
			{
				delete _texture;
				mTextures.erase(item);
				break;
			}
		}
	}

	ITexture* OgreRenderManager::getByName(const std::string& _name)
	{
		MapTexture::const_iterator item = mTextures.find(_name);
		return item == mTextures.end() ? nullptr : item->second;
	}

	void OgreRenderManager::clearTextures()
	{
		for (MapTexture::iterator item=mTextures.begin(); item!=mTextures.end(); ++item)
		{
			delete item->second;
		}
		mTextures.clear();
	}

	IVertexBuffer* OgreRenderManager::createVertexBuffer()
	{
		return new OgreVertexBuffer();
	}

	void OgreRenderManager::destroyVertexBuffer(IVertexBuffer* _buffer)
	{
		delete _buffer;
	}

	void OgreRenderManager::setActiveViewport(size_t _num)
	{
		if (_num == mActiveViewport) return;
		MYGUI_ASSERT(mWindow, "Gui is not initialised.");
		MYGUI_ASSERT(mWindow->getNumViewports() >= _num, "index out of range");
		mActiveViewport = _num;
		//
		windowResized(mWindow);
	}

	//
	void OgreRenderManager::windowResized(Ogre::RenderWindow* rw)
	{
		Ogre::Viewport * port = rw->getViewport(mActiveViewport);
		mViewSize.set(port->getActualWidth(), port->getActualHeight());

		//
		mUpdate = true;

		if (mRenderSystem != nullptr)
		{
			mRenderTargetInfo.maximumDepth = mRenderSystem->getMaximumDepthInputValue();
			mRenderTargetInfo.hOffset = mRenderSystem->getHorizontalTexelOffset() / float(mViewSize.width);
			mRenderTargetInfo.vOffset = mRenderSystem->getVerticalTexelOffset() / float(mViewSize.height);
			mRenderTargetInfo.aspectCoef = float(mViewSize.height) / float(mViewSize.width);
			mRenderTargetInfo.pixScaleX = 1.0 / float(mViewSize.width);
			mRenderTargetInfo.pixScaleY = 1.0 / float(mViewSize.height);
		}

		Gui* gui = Gui::getInstancePtr();
		if (gui != nullptr) gui->resizeWindow(mViewSize);
	}

	void OgreRenderManager::doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count)
	{
		OgreTexture* texture = static_cast<OgreTexture*>(_texture);

		mRenderSystem->_setTexture(0, true, texture->getOgreTexture());

		OgreVertexBuffer* buffer = static_cast<OgreVertexBuffer*>(_buffer);
		Ogre::RenderOperation* operation = buffer->getRenderOperation();
		operation->vertexData->vertexCount = _count;

		mRenderSystem->_render(*operation);
	}

	void OgreRenderManager::doRender(IVertexBuffer* _buffer, const std::string& _texture, size_t _count)
	{
		mRenderSystem->_setTexture(0, true, _texture);

		OgreVertexBuffer* buffer = static_cast<OgreVertexBuffer*>(_buffer);
		Ogre::RenderOperation* operation = buffer->getRenderOperation();
		operation->vertexData->vertexCount = _count;

		mRenderSystem->_render(*operation);
	}

	void OgreRenderManager::begin()
	{
		// set-up matrices
		mRenderSystem->_setWorldMatrix(Ogre::Matrix4::IDENTITY);
		mRenderSystem->_setViewMatrix(Ogre::Matrix4::IDENTITY);
		mRenderSystem->_setProjectionMatrix(Ogre::Matrix4::IDENTITY);

		// initialise render settings
		mRenderSystem->setLightingEnabled(false);
		mRenderSystem->_setDepthBufferParams(false, false);
		mRenderSystem->_setDepthBias(0, 0);
		mRenderSystem->_setCullingMode(Ogre::CULL_NONE);
		mRenderSystem->_setFog(Ogre::FOG_NONE);
		mRenderSystem->_setColourBufferWriteEnabled(true, true, true, true);
		mRenderSystem->unbindGpuProgram(Ogre::GPT_FRAGMENT_PROGRAM);
		mRenderSystem->unbindGpuProgram(Ogre::GPT_VERTEX_PROGRAM);
		mRenderSystem->setShadingType(Ogre::SO_GOURAUD);
		//mRenderSystem->_setPolygonMode(Ogre::PM_SOLID);

		// initialise texture settings
		mRenderSystem->_setTextureCoordCalculation(0, Ogre::TEXCALC_NONE);
		mRenderSystem->_setTextureCoordSet(0, 0);
		mRenderSystem->_setTextureUnitFiltering(0, Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE);
		mRenderSystem->_setTextureAddressingMode(0, mTextureAddressMode);
		mRenderSystem->_setTextureMatrix(0, Ogre::Matrix4::IDENTITY);
#if OGRE_VERSION < MYGUI_DEFINE_VERSION(1, 6, 0)
		mRenderSystem->_setAlphaRejectSettings(Ogre::CMPF_ALWAYS_PASS, 0);
#else
		mRenderSystem->_setAlphaRejectSettings(Ogre::CMPF_ALWAYS_PASS, 0, false);
#endif
		mRenderSystem->_setTextureBlendMode(0, mColorBlendMode);
		mRenderSystem->_setTextureBlendMode(0, mAlphaBlendMode);
		mRenderSystem->_disableTextureUnitsFrom(1);

		// enable alpha blending
		mRenderSystem->_setSceneBlending(Ogre::SBF_SOURCE_ALPHA, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA);
	}

	void OgreRenderManager::end()
	{
	}

} // namespace MyGUI
<commit_msg>possibility to initialise MyGUI without Ogre viewport<commit_after>/*!
	@file
	@author		Albert Semenov
	@date		04/2008
	@module
*/
/*
	This file is part of MyGUI.

	MyGUI 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 3 of the License, or
	(at your option) any later version.

	MyGUI 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 MyGUI.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "MyGUI_Precompiled.h"
#include "MyGUI_OgreRenderManager.h"
#include "MyGUI_OgreTexture.h"
#include "MyGUI_OgreVertexBuffer.h"
#include "MyGUI_LogManager.h"
#include "MyGUI_Gui.h"

namespace MyGUI
{

	MYGUI_INSTANCE_IMPLEMENT(OgreRenderManager);

	void OgreRenderManager::initialise(Ogre::RenderWindow* _window)
	{
		//MYGUI_ASSERT(false == mIsInitialise, INSTANCE_TYPE_NAME << " initialised twice");
		//MYGUI_LOG(Info, "* Initialise: " << INSTANCE_TYPE_NAME);

		//
		mSceneManager = nullptr;
		mUpdate = false;
		//mMaximumDepth = 0;
		mListener = nullptr;
		mRenderSystem = nullptr;

		mColorBlendMode.blendType	= Ogre::LBT_COLOUR;
		mColorBlendMode.source1		= Ogre::LBS_TEXTURE;
		mColorBlendMode.source2		= Ogre::LBS_DIFFUSE;
		mColorBlendMode.operation	= Ogre::LBX_MODULATE;

		mAlphaBlendMode.blendType	= Ogre::LBT_ALPHA;
		mAlphaBlendMode.source1		= Ogre::LBS_TEXTURE;
		mAlphaBlendMode.source2		= Ogre::LBS_DIFFUSE;
		mAlphaBlendMode.operation	= Ogre::LBX_MODULATE;

		mTextureAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP;
		mTextureAddressMode.v = Ogre::TextureUnitState::TAM_CLAMP;
		mTextureAddressMode.w = Ogre::TextureUnitState::TAM_CLAMP;

		Ogre::Root * root = Ogre::Root::getSingletonPtr();
		if (root != nullptr)
		{
			//
			Ogre::VertexElementType vertext_type = root->getRenderSystem()->getColourVertexElementType();
			if (vertext_type == Ogre::VET_COLOUR_ARGB) mVertexFormat = VertexColourType::ColourARGB;
			else if (vertext_type == Ogre::VET_COLOUR_ABGR) mVertexFormat = VertexColourType::ColourABGR;

			Ogre::SceneManagerEnumerator::SceneManagerIterator iter = root->getSceneManagerIterator();
			if (iter.hasMoreElements())
			{
				mSceneManager = iter.getNext();
				mSceneManager->addRenderQueueListener(this);
			}

			//
			mRenderSystem = root->getRenderSystem();
			if (mRenderSystem != nullptr)
			{
				mRenderSystem->addListener(this);

				//mMaximumDepth = mRenderSystem->getMaximumDepthInputValue();
				//mTexelOffset.set(mRenderSystem->getHorizontalTexelOffset(), mRenderSystem->getVerticalTexelOffset());
			}
		}

		//
		mActiveViewport = 0;
		//
		mWindow = _window;
		if (mWindow != nullptr && mWindow->getNumViewports() > 0)
		{
			//MYGUI_ASSERT(mWindow->getNumViewports(), "You must have viewport for MyGUI initialisation.");
			//mViewSize.set(mWindow->getViewport(mActiveViewport)->getActualWidth(), mWindow->getViewport(mActiveViewport)->getActualHeight());
			Ogre::Viewport* port = mWindow->getViewport(mActiveViewport);
			mViewSize.set(port->getActualWidth(), port->getActualHeight());

			if (mRenderSystem != nullptr)
			{
				mRenderTargetInfo.maximumDepth = mRenderSystem->getMaximumDepthInputValue();
				mRenderTargetInfo.hOffset = mRenderSystem->getHorizontalTexelOffset() / float(mViewSize.width);
				mRenderTargetInfo.vOffset = mRenderSystem->getVerticalTexelOffset() / float(mViewSize.height);
				mRenderTargetInfo.aspectCoef = float(mViewSize.height) / float(mViewSize.width);
				mRenderTargetInfo.pixScaleX = 1.0 / float(mViewSize.width);
				mRenderTargetInfo.pixScaleY = 1.0 / float(mViewSize.height);
			}
		}
		else
		{
			mActiveViewport = -1;
		}

		mRenderTargetInfo.rttFlipY = Ogre::Root::getSingleton().getRenderSystem()->getName( ) == "OpenGL Rendering Subsystem";

		//
		if (mWindow != nullptr)
		{
			Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
			windowResized(mWindow);
		}

		//MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully initialized");
		mIsInitialise = true;
	}

	void OgreRenderManager::shutdown()
	{
		if (false == mIsInitialise) return;
		//MYGUI_LOG(Info, "* Shutdown: " << INSTANCE_TYPE_NAME);

		clearTextures();

		//
		if (mWindow != nullptr)
		{
			Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
		}

		//
		Ogre::Root * root = Ogre::Root::getSingletonPtr();
		if (root != nullptr)
		{
			root->getRenderSystem()->removeListener(this);
		}

		setSceneManager(nullptr);

		//MYGUI_LOG(Info, INSTANCE_TYPE_NAME << " successfully shutdown");
		mIsInitialise = false;
	}

	void OgreRenderManager::renderQueueStarted(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& skipThisInvocation)
	{
		if (Ogre::RENDER_QUEUE_OVERLAY != queueGroupId) return;

		Ogre::Viewport * vp = mSceneManager->getCurrentViewport();
		if (nullptr == vp || !vp->getOverlaysEnabled()) return;

		if (mListener != nullptr)
		{
			begin();
			mListener->doRender(mUpdate);
			end();
		}

		//
		mUpdate = false;
	}

	void OgreRenderManager::renderQueueEnded(Ogre::uint8 queueGroupId, const Ogre::String& invocation, bool& repeatThisInvocation)
	{
	}

	void OgreRenderManager::setSceneManager(Ogre::SceneManager * _scene)
	{
		if (nullptr != mSceneManager) mSceneManager->removeRenderQueueListener(this);
		mSceneManager = _scene;
		if (nullptr != mSceneManager) mSceneManager->addRenderQueueListener(this);
	}

	void OgreRenderManager::eventOccurred(const Ogre::String& eventName, const Ogre::NameValuePairList* parameters)
	{
		if(eventName == "DeviceLost")
		{
		}
		else if(eventName == "DeviceRestored")
		{
			//
			mUpdate = true;
		}
	}

	void OgreRenderManager::setRenderQueueListener(IRenderQueueListener* _listener)
	{
		mListener = _listener;
		mUpdate = true;
	}

	ITexture* OgreRenderManager::createTexture(const std::string& _name, const std::string& _group)
	{
		MapTexture::const_iterator item = mTextures.find(_name);
		MYGUI_ASSERT(item==mTextures.end(), "Resource '" << _name << "' already exist");

		OgreTexture* texture = new OgreTexture(_name, _group);
		mTextures[_name] = texture;

		return texture;
	}

	void OgreRenderManager::destroyTexture(ITexture* _texture)
	{
		for (MapTexture::iterator item=mTextures.begin(); item!=mTextures.end(); ++item)
		{
			if (item->second == _texture)
			{
				delete _texture;
				mTextures.erase(item);
				break;
			}
		}
	}

	ITexture* OgreRenderManager::getByName(const std::string& _name)
	{
		MapTexture::const_iterator item = mTextures.find(_name);
		return item == mTextures.end() ? nullptr : item->second;
	}

	void OgreRenderManager::clearTextures()
	{
		for (MapTexture::iterator item=mTextures.begin(); item!=mTextures.end(); ++item)
		{
			delete item->second;
		}
		mTextures.clear();
	}

	IVertexBuffer* OgreRenderManager::createVertexBuffer()
	{
		return new OgreVertexBuffer();
	}

	void OgreRenderManager::destroyVertexBuffer(IVertexBuffer* _buffer)
	{
		delete _buffer;
	}

	void OgreRenderManager::setActiveViewport(size_t _num)
	{
		if (_num == mActiveViewport) return;
		MYGUI_ASSERT(mWindow, "Gui is not initialised.");
		MYGUI_ASSERT(mWindow->getNumViewports() >= _num, "index out of range");
		mActiveViewport = _num;
		Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, this);
		Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
		//
		windowResized(mWindow);
	}

	//
	void OgreRenderManager::windowResized(Ogre::RenderWindow* rw)
	{
		if(rw->getNumViewports() > 0)
		{
			Ogre::Viewport * port = rw->getViewport(mActiveViewport);
			mViewSize.set(port->getActualWidth(), port->getActualHeight());

			//
			mUpdate = true;

			if (mRenderSystem != nullptr)
			{
				mRenderTargetInfo.maximumDepth = mRenderSystem->getMaximumDepthInputValue();
				mRenderTargetInfo.hOffset = mRenderSystem->getHorizontalTexelOffset() / float(mViewSize.width);
				mRenderTargetInfo.vOffset = mRenderSystem->getVerticalTexelOffset() / float(mViewSize.height);
				mRenderTargetInfo.aspectCoef = float(mViewSize.height) / float(mViewSize.width);
				mRenderTargetInfo.pixScaleX = 1.0 / float(mViewSize.width);
				mRenderTargetInfo.pixScaleY = 1.0 / float(mViewSize.height);
			}

			Gui* gui = Gui::getInstancePtr();
			if (gui != nullptr) gui->resizeWindow(mViewSize);
		}
	}

	void OgreRenderManager::doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count)
	{
		OgreTexture* texture = static_cast<OgreTexture*>(_texture);

		mRenderSystem->_setTexture(0, true, texture->getOgreTexture());

		OgreVertexBuffer* buffer = static_cast<OgreVertexBuffer*>(_buffer);
		Ogre::RenderOperation* operation = buffer->getRenderOperation();
		operation->vertexData->vertexCount = _count;

		mRenderSystem->_render(*operation);
	}

	void OgreRenderManager::doRender(IVertexBuffer* _buffer, const std::string& _texture, size_t _count)
	{
		mRenderSystem->_setTexture(0, true, _texture);

		OgreVertexBuffer* buffer = static_cast<OgreVertexBuffer*>(_buffer);
		Ogre::RenderOperation* operation = buffer->getRenderOperation();
		operation->vertexData->vertexCount = _count;

		mRenderSystem->_render(*operation);
	}

	void OgreRenderManager::begin()
	{
		// set-up matrices
		mRenderSystem->_setWorldMatrix(Ogre::Matrix4::IDENTITY);
		mRenderSystem->_setViewMatrix(Ogre::Matrix4::IDENTITY);
		mRenderSystem->_setProjectionMatrix(Ogre::Matrix4::IDENTITY);

		// initialise render settings
		mRenderSystem->setLightingEnabled(false);
		mRenderSystem->_setDepthBufferParams(false, false);
		mRenderSystem->_setDepthBias(0, 0);
		mRenderSystem->_setCullingMode(Ogre::CULL_NONE);
		mRenderSystem->_setFog(Ogre::FOG_NONE);
		mRenderSystem->_setColourBufferWriteEnabled(true, true, true, true);
		mRenderSystem->unbindGpuProgram(Ogre::GPT_FRAGMENT_PROGRAM);
		mRenderSystem->unbindGpuProgram(Ogre::GPT_VERTEX_PROGRAM);
		mRenderSystem->setShadingType(Ogre::SO_GOURAUD);
		//mRenderSystem->_setPolygonMode(Ogre::PM_SOLID);

		// initialise texture settings
		mRenderSystem->_setTextureCoordCalculation(0, Ogre::TEXCALC_NONE);
		mRenderSystem->_setTextureCoordSet(0, 0);
		mRenderSystem->_setTextureUnitFiltering(0, Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE);
		mRenderSystem->_setTextureAddressingMode(0, mTextureAddressMode);
		mRenderSystem->_setTextureMatrix(0, Ogre::Matrix4::IDENTITY);
#if OGRE_VERSION < MYGUI_DEFINE_VERSION(1, 6, 0)
		mRenderSystem->_setAlphaRejectSettings(Ogre::CMPF_ALWAYS_PASS, 0);
#else
		mRenderSystem->_setAlphaRejectSettings(Ogre::CMPF_ALWAYS_PASS, 0, false);
#endif
		mRenderSystem->_setTextureBlendMode(0, mColorBlendMode);
		mRenderSystem->_setTextureBlendMode(0, mAlphaBlendMode);
		mRenderSystem->_disableTextureUnitsFrom(1);

		// enable alpha blending
		mRenderSystem->_setSceneBlending(Ogre::SBF_SOURCE_ALPHA, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA);
	}

	void OgreRenderManager::end()
	{
	}

} // namespace MyGUI<|endoftext|>