<commit_before>//
//  kern_start.cpp
//  Shiki
//
//  Copyright © 2016-2017 vit9696. All rights reserved.
//

#include <Headers/plugin_start.hpp>
#include <Headers/kern_api.hpp>

#include "kern_resources.hpp"

static void disableSection(uint32_t section) {
	for (size_t i = 0; i < ADDPR(procInfoSize); i++) {
		if (ADDPR(procInfo)[i].section == section) {
			ADDPR(procInfo)[i].section = SectionUnused;
		}
	}

	for (size_t i = 0; i < ADDPR(binaryModSize); i++) {
		auto patches = ADDPR(binaryMod)[i].patches;
		for (size_t j = 0; j < ADDPR(binaryMod)[i].count; j++) {
			if (patches[j].section == section) {
				patches[j].section = SectionUnused;
			}
		}
	}
}

static void shikiStart() {
	// Attempt to support fps.1_0 in Safari
	char tmp[16];
	bool patchStreamVideo = PE_parse_boot_argn("-shikifps", tmp, sizeof(tmp));
	bool leaveForceAccelRenderer = true;
	bool leaveBGRASupport = true;

	if (PE_parse_boot_argn("shikigva", tmp, sizeof(tmp))) {
		leaveForceAccelRenderer = !(tmp[0] & 1);
		leaveBGRASupport = !(tmp[0] & 2);
	}

	if (PE_parse_boot_argn("-shikigva", tmp, sizeof(tmp))) {
		SYSLOG("shiki", "-shikigva is deprecated use shikgva=1 instead");
		leaveForceAccelRenderer = false;
	}

	// Disable unused SectionFSTREAM
	if (!patchStreamVideo)
		disableSection(SectionNSTREAM);

	if (leaveForceAccelRenderer)
		disableSection(SectionOFFLINE);

	if (leaveBGRASupport)
		disableSection(SectionBGRA);

	lilu.onProcLoad(ADDPR(procInfo), ADDPR(procInfoSize), nullptr, nullptr, ADDPR(binaryMod), ADDPR(binaryModSize));
}

static const char *bootargOff[] {
	"-shikioff",
	// Additionally disable during recovery/installation
	"rp0",
	"rp",
	"container-dmg",
	"root-dmg",
	"auth-root-dmg",
	// As well as safe mode
	"-x"
};

static const char *bootargDebug[] {
	"-shikidbg"
};

static const char *bootargBeta[] {
	"-shikibeta"
};

PluginConfiguration ADDPR(config) {
	xStringify(PRODUCT_NAME),
	parseModuleVersion(xStringify(MODULE_VERSION)),
	bootargOff,
	arrsize(bootargOff),
	bootargDebug,
	arrsize(bootargDebug),
	bootargBeta,
	arrsize(bootargBeta),
	KernelVersion::Mavericks,
	KernelVersion::HighSierra,
	shikiStart
};
<commit_msg>Update plugin requirements for 1.2.0<commit_after>//
//  kern_start.cpp
//  Shiki
//
//  Copyright © 2016-2017 vit9696. All rights reserved.
//

#include <Headers/plugin_start.hpp>
#include <Headers/kern_api.hpp>

#include "kern_resources.hpp"

static void disableSection(uint32_t section) {
	for (size_t i = 0; i < ADDPR(procInfoSize); i++) {
		if (ADDPR(procInfo)[i].section == section) {
			ADDPR(procInfo)[i].section = SectionUnused;
		}
	}

	for (size_t i = 0; i < ADDPR(binaryModSize); i++) {
		auto patches = ADDPR(binaryMod)[i].patches;
		for (size_t j = 0; j < ADDPR(binaryMod)[i].count; j++) {
			if (patches[j].section == section) {
				patches[j].section = SectionUnused;
			}
		}
	}
}

static void shikiStart() {
	// Attempt to support fps.1_0 in Safari
	char tmp[16];
	bool patchStreamVideo = PE_parse_boot_argn("-shikifps", tmp, sizeof(tmp));
	bool leaveForceAccelRenderer = true;
	bool leaveBGRASupport = true;

	if (PE_parse_boot_argn("shikigva", tmp, sizeof(tmp))) {
		leaveForceAccelRenderer = !(tmp[0] & 1);
		leaveBGRASupport = !(tmp[0] & 2);
	}

	if (PE_parse_boot_argn("-shikigva", tmp, sizeof(tmp))) {
		SYSLOG("shiki", "-shikigva is deprecated use shikgva=1 instead");
		leaveForceAccelRenderer = false;
	}

	// Disable unused SectionFSTREAM
	if (!patchStreamVideo)
		disableSection(SectionNSTREAM);

	if (leaveForceAccelRenderer)
		disableSection(SectionOFFLINE);

	if (leaveBGRASupport)
		disableSection(SectionBGRA);

	lilu.onProcLoad(ADDPR(procInfo), ADDPR(procInfoSize), nullptr, nullptr, ADDPR(binaryMod), ADDPR(binaryModSize));
}

static const char *bootargOff[] {
	"-shikioff"
};

static const char *bootargDebug[] {
	"-shikidbg"
};

static const char *bootargBeta[] {
	"-shikibeta"
};

PluginConfiguration ADDPR(config) {
	xStringify(PRODUCT_NAME),
	parseModuleVersion(xStringify(MODULE_VERSION)),
	LiluAPI::AllowNormal,
	bootargOff,
	arrsize(bootargOff),
	bootargDebug,
	arrsize(bootargDebug),
	bootargBeta,
	arrsize(bootargBeta),
	KernelVersion::Mavericks,
	KernelVersion::HighSierra,
	shikiStart
};
<|endoftext|>


<commit_before>// Qt includes
#include <QDateTime>
#include <QTimer>

#include "LinearColorSmoothing.h"
#include <hyperion/Hyperion.h>

#include <cmath>

using namespace hyperion;

const int64_t  DEFAUL_SETTLINGTIME    = 200;	// settlingtime in ms
const double   DEFAUL_UPDATEFREQUENCY = 25;	// updatefrequncy in hz
const int64_t  DEFAUL_UPDATEINTERVALL = static_cast<int64_t>(1000 / DEFAUL_UPDATEFREQUENCY); // updateintervall in ms
const unsigned DEFAUL_OUTPUTDEPLAY    = 0;	// outputdelay in ms

LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument& config, Hyperion* hyperion)
	: QObject(hyperion)
	, _log(Logger::getInstance("SMOOTHING"))
	, _hyperion(hyperion)
	, _updateInterval(DEFAUL_UPDATEINTERVALL)
	, _settlingTime(DEFAUL_SETTLINGTIME)
	, _timer(new QTimer(this))
	, _outputDelay(DEFAUL_OUTPUTDEPLAY)
	, _writeToLedsEnable(false)
	, _continuousOutput(false)
	, _pause(false)
	, _currentConfigId(0)
	, _enabled(false)
{
	// init cfg 0 (default)
	addConfig(DEFAUL_SETTLINGTIME, DEFAUL_UPDATEFREQUENCY, DEFAUL_OUTPUTDEPLAY);
	handleSettingsUpdate(settings::SMOOTHING, config);
	selectConfig(0, true);

	// add pause on cfg 1
	SMOOTHING_CFG cfg = {true, 0, 0, 0};
	_cfgList.append(cfg);

	// listen for comp changes
	connect(_hyperion, &Hyperion::compStateChangeRequest, this, &LinearColorSmoothing::componentStateChange);
	// timer
	connect(_timer, &QTimer::timeout, this, &LinearColorSmoothing::updateLeds);
}

void LinearColorSmoothing::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
{
	if(type == settings::SMOOTHING)
	{
		//	std::cout << "LinearColorSmoothing::handleSettingsUpdate" << std::endl;
		//	std::cout << config.toJson().toStdString() << std::endl;

		QJsonObject obj = config.object();
		if(enabled() != obj["enable"].toBool(true))
			setEnable(obj["enable"].toBool(true));

		_continuousOutput = obj["continuousOutput"].toBool(true);

		SMOOTHING_CFG cfg = {false,
							 static_cast<int64_t>(obj["time_ms"].toInt(DEFAUL_SETTLINGTIME)),
							 static_cast<int64_t>(1000.0/obj["updateFrequency"].toDouble(DEFAUL_UPDATEFREQUENCY)),
							 static_cast<unsigned>(obj["updateDelay"].toInt(DEFAUL_OUTPUTDEPLAY))
							};
		//Debug( _log, "smoothing cfg_id %d: pause: %d bool, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _currentConfigId, cfg.pause, cfg.settlingTime, cfg.updateInterval, unsigned(1000.0/cfg.updateInterval), cfg.outputDelay );
		_cfgList[0] = cfg;

		// if current id is 0, we need to apply the settings (forced)
		if( _currentConfigId == 0)
		{
			//Debug( _log, "_currentConfigId == 0");
			selectConfig(0, true);
		}
		else
		{
			//Debug( _log, "_currentConfigId != 0");
		}
	}
}

int LinearColorSmoothing::write(const std::vector<ColorRgb> &ledValues)
{
	// received a new target color
	if (_previousValues.empty())
	{
		// not initialized yet
		_targetTime = QDateTime::currentMSecsSinceEpoch() + _settlingTime;
		_targetValues = ledValues;

		_previousTime = QDateTime::currentMSecsSinceEpoch();
		_previousValues = ledValues;

		//Debug( _log, "Start Smoothing timer: settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames", _settlingTime, _updateInterval, unsigned(1000.0/_updateInterval), _outputDelay );
		QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval));
	}
	else
	{
		//std::cout << "LinearColorSmoothing::write> "; LedDevice::printLedValues ( ledValues );

		_targetTime = QDateTime::currentMSecsSinceEpoch() + _settlingTime;
		memcpy(_targetValues.data(), ledValues.data(), ledValues.size() * sizeof(ColorRgb));

		//std::cout << "LinearColorSmoothing::write> _targetValues: "; LedDevice::printLedValues ( _targetValues );
	}

	return 0;
}

int LinearColorSmoothing::updateLedValues(const std::vector<ColorRgb>& ledValues)
{
	int retval = 0;
	if (!_enabled)
	{
		return -1;
	}
	else
	{
		retval = write(ledValues);
	}
	return retval;
}

void LinearColorSmoothing::updateLeds()
{
	int64_t now = QDateTime::currentMSecsSinceEpoch();
	int64_t deltaTime = _targetTime - now;

	//Debug(_log, "elapsed Time [%d], _targetTime [%d] - now [%d], deltaTime [%d]", now -_previousTime, _targetTime, now, deltaTime);
	if (deltaTime < 0)
	{
		memcpy(_previousValues.data(), _targetValues.data(), _targetValues.size() * sizeof(ColorRgb));
		_previousTime = now;

		queueColors(_previousValues);
		_writeToLedsEnable = _continuousOutput;
	}
	else
	{
		_writeToLedsEnable = true;

		//std::cout << "LinearColorSmoothing::updateLeds> _previousValues: "; LedDevice::printLedValues ( _previousValues );

		float k = 1.0f - 1.0f * deltaTime / (_targetTime - _previousTime);

		int reddif = 0, greendif = 0, bluedif = 0;

		for (size_t i = 0; i < _previousValues.size(); ++i)
		{
			ColorRgb & prev   = _previousValues[i];
			ColorRgb & target = _targetValues[i];

			reddif   = target.red   - prev.red;
			greendif = target.green - prev.green;
			bluedif  = target.blue  - prev.blue;

			prev.red   += (reddif   < 0 ? -1:1) * std::ceil(k * std::abs(reddif));
			prev.green += (greendif < 0 ? -1:1) * std::ceil(k * std::abs(greendif));
			prev.blue  += (bluedif  < 0 ? -1:1) * std::ceil(k * std::abs(bluedif));
		}
		_previousTime = now;

		//std::cout << "LinearColorSmoothing::updateLeds> _targetValues: "; LedDevice::printLedValues ( _targetValues );

		queueColors(_previousValues);
	}
}

void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> & ledColors)
{
	//Debug(_log, "queueColors -  _outputDelay[%d] _outputQueue.size() [%d], _writeToLedsEnable[%d]", _outputDelay, _outputQueue.size(), _writeToLedsEnable);
	if (_outputDelay == 0)
	{
		// No output delay => immediate write
		if ( _writeToLedsEnable && !_pause)
		{
//			if ( ledColors.size() == 0 )
//				qFatal ("No LedValues! - in LinearColorSmoothing::queueColors() - _outputDelay == 0");
//			else
			emit _hyperion->ledDeviceData(ledColors);
		}
	}
	else
	{
		// Push new colors in the delay-buffer
		if ( _writeToLedsEnable )
			_outputQueue.push_back(ledColors);

		// If the delay-buffer is filled pop the front and write to device
		if (_outputQueue.size() > 0 )
		{
			if ( _outputQueue.size() > _outputDelay || !_writeToLedsEnable )
			{
				if (!_pause)
				{
					emit _hyperion->ledDeviceData(_outputQueue.front());
				}
				_outputQueue.pop_front();
			}
		}
	}
}

void LinearColorSmoothing::clearQueuedColors()
{
	QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
	_previousValues.clear();

	_targetValues.clear();
}

void LinearColorSmoothing::componentStateChange(const hyperion::Components component, const bool state)
{
	_writeToLedsEnable = state;
	if(component == hyperion::COMP_LEDDEVICE)
	{
		clearQueuedColors();
	}

	if(component == hyperion::COMP_SMOOTHING)
	{
		setEnable(state);
	}
}

void LinearColorSmoothing::setEnable(bool enable)
{
	_enabled = enable;
	if (!_enabled)
	{
		clearQueuedColors();
	}
	// update comp register
	_hyperion->setNewComponentState(hyperion::COMP_SMOOTHING, enable);
}

void LinearColorSmoothing::setPause(bool pause)
{
	_pause = pause;
}

unsigned LinearColorSmoothing::addConfig(int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
{
	SMOOTHING_CFG cfg = {false, settlingTime_ms, int64_t(1000.0/ledUpdateFrequency_hz), updateDelay};
	_cfgList.append(cfg);

	//Debug( _log, "smoothing cfg %d: pause: %d bool, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _cfgList.count()-1, cfg.pause, cfg.settlingTime, cfg.updateInterval, unsigned(1000.0/cfg.updateInterval), cfg.outputDelay );
	return _cfgList.count() - 1;
}

unsigned LinearColorSmoothing::updateConfig(unsigned cfgID, int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
{
	unsigned updatedCfgID = cfgID;
	if ( cfgID < static_cast<unsigned>(_cfgList.count()) )
	{
		SMOOTHING_CFG cfg = {false, settlingTime_ms, int64_t(1000.0/ledUpdateFrequency_hz), updateDelay};
		_cfgList[updatedCfgID] = cfg;
	}
	else
	{
		updatedCfgID = addConfig ( settlingTime_ms, ledUpdateFrequency_hz, updateDelay);
	}
//	Debug( _log, "smoothing updatedCfgID %u: settlingTime: %d ms, "
//				 "interval: %d ms (%u Hz), updateDelay: %u frames",  cfgID, _settlingTime, int64_t(1000.0/ledUpdateFrequency_hz), unsigned(ledUpdateFrequency_hz), updateDelay );
	return updatedCfgID;
}

bool LinearColorSmoothing::selectConfig(unsigned cfg, const bool& force)
{
	if (_currentConfigId == cfg && !force)
	{
		//Debug( _log, "selectConfig SAME as before, not FORCED - _currentConfigId [%u], force [%d]", cfg, force);
		//Debug( _log, "current smoothing cfg: %d, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _currentConfigId, _settlingTime, _updateInterval, unsigned(1000.0/_updateInterval), _outputDelay );
		return true;
	}

	//Debug( _log, "selectConfig FORCED - _currentConfigId [%u], force [%d]", cfg, force);
	if ( cfg < (unsigned)_cfgList.count())
	{
		_settlingTime     = _cfgList[cfg].settlingTime;
		_outputDelay      = _cfgList[cfg].outputDelay;
		_pause            = _cfgList[cfg].pause;

		if (_cfgList[cfg].updateInterval != _updateInterval)
		{

			QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
			_updateInterval = _cfgList[cfg].updateInterval;
			if ( this->enabled() && this->_writeToLedsEnable )
			{
				//Debug( _log, "_cfgList[cfg].updateInterval != _updateInterval - Restart timer - _updateInterval [%d]", _updateInterval);
				QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval));
			}
			else
			{
				//Debug( _log, "Smoothing disabled, do NOT restart timer");
			}
		}
		_currentConfigId = cfg;
		// Debug( _log, "current smoothing cfg: %d, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _currentConfigId, _settlingTime, _updateInterval, unsigned(1000.0/_updateInterval), _outputDelay );
		//	DebugIf( enabled() && !_pause, _log, "set smoothing cfg: %u settlingTime: %d ms, interval: %d ms,  updateDelay: %u frames",  _currentConfigId, _settlingTime, _updateInterval,  _outputDelay );
		// DebugIf( _pause, _log, "set smoothing cfg: %d, pause",  _currentConfigId );

		return true;
	}

	// reset to default
	_currentConfigId = 0;
	return false;
}
<commit_msg>Fix heap corruption (#862)<commit_after>// Qt includes
#include <QDateTime>
#include <QTimer>

#include "LinearColorSmoothing.h"
#include <hyperion/Hyperion.h>

#include <cmath>

using namespace hyperion;

const int64_t  DEFAUL_SETTLINGTIME    = 200;	// settlingtime in ms
const double   DEFAUL_UPDATEFREQUENCY = 25;	// updatefrequncy in hz
const int64_t  DEFAUL_UPDATEINTERVALL = static_cast<int64_t>(1000 / DEFAUL_UPDATEFREQUENCY); // updateintervall in ms
const unsigned DEFAUL_OUTPUTDEPLAY    = 0;	// outputdelay in ms

LinearColorSmoothing::LinearColorSmoothing(const QJsonDocument& config, Hyperion* hyperion)
	: QObject(hyperion)
	, _log(Logger::getInstance("SMOOTHING"))
	, _hyperion(hyperion)
	, _updateInterval(DEFAUL_UPDATEINTERVALL)
	, _settlingTime(DEFAUL_SETTLINGTIME)
	, _timer(new QTimer(this))
	, _outputDelay(DEFAUL_OUTPUTDEPLAY)
	, _writeToLedsEnable(false)
	, _continuousOutput(false)
	, _pause(false)
	, _currentConfigId(0)
	, _enabled(false)
{
	// init cfg 0 (default)
	addConfig(DEFAUL_SETTLINGTIME, DEFAUL_UPDATEFREQUENCY, DEFAUL_OUTPUTDEPLAY);
	handleSettingsUpdate(settings::SMOOTHING, config);
	selectConfig(0, true);

	// add pause on cfg 1
	SMOOTHING_CFG cfg = {true, 0, 0, 0};
	_cfgList.append(cfg);

	// listen for comp changes
	connect(_hyperion, &Hyperion::compStateChangeRequest, this, &LinearColorSmoothing::componentStateChange);
	// timer
	connect(_timer, &QTimer::timeout, this, &LinearColorSmoothing::updateLeds);
}

void LinearColorSmoothing::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
{
	if(type == settings::SMOOTHING)
	{
		//	std::cout << "LinearColorSmoothing::handleSettingsUpdate" << std::endl;
		//	std::cout << config.toJson().toStdString() << std::endl;

		QJsonObject obj = config.object();
		if(enabled() != obj["enable"].toBool(true))
			setEnable(obj["enable"].toBool(true));

		_continuousOutput = obj["continuousOutput"].toBool(true);

		SMOOTHING_CFG cfg = {false,
							 static_cast<int64_t>(obj["time_ms"].toInt(DEFAUL_SETTLINGTIME)),
							 static_cast<int64_t>(1000.0/obj["updateFrequency"].toDouble(DEFAUL_UPDATEFREQUENCY)),
							 static_cast<unsigned>(obj["updateDelay"].toInt(DEFAUL_OUTPUTDEPLAY))
							};
		//Debug( _log, "smoothing cfg_id %d: pause: %d bool, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _currentConfigId, cfg.pause, cfg.settlingTime, cfg.updateInterval, unsigned(1000.0/cfg.updateInterval), cfg.outputDelay );
		_cfgList[0] = cfg;

		// if current id is 0, we need to apply the settings (forced)
		if( _currentConfigId == 0)
		{
			//Debug( _log, "_currentConfigId == 0");
			selectConfig(0, true);
		}
		else
		{
			//Debug( _log, "_currentConfigId != 0");
		}
	}
}

int LinearColorSmoothing::write(const std::vector<ColorRgb> &ledValues)
{
	_targetTime = QDateTime::currentMSecsSinceEpoch() + _settlingTime;
	_targetValues = ledValues;

	// received a new target color
	if (_previousValues.empty())
	{
		// not initialized yet
		_previousTime = QDateTime::currentMSecsSinceEpoch();
		_previousValues = ledValues;

		//Debug( _log, "Start Smoothing timer: settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames", _settlingTime, _updateInterval, unsigned(1000.0/_updateInterval), _outputDelay );
		QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval));
	}

	return 0;
}

int LinearColorSmoothing::updateLedValues(const std::vector<ColorRgb>& ledValues)
{
	int retval = 0;
	if (!_enabled)
	{
		return -1;
	}
	else
	{
		retval = write(ledValues);
	}
	return retval;
}

void LinearColorSmoothing::updateLeds()
{
	int64_t now = QDateTime::currentMSecsSinceEpoch();
	int64_t deltaTime = _targetTime - now;

	//Debug(_log, "elapsed Time [%d], _targetTime [%d] - now [%d], deltaTime [%d]", now -_previousTime, _targetTime, now, deltaTime);
	if (deltaTime < 0)
	{
		_previousValues = _targetValues;
		_previousTime = now;

		queueColors(_previousValues);
		_writeToLedsEnable = _continuousOutput;
	}
	else
	{
		_writeToLedsEnable = true;

		//std::cout << "LinearColorSmoothing::updateLeds> _previousValues: "; LedDevice::printLedValues ( _previousValues );

		float k = 1.0f - 1.0f * deltaTime / (_targetTime - _previousTime);

		int reddif = 0, greendif = 0, bluedif = 0;

		for (size_t i = 0; i < _previousValues.size(); ++i)
		{
			ColorRgb & prev   = _previousValues[i];
			ColorRgb & target = _targetValues[i];

			reddif   = target.red   - prev.red;
			greendif = target.green - prev.green;
			bluedif  = target.blue  - prev.blue;

			prev.red   += (reddif   < 0 ? -1:1) * std::ceil(k * std::abs(reddif));
			prev.green += (greendif < 0 ? -1:1) * std::ceil(k * std::abs(greendif));
			prev.blue  += (bluedif  < 0 ? -1:1) * std::ceil(k * std::abs(bluedif));
		}
		_previousTime = now;

		//std::cout << "LinearColorSmoothing::updateLeds> _targetValues: "; LedDevice::printLedValues ( _targetValues );

		queueColors(_previousValues);
	}
}

void LinearColorSmoothing::queueColors(const std::vector<ColorRgb> & ledColors)
{
	//Debug(_log, "queueColors -  _outputDelay[%d] _outputQueue.size() [%d], _writeToLedsEnable[%d]", _outputDelay, _outputQueue.size(), _writeToLedsEnable);
	if (_outputDelay == 0)
	{
		// No output delay => immediate write
		if ( _writeToLedsEnable && !_pause)
		{
//			if ( ledColors.size() == 0 )
//				qFatal ("No LedValues! - in LinearColorSmoothing::queueColors() - _outputDelay == 0");
//			else
			emit _hyperion->ledDeviceData(ledColors);
		}
	}
	else
	{
		// Push new colors in the delay-buffer
		if ( _writeToLedsEnable )
			_outputQueue.push_back(ledColors);

		// If the delay-buffer is filled pop the front and write to device
		if (_outputQueue.size() > 0 )
		{
			if ( _outputQueue.size() > _outputDelay || !_writeToLedsEnable )
			{
				if (!_pause)
				{
					emit _hyperion->ledDeviceData(_outputQueue.front());
				}
				_outputQueue.pop_front();
			}
		}
	}
}

void LinearColorSmoothing::clearQueuedColors()
{
	QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
	_previousValues.clear();

	_targetValues.clear();
}

void LinearColorSmoothing::componentStateChange(const hyperion::Components component, const bool state)
{
	_writeToLedsEnable = state;
	if(component == hyperion::COMP_LEDDEVICE)
	{
		clearQueuedColors();
	}

	if(component == hyperion::COMP_SMOOTHING)
	{
		setEnable(state);
	}
}

void LinearColorSmoothing::setEnable(bool enable)
{
	_enabled = enable;
	if (!_enabled)
	{
		clearQueuedColors();
	}
	// update comp register
	_hyperion->setNewComponentState(hyperion::COMP_SMOOTHING, enable);
}

void LinearColorSmoothing::setPause(bool pause)
{
	_pause = pause;
}

unsigned LinearColorSmoothing::addConfig(int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
{
	SMOOTHING_CFG cfg = {false, settlingTime_ms, int64_t(1000.0/ledUpdateFrequency_hz), updateDelay};
	_cfgList.append(cfg);

	//Debug( _log, "smoothing cfg %d: pause: %d bool, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _cfgList.count()-1, cfg.pause, cfg.settlingTime, cfg.updateInterval, unsigned(1000.0/cfg.updateInterval), cfg.outputDelay );
	return _cfgList.count() - 1;
}

unsigned LinearColorSmoothing::updateConfig(unsigned cfgID, int settlingTime_ms, double ledUpdateFrequency_hz, unsigned updateDelay)
{
	unsigned updatedCfgID = cfgID;
	if ( cfgID < static_cast<unsigned>(_cfgList.count()) )
	{
		SMOOTHING_CFG cfg = {false, settlingTime_ms, int64_t(1000.0/ledUpdateFrequency_hz), updateDelay};
		_cfgList[updatedCfgID] = cfg;
	}
	else
	{
		updatedCfgID = addConfig ( settlingTime_ms, ledUpdateFrequency_hz, updateDelay);
	}
//	Debug( _log, "smoothing updatedCfgID %u: settlingTime: %d ms, "
//				 "interval: %d ms (%u Hz), updateDelay: %u frames",  cfgID, _settlingTime, int64_t(1000.0/ledUpdateFrequency_hz), unsigned(ledUpdateFrequency_hz), updateDelay );
	return updatedCfgID;
}

bool LinearColorSmoothing::selectConfig(unsigned cfg, const bool& force)
{
	if (_currentConfigId == cfg && !force)
	{
		//Debug( _log, "selectConfig SAME as before, not FORCED - _currentConfigId [%u], force [%d]", cfg, force);
		//Debug( _log, "current smoothing cfg: %d, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _currentConfigId, _settlingTime, _updateInterval, unsigned(1000.0/_updateInterval), _outputDelay );
		return true;
	}

	//Debug( _log, "selectConfig FORCED - _currentConfigId [%u], force [%d]", cfg, force);
	if ( cfg < (unsigned)_cfgList.count())
	{
		_settlingTime     = _cfgList[cfg].settlingTime;
		_outputDelay      = _cfgList[cfg].outputDelay;
		_pause            = _cfgList[cfg].pause;

		if (_cfgList[cfg].updateInterval != _updateInterval)
		{

			QMetaObject::invokeMethod(_timer, "stop", Qt::QueuedConnection);
			_updateInterval = _cfgList[cfg].updateInterval;
			if ( this->enabled() && this->_writeToLedsEnable )
			{
				//Debug( _log, "_cfgList[cfg].updateInterval != _updateInterval - Restart timer - _updateInterval [%d]", _updateInterval);
				QMetaObject::invokeMethod(_timer, "start", Qt::QueuedConnection, Q_ARG(int, _updateInterval));
			}
			else
			{
				//Debug( _log, "Smoothing disabled, do NOT restart timer");
			}
		}
		_currentConfigId = cfg;
		// Debug( _log, "current smoothing cfg: %d, settlingTime: %d ms, interval: %d ms (%u Hz), updateDelay: %u frames",  _currentConfigId, _settlingTime, _updateInterval, unsigned(1000.0/_updateInterval), _outputDelay );
		//	DebugIf( enabled() && !_pause, _log, "set smoothing cfg: %u settlingTime: %d ms, interval: %d ms,  updateDelay: %u frames",  _currentConfigId, _settlingTime, _updateInterval,  _outputDelay );
		// DebugIf( _pause, _log, "set smoothing cfg: %d, pause",  _currentConfigId );

		return true;
	}

	// reset to default
	_currentConfigId = 0;
	return false;
}
<|endoftext|>


<commit_before>#include "WinWindow.h"
#include "Library.h"

#include <QGridLayout>
#include <QMouseEvent>

#include <windows.h>
#include <windowsx.h>

WinWindow::WinWindow(HWND hWnd) : QWinWidget(hWnd)
{
    windowHandle = hWnd;

    setObjectName("winPanel");

    mainPanel = new WinPanel(this);

    QGridLayout* layout = new QGridLayout();
    layout->setMargin(0);
    setLayout(layout);
    layout->addWidget(mainPanel);

    mainPanel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    this->adjustSize();
    this->show();
}

#if QT_VERSION >= 0x050000
bool WinWindow::nativeEvent(const QByteArray&, void* msg, long*)
{
#else
bool WinPanel::winEvent(MSG* message, long*)
{
#endif
#if QT_VERSION >= 0x050000
    MSG* message = (MSG*) msg;
#endif
    switch(message->message)
    {
    case WM_SYSKEYDOWN:
    {
        if (message->wParam == VK_SPACE)
        {
            RECT winrect;
            GetWindowRect(windowHandle, &winrect);
            TrackPopupMenu(GetSystemMenu(windowHandle, false), TPM_TOPALIGN | TPM_LEFTALIGN, winrect.left + 5, winrect.top + 5, 0, windowHandle, NULL);
            break;
        }
    }
    case WM_KEYDOWN:
    {
        if (message->wParam == VK_F5 ||
                message->wParam == VK_F6 ||
                message->wParam == VK_F7)
        {
            SendMessage(windowHandle, WM_KEYDOWN, message->wParam, message->lParam);
            break;
        }
    }
    }

    return false;
}

void WinWindow::mousePressEvent(QMouseEvent* event)
{
    if (event->button() == Qt::LeftButton)
    {
        ReleaseCapture();
        SendMessage(windowHandle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
    }

    if (event->type() == QEvent::MouseButtonDblClick)
    {
        if (event->button() == Qt::LeftButton)
        {
            WINDOWPLACEMENT wp;
            wp.length = sizeof(WINDOWPLACEMENT);
            GetWindowPlacement(parentWindow(), &wp);
            if (wp.showCmd == SW_MAXIMIZE)
            {
                ShowWindow(parentWindow(), SW_RESTORE);
            }
            else
            {
                ShowWindow(parentWindow(), SW_MAXIMIZE);
            }
        }
    }
}

void WinWindow::minimize()
{
    ShowWindow(parentWindow(), SW_MINIMIZE);
}

void WinWindow::maximize()
{
    WINDOWPLACEMENT wp;
    wp.length = sizeof(WINDOWPLACEMENT);
    GetWindowPlacement(parentWindow(), &wp);
    if (wp.showCmd == SW_MAXIMIZE)
    {
        ShowWindow(parentWindow(), SW_RESTORE);
    }
    else
    {
        ShowWindow(parentWindow(), SW_MAXIMIZE);
    }
}

void WinWindow::closeWindow()
{
    PostQuitMessage(0);
}
<commit_msg>Adjust mouse event region on Windows<commit_after>#include "WinWindow.h"
#include "Library.h"

#include <QGridLayout>
#include <QMouseEvent>

#include <windows.h>
#include <windowsx.h>

WinWindow::WinWindow(HWND hWnd) : QWinWidget(hWnd)
{
    windowHandle = hWnd;

    setObjectName("winPanel");

    mainPanel = new WinPanel(this);

    QGridLayout* layout = new QGridLayout();
    layout->setMargin(0);
    setLayout(layout);
    layout->addWidget(mainPanel);

    mainPanel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    this->adjustSize();
    this->show();
}

#if QT_VERSION >= 0x050000
bool WinWindow::nativeEvent(const QByteArray&, void* msg, long*)
{
#else
bool WinPanel::winEvent(MSG* message, long*)
{
#endif
#if QT_VERSION >= 0x050000
    MSG* message = (MSG*) msg;
#endif
    switch(message->message)
    {
    case WM_SYSKEYDOWN:
    {
        if (message->wParam == VK_SPACE)
        {
            RECT winrect;
            GetWindowRect(windowHandle, &winrect);
            TrackPopupMenu(GetSystemMenu(windowHandle, false), TPM_TOPALIGN | TPM_LEFTALIGN, winrect.left + 5, winrect.top + 5, 0, windowHandle, NULL);
            break;
        }
    }
    case WM_KEYDOWN:
    {
        if (message->wParam == VK_F5 ||
                message->wParam == VK_F6 ||
                message->wParam == VK_F7)
        {
            SendMessage(windowHandle, WM_KEYDOWN, message->wParam, message->lParam);
            break;
        }
    }
    }

    return false;
}

void WinWindow::mousePressEvent(QMouseEvent* event)
{
    if (event->pos().y() < 32)
    {
        if (event->button() == Qt::LeftButton)
        {
            ReleaseCapture();
            SendMessage(windowHandle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
        }

        if (event->type() == QEvent::MouseButtonDblClick)
        {
            if (event->button() == Qt::LeftButton)
            {
                WINDOWPLACEMENT wp;
                wp.length = sizeof(WINDOWPLACEMENT);
                GetWindowPlacement(parentWindow(), &wp);
                if (wp.showCmd == SW_MAXIMIZE)
                {
                    ShowWindow(parentWindow(), SW_RESTORE);
                }
                else
                {
                    ShowWindow(parentWindow(), SW_MAXIMIZE);
                }
            }
        }
    }
}

void WinWindow::minimize()
{
    ShowWindow(parentWindow(), SW_MINIMIZE);
}

void WinWindow::maximize()
{
    WINDOWPLACEMENT wp;
    wp.length = sizeof(WINDOWPLACEMENT);
    GetWindowPlacement(parentWindow(), &wp);
    if (wp.showCmd == SW_MAXIMIZE)
    {
        ShowWindow(parentWindow(), SW_RESTORE);
    }
    else
    {
        ShowWindow(parentWindow(), SW_MAXIMIZE);
    }
}

void WinWindow::closeWindow()
{
    PostQuitMessage(0);
}
<|endoftext|>


<commit_before>/**
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2004 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */
/**
 * $Id: FBO.c,v 1.1.1.1 2005/12/23 18:05:00 psperl Exp $
 *
 * Render this methods
 */

#include <stdio.h>
//#include <GL/gl.h>
#include <iostream>
#include "Common.hpp"
#include "FBO.hpp"

RenderTarget::~RenderTarget() {

	glDeleteTextures( 1, &this->textureID[0]);

#ifdef USE_FBO
	if (useFBO)
         {
		glDeleteTextures( 1, &this->textureID[1] );
		glDeleteRenderbuffersEXT(1,  &this->depthb[0]);
		glDeleteFramebuffersEXT(1, &this->fbuffer[0]);
		if(renderToTexture)
		  {
		    glDeleteTextures( 1, &this->textureID[2] );
		    glDeleteRenderbuffersEXT(1,  &this->depthb[1]);
		    glDeleteFramebuffersEXT(1, &this->fbuffer[1]);
		  }
         }
#endif

}

GLuint RenderTarget::initRenderToTexture()
{
#ifdef USE_FBO

  if (this->useFBO==1)
    {
      this->renderToTexture=1;

      GLuint   fb2, depth_rb2;
      glGenFramebuffersEXT(1, &fb2);
      glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb2 );
      glGenRenderbuffersEXT(1, &depth_rb2);
      glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, depth_rb2 );

      glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize  );
      glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb2 );
      this->fbuffer[1] = fb2;
      this->depthb[1]=  depth_rb2;
      glGenTextures(1, &this->textureID[2]);
      glBindTexture(GL_TEXTURE_2D, this->textureID[2]);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
      glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->textureID[2], 0 );
      return this->textureID[2];
    }
#endif
return -1;

}

/** Creates new pbuffers */
RenderTarget::RenderTarget(int texsize, int width, int height) : useFBO(false) {

   int mindim = 0;
   int origtexsize = 0;

   this->renderToTexture = 0;
   this->texsize = texsize;

#ifdef USE_FBO
   glewInit();
      // Forceably disable FBO if user requested it but the video card / driver lacks
      // the appropraite frame buffer extension.
      if (useFBO = glewIsSupported("GL_EXT_framebuffer_object"))
	{

	  GLuint   fb,  depth_rb, rgba_tex,  other_tex;
	  glGenFramebuffersEXT(1, &fb);
	  glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb );

	  glGenRenderbuffersEXT(1, &depth_rb);
	  glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, depth_rb );
	  glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize  );
	  glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb );
	  this->fbuffer[0] = fb;
	  this->depthb[0]=  depth_rb;

	  glGenTextures(1, &other_tex);
	  glBindTexture(GL_TEXTURE_2D,other_tex);
	  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
	  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	  //glGenerateMipmapEXT(GL_TEXTURE_2D);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	  glGenTextures(1, &rgba_tex);
	  glBindTexture(GL_TEXTURE_2D, rgba_tex);
	  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	  //glGenerateMipmapEXT(GL_TEXTURE_2D);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	  glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, rgba_tex, 0 );
	  this->textureID[0] = rgba_tex;
	  this->textureID[1] = other_tex;

	  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	  if (status == GL_FRAMEBUFFER_COMPLETE_EXT) {
	    return;
	  }
	  std::cerr << "[projecM] warning: FBO support not detected. Using fallback." << std::endl;
	}

#endif

// Can reach here via two code paths:
// (1) useFBO was set to false externally by cmake / system setting / etc.
// (2) useFBO was true but forced to false as it failed to pass all the GLU extension checks.

    /** Fallback pbuffer creation via teximage hack */
    /** Check the texture size against the viewport size */
    /** If the viewport is smaller, then we'll need to scale the texture size down */
    /** If the viewport is larger, scale it up */
    mindim = width < height ? width : height;
    origtexsize = this->texsize;
    this->texsize = nearestPower2( mindim, SCALE_MINIFY );
        glGenTextures(1, &this->textureID[0] );

        glBindTexture(GL_TEXTURE_2D, this->textureID[0] );
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glTexImage2D(GL_TEXTURE_2D,
		    0,
		    GL_RGB,
		    this->texsize, this->texsize,
		    0,
		    GL_RGBA,
		    GL_UNSIGNED_BYTE,
		    NULL);

    return;
  }

  void RenderTarget::fallbackRescale(int width, int height)
  {
	int mindim = width < height ? width : height;
    int origtexsize = this->texsize;
    this->texsize = nearestPower2( mindim, SCALE_MINIFY );

    /* Create the texture that will be bound to the render this */
    /*

        if ( this->texsize != origtexsize ) {

            glDeleteTextures( 1, &this->textureID[0] );
          }
    */

        glGenTextures(1, &this->textureID[0] );

        glBindTexture(GL_TEXTURE_2D, this->textureID[0] );
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glTexImage2D(GL_TEXTURE_2D,
		    0,
		    GL_RGB,
		    this->texsize, this->texsize,
		    0,
		    GL_RGBA,
		    GL_UNSIGNED_BYTE,
		    NULL);

  }

/** Destroys the pbuffer */

/** Locks the pbuffer */
void RenderTarget::lock() {

#ifdef USE_FBO
  if(this->useFBO)
    {
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->fbuffer[0]);
    }
#endif
    }

/** Unlocks the pbuffer */
void RenderTarget::unlock() {

#ifdef USE_FBO
  if(this->useFBO)
    {
      glBindTexture( GL_TEXTURE_2D, this->textureID[1] );
      glCopyTexSubImage2D( GL_TEXTURE_2D,
                         0, 0, 0, 0, 0,
                         this->texsize, this->texsize );
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
      return;
    }
#endif
    /** Fallback texture path */

    glBindTexture( GL_TEXTURE_2D, this->textureID[0] );

	glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, this->texsize, this->texsize );
  }

/**
 * Calculates the nearest power of two to the given number using the
 * appropriate rule
 */
int RenderTarget::nearestPower2( int value, TextureScale scaleRule ) {

    int x = value;
    int power = 0;

    while ( ( x & 0x01 ) != 1 ) {
        x >>= 1;
      }

    if ( x == 1 ) {
        return value;
      } else {
        x = value;
        while ( x != 0 ) {
            x >>= 1;
            power++;
          }
        switch ( scaleRule ) {
            case SCALE_NEAREST:
                if ( ( ( 1 << power ) - value ) <= ( value - ( 1 << ( power - 1 ) ) ) ) {
                    return 1 << power;
                  } else {
                    return 1 << ( power - 1 );
                  }
            case SCALE_MAGNIFY:
                return 1 << power;
            case SCALE_MINIFY:
                return 1 << ( power - 1 );
            default:
                break;
          }
      }
    return 0;
  }
<commit_msg>Unbind FBO when done<commit_after>/**
 * projectM -- Milkdrop-esque visualisation SDK
 * Copyright (C)2003-2004 projectM Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * See 'LICENSE.txt' included within this release
 *
 */
/**
 * $Id: FBO.c,v 1.1.1.1 2005/12/23 18:05:00 psperl Exp $
 *
 * Render this methods
 */

#include <stdio.h>
//#include <GL/gl.h>
#include <iostream>
#include "Common.hpp"
#include "FBO.hpp"

RenderTarget::~RenderTarget() {

	glDeleteTextures( 1, &this->textureID[0]);

#ifdef USE_FBO
	if (useFBO)
         {
		glDeleteTextures( 1, &this->textureID[1] );
		glDeleteRenderbuffersEXT(1,  &this->depthb[0]);
		glDeleteFramebuffersEXT(1, &this->fbuffer[0]);
		if(renderToTexture)
		  {
		    glDeleteTextures( 1, &this->textureID[2] );
		    glDeleteRenderbuffersEXT(1,  &this->depthb[1]);
		    glDeleteFramebuffersEXT(1, &this->fbuffer[1]);
		  }
         }
#endif

}

GLuint RenderTarget::initRenderToTexture()
{
#ifdef USE_FBO

  if (this->useFBO==1)
    {
      this->renderToTexture=1;

      GLuint   fb2, depth_rb2;
      glGenFramebuffersEXT(1, &fb2);
      glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb2 );
      glGenRenderbuffersEXT(1, &depth_rb2);
      glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, depth_rb2 );

      glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize  );
      glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb2 );
      this->fbuffer[1] = fb2;
      this->depthb[1]=  depth_rb2;
      glGenTextures(1, &this->textureID[2]);
      glBindTexture(GL_TEXTURE_2D, this->textureID[2]);
      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
      glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
      glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, this->textureID[2], 0 );
      return this->textureID[2];
    }
#endif
return -1;

}

/** Creates new pbuffers */
RenderTarget::RenderTarget(int texsize, int width, int height) : useFBO(false) {

   int mindim = 0;
   int origtexsize = 0;

   this->renderToTexture = 0;
   this->texsize = texsize;

#ifdef USE_FBO
   glewInit();
      // Forceably disable FBO if user requested it but the video card / driver lacks
      // the appropraite frame buffer extension.
      if (useFBO = glewIsSupported("GL_EXT_framebuffer_object"))
	{

	  GLuint   fb,  depth_rb, rgba_tex,  other_tex;
	  glGenFramebuffersEXT(1, &fb);
	  glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb );

	  glGenRenderbuffersEXT(1, &depth_rb);
	  glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, depth_rb );
	  glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, this->texsize,this->texsize  );
	  glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb );
	  this->fbuffer[0] = fb;
	  this->depthb[0]=  depth_rb;

	  glGenTextures(1, &other_tex);
	  glBindTexture(GL_TEXTURE_2D,other_tex);
	  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
	  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	  //glGenerateMipmapEXT(GL_TEXTURE_2D);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	  glGenTextures(1, &rgba_tex);
	  glBindTexture(GL_TEXTURE_2D, rgba_tex);
	  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	  glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, texsize, texsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	  //glGenerateMipmapEXT(GL_TEXTURE_2D);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

	  glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, rgba_tex, 0 );
	  this->textureID[0] = rgba_tex;
	  this->textureID[1] = other_tex;

	  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);

	  glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0);

	  if (status == GL_FRAMEBUFFER_COMPLETE_EXT) {
	    return;
	  }
	  std::cerr << "[projecM] warning: FBO support not detected. Using fallback." << std::endl;
	}

#endif

// Can reach here via two code paths:
// (1) useFBO was set to false externally by cmake / system setting / etc.
// (2) useFBO was true but forced to false as it failed to pass all the GLU extension checks.

    /** Fallback pbuffer creation via teximage hack */
    /** Check the texture size against the viewport size */
    /** If the viewport is smaller, then we'll need to scale the texture size down */
    /** If the viewport is larger, scale it up */
    mindim = width < height ? width : height;
    origtexsize = this->texsize;
    this->texsize = nearestPower2( mindim, SCALE_MINIFY );
        glGenTextures(1, &this->textureID[0] );

        glBindTexture(GL_TEXTURE_2D, this->textureID[0] );
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glTexImage2D(GL_TEXTURE_2D,
		    0,
		    GL_RGB,
		    this->texsize, this->texsize,
		    0,
		    GL_RGBA,
		    GL_UNSIGNED_BYTE,
		    NULL);

    return;
  }

  void RenderTarget::fallbackRescale(int width, int height)
  {
	int mindim = width < height ? width : height;
    int origtexsize = this->texsize;
    this->texsize = nearestPower2( mindim, SCALE_MINIFY );

    /* Create the texture that will be bound to the render this */
    /*

        if ( this->texsize != origtexsize ) {

            glDeleteTextures( 1, &this->textureID[0] );
          }
    */

        glGenTextures(1, &this->textureID[0] );

        glBindTexture(GL_TEXTURE_2D, this->textureID[0] );
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        glTexImage2D(GL_TEXTURE_2D,
		    0,
		    GL_RGB,
		    this->texsize, this->texsize,
		    0,
		    GL_RGBA,
		    GL_UNSIGNED_BYTE,
		    NULL);

  }

/** Destroys the pbuffer */

/** Locks the pbuffer */
void RenderTarget::lock() {

#ifdef USE_FBO
  if(this->useFBO)
    {
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, this->fbuffer[0]);
    }
#endif
    }

/** Unlocks the pbuffer */
void RenderTarget::unlock() {

#ifdef USE_FBO
  if(this->useFBO)
    {
      glBindTexture( GL_TEXTURE_2D, this->textureID[1] );
      glCopyTexSubImage2D( GL_TEXTURE_2D,
                         0, 0, 0, 0, 0,
                         this->texsize, this->texsize );
      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
      return;
    }
#endif
    /** Fallback texture path */

    glBindTexture( GL_TEXTURE_2D, this->textureID[0] );

	glCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, 0, 0, this->texsize, this->texsize );
  }

/**
 * Calculates the nearest power of two to the given number using the
 * appropriate rule
 */
int RenderTarget::nearestPower2( int value, TextureScale scaleRule ) {

    int x = value;
    int power = 0;

    while ( ( x & 0x01 ) != 1 ) {
        x >>= 1;
      }

    if ( x == 1 ) {
        return value;
      } else {
        x = value;
        while ( x != 0 ) {
            x >>= 1;
            power++;
          }
        switch ( scaleRule ) {
            case SCALE_NEAREST:
                if ( ( ( 1 << power ) - value ) <= ( value - ( 1 << ( power - 1 ) ) ) ) {
                    return 1 << power;
                  } else {
                    return 1 << ( power - 1 );
                  }
            case SCALE_MAGNIFY:
                return 1 << power;
            case SCALE_MINIFY:
                return 1 << ( power - 1 );
            default:
                break;
          }
      }
    return 0;
  }
<|endoftext|>


<commit_before>//
//  Copyright Silvin Lubecki 2010
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef OPENCLAM_ERROR_HPP_INCLUDED
#define OPENCLAM_ERROR_HPP_INCLUDED

#include <boost/lexical_cast.hpp>

#define ERROR_HANDLER( CODE )   \
    cl_int error;               \
    CODE                        \
    if( error != CL_SUCCESS )   \
        throw std::runtime_error( "Openclam error '" + boost::lexical_cast< std::string >( error ) + "' at : '" + #CODE );

#endif // #ifndef OPENCLAM_ERROR_HPP_INCLUDED<commit_msg>warning fixed<commit_after>//
//  Copyright Silvin Lubecki 2010
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//

#ifndef OPENCLAM_ERROR_HPP_INCLUDED
#define OPENCLAM_ERROR_HPP_INCLUDED

#pragma warning( push )
#pragma warning( disable: 4702 )
#include <boost/lexical_cast.hpp>
#pragma warning( pop )

#define ERROR_HANDLER( CODE )   \
    cl_int error;               \
    CODE                        \
    if( error != CL_SUCCESS )   \
        throw std::runtime_error( "Openclam error '" + boost::lexical_cast< std::string >( error ) + "' at : '" + #CODE );

#endif // #ifndef OPENCLAM_ERROR_HPP_INCLUDED<|endoftext|>


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

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

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

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

#include "paddle/fluid/operators/assign_op.h"

#include <string>

namespace paddle {
namespace framework {
class OpDesc;
class Variable;
}  // namespace framework
namespace imperative {
class OpBase;
}  // namespace imperative
namespace platform {
struct CPUPlace;
struct CUDAPlace;
struct float16;
}  // namespace platform
}  // namespace paddle

namespace paddle {
namespace operators {

class AssignOp : public framework::OperatorWithKernel {
 public:
  AssignOp(const std::string &type, const framework::VariableNameMap &inputs,
           const framework::VariableNameMap &outputs,
           const framework::AttributeMap &attrs)
      : OperatorWithKernel(type, inputs, outputs, attrs) {}

  void InferShape(framework::InferShapeContext *ctx) const override {
    if (ctx->HasInput("X")) {
      auto type = ctx->GetInputsVarType("X")[0];
      if (type == framework::proto::VarType::SELECTED_ROWS ||
          type == framework::proto::VarType::LOD_TENSOR) {
        ctx->SetOutputDim("Out", ctx->GetInputDim("X"));
        if (type == framework::proto::VarType::LOD_TENSOR) {
          ctx->ShareLoD("X", /*->*/ "Out");
        }
      } else if (type == framework::proto::VarType::LOD_TENSOR_ARRAY) {
        if (ctx->IsRuntime()) {
          // The runtime output shape is determined in kernel.
          return;
        } else {
          ctx->SetOutputDim("Out", ctx->GetInputDim("X"));
        }
      }
    }
  }

 protected:
  framework::OpKernelType GetKernelTypeForVar(
      const std::string &var_name, const framework::Tensor &tensor,
      const framework::OpKernelType &expected_kernel_type) const override {
    return framework::OpKernelType(expected_kernel_type.data_type_,
                                   expected_kernel_type.place_,
                                   tensor.layout());
  }

  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext &ctx) const override {
    const framework::Variable *var = ctx.InputVar("X");
    if (var->IsType<framework::LoDTensorArray>()) {
      auto t_arr = var->Get<framework::LoDTensorArray>();
      // NOTE(liym27): Support an empty tensor array as Input.
      // And set the kernel type is float.
      if (t_arr.size() == 0) {
        return framework::OpKernelType(framework::proto::VarType::FP32,
                                       ctx.device_context());
      }
    }

    return framework::OpKernelType(
        OperatorWithKernel::IndicateVarDataType(ctx, "X"),
        ctx.device_context());
  }
};

class AssignInferVarType : public framework::VarTypeInference {
 public:
  void operator()(framework::InferVarTypeContext *ctx) const override {
    ctx->SyncTypeAndDataType("X", "Out");
  }
};

class AssignKernel {
 public:
  void operator()(const framework::ExecutionContext &ctx) const {
    auto *x = ctx.InputVar("X");
    if (x == nullptr) {
      return;
    }
    PADDLE_ENFORCE_EQ(
        ctx.HasOutput("Out"), true,
        platform::errors::NotFound("Output(Out) of assign_op is not found."));
    auto *out = ctx.OutputVar("Out");
    platform::DeviceContextPool &pool = platform::DeviceContextPool::Instance();
    auto &dev_ctx = *pool.Get(ctx.GetPlace());

    framework::VisitVarType(*x, AssignFunctor(out, dev_ctx));
  }
};

class AssignOpProtoMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X",
             "(LoDTensor, SelectedRows or LoDTensorArray) The input variable "
             "could be LoDTensor, SelectedRows or LoDTensorArray.")
        .AsDispensable();
    AddOutput("Out",
              "(LoDTensor, SelectedRows or LoDTensorArray) The type of output "
              "is the same as input X.");
    AddComment(R"DOC(Assign Operator

Out = X,  when type in [LoDTensor/SelectedRows/LoDTensorArray]
raise error if the type is not listed above.
)DOC");
  }
};

template <typename T>
class AssignGradMaker : public framework::SingleGradOpMaker<T> {
 public:
  using framework::SingleGradOpMaker<T>::SingleGradOpMaker;

 protected:
  void Apply(GradOpPtr<T> op) const override {
    op->SetType("assign");
    op->SetInput("X", this->OutputGrad("Out"));
    op->SetOutput("Out", this->InputGrad("X"));
  }
};

DECLARE_INPLACE_OP_INFERER(AssignOpInplaceInferer, {"X", "Out"});

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
namespace plat = paddle::platform;
REGISTER_OPERATOR(assign, ops::AssignOp,
                  ops::AssignGradMaker<paddle::framework::OpDesc>,
                  ops::AssignGradMaker<paddle::imperative::OpBase>,
                  ops::AssignOpProtoMaker, ops::AssignOpInplaceInferer,
                  ops::AssignInferVarType);

REGISTER_OP_CPU_KERNEL_FUNCTOR(assign, float, ops::AssignKernel, double,
                               ops::AssignKernel, int, ops::AssignKernel,
                               int64_t, ops::AssignKernel, bool,
                               ops::AssignKernel, plat::float16,
                               ops::AssignKernel, plat::bfloat16,
                               ops::AssignKernel);

#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
REGISTER_OP_CUDA_KERNEL_FUNCTOR(assign, float, ops::AssignKernel, double,
                                ops::AssignKernel, int, ops::AssignKernel,
                                int64_t, ops::AssignKernel, bool,
                                ops::AssignKernel, plat::float16,
                                ops::AssignKernel);
#endif
<commit_msg>fix assign bug support fp16 uint8 (#35153)<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.

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

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

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

#include "paddle/fluid/operators/assign_op.h"

#include <string>

namespace paddle {
namespace framework {
class OpDesc;
class Variable;
}  // namespace framework
namespace imperative {
class OpBase;
}  // namespace imperative
namespace platform {
struct CPUPlace;
struct CUDAPlace;
struct float16;
}  // namespace platform
}  // namespace paddle

namespace paddle {
namespace operators {

class AssignOp : public framework::OperatorWithKernel {
 public:
  AssignOp(const std::string &type, const framework::VariableNameMap &inputs,
           const framework::VariableNameMap &outputs,
           const framework::AttributeMap &attrs)
      : OperatorWithKernel(type, inputs, outputs, attrs) {}

  void InferShape(framework::InferShapeContext *ctx) const override {
    if (ctx->HasInput("X")) {
      auto type = ctx->GetInputsVarType("X")[0];
      if (type == framework::proto::VarType::SELECTED_ROWS ||
          type == framework::proto::VarType::LOD_TENSOR) {
        ctx->SetOutputDim("Out", ctx->GetInputDim("X"));
        if (type == framework::proto::VarType::LOD_TENSOR) {
          ctx->ShareLoD("X", /*->*/ "Out");
        }
      } else if (type == framework::proto::VarType::LOD_TENSOR_ARRAY) {
        if (ctx->IsRuntime()) {
          // The runtime output shape is determined in kernel.
          return;
        } else {
          ctx->SetOutputDim("Out", ctx->GetInputDim("X"));
        }
      }
    }
  }

 protected:
  framework::OpKernelType GetKernelTypeForVar(
      const std::string &var_name, const framework::Tensor &tensor,
      const framework::OpKernelType &expected_kernel_type) const override {
    return framework::OpKernelType(expected_kernel_type.data_type_,
                                   expected_kernel_type.place_,
                                   tensor.layout());
  }

  framework::OpKernelType GetExpectedKernelType(
      const framework::ExecutionContext &ctx) const override {
    const framework::Variable *var = ctx.InputVar("X");
    if (var->IsType<framework::LoDTensorArray>()) {
      auto t_arr = var->Get<framework::LoDTensorArray>();
      // NOTE(liym27): Support an empty tensor array as Input.
      // And set the kernel type is float.
      if (t_arr.size() == 0) {
        return framework::OpKernelType(framework::proto::VarType::FP32,
                                       ctx.device_context());
      }
    }

    return framework::OpKernelType(
        OperatorWithKernel::IndicateVarDataType(ctx, "X"),
        ctx.device_context());
  }
};

class AssignInferVarType : public framework::VarTypeInference {
 public:
  void operator()(framework::InferVarTypeContext *ctx) const override {
    ctx->SyncTypeAndDataType("X", "Out");
  }
};

class AssignKernel {
 public:
  void operator()(const framework::ExecutionContext &ctx) const {
    auto *x = ctx.InputVar("X");
    if (x == nullptr) {
      return;
    }
    PADDLE_ENFORCE_EQ(
        ctx.HasOutput("Out"), true,
        platform::errors::NotFound("Output(Out) of assign_op is not found."));
    auto *out = ctx.OutputVar("Out");
    platform::DeviceContextPool &pool = platform::DeviceContextPool::Instance();
    auto &dev_ctx = *pool.Get(ctx.GetPlace());

    framework::VisitVarType(*x, AssignFunctor(out, dev_ctx));
  }
};

class AssignOpProtoMaker : public framework::OpProtoAndCheckerMaker {
 public:
  void Make() override {
    AddInput("X",
             "(LoDTensor, SelectedRows or LoDTensorArray) The input variable "
             "could be LoDTensor, SelectedRows or LoDTensorArray.")
        .AsDispensable();
    AddOutput("Out",
              "(LoDTensor, SelectedRows or LoDTensorArray) The type of output "
              "is the same as input X.");
    AddComment(R"DOC(Assign Operator

Out = X,  when type in [LoDTensor/SelectedRows/LoDTensorArray]
raise error if the type is not listed above.
)DOC");
  }
};

template <typename T>
class AssignGradMaker : public framework::SingleGradOpMaker<T> {
 public:
  using framework::SingleGradOpMaker<T>::SingleGradOpMaker;

 protected:
  void Apply(GradOpPtr<T> op) const override {
    op->SetType("assign");
    op->SetInput("X", this->OutputGrad("Out"));
    op->SetOutput("Out", this->InputGrad("X"));
  }
};

DECLARE_INPLACE_OP_INFERER(AssignOpInplaceInferer, {"X", "Out"});

}  // namespace operators
}  // namespace paddle

namespace ops = paddle::operators;
namespace plat = paddle::platform;
REGISTER_OPERATOR(assign, ops::AssignOp,
                  ops::AssignGradMaker<paddle::framework::OpDesc>,
                  ops::AssignGradMaker<paddle::imperative::OpBase>,
                  ops::AssignOpProtoMaker, ops::AssignOpInplaceInferer,
                  ops::AssignInferVarType);

REGISTER_OP_CPU_KERNEL_FUNCTOR(assign, float, ops::AssignKernel, double,
                               ops::AssignKernel, int, ops::AssignKernel,
                               int64_t, ops::AssignKernel, uint8_t,
                               ops::AssignKernel, bool, ops::AssignKernel,
                               plat::float16, ops::AssignKernel, plat::bfloat16,
                               ops::AssignKernel);

#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
REGISTER_OP_CUDA_KERNEL_FUNCTOR(assign, float, ops::AssignKernel, double,
                                ops::AssignKernel, int, ops::AssignKernel,
                                int64_t, ops::AssignKernel, uint8_t,
                                ops::AssignKernel, bool, ops::AssignKernel,
                                plat::float16, ops::AssignKernel);
#endif
<|endoftext|>


<commit_before>#include "HttpClient.hpp"
#include "EventLoop.hpp"
#include "OutputStream.hpp"
#include "ClientSocket.hpp"
#include "HttpResponseStream.hpp"
#include "Exception.hpp"
#include <cstdlib>
#include <sstream>

// простой URL-парсер, выделяющий хост, порт и путь
static void parseUrl(const String& url, String& host, int& port, String& path)
{
	try
	{
		// проверить, что URL начинается с http://
		static const char* protocol = "http://";
		static const size_t protocolLength = 7;
		if(url.length() < protocolLength || url.compare(0, protocolLength, protocol) != 0)
			THROW_PRIMARY_EXCEPTION("http:// not found");

		// найти слеш, отделяющий хост и порт от пути
		size_t pathSlashPos = url.find('/', protocolLength);
		if(pathSlashPos == url.npos)
			THROW_PRIMARY_EXCEPTION("Path begin slash not found");
		path = url.substr(pathSlashPos);

		// найти двоеточие, обозначающее порт
		size_t portColonPos = url.find(':', protocolLength);
		if(portColonPos == url.npos || portColonPos >= pathSlashPos)
		{
			// если порт не указан
			host = url.substr(protocolLength, pathSlashPos - protocolLength);
			port = 80;
		}
		else
		{
			// если порт указан
			host = url.substr(protocolLength, portColonPos - protocolLength);
			port = atoi(url.substr(portColonPos + 1, pathSlashPos - portColonPos - 1).c_str());
		}
	}
	catch(Exception* exception)
	{
		THROW_SECONDARY_EXCEPTION("URL must be of form http://<host>[:<port>]/[query]", exception);
	}
}

HttpClient::ConnectHandler::ConnectHandler(const String& host, int port, const String& path, ptr<OutputStream> outputStream) :
	outputStream(outputStream)
{
	std::ostringstream request;
	request << "GET " << path << " HTTP/1.1\r\n";
	request << "Connection: close\r\n";
	request << "Host: " << host;
	if(port != 80)
		request << ":" << port;
	request << "\r\n";
	request << "User-Agent: Inanity/1.0\r\n";
	request << "\r\n";
	this->request = request.str();
}

void HttpClient::ConnectHandler::OnEvent(ptr<ClientSocket> socket)
{
	if(!socket)
	{
		outputStream->Flush();
		return;
	}

	// указать, куда записывать ответ
	socket->SetStreamToWriteInput(NEW(HttpResponseStream(outputStream)));
	// отправить HTTP-запрос
	socket->GetOutputStream()->Write(request.c_str(), request.length());
}

void HttpClient::Fetch(ptr<EventLoop> eventLoop, const String& url, ptr<OutputStream> outputStream)
{
	try
	{
		String host, path;
		int port;
		parseUrl(url, host, port, path);
		eventLoop->Connect(host, port, NEW(ConnectHandler(host, port, path, outputStream)));
	}
	catch(Exception* exception)
	{
		THROW_SECONDARY_EXCEPTION("Can't fetch http", exception);
	}
}
<commit_msg>string fix<commit_after>#include "HttpClient.hpp"
#include "EventLoop.hpp"
#include "OutputStream.hpp"
#include "ClientSocket.hpp"
#include "HttpResponseStream.hpp"
#include "Exception.hpp"
#include <cstdlib>
#include <sstream>

// простой URL-парсер, выделяющий хост, порт и путь
static void parseUrl(const String& url, String& host, int& port, String& path)
{
	try
	{
		// проверить, что URL начинается с http://
		static const char* protocol = "http://";
		static const size_t protocolLength = 7;
		if(url.length() < protocolLength || url.compare(0, protocolLength, protocol) != 0)
			THROW_PRIMARY_EXCEPTION("http:// not found");

		// найти слеш, отделяющий хост и порт от пути
		size_t pathSlashPos = url.find('/', protocolLength);
		if(pathSlashPos == url.npos)
			THROW_PRIMARY_EXCEPTION("Path begin slash not found");
		path = url.substr(pathSlashPos);

		// найти двоеточие, обозначающее порт
		size_t portColonPos = url.find(':', protocolLength);
		if(portColonPos == url.npos || portColonPos >= pathSlashPos)
		{
			// если порт не указан
			host = url.substr(protocolLength, pathSlashPos - protocolLength);
			port = 80;
		}
		else
		{
			// если порт указан
			host = url.substr(protocolLength, portColonPos - protocolLength);
			port = atoi(url.substr(portColonPos + 1, pathSlashPos - portColonPos - 1).c_str());
		}
	}
	catch(Exception* exception)
	{
		THROW_SECONDARY_EXCEPTION("URL must be of form http://<host>[:<port>]/[<query>]", exception);
	}
}

HttpClient::ConnectHandler::ConnectHandler(const String& host, int port, const String& path, ptr<OutputStream> outputStream) :
	outputStream(outputStream)
{
	std::ostringstream request;
	request << "GET " << path << " HTTP/1.1\r\n";
	request << "Connection: close\r\n";
	request << "Host: " << host;
	if(port != 80)
		request << ":" << port;
	request << "\r\n";
	request << "User-Agent: Inanity/1.0\r\n";
	request << "\r\n";
	this->request = request.str();
}

void HttpClient::ConnectHandler::OnEvent(ptr<ClientSocket> socket)
{
	if(!socket)
	{
		outputStream->Flush();
		return;
	}

	// указать, куда записывать ответ
	socket->SetStreamToWriteInput(NEW(HttpResponseStream(outputStream)));
	// отправить HTTP-запрос
	socket->GetOutputStream()->Write(request.c_str(), request.length());
}

void HttpClient::Fetch(ptr<EventLoop> eventLoop, const String& url, ptr<OutputStream> outputStream)
{
	try
	{
		String host, path;
		int port;
		parseUrl(url, host, port, path);
		eventLoop->Connect(host, port, NEW(ConnectHandler(host, port, path, outputStream)));
	}
	catch(Exception* exception)
	{
		THROW_SECONDARY_EXCEPTION("Can't fetch http", exception);
	}
}
<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "qmljsidcollector.h"
#include "qmljsdocument.h"
#include <qmljs/parser/qmljsast_p.h>
#include <qmljs/parser/qmljslexer_p.h>
#include <qmljs/parser/qmljsparser_p.h>
#include <qmljs/parser/qmljsnodepool_p.h>
#include <qmljs/parser/qmljsastfwd_p.h>
#include <QtCore/QDir>

using namespace QmlJS;
using namespace QmlJS;
using namespace QmlJS::AST;

Document::Document(const QString &fileName)
    : _engine(0)
    , _pool(0)
    , _ast(0)
    , _documentRevision(0)
    , _parsedCorrectly(false)
    , _fileName(fileName)
{
    QFileInfo fileInfo(fileName);
    _path = fileInfo.absolutePath();
    _componentName = fileInfo.baseName();
    if (! _componentName.isEmpty()) {
        // ### TODO: check the component name.
        if (! _componentName.at(0).isUpper())
            _componentName.clear();
    }
}

Document::~Document()
{
    if (_engine)
        delete _engine;

    if (_pool)
        delete _pool;

    qDeleteAll(_symbols);
}

Document::Ptr Document::create(const QString &fileName)
{
    Document::Ptr doc(new Document(fileName));
    return doc;
}

AST::UiProgram *Document::qmlProgram() const
{
    return cast<UiProgram *>(_ast);
}

AST::Program *Document::jsProgram() const
{
    return cast<Program *>(_ast);
}

AST::ExpressionNode *Document::expression() const
{
    if (_ast)
        return _ast->expressionCast();

    return 0;
}

AST::Node *Document::ast() const
{
    return _ast;
}

QList<DiagnosticMessage> Document::diagnosticMessages() const
{
    return _diagnosticMessages;
}

QString Document::source() const
{
    return _source;
}

void Document::setSource(const QString &source)
{
    _source = source;
}

int Document::documentRevision() const
{
    return _documentRevision;
}

void Document::setDocumentRevision(int revision)
{
    _documentRevision = revision;
}

bool Document::parseQml()
{
    Q_ASSERT(! _engine);
    Q_ASSERT(! _pool);
    Q_ASSERT(! _ast);

    _engine = new Engine();
    _pool = new NodePool(_fileName, _engine);
    _ids.clear();

    Lexer lexer(_engine);
    Parser parser(_engine);

    lexer.setCode(_source, /*line = */ 1);

    _parsedCorrectly = parser.parse();
    _ast = parser.ast();
    _diagnosticMessages = parser.diagnosticMessages();

    if (qmlProgram()) {
        for (QmlJS::AST::UiObjectMemberList *iter = qmlProgram()->members; iter; iter = iter->next)
            if (iter->member)
                _symbols.append(new SymbolFromFile(_fileName, iter->member));

         Internal::IdCollector collect;
        _ids = collect(*this);
        if (_diagnosticMessages.isEmpty())
            _diagnosticMessages = collect.diagnosticMessages();
    }

    return _parsedCorrectly;
}

bool Document::parseJavaScript()
{
    Q_ASSERT(! _engine);
    Q_ASSERT(! _pool);
    Q_ASSERT(! _ast);

    _engine = new Engine();
    _pool = new NodePool(_fileName, _engine);
    _ids.clear();

    Lexer lexer(_engine);
    Parser parser(_engine);

    lexer.setCode(_source, /*line = */ 1);

    _parsedCorrectly = parser.parseProgram();
    _ast = cast<Program*>(parser.rootNode());
    _diagnosticMessages = parser.diagnosticMessages();

    return _parsedCorrectly;
}

bool Document::parseExpression()
{
    Q_ASSERT(! _engine);
    Q_ASSERT(! _pool);
    Q_ASSERT(! _ast);

    _engine = new Engine();
    _pool = new NodePool(_fileName, _engine);
    _ids.clear();

    Lexer lexer(_engine);
    Parser parser(_engine);

    lexer.setCode(_source, /*line = */ 1);

    _parsedCorrectly = parser.parseExpression();
    _ast = parser.rootNode();
    if (_ast)
        _ast = _ast->expressionCast();
    _diagnosticMessages = parser.diagnosticMessages();

    return _parsedCorrectly;
}

SymbolFromFile *Document::findSymbol(QmlJS::AST::Node *node) const
{
    foreach (Symbol *symbol, _symbols)
        if (symbol->isSymbolFromFile())
            if (symbol->asSymbolFromFile()->node() == node)
                return symbol->asSymbolFromFile();

    return 0;
}

Snapshot::Snapshot()
{
}

Snapshot::~Snapshot()
{
}

void Snapshot::insert(const Document::Ptr &document)
{
    if (document && (document->qmlProgram() || document->jsProgram()))
        _documents.insert(document->fileName(), document);
}

Document::PtrList Snapshot::importedDocuments(const Document::Ptr &doc, const QString &importPath) const
{
    // ### TODO: maybe we should add all imported documents in the parse Document::parse() method, regardless of whether they're in the path or not.

    Document::PtrList result;

    QString docPath = doc->path();
    docPath += QLatin1Char('/');
    docPath += importPath;
    docPath = QDir::cleanPath(docPath);

    foreach (Document::Ptr candidate, _documents) {
        if (candidate == doc)
            continue; // ignore this document
        else if (! candidate->qmlProgram())
            continue; // skip JS documents

        if (candidate->path() == doc->path() || candidate->path() == docPath)
            result.append(candidate);
    }

    return result;
}

QMap<QString, Document::Ptr> Snapshot::componentsDefinedByImportedDocuments(const Document::Ptr &doc, const QString &importPath) const
{
    QMap<QString, Document::Ptr> result;

    const QString docPath = doc->path() + '/' + importPath;

    foreach (Document::Ptr candidate, *this) {
        if (candidate == doc)
            continue;

        if (candidate->path() == doc->path() || candidate->path() == docPath)
            result.insert(candidate->componentName(), candidate);
    }

    return result;
}
<commit_msg>Check the file extension before computing the component's name.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "qmljsidcollector.h"
#include "qmljsdocument.h"
#include <qmljs/parser/qmljsast_p.h>
#include <qmljs/parser/qmljslexer_p.h>
#include <qmljs/parser/qmljsparser_p.h>
#include <qmljs/parser/qmljsnodepool_p.h>
#include <qmljs/parser/qmljsastfwd_p.h>
#include <QtCore/QDir>

using namespace QmlJS;
using namespace QmlJS;
using namespace QmlJS::AST;

Document::Document(const QString &fileName)
    : _engine(0)
    , _pool(0)
    , _ast(0)
    , _documentRevision(0)
    , _parsedCorrectly(false)
    , _fileName(fileName)
{
    QFileInfo fileInfo(fileName);
    _path = fileInfo.absolutePath();

    if (fileInfo.suffix() == QLatin1String("qml")) {
        _componentName = fileInfo.baseName();

        if (! _componentName.isEmpty()) {
            // ### TODO: check the component name.

            if (! _componentName.at(0).isUpper())
                _componentName.clear();
        }
    }
}

Document::~Document()
{
    if (_engine)
        delete _engine;

    if (_pool)
        delete _pool;

    qDeleteAll(_symbols);
}

Document::Ptr Document::create(const QString &fileName)
{
    Document::Ptr doc(new Document(fileName));
    return doc;
}

AST::UiProgram *Document::qmlProgram() const
{
    return cast<UiProgram *>(_ast);
}

AST::Program *Document::jsProgram() const
{
    return cast<Program *>(_ast);
}

AST::ExpressionNode *Document::expression() const
{
    if (_ast)
        return _ast->expressionCast();

    return 0;
}

AST::Node *Document::ast() const
{
    return _ast;
}

QList<DiagnosticMessage> Document::diagnosticMessages() const
{
    return _diagnosticMessages;
}

QString Document::source() const
{
    return _source;
}

void Document::setSource(const QString &source)
{
    _source = source;
}

int Document::documentRevision() const
{
    return _documentRevision;
}

void Document::setDocumentRevision(int revision)
{
    _documentRevision = revision;
}

bool Document::parseQml()
{
    Q_ASSERT(! _engine);
    Q_ASSERT(! _pool);
    Q_ASSERT(! _ast);

    _engine = new Engine();
    _pool = new NodePool(_fileName, _engine);
    _ids.clear();

    Lexer lexer(_engine);
    Parser parser(_engine);

    lexer.setCode(_source, /*line = */ 1);

    _parsedCorrectly = parser.parse();
    _ast = parser.ast();
    _diagnosticMessages = parser.diagnosticMessages();

    if (qmlProgram()) {
        for (QmlJS::AST::UiObjectMemberList *iter = qmlProgram()->members; iter; iter = iter->next)
            if (iter->member)
                _symbols.append(new SymbolFromFile(_fileName, iter->member));

         Internal::IdCollector collect;
        _ids = collect(*this);
        if (_diagnosticMessages.isEmpty())
            _diagnosticMessages = collect.diagnosticMessages();
    }

    return _parsedCorrectly;
}

bool Document::parseJavaScript()
{
    Q_ASSERT(! _engine);
    Q_ASSERT(! _pool);
    Q_ASSERT(! _ast);

    _engine = new Engine();
    _pool = new NodePool(_fileName, _engine);
    _ids.clear();

    Lexer lexer(_engine);
    Parser parser(_engine);

    lexer.setCode(_source, /*line = */ 1);

    _parsedCorrectly = parser.parseProgram();
    _ast = cast<Program*>(parser.rootNode());
    _diagnosticMessages = parser.diagnosticMessages();

    return _parsedCorrectly;
}

bool Document::parseExpression()
{
    Q_ASSERT(! _engine);
    Q_ASSERT(! _pool);
    Q_ASSERT(! _ast);

    _engine = new Engine();
    _pool = new NodePool(_fileName, _engine);
    _ids.clear();

    Lexer lexer(_engine);
    Parser parser(_engine);

    lexer.setCode(_source, /*line = */ 1);

    _parsedCorrectly = parser.parseExpression();
    _ast = parser.rootNode();
    if (_ast)
        _ast = _ast->expressionCast();
    _diagnosticMessages = parser.diagnosticMessages();

    return _parsedCorrectly;
}

SymbolFromFile *Document::findSymbol(QmlJS::AST::Node *node) const
{
    foreach (Symbol *symbol, _symbols)
        if (symbol->isSymbolFromFile())
            if (symbol->asSymbolFromFile()->node() == node)
                return symbol->asSymbolFromFile();

    return 0;
}

Snapshot::Snapshot()
{
}

Snapshot::~Snapshot()
{
}

void Snapshot::insert(const Document::Ptr &document)
{
    if (document && (document->qmlProgram() || document->jsProgram()))
        _documents.insert(document->fileName(), document);
}

Document::PtrList Snapshot::importedDocuments(const Document::Ptr &doc, const QString &importPath) const
{
    // ### TODO: maybe we should add all imported documents in the parse Document::parse() method, regardless of whether they're in the path or not.

    Document::PtrList result;

    QString docPath = doc->path();
    docPath += QLatin1Char('/');
    docPath += importPath;
    docPath = QDir::cleanPath(docPath);

    foreach (Document::Ptr candidate, _documents) {
        if (candidate == doc)
            continue; // ignore this document
        else if (! candidate->qmlProgram())
            continue; // skip JS documents

        if (candidate->path() == doc->path() || candidate->path() == docPath)
            result.append(candidate);
    }

    return result;
}

QMap<QString, Document::Ptr> Snapshot::componentsDefinedByImportedDocuments(const Document::Ptr &doc, const QString &importPath) const
{
    QMap<QString, Document::Ptr> result;

    const QString docPath = doc->path() + '/' + importPath;

    foreach (Document::Ptr candidate, *this) {
        if (candidate == doc)
            continue;

        if (candidate->path() == doc->path() || candidate->path() == docPath)
            result.insert(candidate->componentName(), candidate);
    }

    return result;
}
<|endoftext|>