<commit_before>// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: not %run %t 2>&1 | FileCheck %s

#include <stdio.h>

char bigchunk[1 << 30];

int main() {
  printf("Hello, world!\n");
  scanf("%s", bigchunk);
// CHECK-NOT: Hello, world!
// CHECK: Shadow memory range interleaves with an existing memory mapping.
// CHECK: ASan shadow was supposed to be located in the [0x2fff0000-0x{{.*}}ffff] range.
// CHECK: Dumping process modules:
// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}shadow_mapping_failure
// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}kernel32.dll
// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}ntdll.dll
}
<commit_msg>[asan] Remove CHECK line for kernel32.dll<commit_after>// RUN: %clang_cl_asan -O0 %s -Fe%t
// RUN: not %run %t 2>&1 | FileCheck %s

#include <stdio.h>

char bigchunk[1 << 30];

int main() {
  printf("Hello, world!\n");
  scanf("%s", bigchunk);
// CHECK-NOT: Hello, world!
// CHECK: Shadow memory range interleaves with an existing memory mapping.
// CHECK: ASan shadow was supposed to be located in the [0x2fff0000-0x{{.*}}ffff] range.
// CHECK: Dumping process modules:
// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}shadow_mapping_failure
// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}ntdll.dll
}
<|endoftext|>


<commit_before>#include <boost/shared_ptr.hpp>
#include <boost/concept_check.hpp>
#include <iostream>
#include <iomanip>

#include <TClass.h>
#include <TDataMember.h>
#include <TDataType.h>
#include <TFile.h>
#include <TKey.h>
#include <TMemberInspector.h>
#include <TStreamerElement.h>
#include <TVirtualStreamerInfo.h>
#include <TROOT.h>

using namespace ROOT;

class MyInspector: public TMemberInspector
{
private:
    unsigned tabs;
public:
    MyInspector(): tabs(0)
    {
    }

    void Inspect(TClass* klass, const char* parent, const char* name, const void* addr)
    {
        std::string indent(tabs, '\t');

        TDataType* memberType = NULL;
        TString memberTypeName;
        TString memberFullTypeName;
        TString memberName;
        TString memberValueAsStr;
        Bool_t  isPointer;

        if (TDataMember* member = klass->GetDataMember(name)) {
            memberTypeName     = member->GetTypeName();
            memberFullTypeName = member->GetFullTypeName();
            memberType         = member->GetDataType(); // Only for basic types
            memberName         = member->GetName();
            isPointer          = member->IsaPointer();
        }
        else if (!klass->IsLoaded()) {
            // The class hasn't been loaded
            TVirtualStreamerInfo* info = klass->GetStreamerInfo();
            if (!info) return;
            const char* cursor = name;
            while ((*cursor) == '*') ++cursor;
            TString elname(cursor);
            Ssiz_t pos = elname.Index("[");
            if (pos != kNPOS)
                elname.Remove(pos);
            TStreamerElement* element = static_cast<TStreamerElement*>(info->GetElements()->FindObject(elname.Data()));
            if (!element) return;
            memberFullTypeName = element->GetTypeName();
            memberType     = gROOT->GetType(memberTypeName);
            memberName = element->GetName();
            isPointer = element->IsaPointer() || element->GetType() == TVirtualStreamerInfo::kCharStar;

            memberTypeName = memberFullTypeName;
        }
        else {
            return;
        }

        TClass* dataClass = NULL;
        if (isPointer) {
            char buffer[32];
            snprintf(buffer, sizeof(buffer), "0x%lx", (off64_t)addr);
            memberValueAsStr = buffer;
        }
        else if(memberType) {
            memberValueAsStr = memberType->AsString((void*)addr);
        }
        else {
            char buffer[32];
            dataClass = TClass::GetClass(memberFullTypeName);

            if (dataClass == TString::Class()) {
                TString* str = (TString*)addr;
                memberValueAsStr = *str;
                dataClass = NULL;
            }
            else {
                snprintf(buffer, sizeof(buffer), "-> 0x%lx", (off64_t)addr);
                memberValueAsStr = buffer;
            }
        }

        std::cout << indent << std::setw(20) << memberFullTypeName << " "
                  << klass->GetName() << "::" << memberName << " = " << memberValueAsStr
                  << std::endl;
    }

    void Inspect(const TDirectory* dir)
    {
        std::string indent(tabs, '\t');

        Int_t nelements = dir->GetNkeys();
        std::cout << indent << nelements << " elements" << std::endl;

        TList* keys = dir->GetListOfKeys();
        for (Int_t i = 0; i < nelements; ++i) {
            TKey* key = static_cast<TKey*>(keys->At(i));
            std::cout << indent << key->GetName() << std::endl;
            ++tabs;
            key->ReadObj()->ShowMembers(*this);
            --tabs;
        }
    }

    void Inspect(const TCollection* collection)
    {
        std::string indent(tabs, '\t');

        std::cout << indent << "Collection!" << std::endl;
    }
};

int main(int argc, char** argv)
{
    if (argc < 2) {
        std::cerr << "Expecting a file name as a parameter" << std::endl;
        return -1;
    }

    boost::shared_ptr<TFile> f(new TFile(argv[1]));
    MyInspector inspector;

    // Call inspect on the file
    inspector.Inspect(f.get());

    return 0;
}
<commit_msg>Removed Inspect(CollectioN)<commit_after>#include <boost/shared_ptr.hpp>
#include <boost/concept_check.hpp>
#include <iostream>
#include <iomanip>

#include <TClass.h>
#include <TDataMember.h>
#include <TDataType.h>
#include <TFile.h>
#include <TKey.h>
#include <TMemberInspector.h>
#include <TStreamerElement.h>
#include <TVirtualStreamerInfo.h>
#include <TROOT.h>

using namespace ROOT;

class MyInspector: public TMemberInspector
{
private:
    unsigned tabs;
public:
    MyInspector(): tabs(0)
    {
    }

    void Inspect(TClass* klass, const char* parent, const char* name, const void* addr)
    {
        std::string indent(tabs, '\t');

        TDataType* memberType = NULL;
        TString memberTypeName;
        TString memberFullTypeName;
        TString memberName;
        TString memberValueAsStr;
        Bool_t  isPointer;

        if (TDataMember* member = klass->GetDataMember(name)) {
            memberTypeName     = member->GetTypeName();
            memberFullTypeName = member->GetFullTypeName();
            memberType         = member->GetDataType(); // Only for basic types
            memberName         = member->GetName();
            isPointer          = member->IsaPointer();
        }
        else if (!klass->IsLoaded()) {
            // The class hasn't been loaded
            TVirtualStreamerInfo* info = klass->GetStreamerInfo();
            if (!info) return;
            const char* cursor = name;
            while ((*cursor) == '*') ++cursor;
            TString elname(cursor);
            Ssiz_t pos = elname.Index("[");
            if (pos != kNPOS)
                elname.Remove(pos);
            TStreamerElement* element = static_cast<TStreamerElement*>(info->GetElements()->FindObject(elname.Data()));
            if (!element) return;
            memberFullTypeName = element->GetTypeName();
            memberType     = gROOT->GetType(memberTypeName);
            memberName = element->GetName();
            isPointer = element->IsaPointer() || element->GetType() == TVirtualStreamerInfo::kCharStar;

            memberTypeName = memberFullTypeName;
        }
        else {
            return;
        }

        TClass* dataClass = NULL;
        if (isPointer) {
            char buffer[32];
            snprintf(buffer, sizeof(buffer), "0x%lx", (off64_t)addr);
            memberValueAsStr = buffer;
        }
        else if(memberType) {
            memberValueAsStr = memberType->AsString((void*)addr);
        }
        else {
            char buffer[32];
            dataClass = TClass::GetClass(memberFullTypeName);

            if (dataClass == TString::Class()) {
                TString* str = (TString*)addr;
                memberValueAsStr = *str;
                dataClass = NULL;
            }
            else {
                snprintf(buffer, sizeof(buffer), "-> 0x%lx", (off64_t)addr);
                memberValueAsStr = buffer;
            }
        }

        std::cout << indent << std::setw(20) << memberFullTypeName << " "
                  << klass->GetName() << "::" << memberName << " = " << memberValueAsStr
                  << std::endl;
    }

    void Inspect(const TDirectory* dir)
    {
        std::string indent(tabs, '\t');

        Int_t nelements = dir->GetNkeys();
        std::cout << indent << nelements << " elements" << std::endl;

        TList* keys = dir->GetListOfKeys();
        for (Int_t i = 0; i < nelements; ++i) {
            TKey* key = static_cast<TKey*>(keys->At(i));
            std::cout << indent << key->GetName() << std::endl;
            ++tabs;
            key->ReadObj()->ShowMembers(*this);
            --tabs;
        }
    }
};

int main(int argc, char** argv)
{
    if (argc < 2) {
        std::cerr << "Expecting a file name as a parameter" << std::endl;
        return -1;
    }

    boost::shared_ptr<TFile> f(new TFile(argv[1]));
    MyInspector inspector;

    // Call inspect on the file
    inspector.Inspect(f.get());

    return 0;
}
<|endoftext|>


<commit_before>#include "ics3/ics3.hpp"

#include "core.hpp"
#include "ics3/angle.hpp"
#include "ics3/eeprom.hpp"
#include "ics3/parameter.hpp"
#include "ics3/id.hpp"

ics::ICS3::ICS3(const char* path, ICSBaudrate baudrate) throw(std::invalid_argument, std::runtime_error)
  : core(Core::getReference(path, static_cast<speed_t>(baudrate)))
{
}

ics::Angle ics::ICS3::move(const ID &id, Angle angle) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(3), rx(6);
  uint16_t send = angle.getRaw();
  tx[0] = 0x80 | id.get();
  tx[1] = 0x7F & (send >> 7);
  tx[2] = 0x7F & send;
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error e) {
    throw e;
  }
  uint16_t receive = (rx[4] << 7) | rx[5];
  try {
    angle.setRaw(receive);
  } catch (std::invalid_argument) {
    throw std::runtime_error("Receive angle error");
  }
  return angle;
}

ics::Parameter ics::ICS3::get(const ID &id, Parameter param) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(2), rx(5);
  tx[0] = 0xA0 | id.get();
  tx[1] = param.getSc();
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error e) {
    throw e;
  }
  param.set(rx[4]);
  return param;
}

void ics::ICS3::set(const ID &id, const Parameter &param) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(3), rx(6);
  tx[0] = 0xC0 | id.get();
  tx[1] = param.getSc();
  tx[2] = param.get();
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error e) {
    throw e;
  }
}

ics::Eeprom ics::ICS3::getRom(const ID &id) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(2), rx(68);
  tx[0] = 0xA0 | id.get();
  tx[1] = 0;
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error e) {
    throw e;
  }
  Eeprom rom;
  std::copy(rx.begin() + 2, rx.end(), rom.data.begin());
  return rom;
}

void ics::ICS3::setRom(const ID &id, const Eeprom &rom) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(66), rx(68);
  tx[0] = 0xC0 | id.get();
  tx[2] = 0;
  std::copy(rom.data.begin(), rom.data.end(), tx.begin() + 2);
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error e) {
    throw e;
  }
}
<commit_msg>Update ics3.cpp<commit_after>#include "ics3/ics3.hpp"

#include "core.hpp"
#include "ics3/angle.hpp"
#include "ics3/eeprom.hpp"
#include "ics3/parameter.hpp"
#include "ics3/id.hpp"

ics::ICS3::ICS3(const char* path, ICSBaudrate baudrate) throw(std::invalid_argument, std::runtime_error)
  : core(Core::getReference(path, static_cast<speed_t>(baudrate)))
{}

ics::Angle ics::ICS3::move(const ID& id, Angle angle) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(3), rx(6);
  uint16_t send = angle.getRaw();
  tx[0] = 0x80 | id.get();
  tx[1] = 0x7F & (send >> 7);
  tx[2] = 0x7F & send;
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error& e) {
    throw;
  }
  uint16_t receive = (rx[4] << 7) | rx[5];
  try {
    angle.setRaw(receive);
  } catch (std::invalid_argument& e) {
    throw std::runtime_error("Receive angle error");
  }
  return angle;
}

ics::Parameter ics::ICS3::get(const ID& id, Parameter param) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(2), rx(5);
  tx[0] = 0xA0 | id.get();
  tx[1] = param.getSc();
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error& e) {
    throw;
  }
  param.set(rx[4]);
  return param;
}

void ics::ICS3::set(const ID& id, const Parameter& param) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(3), rx(6);
  tx[0] = 0xC0 | id.get();
  tx[1] = param.getSc();
  tx[2] = param.get();
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error& e) {
    throw;
  }
}

ics::Eeprom ics::ICS3::getRom(const ID& id) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(2), rx(68);
  tx[0] = 0xA0 | id.get();
  tx[1] = 0;
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error& e) {
    throw;
  }
  Eeprom rom;
  std::copy(rx.begin() + 2, rx.end(), rom.data.begin());
  return rom;
}

void ics::ICS3::setRom(const ID& id, const Eeprom& rom) const throw(std::runtime_error) {
  static std::vector<unsigned char> tx(66), rx(68);
  tx[0] = 0xC0 | id.get();
  tx[2] = 0;
  std::copy(rom.data.begin(), rom.data.end(), tx.begin() + 2);
  try {
    core.communicate(tx, rx);
  } catch (std::runtime_error& e) {
    throw;
  }
}
<|endoftext|>


<commit_before>// Copyright 2019, Institute for Artificial Intelligence - University of Bremen
// Author: Andrei Haidu (http://haidu.eu)

#include "Events/SLSlicingEventHandler.h"
#include "SLEntitiesManager.h"
#include "Tags.h"
#if SL_WITH_SLICING
#include "SlicingBladeComponent.h"
#endif // SL_WITH_SLICING

// UUtils
#include "Ids.h"

// Set parent
void FSLSlicingEventHandler::Init(UObject* InParent)
{
	if (!bIsInit)
	{
		// Make sure the mappings singleton is initialized (the handler uses it)
		if (!FSLEntitiesManager::GetInstance()->IsInit())
		{
			FSLEntitiesManager::GetInstance()->Init(InParent->GetWorld());
		}

#if SL_WITH_SLICING
		// Check if parent is of right type
		Parent = Cast<USlicingBladeComponent>(InParent);
#endif // SL_WITH_SLICING

		if (Parent)
		{
			// Mark as initialized
			bIsInit = true;
		}
	}
}

// Bind to input delegates
void FSLSlicingEventHandler::Start()
{
	if (!bIsStarted && bIsInit)
	{
#if SL_WITH_SLICING
		// Subscribe to the forwarded semantically annotated Slicing broadcasts
		Parent->OnBeginSlicing.AddRaw(this, &FSLSlicingEventHandler::OnSLSlicingBegin);
		Parent->OnEndSlicingFail.AddRaw(this, &FSLSlicingEventHandler::OnSLSlicingEndFail);
		Parent->OnEndSlicingSuccess.AddRaw(this, &FSLSlicingEventHandler::OnSLSlicingEndSuccess);
		Parent->OnObjectCreation.AddRaw(this, &FSLSlicingEventHandler::OnSLObjectCreation);
		Parent->OnObjectDestruction.AddRaw(this, &FSLSlicingEventHandler::OnSLObjectDestruction);
#endif // SL_WITH_SLICING

		// Mark as started
		bIsStarted = true;
	}
}

// Terminate listener, finish and publish remaining events
void FSLSlicingEventHandler::Finish(float EndTime, bool bForced)
{
	if (!bIsFinished && (bIsInit || bIsStarted))
	{
		FSLSlicingEventHandler::FinishAllEvents(EndTime);

		// TODO use dynamic delegates to be able to unbind from them
		// https://docs.unrealengine.com/en-us/Programming/UnrealArchitecture/Delegates/Dynamic
		// this would mean that the handler will need to inherit from UObject

		// Mark finished
		bIsStarted = false;
		bIsInit = false;
		bIsFinished = true;
	}
}

// Start new Slicing event
void FSLSlicingEventHandler::AddNewEvent(const FSLEntity& PerformedBy, const FSLEntity& DeviceUsed, const FSLEntity& ObjectActedOn, float StartTime)
{
	// Start a semantic Slicing event
	TSharedPtr<FSLSlicingEvent> Event = MakeShareable(new FSLSlicingEvent(
		FIds::NewGuidInBase64Url(), StartTime,
		FIds::PairEncodeCantor(PerformedBy.Obj->GetUniqueID(), ObjectActedOn.Obj->GetUniqueID()),
		PerformedBy, DeviceUsed, ObjectActedOn));
	// Add event to the pending array
	StartedEvents.Emplace(Event);
}

// Publish finished event
bool FSLSlicingEventHandler::FinishEvent(UObject* ObjectActedOn, bool taskSuccess, float EndTime, const FSLEntity& OutputsCreated = FSLEntity::FSLEntity())
{
	// Use iterator to be able to remove the entry from the array
	for (auto EventItr(StartedEvents.CreateIterator()); EventItr; ++EventItr)
	{
		// It is enough to compare against the other id when searching
		if ((*EventItr)->ObjectActedOn.Obj == ObjectActedOn)
		{
			// Set end time and publish event
			(*EventItr)->End = EndTime;
			(*EventItr)->TaskSuccess = taskSuccess;
			(*EventItr)->OutputsCreated = OutputsCreated;
			OnSemanticEvent.ExecuteIfBound(*EventItr);
			// Remove event from the pending list
			EventItr.RemoveCurrent();
			return true;
		}
	}
	return false;
}

// Terminate and publish pending events (this usually is called at end play)
void FSLSlicingEventHandler::FinishAllEvents(float EndTime)
{
	// Finish events
	for (auto& Ev : StartedEvents)
	{
		// Set end time and publish event
		Ev->End = EndTime;
		OnSemanticEvent.ExecuteIfBound(Ev);
	}
	StartedEvents.Empty();
}

// Event called when a semantic Slicing event begins
void FSLSlicingEventHandler::OnSLSlicingBegin(UObject* PerformedBy, UObject* DeviceUsed, UObject* ObjectActedOn, float Time)
{
	// Check that the objects are semantically annotated
  	FSLEntity PerformedByEntity = FSLEntitiesManager::GetInstance()->GetEntity(PerformedBy);
	FSLEntity DeviceUsedEntity = FSLEntitiesManager::GetInstance()->GetEntity(DeviceUsed);
	FSLEntity CutEntity = FSLEntitiesManager::GetInstance()->GetEntity(ObjectActedOn);
	if (PerformedByEntity.IsSet()
		&& CutEntity.IsSet()
		&& DeviceUsedEntity.IsSet())
	{
		FSLSlicingEventHandler::AddNewEvent(PerformedByEntity, DeviceUsedEntity, CutEntity, Time);
	}
}

// Event called when a semantic Slicing event ends
void FSLSlicingEventHandler::OnSLSlicingEndFail(UObject* PerformedBy, UObject* ObjectActedOn, float Time)
{
	FSLEntity PerformedByEntity = FSLEntitiesManager::GetInstance()->GetEntity(PerformedBy);
	FSLEntity CutEntity = FSLEntitiesManager::GetInstance()->GetEntity(ObjectActedOn);
	if (PerformedByEntity.IsSet()
		&& CutEntity.IsSet())
	{
		FSLSlicingEventHandler::FinishEvent(ObjectActedOn, false, Time);
	}
}

// Event called when a semantic Slicing event ends
void FSLSlicingEventHandler::OnSLSlicingEndSuccess(UObject* PerformedBy, UObject* ObjectActedOn, UObject* OutputsCreated, float Time)
{
	FSLEntity PerformedByEntity = FSLEntitiesManager::GetInstance()->GetEntity(PerformedBy);
	FSLEntity CutEntity = FSLEntitiesManager::GetInstance()->GetEntity(ObjectActedOn);
	FSLEntity OutputsCreatedEntity = FSLEntitiesManager::GetInstance()->GetEntity(OutputsCreated);
	if (PerformedByEntity.IsSet()
		&& CutEntity.IsSet()
		&& OutputsCreatedEntity.IsSet())
	{
		FSLSlicingEventHandler::FinishEvent(ObjectActedOn, true, Time, OutputsCreatedEntity);
	}
}

// Event called when new objects are created
void FSLSlicingEventHandler::OnSLObjectCreation(UObject* TransformedObject, UObject* NewSlice, float Time)
{
	// Only create Id for new Slice and use same old ID for Original object
	FString IdValue = FIds::NewGuidInBase64() + "_";
	IdValue.Append(FTags::GetValue(TransformedObject, "SemLog", "Id"));
	FTags::AddKeyValuePair(NewSlice, "SemLog", "Id", IdValue, true);

	if (FSLEntitiesManager::GetInstance()->AddObject(TransformedObject) &&
		FSLEntitiesManager::GetInstance()->AddObject(NewSlice))
	{
		UE_LOG(LogTemp, Error, TEXT(">>Items Have been Created"));
	}
}

// Event called when an object is destroyed
void FSLSlicingEventHandler::OnSLObjectDestruction(UObject* ObjectActedOn, float Time)
{
	FSLEntity OtherItem = FSLEntitiesManager::GetInstance()->GetEntity(ObjectActedOn);
	if (OtherItem.IsSet())
	{
		FSLEntitiesManager::GetInstance()->RemoveEntity(ObjectActedOn);
	}
}
<commit_msg>Changing the default parameter behavior: the ctor can be called without giving the name of the struct<commit_after>// Copyright 2019, Institute for Artificial Intelligence - University of Bremen
// Author: Andrei Haidu (http://haidu.eu)

#include "Events/SLSlicingEventHandler.h"
#include "SLEntitiesManager.h"
#include "Tags.h"
#if SL_WITH_SLICING
#include "SlicingBladeComponent.h"
#endif // SL_WITH_SLICING

// UUtils
#include "Ids.h"

// Set parent
void FSLSlicingEventHandler::Init(UObject* InParent)
{
	if (!bIsInit)
	{
		// Make sure the mappings singleton is initialized (the handler uses it)
		if (!FSLEntitiesManager::GetInstance()->IsInit())
		{
			FSLEntitiesManager::GetInstance()->Init(InParent->GetWorld());
		}

#if SL_WITH_SLICING
		// Check if parent is of right type
		Parent = Cast<USlicingBladeComponent>(InParent);
#endif // SL_WITH_SLICING

		if (Parent)
		{
			// Mark as initialized
			bIsInit = true;
		}
	}
}

// Bind to input delegates
void FSLSlicingEventHandler::Start()
{
	if (!bIsStarted && bIsInit)
	{
#if SL_WITH_SLICING
		// Subscribe to the forwarded semantically annotated Slicing broadcasts
		Parent->OnBeginSlicing.AddRaw(this, &FSLSlicingEventHandler::OnSLSlicingBegin);
		Parent->OnEndSlicingFail.AddRaw(this, &FSLSlicingEventHandler::OnSLSlicingEndFail);
		Parent->OnEndSlicingSuccess.AddRaw(this, &FSLSlicingEventHandler::OnSLSlicingEndSuccess);
		Parent->OnObjectCreation.AddRaw(this, &FSLSlicingEventHandler::OnSLObjectCreation);
		Parent->OnObjectDestruction.AddRaw(this, &FSLSlicingEventHandler::OnSLObjectDestruction);
#endif // SL_WITH_SLICING

		// Mark as started
		bIsStarted = true;
	}
}

// Terminate listener, finish and publish remaining events
void FSLSlicingEventHandler::Finish(float EndTime, bool bForced)
{
	if (!bIsFinished && (bIsInit || bIsStarted))
	{
		FSLSlicingEventHandler::FinishAllEvents(EndTime);

		// TODO use dynamic delegates to be able to unbind from them
		// https://docs.unrealengine.com/en-us/Programming/UnrealArchitecture/Delegates/Dynamic
		// this would mean that the handler will need to inherit from UObject

		// Mark finished
		bIsStarted = false;
		bIsInit = false;
		bIsFinished = true;
	}
}

// Start new Slicing event
void FSLSlicingEventHandler::AddNewEvent(const FSLEntity& PerformedBy, const FSLEntity& DeviceUsed, const FSLEntity& ObjectActedOn, float StartTime)
{
	// Start a semantic Slicing event
	TSharedPtr<FSLSlicingEvent> Event = MakeShareable(new FSLSlicingEvent(
		FIds::NewGuidInBase64Url(), StartTime,
		FIds::PairEncodeCantor(PerformedBy.Obj->GetUniqueID(), ObjectActedOn.Obj->GetUniqueID()),
		PerformedBy, DeviceUsed, ObjectActedOn));
	// Add event to the pending array
	StartedEvents.Emplace(Event);
}

// Publish finished event
bool FSLSlicingEventHandler::FinishEvent(UObject* ObjectActedOn, bool taskSuccess, float EndTime, const FSLEntity& OutputsCreated = FSLEntity())
{
	// Use iterator to be able to remove the entry from the array
	for (auto EventItr(StartedEvents.CreateIterator()); EventItr; ++EventItr)
	{
		// It is enough to compare against the other id when searching
		if ((*EventItr)->ObjectActedOn.Obj == ObjectActedOn)
		{
			// Set end time and publish event
			(*EventItr)->End = EndTime;
			(*EventItr)->TaskSuccess = taskSuccess;
			(*EventItr)->OutputsCreated = OutputsCreated;
			OnSemanticEvent.ExecuteIfBound(*EventItr);
			// Remove event from the pending list
			EventItr.RemoveCurrent();
			return true;
		}
	}
	return false;
}

// Terminate and publish pending events (this usually is called at end play)
void FSLSlicingEventHandler::FinishAllEvents(float EndTime)
{
	// Finish events
	for (auto& Ev : StartedEvents)
	{
		// Set end time and publish event
		Ev->End = EndTime;
		OnSemanticEvent.ExecuteIfBound(Ev);
	}
	StartedEvents.Empty();
}

// Event called when a semantic Slicing event begins
void FSLSlicingEventHandler::OnSLSlicingBegin(UObject* PerformedBy, UObject* DeviceUsed, UObject* ObjectActedOn, float Time)
{
	// Check that the objects are semantically annotated
  	FSLEntity PerformedByEntity = FSLEntitiesManager::GetInstance()->GetEntity(PerformedBy);
	FSLEntity DeviceUsedEntity = FSLEntitiesManager::GetInstance()->GetEntity(DeviceUsed);
	FSLEntity CutEntity = FSLEntitiesManager::GetInstance()->GetEntity(ObjectActedOn);
	if (PerformedByEntity.IsSet()
		&& CutEntity.IsSet()
		&& DeviceUsedEntity.IsSet())
	{
		FSLSlicingEventHandler::AddNewEvent(PerformedByEntity, DeviceUsedEntity, CutEntity, Time);
	}
}

// Event called when a semantic Slicing event ends
void FSLSlicingEventHandler::OnSLSlicingEndFail(UObject* PerformedBy, UObject* ObjectActedOn, float Time)
{
	FSLEntity PerformedByEntity = FSLEntitiesManager::GetInstance()->GetEntity(PerformedBy);
	FSLEntity CutEntity = FSLEntitiesManager::GetInstance()->GetEntity(ObjectActedOn);
	if (PerformedByEntity.IsSet()
		&& CutEntity.IsSet())
	{
		FSLSlicingEventHandler::FinishEvent(ObjectActedOn, false, Time);
	}
}

// Event called when a semantic Slicing event ends
void FSLSlicingEventHandler::OnSLSlicingEndSuccess(UObject* PerformedBy, UObject* ObjectActedOn, UObject* OutputsCreated, float Time)
{
	FSLEntity PerformedByEntity = FSLEntitiesManager::GetInstance()->GetEntity(PerformedBy);
	FSLEntity CutEntity = FSLEntitiesManager::GetInstance()->GetEntity(ObjectActedOn);
	FSLEntity OutputsCreatedEntity = FSLEntitiesManager::GetInstance()->GetEntity(OutputsCreated);
	if (PerformedByEntity.IsSet()
		&& CutEntity.IsSet()
		&& OutputsCreatedEntity.IsSet())
	{
		FSLSlicingEventHandler::FinishEvent(ObjectActedOn, true, Time, OutputsCreatedEntity);
	}
}

// Event called when new objects are created
void FSLSlicingEventHandler::OnSLObjectCreation(UObject* TransformedObject, UObject* NewSlice, float Time)
{
	// Only create Id for new Slice and use same old ID for Original object
	FString IdValue = FIds::NewGuidInBase64() + "_";
	IdValue.Append(FTags::GetValue(TransformedObject, "SemLog", "Id"));
	FTags::AddKeyValuePair(NewSlice, "SemLog", "Id", IdValue, true);

	if (FSLEntitiesManager::GetInstance()->AddObject(TransformedObject) &&
		FSLEntitiesManager::GetInstance()->AddObject(NewSlice))
	{
		UE_LOG(LogTemp, Error, TEXT(">>Items Have been Created"));
	}
}

// Event called when an object is destroyed
void FSLSlicingEventHandler::OnSLObjectDestruction(UObject* ObjectActedOn, float Time)
{
	FSLEntity OtherItem = FSLEntitiesManager::GetInstance()->GetEntity(ObjectActedOn);
	if (OtherItem.IsSet())
	{
		FSLEntitiesManager::GetInstance()->RemoveEntity(ObjectActedOn);
	}
}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.h"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBinaryDilateImageFilter.txx"
#include "itkBinaryErodeImageFilter.txx"
#include "itkBinaryFunctorImageFilter.txx"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinaryThresholdImageFilter.txx"
#include "itkBinomialBlurImageFilter.txx"
#include "itkBloxBoundaryPointToCoreAtomImageFilter.txx"
#include "itkCannyEdgeDetectionImageFilter.txx"
#include "itkCastImageFilter.h"
#include "itkChangeInformationImageFilter.txx"
#include "itkConfidenceConnectedImageFilter.txx"
#include "itkConnectedThresholdImageFilter.txx"
#include "itkConstantPadImageFilter.txx"
#include "itkCosImageFilter.h"
#include "itkCropImageFilter.txx"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkDanielssonDistanceMapImageFilter.txx"
#include "itkDerivativeImageFilter.txx"
#include "itkDifferenceOfGaussiansGradientImageFilter.txx"
#include "itkDiscreteGaussianImageFilter.txx"
#include "itkDivideImageFilter.h"
#include "itkEdgePotentialImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.txx"
#include "itkExpImageFilter.h"
#include "itkExpandImageFilter.txx"
#include "itkExtractImageFilter.txx"
#include "itkExtractImageFilterRegionCopier.h"
#include "itkFileIOToImageFilter.txx"
#include "itkFlipImageFilter.txx"
#include "itkGaussianImageSource.txx"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.txx"
#include "itkGradientImageToBloxBoundaryPointImageFilter.txx"
#include "itkGradientMagnitudeImageFilter.txx"
#include "itkGradientNDAnisotropicDiffusionFunction.txx"
#include "itkGradientRecursiveGaussianImageFilter.txx"
#include "itkGradientToMagnitudeImageFilter.txx"
#include "itkGrayscaleDilateImageFilter.txx"
#include "itkGrayscaleErodeImageFilter.txx"
#include "itkGrayscaleFunctionDilateImageFilter.txx"
#include "itkGrayscaleFunctionErodeImageFilter.txx"
#include "itkHardConnectedComponentImageFilter.txx"
#include "itkImageToMeshFilter.txx"
#include "itkImageToParametricSpaceFilter.txx"
#include "itkImportImageFilter.txx"
#include "itkInteriorExteriorMeshFilter.txx"
#include "itkIsolatedConnectedImageFilter.txx"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.txx"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMeanImageFilter.txx"
#include "itkMedianImageFilter.txx"
#include "itkMinimumMaximumImageCalculator.txx"
#include "itkMinimumMaximumImageFilter.txx"
#include "itkMirrorPadImageFilter.txx"
#include "itkMorphologyImageFilter.txx"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.txx"
#include "itkNeighborhoodConnectedImageFilter.txx"
#include "itkNeighborhoodOperatorImageFilter.txx"
#include "itkNonThreadedShrinkImageFilter.txx"
#include "itkNormalizeImageFilter.txx"
#include "itkPadImageFilter.txx"
#include "itkParametricSpaceToImageSpaceMeshFilter.txx"
#include "itkPermuteAxesImageFilter.txx"
#include "itkPlaheImageFilter.txx"
#include "itkRandomImageSource.txx"
#include "itkRecursiveGaussianImageFilter.txx"
#include "itkRecursiveSeparableImageFilter.txx"
#include "itkReflectImageFilter.txx"
#include "itkReflectiveImageRegionIterator.txx"
#include "itkResampleImageFilter.txx"
#include "itkRescaleIntensityImageFilter.txx"
#include "itkScalarAnisotropicDiffusionFunction.txx"
#include "itkShiftScaleImageFilter.txx"
#include "itkShrinkImageFilter.txx"
#include "itkSimilarityIndexImageFilter.txx"
#include "itkSinImageFilter.h"
#include "itkSobelEdgeDetectionImageFilter.txx"
#include "itkSparseFieldLevelSetImageFilter.txx"
#include "itkSparseLevelSetNode.h"
#include "itkSpatialFunctionImageEvaluatorFilter.txx"
#include "itkSqrtImageFilter.h"
#include "itkStatisticsImageFilter.txx"
#include "itkStreamingImageFilter.txx"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.txx"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.txx"
#include "itkTransformMeshFilter.txx"
#include "itkTwoOutputExampleImageFilter.txx"
#include "itkUnaryFunctorImageFilter.txx"
#include "itkVTKImageExport.txx"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.txx"
#include "itkVectorAnisotropicDiffusionFunction.txx"
#include "itkVectorCastImageFilter.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkVectorExpandImageFilter.txx"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.txx"
#include "itkVectorNeighborhoodOperatorImageFilter.txx"
#include "itkWarpImageFilter.txx"
#include "itkWrapPadImageFilter.txx"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.txx"
#include "itkZeroCrossingImageFilter.txx"

int main ( int argc, char* argv )
{

  return 0;
}

<commit_msg>ENH: Updated to latest headers<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:
  Language:  C++
  Date:
  Version:

Copyright (c) 2000 National Library of Medicine
All rights reserved.

See COPYRIGHT.txt for copyright details.

=========================================================================*/
#include <iostream>
// This file has been generated by BuildHeaderTest.tcl
// Test to include each header file for Insight

#include "itkAcosImageFilter.h"
#include "itkAdaptImageFilter.h"
#include "itkAddImageFilter.h"
#include "itkAnisotropicDiffusionFunction.h"
#include "itkAnisotropicDiffusionImageFilter.h"
#include "itkAsinImageFilter.h"
#include "itkAtan2ImageFilter.h"
#include "itkAtanImageFilter.h"
#include "itkBinaryDilateImageFilter.txx"
#include "itkBinaryErodeImageFilter.txx"
#include "itkBinaryFunctorImageFilter.txx"
#include "itkBinaryMagnitudeImageFilter.h"
#include "itkBinaryThresholdImageFilter.txx"
#include "itkBinomialBlurImageFilter.txx"
#include "itkBloxBoundaryPointToCoreAtomImageFilter.txx"
#include "itkCannyEdgeDetectionImageFilter.txx"
#include "itkCastImageFilter.h"
#include "itkChangeInformationImageFilter.txx"
#include "itkConfidenceConnectedImageFilter.txx"
#include "itkConnectedThresholdImageFilter.txx"
#include "itkConstantPadImageFilter.txx"
#include "itkCosImageFilter.h"
#include "itkCropImageFilter.txx"
#include "itkCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkDanielssonDistanceMapImageFilter.txx"
#include "itkDerivativeImageFilter.txx"
#include "itkDifferenceOfGaussiansGradientImageFilter.txx"
#include "itkDirectedHausdorffDistanceImageFilter.txx"
#include "itkDiscreteGaussianImageFilter.txx"
#include "itkDivideImageFilter.h"
#include "itkEdgePotentialImageFilter.h"
#include "itkEigenAnalysis2DImageFilter.txx"
#include "itkExpImageFilter.h"
#include "itkExpandImageFilter.txx"
#include "itkExtractImageFilter.txx"
#include "itkExtractImageFilterRegionCopier.h"
#include "itkFileIOToImageFilter.txx"
#include "itkFlipImageFilter.txx"
#include "itkGaussianImageSource.txx"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "itkGradientImageFilter.txx"
#include "itkGradientImageToBloxBoundaryPointImageFilter.txx"
#include "itkGradientMagnitudeImageFilter.txx"
#include "itkGradientNDAnisotropicDiffusionFunction.txx"
#include "itkGradientRecursiveGaussianImageFilter.txx"
#include "itkGradientToMagnitudeImageFilter.txx"
#include "itkGrayscaleDilateImageFilter.txx"
#include "itkGrayscaleErodeImageFilter.txx"
#include "itkGrayscaleFunctionDilateImageFilter.txx"
#include "itkGrayscaleFunctionErodeImageFilter.txx"
#include "itkHardConnectedComponentImageFilter.txx"
#include "itkHausdorffDistanceImageFilter.txx"
#include "itkImageToMeshFilter.txx"
#include "itkImageToParametricSpaceFilter.txx"
#include "itkImportImageFilter.txx"
#include "itkInteriorExteriorMeshFilter.txx"
#include "itkIsolatedConnectedImageFilter.txx"
#include "itkJoinImageFilter.h"
#include "itkLaplacianImageFilter.txx"
#include "itkLog10ImageFilter.h"
#include "itkLogImageFilter.h"
#include "itkMeanImageFilter.txx"
#include "itkMedianImageFilter.txx"
#include "itkMinimumMaximumImageCalculator.txx"
#include "itkMinimumMaximumImageFilter.txx"
#include "itkMirrorPadImageFilter.txx"
#include "itkMorphologyImageFilter.txx"
#include "itkMultiplyImageFilter.h"
#include "itkNaryAddImageFilter.h"
#include "itkNaryFunctorImageFilter.txx"
#include "itkNeighborhoodConnectedImageFilter.txx"
#include "itkNeighborhoodOperatorImageFilter.txx"
#include "itkNonThreadedShrinkImageFilter.txx"
#include "itkNormalizeImageFilter.txx"
#include "itkPadImageFilter.txx"
#include "itkParametricSpaceToImageSpaceMeshFilter.txx"
#include "itkPermuteAxesImageFilter.txx"
#include "itkPlaheImageFilter.txx"
#include "itkRandomImageSource.txx"
#include "itkRecursiveGaussianImageFilter.txx"
#include "itkRecursiveSeparableImageFilter.txx"
#include "itkReflectImageFilter.txx"
#include "itkReflectiveImageRegionIterator.txx"
#include "itkResampleImageFilter.txx"
#include "itkRescaleIntensityImageFilter.txx"
#include "itkScalarAnisotropicDiffusionFunction.txx"
#include "itkShiftScaleImageFilter.txx"
#include "itkShrinkImageFilter.txx"
#include "itkSimilarityIndexImageFilter.txx"
#include "itkSinImageFilter.h"
#include "itkSobelEdgeDetectionImageFilter.txx"
#include "itkSparseFieldLevelSetImageFilter.txx"
#include "itkSparseLevelSetNode.h"
#include "itkSpatialFunctionImageEvaluatorFilter.txx"
#include "itkSqrtImageFilter.h"
#include "itkStatisticsImageFilter.txx"
#include "itkStreamingImageFilter.txx"
#include "itkSubtractImageFilter.h"
#include "itkTanImageFilter.h"
#include "itkTernaryAddImageFilter.h"
#include "itkTernaryFunctorImageFilter.txx"
#include "itkTernaryMagnitudeImageFilter.h"
#include "itkTernaryMagnitudeSquaredImageFilter.h"
#include "itkThresholdImageFilter.txx"
#include "itkTransformMeshFilter.txx"
#include "itkTwoOutputExampleImageFilter.txx"
#include "itkUnaryFunctorImageFilter.txx"
#include "itkVTKImageExport.txx"
#include "itkVTKImageExportBase.h"
#include "itkVTKImageImport.txx"
#include "itkVectorAnisotropicDiffusionFunction.txx"
#include "itkVectorCastImageFilter.h"
#include "itkVectorCurvatureAnisotropicDiffusionImageFilter.h"
#include "itkVectorCurvatureNDAnisotropicDiffusionFunction.txx"
#include "itkVectorExpandImageFilter.txx"
#include "itkVectorGradientAnisotropicDiffusionImageFilter.h"
#include "itkVectorGradientNDAnisotropicDiffusionFunction.txx"
#include "itkVectorNeighborhoodOperatorImageFilter.txx"
#include "itkWarpImageFilter.txx"
#include "itkWrapPadImageFilter.txx"
#include "itkZeroCrossingBasedEdgeDetectionImageFilter.txx"
#include "itkZeroCrossingImageFilter.txx"

int main ( int argc, char* argv )
{

  return 0;
}

<|endoftext|>


<commit_before><commit_msg>Include <stdlib.h> for the declarations of memcpy, malloc, free. This is needed for the "chromium-rel-linux-jaunty" builder.<commit_after><|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                          License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#pragma once

#ifndef OPENCV_CUDEV_UTIL_SATURATE_CAST_HPP
#define OPENCV_CUDEV_UTIL_SATURATE_CAST_HPP

#include "../common.hpp"
#if __CUDACC_VER_MAJOR__ >= 9
#include <cuda_fp16.h>
#endif

namespace cv { namespace cudev {

//! @addtogroup cudev
//! @{

template <typename T> __device__ __forceinline__ T saturate_cast(uchar v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(schar v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(ushort v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(short v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(uint v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(int v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(float v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(double v) { return T(v); }

template <> __device__ __forceinline__ uchar saturate_cast<uchar>(schar v)
{
    uint res = 0;
    int vi = v;
    asm("cvt.sat.u8.s8 %0, %1;" : "=r"(res) : "r"(vi));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(short v)
{
    uint res = 0;
    asm("cvt.sat.u8.s16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(ushort v)
{
    uint res = 0;
    asm("cvt.sat.u8.u16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(int v)
{
    uint res = 0;
    asm("cvt.sat.u8.s32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(uint v)
{
    uint res = 0;
    asm("cvt.sat.u8.u32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(float v)
{
    uint res = 0;
    asm("cvt.rni.sat.u8.f32 %0, %1;" : "=r"(res) : "f"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(double v)
{
    uint res = 0;
    asm("cvt.rni.sat.u8.f64 %0, %1;" : "=r"(res) : "d"(v));
    return res;
}

template <> __device__ __forceinline__ schar saturate_cast<schar>(uchar v)
{
    uint res = 0;
    uint vi = v;
    asm("cvt.sat.s8.u8 %0, %1;" : "=r"(res) : "r"(vi));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(short v)
{
    uint res = 0;
    asm("cvt.sat.s8.s16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(ushort v)
{
    uint res = 0;
    asm("cvt.sat.s8.u16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(int v)
{
    uint res = 0;
    asm("cvt.sat.s8.s32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(uint v)
{
    uint res = 0;
    asm("cvt.sat.s8.u32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(float v)
{
    uint res = 0;
    asm("cvt.rni.sat.s8.f32 %0, %1;" : "=r"(res) : "f"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(double v)
{
    uint res = 0;
    asm("cvt.rni.sat.s8.f64 %0, %1;" : "=r"(res) : "d"(v));
    return res;
}

template <> __device__ __forceinline__ ushort saturate_cast<ushort>(schar v)
{
    ushort res = 0;
    int vi = v;
    asm("cvt.sat.u16.s8 %0, %1;" : "=h"(res) : "r"(vi));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(short v)
{
    ushort res = 0;
    asm("cvt.sat.u16.s16 %0, %1;" : "=h"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(int v)
{
    ushort res = 0;
    asm("cvt.sat.u16.s32 %0, %1;" : "=h"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(uint v)
{
    ushort res = 0;
    asm("cvt.sat.u16.u32 %0, %1;" : "=h"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(float v)
{
    ushort res = 0;
    asm("cvt.rni.sat.u16.f32 %0, %1;" : "=h"(res) : "f"(v));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(double v)
{
    ushort res = 0;
    asm("cvt.rni.sat.u16.f64 %0, %1;" : "=h"(res) : "d"(v));
    return res;
}

template <> __device__ __forceinline__ short saturate_cast<short>(ushort v)
{
    short res = 0;
    asm("cvt.sat.s16.u16 %0, %1;" : "=h"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ short saturate_cast<short>(int v)
{
    short res = 0;
    asm("cvt.sat.s16.s32 %0, %1;" : "=h"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ short saturate_cast<short>(uint v)
{
    short res = 0;
    asm("cvt.sat.s16.u32 %0, %1;" : "=h"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ short saturate_cast<short>(float v)
{
    short res = 0;
    asm("cvt.rni.sat.s16.f32 %0, %1;" : "=h"(res) : "f"(v));
    return res;
}
template <> __device__ __forceinline__ short saturate_cast<short>(double v)
{
    short res = 0;
    asm("cvt.rni.sat.s16.f64 %0, %1;" : "=h"(res) : "d"(v));
    return res;
}

template <> __device__ __forceinline__ int saturate_cast<int>(uint v)
{
    int res = 0;
    asm("cvt.sat.s32.u32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ int saturate_cast<int>(float v)
{
    return __float2int_rn(v);
}
template <> __device__ __forceinline__ int saturate_cast<int>(double v)
{
#if CV_CUDEV_ARCH >= 130
    return __double2int_rn(v);
#else
    return saturate_cast<int>((float) v);
#endif
}

template <> __device__ __forceinline__ uint saturate_cast<uint>(schar v)
{
    uint res = 0;
    int vi = v;
    asm("cvt.sat.u32.s8 %0, %1;" : "=r"(res) : "r"(vi));
    return res;
}
template <> __device__ __forceinline__ uint saturate_cast<uint>(short v)
{
    uint res = 0;
    asm("cvt.sat.u32.s16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ uint saturate_cast<uint>(int v)
{
    uint res = 0;
    asm("cvt.sat.u32.s32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ uint saturate_cast<uint>(float v)
{
    return __float2uint_rn(v);
}
template <> __device__ __forceinline__ uint saturate_cast<uint>(double v)
{
#if CV_CUDEV_ARCH >= 130
    return __double2uint_rn(v);
#else
    return saturate_cast<uint>((float) v);
#endif
}

template <typename T, typename D> __device__ __forceinline__ D cast_fp16(T v);

template <> __device__ __forceinline__ float cast_fp16<short, float>(short v)
{
#if __CUDACC_VER_MAJOR__ >= 9
  return float(*(__half*)&v);
#else
    return __half2float(v);
#endif
}

template <> __device__ __forceinline__ short cast_fp16<float, short>(float v)
{
#if __CUDACC_VER_MAJOR__ >= 9
  __half h(v);
  return *(short*)&v;
#else
  return (short)__float2half_rn(v);
#endif
}
//! @}

}}

#endif
<commit_msg>fix CvFp16Test failure<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                          License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#pragma once

#ifndef OPENCV_CUDEV_UTIL_SATURATE_CAST_HPP
#define OPENCV_CUDEV_UTIL_SATURATE_CAST_HPP

#include "../common.hpp"
#if __CUDACC_VER_MAJOR__ >= 9
#include <cuda_fp16.h>
#endif

namespace cv { namespace cudev {

//! @addtogroup cudev
//! @{

template <typename T> __device__ __forceinline__ T saturate_cast(uchar v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(schar v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(ushort v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(short v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(uint v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(int v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(float v) { return T(v); }
template <typename T> __device__ __forceinline__ T saturate_cast(double v) { return T(v); }

template <> __device__ __forceinline__ uchar saturate_cast<uchar>(schar v)
{
    uint res = 0;
    int vi = v;
    asm("cvt.sat.u8.s8 %0, %1;" : "=r"(res) : "r"(vi));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(short v)
{
    uint res = 0;
    asm("cvt.sat.u8.s16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(ushort v)
{
    uint res = 0;
    asm("cvt.sat.u8.u16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(int v)
{
    uint res = 0;
    asm("cvt.sat.u8.s32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(uint v)
{
    uint res = 0;
    asm("cvt.sat.u8.u32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(float v)
{
    uint res = 0;
    asm("cvt.rni.sat.u8.f32 %0, %1;" : "=r"(res) : "f"(v));
    return res;
}
template <> __device__ __forceinline__ uchar saturate_cast<uchar>(double v)
{
    uint res = 0;
    asm("cvt.rni.sat.u8.f64 %0, %1;" : "=r"(res) : "d"(v));
    return res;
}

template <> __device__ __forceinline__ schar saturate_cast<schar>(uchar v)
{
    uint res = 0;
    uint vi = v;
    asm("cvt.sat.s8.u8 %0, %1;" : "=r"(res) : "r"(vi));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(short v)
{
    uint res = 0;
    asm("cvt.sat.s8.s16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(ushort v)
{
    uint res = 0;
    asm("cvt.sat.s8.u16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(int v)
{
    uint res = 0;
    asm("cvt.sat.s8.s32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(uint v)
{
    uint res = 0;
    asm("cvt.sat.s8.u32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(float v)
{
    uint res = 0;
    asm("cvt.rni.sat.s8.f32 %0, %1;" : "=r"(res) : "f"(v));
    return res;
}
template <> __device__ __forceinline__ schar saturate_cast<schar>(double v)
{
    uint res = 0;
    asm("cvt.rni.sat.s8.f64 %0, %1;" : "=r"(res) : "d"(v));
    return res;
}

template <> __device__ __forceinline__ ushort saturate_cast<ushort>(schar v)
{
    ushort res = 0;
    int vi = v;
    asm("cvt.sat.u16.s8 %0, %1;" : "=h"(res) : "r"(vi));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(short v)
{
    ushort res = 0;
    asm("cvt.sat.u16.s16 %0, %1;" : "=h"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(int v)
{
    ushort res = 0;
    asm("cvt.sat.u16.s32 %0, %1;" : "=h"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(uint v)
{
    ushort res = 0;
    asm("cvt.sat.u16.u32 %0, %1;" : "=h"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(float v)
{
    ushort res = 0;
    asm("cvt.rni.sat.u16.f32 %0, %1;" : "=h"(res) : "f"(v));
    return res;
}
template <> __device__ __forceinline__ ushort saturate_cast<ushort>(double v)
{
    ushort res = 0;
    asm("cvt.rni.sat.u16.f64 %0, %1;" : "=h"(res) : "d"(v));
    return res;
}

template <> __device__ __forceinline__ short saturate_cast<short>(ushort v)
{
    short res = 0;
    asm("cvt.sat.s16.u16 %0, %1;" : "=h"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ short saturate_cast<short>(int v)
{
    short res = 0;
    asm("cvt.sat.s16.s32 %0, %1;" : "=h"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ short saturate_cast<short>(uint v)
{
    short res = 0;
    asm("cvt.sat.s16.u32 %0, %1;" : "=h"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ short saturate_cast<short>(float v)
{
    short res = 0;
    asm("cvt.rni.sat.s16.f32 %0, %1;" : "=h"(res) : "f"(v));
    return res;
}
template <> __device__ __forceinline__ short saturate_cast<short>(double v)
{
    short res = 0;
    asm("cvt.rni.sat.s16.f64 %0, %1;" : "=h"(res) : "d"(v));
    return res;
}

template <> __device__ __forceinline__ int saturate_cast<int>(uint v)
{
    int res = 0;
    asm("cvt.sat.s32.u32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ int saturate_cast<int>(float v)
{
    return __float2int_rn(v);
}
template <> __device__ __forceinline__ int saturate_cast<int>(double v)
{
#if CV_CUDEV_ARCH >= 130
    return __double2int_rn(v);
#else
    return saturate_cast<int>((float) v);
#endif
}

template <> __device__ __forceinline__ uint saturate_cast<uint>(schar v)
{
    uint res = 0;
    int vi = v;
    asm("cvt.sat.u32.s8 %0, %1;" : "=r"(res) : "r"(vi));
    return res;
}
template <> __device__ __forceinline__ uint saturate_cast<uint>(short v)
{
    uint res = 0;
    asm("cvt.sat.u32.s16 %0, %1;" : "=r"(res) : "h"(v));
    return res;
}
template <> __device__ __forceinline__ uint saturate_cast<uint>(int v)
{
    uint res = 0;
    asm("cvt.sat.u32.s32 %0, %1;" : "=r"(res) : "r"(v));
    return res;
}
template <> __device__ __forceinline__ uint saturate_cast<uint>(float v)
{
    return __float2uint_rn(v);
}
template <> __device__ __forceinline__ uint saturate_cast<uint>(double v)
{
#if CV_CUDEV_ARCH >= 130
    return __double2uint_rn(v);
#else
    return saturate_cast<uint>((float) v);
#endif
}

template <typename T, typename D> __device__ __forceinline__ D cast_fp16(T v);

template <> __device__ __forceinline__ float cast_fp16<short, float>(short v)
{
#if __CUDACC_VER_MAJOR__ >= 9
  return float(*(__half*)&v);
#else
    return __half2float(v);
#endif
}

template <> __device__ __forceinline__ short cast_fp16<float, short>(float v)
{
#if __CUDACC_VER_MAJOR__ >= 9
  __half h(v);
  return *(short*)&h;
#else
  return (short)__float2half_rn(v);
#endif
}
//! @}

}}

#endif
<|endoftext|>


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

#include "net/curvecp/messenger.h"

#include "base/logging.h"
#include "base/message_loop.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/curvecp/protocol.h"

// Basic protocol design:
//
// OnTimeout:    Called when the timeout timer pops.
//   - call SendMessage()
//   - call RecvMessage()
//
// OnSendTimer:  Called when the send-timer pops.
//   - call SendMessage()
//   - call RecvMessage()
//
// OnMessage:    Called when a message arrived from the packet layer
//   - add the message to the receive queue
//   - call RecvMessage()
//
// Write:        Called by application to write data to remote
//   - add the data to the send_buffer
//   - call SendMessage()
//
// SendMessage:  Called to Send a message to the remote
//   - msg = first message to retransmit where retransmit timer popped
//   - if msg == NULL
//   -   msg = create a new message from the send buffer
//   - if msg != NULL
//   -   send message to the packet layer
//   -   setTimer(OnSendTimer, send_rate);
//
// RecvMessage:  Called to process a Received message from the remote
//   - calculate RTT
//   - calculate Send Rate
//   - acknowledge data from received message
//   - resetTimeout
//      - timeout = now + rtt_timeout
//      - if currrent_timeout > timeout
//         setTimer(OnTimeout, timeout)

namespace net {

// Maximum number of write blocks.
static const size_t kMaxWriteQueueMessages = 128;

// Size of the send buffer.
static const size_t kSendBufferSize = (128 * 1024);
// Size of the receive buffer.
static const size_t kReceiveBufferSize = (128 * 1024);

Messenger::Messenger(Packetizer* packetizer)
    : packetizer_(packetizer),
      send_buffer_(kSendBufferSize),
      send_complete_callback_(NULL),
      receive_complete_callback_(NULL),
      pending_receive_length_(0),
      send_message_in_progress_(false),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          send_message_callback_(this, &Messenger::OnSendMessageComplete)),
      ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
}

Messenger::~Messenger() {
}

int Messenger::Read(IOBuffer* buf, int buf_len, CompletionCallback* callback) {
  DCHECK(CalledOnValidThread());
  DCHECK(!receive_complete_callback_);

  if (!received_list_.bytes_available()) {
    receive_complete_callback_ = callback;
    pending_receive_ = buf;
    pending_receive_length_ = buf_len;
    return ERR_IO_PENDING;
  }

  int bytes_read = InternalRead(buf, buf_len);
  DCHECK_LT(0, bytes_read);
  return bytes_read;
}

int Messenger::Write(IOBuffer* buf, int buf_len, CompletionCallback* callback) {
  DCHECK(CalledOnValidThread());
  DCHECK(!pending_send_.get());   // Already a write pending!
  DCHECK(!send_complete_callback_);
  DCHECK_LT(0, buf_len);

  int len = send_buffer_.write(buf->data(), buf_len);
  if (!send_timer_.IsRunning())
    send_timer_.Start(base::TimeDelta(), this, &Messenger::OnSendTimer);
  if (len)
    return len;

  // We couldn't add data to the send buffer, so block the application.
  pending_send_ = buf;
  pending_send_length_ = buf_len;
  send_complete_callback_ = callback;
  return ERR_IO_PENDING;
}

void Messenger::OnConnection(ConnectionKey key) {
  LOG(ERROR) << "Client Connect: " << key.ToString();
  key_ = key;
}

void Messenger::OnClose(Packetizer* packetizer, ConnectionKey key) {
  LOG(ERROR) << "Got Close!";
}

void Messenger::OnMessage(Packetizer* packetizer,
                          ConnectionKey key,
                          unsigned char* msg,
                          size_t length) {
  DCHECK(key == key_);

  // Do basic message sanity checking.
  if (length < sizeof(Message))
    return;
  if (length > static_cast<size_t>(kMaxMessageLength))
    return;

  // Add message to received queue.
  scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(length));
  memcpy(buffer->data(), msg, length);
  read_queue_.push_back(buffer);

  // Process a single received message
  RecvMessage();
}

int Messenger::InternalRead(IOBuffer* buffer, int buffer_length) {
  return received_list_.ReadBytes(buffer, buffer_length);
}

IOBufferWithSize* Messenger::CreateBufferFromSendQueue() {
  DCHECK_LT(0, send_buffer_.length());

  int length = std::min(packetizer_->max_message_payload(),
                        send_buffer_.length());
  IOBufferWithSize* rv = new IOBufferWithSize(length);
  int bytes = send_buffer_.read(rv->data(), length);
  DCHECK_EQ(bytes, length);

  // We consumed data, check to see if someone is waiting to write more data.
  if (send_complete_callback_) {
    DCHECK(pending_send_.get());

    int len = send_buffer_.write(pending_send_->data(), pending_send_length_);
    if (len) {
      pending_send_ = NULL;
      CompletionCallback* callback = send_complete_callback_;
      send_complete_callback_ = NULL;
      callback->Run(len);
    }
  }

  return rv;
}

void Messenger::OnSendMessageComplete(int result) {
  DCHECK_NE(ERR_IO_PENDING, result);

  send_message_in_progress_ = false;

  if (result <= 0) {
    // TODO(mbelshe):  Handle error.
    NOTIMPLEMENTED();
  }

  // If the send timer fired while we were waiting for this send to complete,
  // we need to manually run the timer now.
  if (!send_timer_.IsRunning())
    OnSendTimer();

  if (!send_timeout_timer_.IsRunning()) {
    LOG(ERROR) << "RttTimeout is " << rtt_.rtt_timeout();
    base::TimeDelta delay =
        base::TimeDelta::FromMicroseconds(rtt_.rtt_timeout());
    send_timeout_timer_.Start(delay, this, &Messenger::OnTimeout);
  }
}

void Messenger::OnTimeout() {
  LOG(ERROR) << "OnTimeout fired";
  int64 position = sent_list_.FindPositionOfOldestSentBlock();
  // XXXMB - need to verify that we really need to retransmit...
  if (position >= 0) {
    rtt_.OnTimeout();  // adjust our send rate.
    LOG(ERROR) << "OnTimeout retransmitting: " << position;
    SendMessage(position);
  } else {
    DCHECK_EQ(0u, sent_list_.size());
  }
  RecvMessage();
  received_list_.LogBlockList();
}

void Messenger::OnSendTimer() {
  LOG(ERROR) << "OnSendTimer!";
  DCHECK(!send_timer_.IsRunning());

  // If the send buffer is empty, then we don't need to keep firing.
  if (!send_buffer_.length()) {
    LOG(ERROR) << "OnSendTimer: send_buffer empty";
    return;
  }

  // Set the next send timer.
  LOG(ERROR) << "SendRate is: " << rtt_.send_rate() << "us";
  send_timer_.Start(base::TimeDelta::FromMicroseconds(rtt_.send_rate()),
                    this,
                    &Messenger::OnSendTimer);

  // Create a block from the send_buffer.
  if (!sent_list_.is_full()) {
    scoped_refptr<IOBufferWithSize> buffer = CreateBufferFromSendQueue();
    int64 position = sent_list_.CreateBlock(buffer.get());
    DCHECK_LE(0, position);
    SendMessage(position);
  }

  RecvMessage();  // Try to process an incoming message
}

void Messenger::SendMessage(int64 position) {
  LOG(ERROR) << "SendMessage (position=" << position << ")";
  if (send_message_in_progress_)
    return;  // We're still waiting for the last write to complete.

  IOBufferWithSize* data = sent_list_.FindBlockByPosition(position);
  DCHECK(data != NULL);
  size_t message_size = sizeof(Message) + data->size();
  size_t padded_size = (message_size + 15) & 0xfffffff0;

  scoped_refptr<IOBufferWithSize> message(new IOBufferWithSize(padded_size));
  Message* header = reinterpret_cast<Message*>(message->data());
  memset(header, 0, sizeof(Message));
  uint64 id = sent_list_.GetNewMessageId();
  uint32_pack(header->message_id, id);
  // TODO(mbelshe): Needs to carry EOF flags
  uint16_pack(header->size.val, data->size());
  uint64_pack(header->position, position);
  // TODO(mbelshe): Fill in rest of the header fields.
  //     needs to have the block-position.  He tags each chunk with an
  //     absolute offset into the data stream.
  // Copy the contents of the message into the Message frame.
  memcpy(message->data() + sizeof(Message), data->data(), data->size());

  sent_list_.MarkBlockSent(position, id);

  int rv = packetizer_->SendMessage(key_,
                                    message->data(),
                                    padded_size,
                                    &send_message_callback_);
  if (rv == ERR_IO_PENDING) {
    send_message_in_progress_ = true;
    return;
  }

  // UDP must write all or none.
  DCHECK_EQ(padded_size, static_cast<size_t>(rv));
  OnSendMessageComplete(rv);
}

void Messenger::RecvMessage() {
  if (!read_queue_.size())
    return;

  scoped_refptr<IOBufferWithSize> message(read_queue_.front());
  read_queue_.pop_front();

  Message* header = reinterpret_cast<Message*>(message->data());
  uint16 body_length = uint16_unpack(header->size.val);
  if (body_length < 0)
    return;
  if (body_length > kMaxMessageLength)
    return;
  if (body_length > message->size())
    return;

  uint32 message_id = uint32_unpack(header->message_id);
  if (message_id) {
    LOG(ERROR) << "RecvMessage Message id: " << message_id
               << ", " << body_length << " bytes";
  } else {
    LOG(ERROR) << "RecvMessage ACK ";
  }

  // See if this message has information for recomputing RTT.
  uint32 response_to_msg = uint32_unpack(header->last_message_received);
  base::TimeTicks last_sent_time = sent_list_.FindLastSendTime(response_to_msg);
  if (!last_sent_time.is_null()) {
    int rtt = (base::TimeTicks::Now() - last_sent_time).InMicroseconds();
    DCHECK_LE(0, rtt);
    LOG(ERROR) << "RTT was: " << rtt << "us";
    rtt_.OnMessage(rtt);
  }

  // Handle acknowledgements
  uint64 start_byte = 0;
  uint64 stop_byte = uint64_unpack(header->acknowledge_1);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_1);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_2);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_2);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_3);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_3);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_4);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_4);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_5);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_5);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_6);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  if (!header->is_ack()) {
    // Add to our received block list
    uint64 position = uint64_unpack(header->position);
    scoped_refptr<IOBuffer> buffer(new IOBuffer(body_length));
    memcpy(buffer->data(), message->data() + sizeof(Message), body_length);
    received_list_.AddBlock(position, buffer, body_length);

    SendAck(message_id);
  }

  // If we have data available, and a read is pending, notify the callback.
  if (received_list_.bytes_available() && receive_complete_callback_) {
    // Pass the data up to the caller.
    int bytes_read = InternalRead(pending_receive_, pending_receive_length_);
    CompletionCallback* callback = receive_complete_callback_;
    receive_complete_callback_ = NULL;
    callback->Run(bytes_read);
  }
}

void Messenger::SendAck(uint32 last_message_received) {
  scoped_refptr<IOBuffer> buffer(new IOBuffer(sizeof(Message)));
  memset(buffer->data(), 0, sizeof(Message));
  Message* message = reinterpret_cast<Message*>(buffer->data());
  uint32_pack(message->last_message_received, last_message_received);
  uint64_pack(message->acknowledge_1, received_list_.bytes_received());
  LOG(ERROR) << "SendAck " << received_list_.bytes_received();
  // TODO(mbelshe): fill in remainder of selective acknowledgements

  // TODO(mbelshe): Fix this - it is totally possible to have a send message
  //                in progress here...
  DCHECK(!send_message_in_progress_);

  int rv = packetizer_->SendMessage(key_,
                                    buffer->data(),
                                    sizeof(Message),
                                    &send_message_callback_);
  // TODO(mbelshe): Fix me!  Deal with the error cases
  DCHECK(rv == sizeof(Message));
}

}  // namespace net
<commit_msg>Remove unnecessary check which was invalid anyway.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/curvecp/messenger.h"

#include "base/logging.h"
#include "base/message_loop.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/curvecp/protocol.h"

// Basic protocol design:
//
// OnTimeout:    Called when the timeout timer pops.
//   - call SendMessage()
//   - call RecvMessage()
//
// OnSendTimer:  Called when the send-timer pops.
//   - call SendMessage()
//   - call RecvMessage()
//
// OnMessage:    Called when a message arrived from the packet layer
//   - add the message to the receive queue
//   - call RecvMessage()
//
// Write:        Called by application to write data to remote
//   - add the data to the send_buffer
//   - call SendMessage()
//
// SendMessage:  Called to Send a message to the remote
//   - msg = first message to retransmit where retransmit timer popped
//   - if msg == NULL
//   -   msg = create a new message from the send buffer
//   - if msg != NULL
//   -   send message to the packet layer
//   -   setTimer(OnSendTimer, send_rate);
//
// RecvMessage:  Called to process a Received message from the remote
//   - calculate RTT
//   - calculate Send Rate
//   - acknowledge data from received message
//   - resetTimeout
//      - timeout = now + rtt_timeout
//      - if currrent_timeout > timeout
//         setTimer(OnTimeout, timeout)

namespace net {

// Maximum number of write blocks.
static const size_t kMaxWriteQueueMessages = 128;

// Size of the send buffer.
static const size_t kSendBufferSize = (128 * 1024);
// Size of the receive buffer.
static const size_t kReceiveBufferSize = (128 * 1024);

Messenger::Messenger(Packetizer* packetizer)
    : packetizer_(packetizer),
      send_buffer_(kSendBufferSize),
      send_complete_callback_(NULL),
      receive_complete_callback_(NULL),
      pending_receive_length_(0),
      send_message_in_progress_(false),
      ALLOW_THIS_IN_INITIALIZER_LIST(
          send_message_callback_(this, &Messenger::OnSendMessageComplete)),
      ALLOW_THIS_IN_INITIALIZER_LIST(factory_(this)) {
}

Messenger::~Messenger() {
}

int Messenger::Read(IOBuffer* buf, int buf_len, CompletionCallback* callback) {
  DCHECK(CalledOnValidThread());
  DCHECK(!receive_complete_callback_);

  if (!received_list_.bytes_available()) {
    receive_complete_callback_ = callback;
    pending_receive_ = buf;
    pending_receive_length_ = buf_len;
    return ERR_IO_PENDING;
  }

  int bytes_read = InternalRead(buf, buf_len);
  DCHECK_LT(0, bytes_read);
  return bytes_read;
}

int Messenger::Write(IOBuffer* buf, int buf_len, CompletionCallback* callback) {
  DCHECK(CalledOnValidThread());
  DCHECK(!pending_send_.get());   // Already a write pending!
  DCHECK(!send_complete_callback_);
  DCHECK_LT(0, buf_len);

  int len = send_buffer_.write(buf->data(), buf_len);
  if (!send_timer_.IsRunning())
    send_timer_.Start(base::TimeDelta(), this, &Messenger::OnSendTimer);
  if (len)
    return len;

  // We couldn't add data to the send buffer, so block the application.
  pending_send_ = buf;
  pending_send_length_ = buf_len;
  send_complete_callback_ = callback;
  return ERR_IO_PENDING;
}

void Messenger::OnConnection(ConnectionKey key) {
  LOG(ERROR) << "Client Connect: " << key.ToString();
  key_ = key;
}

void Messenger::OnClose(Packetizer* packetizer, ConnectionKey key) {
  LOG(ERROR) << "Got Close!";
}

void Messenger::OnMessage(Packetizer* packetizer,
                          ConnectionKey key,
                          unsigned char* msg,
                          size_t length) {
  DCHECK(key == key_);

  // Do basic message sanity checking.
  if (length < sizeof(Message))
    return;
  if (length > static_cast<size_t>(kMaxMessageLength))
    return;

  // Add message to received queue.
  scoped_refptr<IOBufferWithSize> buffer(new IOBufferWithSize(length));
  memcpy(buffer->data(), msg, length);
  read_queue_.push_back(buffer);

  // Process a single received message
  RecvMessage();
}

int Messenger::InternalRead(IOBuffer* buffer, int buffer_length) {
  return received_list_.ReadBytes(buffer, buffer_length);
}

IOBufferWithSize* Messenger::CreateBufferFromSendQueue() {
  DCHECK_LT(0, send_buffer_.length());

  int length = std::min(packetizer_->max_message_payload(),
                        send_buffer_.length());
  IOBufferWithSize* rv = new IOBufferWithSize(length);
  int bytes = send_buffer_.read(rv->data(), length);
  DCHECK_EQ(bytes, length);

  // We consumed data, check to see if someone is waiting to write more data.
  if (send_complete_callback_) {
    DCHECK(pending_send_.get());

    int len = send_buffer_.write(pending_send_->data(), pending_send_length_);
    if (len) {
      pending_send_ = NULL;
      CompletionCallback* callback = send_complete_callback_;
      send_complete_callback_ = NULL;
      callback->Run(len);
    }
  }

  return rv;
}

void Messenger::OnSendMessageComplete(int result) {
  DCHECK_NE(ERR_IO_PENDING, result);

  send_message_in_progress_ = false;

  if (result <= 0) {
    // TODO(mbelshe):  Handle error.
    NOTIMPLEMENTED();
  }

  // If the send timer fired while we were waiting for this send to complete,
  // we need to manually run the timer now.
  if (!send_timer_.IsRunning())
    OnSendTimer();

  if (!send_timeout_timer_.IsRunning()) {
    LOG(ERROR) << "RttTimeout is " << rtt_.rtt_timeout();
    base::TimeDelta delay =
        base::TimeDelta::FromMicroseconds(rtt_.rtt_timeout());
    send_timeout_timer_.Start(delay, this, &Messenger::OnTimeout);
  }
}

void Messenger::OnTimeout() {
  LOG(ERROR) << "OnTimeout fired";
  int64 position = sent_list_.FindPositionOfOldestSentBlock();
  // XXXMB - need to verify that we really need to retransmit...
  if (position >= 0) {
    rtt_.OnTimeout();  // adjust our send rate.
    LOG(ERROR) << "OnTimeout retransmitting: " << position;
    SendMessage(position);
  } else {
    DCHECK_EQ(0u, sent_list_.size());
  }
  RecvMessage();
  received_list_.LogBlockList();
}

void Messenger::OnSendTimer() {
  LOG(ERROR) << "OnSendTimer!";
  DCHECK(!send_timer_.IsRunning());

  // If the send buffer is empty, then we don't need to keep firing.
  if (!send_buffer_.length()) {
    LOG(ERROR) << "OnSendTimer: send_buffer empty";
    return;
  }

  // Set the next send timer.
  LOG(ERROR) << "SendRate is: " << rtt_.send_rate() << "us";
  send_timer_.Start(base::TimeDelta::FromMicroseconds(rtt_.send_rate()),
                    this,
                    &Messenger::OnSendTimer);

  // Create a block from the send_buffer.
  if (!sent_list_.is_full()) {
    scoped_refptr<IOBufferWithSize> buffer = CreateBufferFromSendQueue();
    int64 position = sent_list_.CreateBlock(buffer.get());
    DCHECK_LE(0, position);
    SendMessage(position);
  }

  RecvMessage();  // Try to process an incoming message
}

void Messenger::SendMessage(int64 position) {
  LOG(ERROR) << "SendMessage (position=" << position << ")";
  if (send_message_in_progress_)
    return;  // We're still waiting for the last write to complete.

  IOBufferWithSize* data = sent_list_.FindBlockByPosition(position);
  DCHECK(data != NULL);
  size_t message_size = sizeof(Message) + data->size();
  size_t padded_size = (message_size + 15) & 0xfffffff0;

  scoped_refptr<IOBufferWithSize> message(new IOBufferWithSize(padded_size));
  Message* header = reinterpret_cast<Message*>(message->data());
  memset(header, 0, sizeof(Message));
  uint64 id = sent_list_.GetNewMessageId();
  uint32_pack(header->message_id, id);
  // TODO(mbelshe): Needs to carry EOF flags
  uint16_pack(header->size.val, data->size());
  uint64_pack(header->position, position);
  // TODO(mbelshe): Fill in rest of the header fields.
  //     needs to have the block-position.  He tags each chunk with an
  //     absolute offset into the data stream.
  // Copy the contents of the message into the Message frame.
  memcpy(message->data() + sizeof(Message), data->data(), data->size());

  sent_list_.MarkBlockSent(position, id);

  int rv = packetizer_->SendMessage(key_,
                                    message->data(),
                                    padded_size,
                                    &send_message_callback_);
  if (rv == ERR_IO_PENDING) {
    send_message_in_progress_ = true;
    return;
  }

  // UDP must write all or none.
  DCHECK_EQ(padded_size, static_cast<size_t>(rv));
  OnSendMessageComplete(rv);
}

void Messenger::RecvMessage() {
  if (!read_queue_.size())
    return;

  scoped_refptr<IOBufferWithSize> message(read_queue_.front());
  read_queue_.pop_front();

  Message* header = reinterpret_cast<Message*>(message->data());
  uint16 body_length = uint16_unpack(header->size.val);
  if (body_length > kMaxMessageLength)
    return;
  if (body_length > message->size())
    return;

  uint32 message_id = uint32_unpack(header->message_id);
  if (message_id) {
    LOG(ERROR) << "RecvMessage Message id: " << message_id
               << ", " << body_length << " bytes";
  } else {
    LOG(ERROR) << "RecvMessage ACK ";
  }

  // See if this message has information for recomputing RTT.
  uint32 response_to_msg = uint32_unpack(header->last_message_received);
  base::TimeTicks last_sent_time = sent_list_.FindLastSendTime(response_to_msg);
  if (!last_sent_time.is_null()) {
    int rtt = (base::TimeTicks::Now() - last_sent_time).InMicroseconds();
    DCHECK_LE(0, rtt);
    LOG(ERROR) << "RTT was: " << rtt << "us";
    rtt_.OnMessage(rtt);
  }

  // Handle acknowledgements
  uint64 start_byte = 0;
  uint64 stop_byte = uint64_unpack(header->acknowledge_1);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_1);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_2);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_2);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_3);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_3);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_4);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_4);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_5);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  start_byte = stop_byte + uint16_unpack(header->gap_5);
  stop_byte = start_byte + uint16_unpack(header->acknowledge_6);
  sent_list_.AcknowledgeBlocks(start_byte, stop_byte);

  if (!header->is_ack()) {
    // Add to our received block list
    uint64 position = uint64_unpack(header->position);
    scoped_refptr<IOBuffer> buffer(new IOBuffer(body_length));
    memcpy(buffer->data(), message->data() + sizeof(Message), body_length);
    received_list_.AddBlock(position, buffer, body_length);

    SendAck(message_id);
  }

  // If we have data available, and a read is pending, notify the callback.
  if (received_list_.bytes_available() && receive_complete_callback_) {
    // Pass the data up to the caller.
    int bytes_read = InternalRead(pending_receive_, pending_receive_length_);
    CompletionCallback* callback = receive_complete_callback_;
    receive_complete_callback_ = NULL;
    callback->Run(bytes_read);
  }
}

void Messenger::SendAck(uint32 last_message_received) {
  scoped_refptr<IOBuffer> buffer(new IOBuffer(sizeof(Message)));
  memset(buffer->data(), 0, sizeof(Message));
  Message* message = reinterpret_cast<Message*>(buffer->data());
  uint32_pack(message->last_message_received, last_message_received);
  uint64_pack(message->acknowledge_1, received_list_.bytes_received());
  LOG(ERROR) << "SendAck " << received_list_.bytes_received();
  // TODO(mbelshe): fill in remainder of selective acknowledgements

  // TODO(mbelshe): Fix this - it is totally possible to have a send message
  //                in progress here...
  DCHECK(!send_message_in_progress_);

  int rv = packetizer_->SendMessage(key_,
                                    buffer->data(),
                                    sizeof(Message),
                                    &send_message_callback_);
  // TODO(mbelshe): Fix me!  Deal with the error cases
  DCHECK(rv == sizeof(Message));
}

}  // namespace net
<|endoftext|>


<commit_before><commit_msg>Make SpdySession::GetSSLInfo work when the SpdySession is constructed using SpdySession::InitializeWithSocket.  The is_secure_ member needs to be set to true.<commit_after><|endoftext|>


<commit_before>#include "Vajra/Engine/Components/DerivedComponents/Camera/Camera.h"
#include "Vajra/Engine/Components/DerivedComponents/Transform/Transform.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/GameObject/GameObject.h"
#include "Vajra/Engine/Lighting/ShadowMap.h"
#include "Vajra/Engine/RenderScene/RenderScene.h"
#include "Vajra/Engine/SceneGraph/RenderLists.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Framework/DeviceUtils/DeviceProperties/DeviceProperties.h"
#include "Vajra/Utilities/OpenGLIncludes.h"

static GLuint g_depth_fbo_id;

#ifdef PLATFORM_IOS
static GLint g_default_fbo;
#define SCREEN_FRAME_BUFFER g_default_fbo
#else
#define SCREEN_FRAME_BUFFER 0
#endif

#ifdef PLATFORM_IOS
#define MULTISAMPLING_ENABLED 1
#else
#define MULTISAMPLING_ENABLED 0
#endif

#if MULTISAMPLING_ENABLED
//Buffer definitions for the MSAA
GLuint msaaFramebuffer,
	   msaaRenderBuffer,
	   msaaDepthBuffer;
#endif
GLuint renderBuffer;

void RenderScene::SetupStuff() {

    GLCALL(glEnable, GL_DEPTH_TEST);

#ifdef PLATFORM_IOS
	GLCALL(glGetIntegerv, GL_FRAMEBUFFER_BINDING, &g_default_fbo);
#endif

	// Create a frame buffer object:
	GLCALL(glGenFramebuffers, 1, &g_depth_fbo_id);
	GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, g_depth_fbo_id);

	// Create a render buffer
    GLCALL(glGenRenderbuffers, 1, &renderBuffer);
    GLCALL(glBindRenderbuffer, GL_RENDERBUFFER, renderBuffer);

    unsigned int depthMap_width, depthMap_height;
    ENGINE->GetShadowMap()->GetDepthMapResolution(depthMap_width, depthMap_height);

	// Create a depth texture:
    GLCALL(glGenTextures, 1, &ENGINE->GetShadowMap()->depthTexture);
	GLCALL(glActiveTexture, GL_TEXTURE2);
    GLCALL(glBindTexture, GL_TEXTURE_2D, ENGINE->GetShadowMap()->depthTexture);
    GLCALL(glTexImage2D, GL_TEXTURE_2D, 0, GL_RGBA, depthMap_width, depthMap_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    //
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE);
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE);

	GLCALL(glFramebufferTexture2D, GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ENGINE->GetShadowMap()->depthTexture, 0);

	// Allocate 16-bit depth buffer
	GLCALL(glRenderbufferStorage, GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, depthMap_width, depthMap_height);

	// Attach the render buffer as depth buffer - will be ignored
	GLCALL(glFramebufferRenderbuffer, GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);

	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {	// GLCALL
		ASSERT(0, "Framebuffer OK");
	}

#if MULTISAMPLING_ENABLED
	//Generate our MSAA Frame and Render buffers
	glGenFramebuffers(1, &msaaFramebuffer);
	glGenRenderbuffers(1, &msaaRenderBuffer);

	//Bind our MSAA buffers
	glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
	glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderBuffer);

	unsigned int numSamples = 4;

	// Generate the msaaDepthBuffer.
	// numSamples will be the number of pixels that the MSAA buffer will use in order to make one pixel on the render buffer.
	glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, numSamples, GL_RGB5_A1, FRAMEWORK->GetDeviceProperties()->GetWidthPixels(), FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaRenderBuffer);
	glGenRenderbuffers(1, &msaaDepthBuffer);

	//Bind the msaa depth buffer.
	glBindRenderbuffer(GL_RENDERBUFFER, msaaDepthBuffer);
	glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, numSamples, GL_DEPTH_COMPONENT16, FRAMEWORK->GetDeviceProperties()->GetWidthPixels() , FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, msaaDepthBuffer);
#endif
}

void RenderScene::CleanupStuff() {

	// TODO [Implement] Call this from somewhere:
	// Free up the frame buffer object:
	GLCALL(glDeleteFramebuffers, 1, &g_depth_fbo_id);
}

void RenderScene::RenderScene(RenderLists* renderLists, Camera* camera) {

#ifdef PLATFORM_IOS
	GLCALL(glGetIntegerv, GL_FRAMEBUFFER_BINDING, &g_default_fbo);
#endif

	GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, SCREEN_FRAME_BUFFER /* default window framebuffer */);
	renderLists->Draw(camera, false, DISTANCE_FROM_CAMERA_COMPARE_TYPE_ortho_z);
}

void RenderScene::RenderScene(RenderLists* renderLists, Camera* camera,
							  DirectionalLight* directionalLight,
							  std::vector<DirectionalLight*> additionalLights) {

#ifdef PLATFORM_IOS
	GLCALL(glGetIntegerv, GL_FRAMEBUFFER_BINDING, &g_default_fbo);
#endif

	std::vector<DirectionalLight*> emptyVector;

	{
		// Switch off blend for depth pass:
    	GLCALL(glDisable, GL_BLEND);

		Camera* depthCamera = ENGINE->GetShadowMap()->GetDepthCamera();
#if defined(DRAWING_DEPTH_BUFFER_CONTENTS)
    	GLCALL(glViewport, 0, 0, FRAMEWORK->GetDeviceProperties()->GetWidthPixels(), FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
		GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, SCREEN_FRAME_BUFFER /* default window framebuffer */);
#else

		/*
	 	 * Draw to the depth buffer:
	 	 */
		unsigned int depthMap_width, depthMap_height;
		ENGINE->GetShadowMap()->GetDepthMapResolution(depthMap_width, depthMap_height);
		//
		GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, g_depth_fbo_id);
    	GLCALL(glViewport, 0, 0, depthMap_width, depthMap_height);
		GLCALL(glClear, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif
		// Depth pass draw:
		ENGINE->GetSceneGraph3D()->SetMainCameraId(depthCamera->GetObject()->GetId());
		renderLists->Draw(depthCamera, nullptr /* no lights in depth pass */, emptyVector /* no lights in depth pass */, true, DISTANCE_FROM_CAMERA_COMPARE_TYPE_perspective);

		// Switch blend back on:
    	GLCALL(glEnable, GL_BLEND);
	}

#if MULTISAMPLING_ENABLED
	glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif

	{
#if !defined(DRAWING_DEPTH_BUFFER_CONTENTS)
		/*
	 	 * Draw again, this time to the screen:
	 	 */
		ENGINE->GetSceneGraph3D()->SetMainCameraId(camera->GetObject()->GetId());
#if !MULTISAMPLING_ENABLED
		GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, SCREEN_FRAME_BUFFER /* default window framebuffer */);
#endif
    	GLCALL(glViewport, 0, 0, FRAMEWORK->GetDeviceProperties()->GetWidthPixels(), FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
		renderLists->Draw(camera, directionalLight, additionalLights, false, DISTANCE_FROM_CAMERA_COMPARE_TYPE_perspective);
#endif
	}

#if MULTISAMPLING_ENABLED
	// Apple (and the khronos group) encourages you to discard depth
    // render buffer contents whenever is possible
    // GLenum attachments[] = {GL_DEPTH_ATTACHMENT};
    // glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 1, attachments);

    //Bind both MSAA and View FrameBuffers.
    glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, msaaFramebuffer);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, SCREEN_FRAME_BUFFER);

    // Call a resolve to combine both buffers
    glResolveMultisampleFramebufferAPPLE();

    // Present final image to screen
    glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
    // [context presentRenderbuffer:GL_RENDERBUFFER];
#endif

}
<commit_msg>Discard framebuffer attachments when they are not needed.<commit_after>#include "Vajra/Engine/Components/DerivedComponents/Camera/Camera.h"
#include "Vajra/Engine/Components/DerivedComponents/Transform/Transform.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/GameObject/GameObject.h"
#include "Vajra/Engine/Lighting/ShadowMap.h"
#include "Vajra/Engine/RenderScene/RenderScene.h"
#include "Vajra/Engine/SceneGraph/RenderLists.h"
#include "Vajra/Engine/SceneGraph/SceneGraph3D.h"
#include "Vajra/Framework/DeviceUtils/DeviceProperties/DeviceProperties.h"
#include "Vajra/Utilities/OpenGLIncludes.h"

static GLuint g_depth_fbo_id;

#ifdef PLATFORM_IOS
static GLint g_default_fbo;
#define SCREEN_FRAME_BUFFER g_default_fbo
#else
#define SCREEN_FRAME_BUFFER 0
#endif

#ifdef PLATFORM_IOS
#define MULTISAMPLING_ENABLED 1
#else
#define MULTISAMPLING_ENABLED 0
#endif

#if MULTISAMPLING_ENABLED
//Buffer definitions for the MSAA
GLuint msaaFramebuffer,
	   msaaRenderBuffer,
	   msaaDepthBuffer;
#endif
GLuint renderBuffer;

void RenderScene::SetupStuff() {

    GLCALL(glEnable, GL_DEPTH_TEST);

#ifdef PLATFORM_IOS
	GLCALL(glGetIntegerv, GL_FRAMEBUFFER_BINDING, &g_default_fbo);
#endif

	// Create a frame buffer object:
	GLCALL(glGenFramebuffers, 1, &g_depth_fbo_id);
	GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, g_depth_fbo_id);

	// Create a render buffer
    GLCALL(glGenRenderbuffers, 1, &renderBuffer);
    GLCALL(glBindRenderbuffer, GL_RENDERBUFFER, renderBuffer);

    unsigned int depthMap_width, depthMap_height;
    ENGINE->GetShadowMap()->GetDepthMapResolution(depthMap_width, depthMap_height);

	// Create a depth texture:
    GLCALL(glGenTextures, 1, &ENGINE->GetShadowMap()->depthTexture);
	GLCALL(glActiveTexture, GL_TEXTURE2);
    GLCALL(glBindTexture, GL_TEXTURE_2D, ENGINE->GetShadowMap()->depthTexture);
    GLCALL(glTexImage2D, GL_TEXTURE_2D, 0, GL_RGBA, depthMap_width, depthMap_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    //
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE);
    GLCALL(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE);

	GLCALL(glFramebufferTexture2D, GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ENGINE->GetShadowMap()->depthTexture, 0);

	// Allocate 16-bit depth buffer
	GLCALL(glRenderbufferStorage, GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, depthMap_width, depthMap_height);

	// Attach the render buffer as depth buffer - will be ignored
	GLCALL(glFramebufferRenderbuffer, GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);

	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {	// GLCALL
		ASSERT(0, "Framebuffer OK");
	}

#if MULTISAMPLING_ENABLED
	//Generate our MSAA Frame and Render buffers
	glGenFramebuffers(1, &msaaFramebuffer);
	glGenRenderbuffers(1, &msaaRenderBuffer);

	//Bind our MSAA buffers
	glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
	glBindRenderbuffer(GL_RENDERBUFFER, msaaRenderBuffer);

	unsigned int numSamples = 4;

	// Generate the msaaDepthBuffer.
	// numSamples will be the number of pixels that the MSAA buffer will use in order to make one pixel on the render buffer.
	glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, numSamples, GL_RGB5_A1, FRAMEWORK->GetDeviceProperties()->GetWidthPixels(), FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaRenderBuffer);
	glGenRenderbuffers(1, &msaaDepthBuffer);

	//Bind the msaa depth buffer.
	glBindRenderbuffer(GL_RENDERBUFFER, msaaDepthBuffer);
	glRenderbufferStorageMultisampleAPPLE(GL_RENDERBUFFER, numSamples, GL_DEPTH_COMPONENT16, FRAMEWORK->GetDeviceProperties()->GetWidthPixels() , FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
	glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, msaaDepthBuffer);
#endif
}

void RenderScene::CleanupStuff() {

	// TODO [Implement] Call this from somewhere:
	// Free up the frame buffer object:
	GLCALL(glDeleteFramebuffers, 1, &g_depth_fbo_id);
}

void RenderScene::RenderScene(RenderLists* renderLists, Camera* camera) {

#ifdef PLATFORM_IOS
	GLCALL(glGetIntegerv, GL_FRAMEBUFFER_BINDING, &g_default_fbo);
#endif

	GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, SCREEN_FRAME_BUFFER /* default window framebuffer */);
	renderLists->Draw(camera, false, DISTANCE_FROM_CAMERA_COMPARE_TYPE_ortho_z);
}

void RenderScene::RenderScene(RenderLists* renderLists, Camera* camera,
							  DirectionalLight* directionalLight,
							  std::vector<DirectionalLight*> additionalLights) {

#ifdef PLATFORM_IOS
	GLCALL(glGetIntegerv, GL_FRAMEBUFFER_BINDING, &g_default_fbo);
#endif

	std::vector<DirectionalLight*> emptyVector;

	{
		// Switch off blend for depth pass:
    	GLCALL(glDisable, GL_BLEND);

		Camera* depthCamera = ENGINE->GetShadowMap()->GetDepthCamera();
#if defined(DRAWING_DEPTH_BUFFER_CONTENTS)
    	GLCALL(glViewport, 0, 0, FRAMEWORK->GetDeviceProperties()->GetWidthPixels(), FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
		GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, SCREEN_FRAME_BUFFER /* default window framebuffer */);
#else

		/*
	 	 * Draw to the depth buffer:
	 	 */
		unsigned int depthMap_width, depthMap_height;
		ENGINE->GetShadowMap()->GetDepthMapResolution(depthMap_width, depthMap_height);
		//
		GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, g_depth_fbo_id);
    	GLCALL(glViewport, 0, 0, depthMap_width, depthMap_height);
		GLCALL(glClear, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif
		// Depth pass draw:
		ENGINE->GetSceneGraph3D()->SetMainCameraId(depthCamera->GetObject()->GetId());
		renderLists->Draw(depthCamera, nullptr /* no lights in depth pass */, emptyVector /* no lights in depth pass */, true, DISTANCE_FROM_CAMERA_COMPARE_TYPE_perspective);

		// Switch blend back on:
    	GLCALL(glEnable, GL_BLEND);
	}

#if MULTISAMPLING_ENABLED
	glBindFramebuffer(GL_FRAMEBUFFER, msaaFramebuffer);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#endif

	{
#if !defined(DRAWING_DEPTH_BUFFER_CONTENTS)
		/*
	 	 * Draw again, this time to the screen:
	 	 */
		ENGINE->GetSceneGraph3D()->SetMainCameraId(camera->GetObject()->GetId());
#if !MULTISAMPLING_ENABLED
		GLCALL(glBindFramebuffer, GL_FRAMEBUFFER, SCREEN_FRAME_BUFFER /* default window framebuffer */);
#endif
    	GLCALL(glViewport, 0, 0, FRAMEWORK->GetDeviceProperties()->GetWidthPixels(), FRAMEWORK->GetDeviceProperties()->GetHeightPixels());
		renderLists->Draw(camera, directionalLight, additionalLights, false, DISTANCE_FROM_CAMERA_COMPARE_TYPE_perspective);
#endif
	}

#if MULTISAMPLING_ENABLED
	// Apple (and the khronos group) encourages you to discard depth
    // render buffer contents whenever is possible
	const GLenum discard1[]  = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT};
	glDiscardFramebufferEXT(GL_READ_FRAMEBUFFER_APPLE, 2, discard1);
	const GLenum discard2[]  = {GL_DEPTH_ATTACHMENT};
	glDiscardFramebufferEXT(GL_DRAW_FRAMEBUFFER_APPLE, 1, discard2);

    //Bind both MSAA and View FrameBuffers.
    glBindFramebuffer(GL_READ_FRAMEBUFFER_APPLE, msaaFramebuffer);
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER_APPLE, SCREEN_FRAME_BUFFER);

    // Call a resolve to combine both buffers
    glResolveMultisampleFramebufferAPPLE();

    // Present final image to screen
    glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
    // [context presentRenderbuffer:GL_RENDERBUFFER];
#endif

}
<|endoftext|>