예제 #1
0
void scContUnit::Iter( SubstituteFunc	func,
					   long				startLocation,
					   long&			limitOffset )
{
	UCS2			chBuf[64];
	UCS2*			chP;
	CharRecordP		startChRec;
	scSpecRecord*	specRec;
	long			startOffset,
					endOffset,
					wordLen;
	
	LockMem( startChRec, specRec );
	
	startOffset = startLocation;
	endOffset 	= startOffset;
	
	for ( ; endOffset < limitOffset; ) {
		startOffset = TXTStartSelectableWord( startChRec, endOffset );
		endOffset 	= TXTEndSelectableWord( startChRec, endOffset );
		wordLen = endOffset - startOffset;
		
		if ( wordLen > 1 ) {
			BuildTestWord( chBuf, startChRec + startOffset, wordLen );
			status stat = (*func)( &chP, chBuf, NULL );
			
			if ( stat == scSuccess || stat == scUserAbort ) {
				if ( !ReplaceWord( startChRec, specRec, startOffset, endOffset,
								   limitOffset, chBuf, chP ) ) {
						UnlockMem( );
						return;
				}
				
				fCharArray.RepairText( fSpecRun, startOffset, endOffset );
				Mark( scREBREAK );
				
				if ( stat == scUserAbort )
					goto exit;
			}
		}
		endOffset = FindNextSpellingWord( startChRec, endOffset, limitOffset );
	}

exit:
	UnlockMem( );
}
예제 #2
0
파일: garbage.C 프로젝트: bmajoros/Epsilon
void GarbageCollector::PerformGC(RunTimeStack &s)
	{
	// Perform mark-and-sweep garbage collection.  We
	// follow every pointer in every activation record
	// in the RunTimeStack, marking all Objects found.
	// Before marking an Object, we make sure it is not
	// already marked, so we don't enter an infinite loop.

	// Then we sweep once through the ObjectList.  For
	// each Object in the ObjectList, if it is not marked,
	// we remove it from the list and delete it; otherwise,
	// we unmark it so it is ready for the next round of
	// mark-and-sweep.

	Mark(s);
	Sweep(s);
	}
예제 #3
0
ColorMenu::ColorMenu (const char *name, BView *_view, int h, int v, float s)
: BMenu (name, h*s, v*s)
{
	index = 0;
	for (int i = 0; i < v; i++)
		for (int j = 0; j < h; j++)
		{
			BRect cframe = BRect (j*s, i*s, (j + 1)*s, (i + 1)*s);
			AddItem (new ColorItem (system_colors()->color_list[index]), cframe);
		}
	Mark (0);
	view = _view;
	hs = h*s;
	vs = v*s;
	parent = NULL;
	fWindow = NULL;
}
예제 #4
0
//*****************************************************************************
// cascading Mark of a CustomAttribute
//*****************************************************************************
HRESULT FilterManager::MarkCustomAttribute(mdCustomAttribute cv)
{
    HRESULT     hr = NOERROR;
    CustomAttributeRec *pRec;

    // We know that the filter table is not null here.  Tell PREFIX that we know it.
    PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL);

    IfFailGo( m_pMiniMd->GetFilterTable()->MarkCustomAttribute( cv ) );

    // Mark the type (and any family) of the CustomAttribue.
    IfFailGo(m_pMiniMd->GetCustomAttributeRecord(RidFromToken(cv), &pRec));
    IfFailGo( Mark(m_pMiniMd->getTypeOfCustomAttribute(pRec)) );

ErrExit:
    return hr;
} // HRESULT FilterManager::MarkCustomAttribute()
예제 #5
0
void
assignAttVar(Word av, Word value, int flags ARG_LD)
{ Word a;
  mark m;

  assert(isAttVar(*av));
  assert(!isRef(*value));
  assert(gTop+8 <= gMax && tTop+6 <= tMax);
  DEBUG(CHK_SECURE, assert(on_attvar_chain(av)));

  DEBUG(1, Sdprintf("assignAttVar(%s)\n", vName(av)));

  if ( isAttVar(*value) )
  { if ( value > av )
    { Word tmp = av;
      av = value;
      value = tmp;
    } else if ( av == value )
      return;
  }

  if( !(flags & ATT_ASSIGNONLY) )
  { a = valPAttVar(*av);
    registerWakeup(av, a, value PASS_LD);
  }

  if ( (flags&ATT_WAKEBINDS) )
    return;

  Mark(m);		/* must be trailed, even if above last choice */
  LD->mark_bar = NO_MARK_BAR;
  TrailAssignment(av);
  DiscardMark(m);

  if ( isAttVar(*value) )
  { DEBUG(1, Sdprintf("Unifying two attvars\n"));
    *av = makeRef(value);
  } else if ( isVar(*value) )
  { DEBUG(1, Sdprintf("Assigning attvar with plain var\n"));
    *av = makeRef(value);			/* JW: Does this happen? */
  } else
    *av = *value;

  return;
}
예제 #6
0
파일: list.cpp 프로젝트: HonzaMD/Krkal2
int CGUIListItem::MouseLeft(float x, float y, UINT mouseState, UINT keyState)
{		// kliknuti levym tlacitkem (mouseState 0 = pusteni, 1 = stisknuti cudlitka)

	if(mouseState)
	{
		if(listBox->markListItem==this)
		{
			OnClick();
			EventArise(EClicked);
		}
		else
		{
			Mark();
		}
	}

	return 0;
}
예제 #7
0
void Registry::GarbageCollect()
{
	// unmark all objects
	MarkAll(false);

	// mark everything that is reachable from the root
	Mark(root, true);

	// everything that is not now marked is not reachable and can be deleted
	deathrow.clear();
	foreach (Instances::value_type const &val, instances)
	{
		StorageBase const *base = val.second;
		if (!base->IsMarked())
		{
			//OM_TRACE_1(4, base->GetHandle().value) << " adding to deathrow";
			deathrow.push_back(base->GetHandle());
		}
	}
예제 #8
0
void CProductCheckListBoxItem::UpdateProductItem(void)
{
	if (Mark())
	{
		m_pItem->SetFlag(PRODUCT_ITEM_Marked);
	}
	else
	{
		m_pItem->ClearFlag(PRODUCT_ITEM_Marked);
	}
	
	if (Select())
	{
		m_pItem->SetFlag(PRODUCT_ITEM_Selected);
	}
	else
	{
		m_pItem->ClearFlag(PRODUCT_ITEM_Selected);
	}
}
예제 #9
0
/* ==================================================================== */
void scTextline::MarkForDeletion( void )
{
	scXRect xrect = QueryExtents( xrect, 1 );
	
	if ( fPara && fPara->GetFirstline() == this )
		fPara->SetFirstline( 0 );

		// de-normalize extents
	if ( fColumn->GetFlowdir().IsVertical() )
		xrect.Translate( fVJOffset, 0 );	
	else								
		xrect.Translate( 0, -fVJOffset );
	
	fInkExtents 	= xrect;
	fPara			= 0; 
	fLineCount		= -1;
	fStartOffset	= -1;
	fEndOffset		= -1;
	Mark( scINVALID );
}	
예제 #10
0
static void
find_levels_r(struct block *b)
{
	int level;

	if (isMarked(b))
		return;

	Mark(b);
	b->link = 0;

	if (JT(b)) {
		find_levels_r(JT(b));
		find_levels_r(JF(b));
		level = MAX(JT(b)->level, JF(b)->level) + 1;
	} else
		level = 0;
	b->level = level;
	b->link = levels[level];
	levels[level] = b;
}
예제 #11
0
//*****************************************************************************
// cascading Mark of all GenericPar associated with a TypeDef or MethodDef token
//*****************************************************************************
HRESULT FilterManager::MarkGenericParamWithParentToken(
    mdToken     tk)
{
    HRESULT     hr = NOERROR;
    RID         ulStart, ulEnd;
    RID         index;
    GenericParamRec *pGenericParamRec;
    mdToken     constraint;
    HENUMInternal hEnum;                // To enumerate constraints.

    // Enumerate the GenericPar
    //@todo: Handle the unsorted case.
    IfFailGo( m_pMiniMd->GetGenericParamsForToken(tk, &ulStart, &ulEnd) );

    for (; ulStart < ulEnd; ++ulStart)
    {
        index = m_pMiniMd->GetGenericParamRid(ulStart);
        IfFailGo(m_pMiniMd->GetGenericParamRecord(index, &pGenericParamRec));

        RID ridConstraint;
        IfFailGo( m_pMiniMd->FindGenericParamConstraintHelper(TokenFromRid(ulStart, mdtGenericParam), &hEnum) );
        while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &ridConstraint))
        {
            // Get the constraint.
            GenericParamConstraintRec *pRec;
            IfFailGo(m_pMiniMd->GetGenericParamConstraintRecord(RidFromToken(ridConstraint), &pRec));
            constraint = m_pMiniMd->getConstraintOfGenericParamConstraint(pRec);

            // Mark it.
            IfFailGo( Mark(constraint) );
        }
        HENUMInternal::ClearEnum(&hEnum);
    }

ErrExit:
    HENUMInternal::ClearEnum(&hEnum);

    return hr;
} // HRESULT FilterManager::MarkGenericParamWithParentToken()
예제 #12
0
//*****************************************************************************
// cascading Mark of an TypeDef token
//*****************************************************************************
HRESULT FilterManager::MarkInterfaceImpls(
    mdTypeDef   td)
{
    HRESULT         hr = NOERROR;
    ULONG           ridStart, ridEnd;
    ULONG           i;
    InterfaceImplRec *pRec;
    
    // We know that the filter table is not null here.  Tell PREFIX that we know it.
    PREFIX_ASSUME(m_pMiniMd->GetFilterTable() != NULL);

    if ( m_pMiniMd->IsSorted(TBL_InterfaceImpl) )
    {
        IfFailGo(m_pMiniMd->getInterfaceImplsForTypeDef(RidFromToken(td), &ridEnd, &ridStart));
    }
    else
    {
        ridStart = 1;
        ridEnd = m_pMiniMd->getCountInterfaceImpls() + 1;
    }

    // Search for the interfaceimpl with the parent of td
    for (i = ridStart; i < ridEnd; i++)
    {
        IfFailGo(m_pMiniMd->GetInterfaceImplRecord(i, &pRec));
        if ( td != m_pMiniMd->getClassOfInterfaceImpl(pRec) )
            continue;

        // found an InterfaceImpl associate with td. Mark the interface row and the interfaceimpl type
        IfFailGo( m_pMiniMd->GetFilterTable()->MarkInterfaceImpl(TokenFromRid(i, mdtInterfaceImpl)) );
        IfFailGo( MarkCustomAttributesWithParentToken(TokenFromRid(i, mdtInterfaceImpl)) );
        // IfFailGo( MarkDeclSecuritiesWithParentToken(TokenFromRid(i, mdtInterfaceImpl)) );
        IfFailGo( Mark(m_pMiniMd->getInterfaceOfInterfaceImpl(pRec)) );
    }
ErrExit:
    return hr;
} // HRESULT FilterManager::MarkInterfaceImpls()
예제 #13
0
void scContUnit::ApplyAnnotation( long			start,
								  long			end,
								  const scAnnotation&	annot )
{
	eChTranType	chTranType	= eNormalTran;
	
	if ( !fRubiArray ) {
		AllocRubiArray();
	}
	else if ( fRubiArray->IsRubiData( start, end ) ) {
		int			nth;
		int			index;
		scRubiData	rd;	
		
		fCharArray.Transform( start, end, eRemoveJapTran, end - start );
		for ( nth = 1; fRubiArray->GetNthRubi( index, rd, nth, start, end );  )
			fRubiArray->RemoveDataAt( index );
	}
	
	if ( annot.fAnnotate ) {
		scRubiData rd( annot.fCharStr, start, end, SpecAtOffset( start + 1 ) );
	
		fRubiArray->AddRubiData( rd );
		
		chTranType = eRubiTran;
	}
	else {
			// i should have already removed any annotations
		if ( fRubiArray->GetNumItems() == 0 )
			DeleteRubiArray();
		chTranType = eRemoveJapTran;
	}
	Mark( scREBREAK );
	ForceRepaint( start, end );	
	fCharArray.Transform( start, end, chTranType, end - start );
}
예제 #14
0
void StencilComp::Write (ostream& out) {
    GraphicComp::Write(out);
    UStencil* stencil = GetStencil();
    Bitmap* image, *mask;
    stencil->GetOriginal(image, mask);

    WriteBitmap(image, out);
    Mark(out);

    if (mask == nil) {
        out << no_mask;
    } else if (mask == image) {
        out << mask_equals_image;
    } else {
        out << valid_mask;
        WriteBitmap(mask, out);
    }

    WriteBgFilled(stencil->BgFilled(), out);
    WriteColor(stencil->GetFgColor(), out);
    WriteColor(stencil->GetBgColor(), out);
    WriteTransformer(stencil->GetTransformer(), out);
    WriteString(_filename, out);
}
예제 #15
0
list<class Mark> Mark::RewriteWithSimpleTokens () {
  list<Mark> ret;
  // example : <{1,2},{a,b,c},{x}> -> <{2},{c},{x}> + <{2},{b},{x}> + <{2},{a},{x}> +  <{1},{c},{x}> + <{1},{b},{x}> + <{1},{a},{x}> 
  
  list<pair <int,int> > pos;
  for (list<vector<Element> >::iterator it = elts.begin() ; it != elts.end() ; it++) {
    pos.push_back( make_pair(0,it->size()) ); 
  }  
  
  list< pair<int,int> >::iterator pit;
  list<vector<Element> >::iterator cit;
  do {
    list<vector<Element> > forret;
    
    for (pit = pos.begin(),cit = elts.begin() ; pit != pos.end() ;pit++,cit++) {
      forret.push_back(vector<Element> (1,(*cit)[pit->first]));
    }
    ret.push_back ( Mark(dom,forret,mult));
  } while (! calcSub::next(pos) );

  
  return ret;

}
예제 #16
0
파일: skins.c 프로젝트: Moorviper/zen2vdr
cSkinDisplayReplay::cProgressBar::cProgressBar(int Width, int Height, int Current, int Total, const cMarks *Marks, tColor ColorSeen, tColor ColorRest, tColor ColorSelected, tColor ColorMark, tColor ColorCurrent)
:cBitmap(Width, Height, 2)
{
  total = Total;
  if (total > 0) {
     int p = Pos(Current);
     DrawRectangle(0, 0, p, Height - 1, ColorSeen);
     DrawRectangle(p + 1, 0, Width - 1, Height - 1, ColorRest);
     if (Marks) {
        bool Start = true;
        for (const cMark *m = Marks->First(); m; m = Marks->Next(m)) {
            int p1 = Pos(m->position);
            if (Start) {
               const cMark *m2 = Marks->Next(m);
               int p2 = Pos(m2 ? m2->position : total);
               int h = Height / 3;
               DrawRectangle(p1, h, p2, Height - h, ColorSelected);
               }
            Mark(p1, Start, m->position == Current, ColorMark, ColorCurrent);
            Start = !Start;
            }
        }
     }
}
예제 #17
0
void scContUnit::CharInsert( long		computedOffset,
							 long&		offset,
							 scKeyRecord&	keyRec,
							 long&		tmMove,
							 short& 	rebreak,
							 Bool		textCleared,
							 TypeSpec	clearedSpec )
{
#if SCDEBUG > 1
	{
		static int doit;
		if ( doit )
			fSpecRun.PrintRun( "scContUnit::CharInsert" );
	}
#endif

#ifdef _RUBI_SUPPORT
	if ( fRubiArray ) {
		if ( fRubiArray->IsRubiData( offset + computedOffset ) ) {
			scRubiData rd;
			fRubiArray->GetRubiAt( rd, offset + computedOffset );
			fCharArray.Transform( rd.fStartOffset, rd.fEndOffset, eRemoveJapTran, 0 );

			fRubiArray->DeleteRubiData( offset );
			if ( !fRubiArray->GetNumItems() )
				DeleteRubiArray();
		}
	}
#endif

	if ( computedOffset >= 0 )
		fCharArray.SetNumSlots( fCharArray.GetNumItems() + 1 );
	
	fCharArray.CharInsert( tmMove, 
						   fSpecRun, 
#ifdef _RUBI_SUPPORT
						   fRubiArray,
#endif
						   offset, 
						   keyRec, 
						   textCleared,
						   clearedSpec );

	fSpecRun.SetContentSize( GetContentSize() );

#if SCDEBUG > 1
	{
		static int doit;
		if ( doit )
			fSpecRun.PrintRun( "void scContUnit::CharInsert 2" );
	}
#endif
			
	scTextline* txl = FindLine( offset );
	if ( txl )
		txl->Mark( scREPAINT ); /* force repaint */

	Mark( scREBREAK );

	rebreak = true;
}
예제 #18
0
void scContUnit::ReadAPPText( stTextImportExport& appText )
{
	fCharArray.ReadAPPText( fSpecRun, appText );
	Mark( scRETABULATE );
}
예제 #19
0
Bool scContUnit::ClearText( long		offset1,
							long		offset2 )
{
	scTextline* txl;
	Bool		entireParaDeleted = false;

	offset1 = MAX( MIN( offset1, GetContentSize() ), 0 );
	offset2 = MIN( MAX( offset2, 0 ), GetContentSize() );

	if ( offset1 == 0 && offset2 == GetContentSize() )
		entireParaDeleted = true;

	if ( entireParaDeleted ) {
		GetCharArray().RemoveBetweenOffsets( offset1, offset2 );
		fSpecRun.SetContentSize( 0 );
		
#ifdef _RUBI_SUPPORT
		DeleteRubiArray();
#endif
	}
	else {
		GetCharArray().RemoveBetweenOffsets( offset1, offset2 );
		fSpecRun.Clear( offset1, offset2 );
		GetCharArray().RepairText( fSpecRun, offset1, offset1 );
		
#ifdef _RUBI_SUPPORT
		if ( GetRubiArray() ) {
			GetRubiArray()->DeleteRubiData( offset1, offset2 );
			if ( !GetRubiArray()->GetNumItems() )
				DeleteRubiArray();
		}
#endif
	}

	Mark( scREBREAK );

		/* break link to first line if we remove that text, the refernece
		 * to this text will be patched in the reformatting process
		 */
	txl 			= GetFirstline();

	if ( txl ) {
		scColumn*	col = txl->GetColumn();
		if ( txl && col->GetRecomposition() ) {
			scTextline* nextTxl;
		
			for ( ; txl && txl->GetPara( ) == this; txl = nextTxl ) {
				nextTxl = txl->GetNextLogical();
				if ( offset2 >= txl->GetEndOffset( ) ) {
						// the delete takes care of patching the para
					txl->MarkForDeletion( );
				}
				else {
					long startOffset = MIN( txl->GetStartOffset( ) - offset2, GetContentSize() );
					long endOffset	 = MIN( txl->GetEndOffset( ) - offset2, GetContentSize() );
				
					txl->SetOffsets( startOffset, endOffset );
				}
			}
		}
	}
	
	return entireParaDeleted;
}
예제 #20
0
/**
 * If the Bsp's point and vector tables are nearly full, reorder them and delete unused ones.
 */
void FBSPOps::bspRefresh( UModel* Model, bool NoRemapSurfs )
{
	FMemMark Mark(FMemStack::Get());
	int32 *VectorRef, *PointRef, *NodeRef, *PolyRef, i;
	TArray<int32*>	VertexRef;
	uint8  B;

	// Remove unreferenced Bsp surfs.
	NodeRef		= new(FMemStack::Get(),MEM_Oned,Model->Nodes.Num())int32;
	PolyRef		= new(FMemStack::Get(),MEM_Oned,Model->Surfs.Num())int32;
	if( Model->Nodes.Num() > 0 )
		TagReferencedNodes( Model, NodeRef, PolyRef, 0 );

	if( NoRemapSurfs )
		FMemory::Memzero(PolyRef,Model->Surfs.Num() * sizeof (int32));

	// Remap Bsp nodes and surfs.
	int32 n=0;
	for( i=0; i<Model->Surfs.Num(); i++ )
	{
		if( PolyRef[i]!=INDEX_NONE )
		{
			Model->Surfs[n] = Model->Surfs[i];
			PolyRef[i]=n++;
		}
	}
	//UE_LOG(LogBSPOps, Log,  TEXT("Polys: %i -> %i"), Model->Surfs.Num(), n );
	Model->Surfs.RemoveAt( n, Model->Surfs.Num()-n );

	n=0;
	for( i=0; i<Model->Nodes.Num(); i++ ) if( NodeRef[i]!=INDEX_NONE )
	{
		Model->Nodes[n] = Model->Nodes[i];
		NodeRef[i]=n++;
	}
	//UE_LOG(LogBSPOps, Log,  TEXT("Nodes: %i -> %i"), Model->Nodes.Num(), n );
	Model->Nodes.RemoveAt( n, Model->Nodes.Num()-n  );

	// Update Bsp nodes.
	for( i=0; i<Model->Nodes.Num(); i++ )
	{
		FBspNode *Node = &Model->Nodes[i];
		Node->iSurf = PolyRef[Node->iSurf];
		if (Node->iFront != INDEX_NONE) Node->iFront = NodeRef[Node->iFront];
		if (Node->iBack  != INDEX_NONE) Node->iBack  = NodeRef[Node->iBack];
		if (Node->iPlane != INDEX_NONE) Node->iPlane = NodeRef[Node->iPlane];
	}

	// Remove unreferenced points and vectors.
	VectorRef = new(FMemStack::Get(),MEM_Oned,Model->Vectors.Num())int32;
	PointRef  = new(FMemStack::Get(),MEM_Oned,Model->Points .Num ())int32;

	// Check Bsp surfs.
	for( i=0; i<Model->Surfs.Num(); i++ )
	{
		FBspSurf *Surf = &Model->Surfs[i];
		VectorRef [Surf->vNormal   ] = 0;
		VectorRef [Surf->vTextureU ] = 0;
		VectorRef [Surf->vTextureV ] = 0;
		PointRef  [Surf->pBase     ] = 0;
	}

	// Check Bsp nodes.
	for( i=0; i<Model->Nodes.Num(); i++ )
	{
		// Tag all points used by nodes.
		FBspNode*	Node		= &Model->Nodes[i];
		FVert*		VertPool	= &Model->Verts[Node->iVertPool];
		for( B=0; B<Node->NumVertices;  B++ )
		{
			PointRef[VertPool->pVertex] = 0;
			VertPool++;
		}
		Node++;
	}

	// Remap points.
	n=0; 
	for( i=0; i<Model->Points.Num(); i++ ) if( PointRef[i]!=INDEX_NONE )
	{
		Model->Points[n] = Model->Points[i];
		PointRef[i] = n++;
	}
	//UE_LOG(LogBSPOps, Log,  TEXT("Points: %i -> %i"), Model->Points.Num(), n );
	Model->Points.RemoveAt( n, Model->Points.Num()-n );
	check(Model->Points.Num()==n);

	// Remap vectors.
	n=0; for (i=0; i<Model->Vectors.Num(); i++) if (VectorRef[i]!=INDEX_NONE)
	{
		Model->Vectors[n] = Model->Vectors[i];
		VectorRef[i] = n++;
	}
	//UE_LOG(LogBSPOps, Log,  TEXT("Vectors: %i -> %i"), Model->Vectors.Num(), n );
	Model->Vectors.RemoveAt( n, Model->Vectors.Num()-n );

	// Update Bsp surfs.
	for( i=0; i<Model->Surfs.Num(); i++ )
	{
		FBspSurf *Surf	= &Model->Surfs[i];
		Surf->vNormal   = VectorRef [Surf->vNormal  ];
		Surf->vTextureU = VectorRef [Surf->vTextureU];
		Surf->vTextureV = VectorRef [Surf->vTextureV];
		Surf->pBase     = PointRef  [Surf->pBase    ];
	}

	// Update Bsp nodes.
	for( i=0; i<Model->Nodes.Num(); i++ )
	{
		FBspNode*	Node		= &Model->Nodes[i];
		FVert*		VertPool	= &Model->Verts[Node->iVertPool];
		for( B=0; B<Node->NumVertices;  B++ )
		{			
			VertPool->pVertex = PointRef [VertPool->pVertex];
			VertPool++;
		}

		Node++;
	}

	// Shrink the objects.
	Model->ShrinkModel();

	Mark.Pop();
}
예제 #21
0
/** Applies Temporal AA to the light shaft source. */
void ApplyTemporalAA(
	FRHICommandListImmediate& RHICmdList,
	FViewInfo& View, 
	const TCHAR* HistoryRTName,
	/** Contains last frame's history, if non-NULL.  This will be updated with the new frame's history. */
	TRefCountPtr<IPooledRenderTarget>* HistoryState,
	/** Source mask (for either occlusion or bloom). */
	TRefCountPtr<IPooledRenderTarget>& LightShaftsSource, 
	/** Output of Temporal AA for the next step in the pipeline. */
	TRefCountPtr<IPooledRenderTarget>& HistoryOutput)
{
	if (View.FinalPostProcessSettings.AntiAliasingMethod == AAM_TemporalAA
		&& HistoryState)
	{
		if (*HistoryState && !View.bCameraCut)
		{
			FMemMark Mark(FMemStack::Get());
			FRenderingCompositePassContext CompositeContext(RHICmdList, View);
			FPostprocessContext Context(CompositeContext.Graph, View);

			// Nodes for input render targets
			FRenderingCompositePass* LightShaftSetup = Context.Graph.RegisterPass( new(FMemStack::Get()) FRCPassPostProcessInput( LightShaftsSource ) );
			FRenderingCompositePass* HistoryInput = Context.Graph.RegisterPass( new(FMemStack::Get()) FRCPassPostProcessInput( *HistoryState ) );

			// Temporal AA node
			FRenderingCompositePass* NodeTemporalAA = Context.Graph.RegisterPass( new(FMemStack::Get()) FRCPassPostProcessLightShaftTemporalAA );

			// Setup inputs on Temporal AA node as the shader expects
			NodeTemporalAA->SetInput( ePId_Input0, LightShaftSetup );
			NodeTemporalAA->SetInput( ePId_Input1, FRenderingCompositeOutputRef( HistoryInput ) );
			NodeTemporalAA->SetInput( ePId_Input2, FRenderingCompositeOutputRef( HistoryInput ) );

			// Reuse a render target from the pool with a consistent name, for vis purposes
			TRefCountPtr<IPooledRenderTarget> NewHistory;
			AllocateOrReuseLightShaftRenderTarget(RHICmdList, NewHistory, HistoryRTName);

			// Setup the output to write to the new history render target
			Context.FinalOutput = FRenderingCompositeOutputRef(NodeTemporalAA);
			Context.FinalOutput.GetOutput()->RenderTargetDesc = NewHistory->GetDesc();
			Context.FinalOutput.GetOutput()->PooledRenderTarget = NewHistory;

			// Execute Temporal AA
			CompositeContext.Process(Context.FinalOutput.GetPass(), TEXT("LightShaftTemporalAA"));

			// Update the view state's render target reference with the new history
			*HistoryState = NewHistory;
			HistoryOutput = NewHistory;
		}
		else
		{
			// Use the current frame's mask for next frame's history, without invoking the Temporal AA shader
			*HistoryState = LightShaftsSource;
			HistoryOutput = LightShaftsSource;
			LightShaftsSource = NULL;

			AllocateOrReuseLightShaftRenderTarget(RHICmdList, LightShaftsSource, HistoryRTName);
		}
	}
	else
	{
		// Temporal AA is disabled or there is no view state - pass through
		HistoryOutput = LightShaftsSource;
	}
}
예제 #22
0
//
// Pick a splitter poly then split a pool of polygons into front and back polygons and
// recurse.
//
// iParent = Parent Bsp node, or INDEX_NONE if this is the root node.
// IsFront = 1 if this is the front node of iParent, 0 of back (undefined if iParent==INDEX_NONE)
//
void FBSPOps::SplitPolyList
(
	UModel				*Model,
	int32                 iParent,
	ENodePlace			NodePlace,
	int32                 NumPolys,
	FPoly				**PolyList,
	EBspOptimization	Opt,
	int32					Balance,
	int32					PortalBias,
	int32					RebuildSimplePolys
)
{
	FMemMark Mark(FMemStack::Get());

	// Keeping track of allocated FPoly structures to delete later on.
	TArray<FPoly*> AllocatedFPolys;

	// To account for big EdPolys split up.
	int32 NumPolysToAlloc = NumPolys + 8 + NumPolys/4;
	int32 NumFront=0; FPoly **FrontList = new(FMemStack::Get(),NumPolysToAlloc)FPoly*;
	int32 NumBack =0; FPoly **BackList  = new(FMemStack::Get(),NumPolysToAlloc)FPoly*;

	FPoly *SplitPoly = FindBestSplit( NumPolys, PolyList, Opt, Balance, PortalBias );

	// Add the splitter poly to the Bsp with either a new BspSurf or an existing one.
	if( RebuildSimplePolys )
	{
		SplitPoly->iLink = Model->Surfs.Num();
	}

	int32 iOurNode	= bspAddNode(Model,iParent,NodePlace,0,SplitPoly);
	int32 iPlaneNode	= iOurNode;

	// Now divide all polygons in the pool into (A) polygons that are
	// in front of Poly, and (B) polygons that are in back of Poly.
	// Coplanar polys are inserted immediately, before recursing.

	// If any polygons are split by Poly, we ignrore the original poly,
	// split it into two polys, and add two new polys to the pool.
	FPoly *FrontEdPoly = new FPoly;
	FPoly *BackEdPoly  = new FPoly;
	// Keep track of allocations.
	AllocatedFPolys.Add( FrontEdPoly );
	AllocatedFPolys.Add( BackEdPoly );

	for( int32 i=0; i<NumPolys; i++ )
	{
		FPoly *EdPoly = PolyList[i];
		if( EdPoly == SplitPoly )
		{
			continue;
		}

		switch( EdPoly->SplitWithPlane( SplitPoly->Vertices[0], SplitPoly->Normal, FrontEdPoly, BackEdPoly, 0 ) )
		{
			case SP_Coplanar:
	            if( RebuildSimplePolys )
				{
					EdPoly->iLink = Model->Surfs.Num()-1;
				}
				iPlaneNode = bspAddNode( Model, iPlaneNode, NODE_Plane, 0, EdPoly );
				break;
			
			case SP_Front:
	            FrontList[NumFront++] = PolyList[i];
				break;
			
			case SP_Back:
	            BackList[NumBack++] = PolyList[i];
				break;
			
			case SP_Split:

				// Create front & back nodes.
				FrontList[NumFront++] = FrontEdPoly;
				BackList [NumBack ++] = BackEdPoly;

				FrontEdPoly = new FPoly;
				BackEdPoly  = new FPoly;
				// Keep track of allocations.
				AllocatedFPolys.Add( FrontEdPoly );
				AllocatedFPolys.Add( BackEdPoly );

				break;
		}
	}

	// Recursively split the front and back pools.
	if( NumFront > 0 ) SplitPolyList( Model, iOurNode, NODE_Front, NumFront, FrontList, Opt, Balance, PortalBias, RebuildSimplePolys );
	if( NumBack  > 0 ) SplitPolyList( Model, iOurNode, NODE_Back,  NumBack,  BackList,  Opt, Balance, PortalBias, RebuildSimplePolys );

	// Delete FPolys allocated above. We cannot use FMemStack::Get() for FPoly as the array data FPoly contains will be allocated in regular memory.
	for( int32 i=0; i<AllocatedFPolys.Num(); i++ )
	{
		FPoly* AllocatedFPoly = AllocatedFPolys[i];
		delete AllocatedFPoly;
	}

	Mark.Pop();
}
예제 #23
0
/**
 * Builds Bsp from the editor polygon set (EdPolys) of a model.
 *
 * Opt     = Bsp optimization, BSP_Lame (fast), BSP_Good (medium), BSP_Optimal (slow)
 * Balance = 0-100, 0=only worry about minimizing splits, 100=only balance tree.
 */
void FBSPOps::bspBuild( UModel* Model, enum EBspOptimization Opt, int32 Balance, int32 PortalBias, int32 RebuildSimplePolys, int32 iNode )
{
	int32 OriginalPolys = Model->Polys->Element.Num();

	// Empty the model's tables.
	if( RebuildSimplePolys==1 )
	{
		// Empty everything but polys.
		Model->EmptyModel( 1, 0 );
	}
	else if( RebuildSimplePolys==0 )
	{
		// Empty node vertices.
		for( int32 i=0; i<Model->Nodes.Num(); i++ )
			Model->Nodes[i].NumVertices = 0;

		// Refresh the Bsp.
		bspRefresh(Model,1);
		
		// Empty nodes.
		Model->EmptyModel( 0, 0 );
	}
	if( Model->Polys->Element.Num() )
	{
		// Allocate polygon pool.
		FMemMark Mark(FMemStack::Get());
		FPoly** PolyList = new( FMemStack::Get(), Model->Polys->Element.Num() )FPoly*;

		// Add all FPolys to active list.
		for( int32 i=0; i<Model->Polys->Element.Num(); i++ )
			if( Model->Polys->Element[i].Vertices.Num() )
				PolyList[i] = &Model->Polys->Element[i];

		// Now split the entire Bsp by splitting the list of all polygons.
		SplitPolyList
		(
			Model,
			INDEX_NONE,
			NODE_Root,
			Model->Polys->Element.Num(),
			PolyList,
			Opt,
			Balance,
			PortalBias,
			RebuildSimplePolys
		);

		// Now build the bounding boxes for all nodes.
		if( RebuildSimplePolys==0 )
		{
			// Remove unreferenced things.
			bspRefresh( Model, 1 );

			// Rebuild all bounding boxes.
			bspBuildBounds( Model );
		}

		Mark.Pop();
	}

//	UE_LOG(LogBSPOps, Log,  TEXT("bspBuild built %i convex polys into %i nodes"), OriginalPolys, Model->Nodes.Num() );
}
예제 #24
0
// Add an editor polygon to the Bsp, and also stick a reference to it
// in the editor polygon's BspNodes list. If the editor polygon has more sides
// than the Bsp will allow, split it up into several sub-polygons.
//
// Returns: Index to newly-created node of Bsp.  If several nodes were created because
// of split polys, returns the parent (highest one up in the Bsp).
int32	FBSPOps::bspAddNode( UModel* Model, int32 iParent, ENodePlace NodePlace, uint32 NodeFlags, FPoly* EdPoly )
{
	if( NodePlace == NODE_Plane )
	{
		// Make sure coplanars are added at the end of the coplanar list so that 
		// we don't insert NF_IsNew nodes with non NF_IsNew coplanar children.
		while( Model->Nodes[iParent].iPlane != INDEX_NONE )
		{
			iParent = Model->Nodes[iParent].iPlane;
		}
	}
	FBspSurf* Surf = NULL;
	if( EdPoly->iLink == Model->Surfs.Num() )
	{
		int32 NewIndex = Model->Surfs.AddZeroed();
		Surf = &Model->Surfs[NewIndex];

		// This node has a new polygon being added by bspBrushCSG; must set its properties here.
		Surf->pBase     	= bspAddPoint  (Model,&EdPoly->Base,1);
		Surf->vNormal   	= bspAddVector (Model,&EdPoly->Normal,1);
		Surf->vTextureU 	= bspAddVector (Model,&EdPoly->TextureU,0);
		Surf->vTextureV 	= bspAddVector (Model,&EdPoly->TextureV,0);
		Surf->Material  	= EdPoly->Material;
		Surf->Actor			= NULL;

		Surf->PolyFlags 	= EdPoly->PolyFlags & ~PF_NoAddToBSP;
		Surf->LightMapScale= EdPoly->LightMapScale;

		// Find the LightmassPrimitiveSettings in the UModel...
		int32 FoundLightmassIndex = INDEX_NONE;
		if (Model->LightmassSettings.Find(EdPoly->LightmassSettings, FoundLightmassIndex) == false)
		{
			FoundLightmassIndex = Model->LightmassSettings.Add(EdPoly->LightmassSettings);
		}
		Surf->iLightmassIndex = FoundLightmassIndex;

		Surf->Actor	 		= EdPoly->Actor;
		Surf->iBrushPoly	= EdPoly->iBrushPoly;

		Surf->Plane			= FPlane(EdPoly->Vertices[0],EdPoly->Normal);
	}
	else
	{
		check(EdPoly->iLink!=INDEX_NONE);
		check(EdPoly->iLink<Model->Surfs.Num());
		Surf = &Model->Surfs[EdPoly->iLink];
	}

	// Set NodeFlags.
	if( Surf->PolyFlags & PF_NotSolid              ) NodeFlags |= NF_NotCsg;
	if( Surf->PolyFlags & (PF_Invisible|PF_Portal) ) NodeFlags |= NF_NotVisBlocking;

	if( EdPoly->Vertices.Num() > FBspNode::MAX_NODE_VERTICES )
	{
		// Split up into two coplanar sub-polygons (one with MAX_NODE_VERTICES vertices and
		// one with all the remaining vertices) and recursively add them.

		// EdPoly1 is just the first MAX_NODE_VERTICES from EdPoly.
		FMemMark Mark(FMemStack::Get());
		FPoly *EdPoly1 = new FPoly;
		*EdPoly1 = *EdPoly;
		EdPoly1->Vertices.RemoveAt(FBspNode::MAX_NODE_VERTICES,EdPoly->Vertices.Num() - FBspNode::MAX_NODE_VERTICES);

		// EdPoly2 is the first vertex from EdPoly, and the last EdPoly->Vertices.Num() - MAX_NODE_VERTICES + 1.
		FPoly *EdPoly2 = new FPoly;
		*EdPoly2 = *EdPoly;
		EdPoly2->Vertices.RemoveAt(1,FBspNode::MAX_NODE_VERTICES - 2);

		int32 iNode = bspAddNode( Model, iParent, NodePlace, NodeFlags, EdPoly1 ); // Add this poly first.
		bspAddNode( Model, iNode,   NODE_Plane, NodeFlags, EdPoly2 ); // Then add other (may be bigger).

		delete EdPoly1;
		delete EdPoly2;

		Mark.Pop();
		return iNode; // Return coplanar "parent" node (not coplanar child)
	}
	else
	{
		// Add node.
		if( NodePlace!=NODE_Root )
		{
			Model->Nodes.ModifyItem( iParent );
		}
		int32 iNode			 = Model->Nodes.AddZeroed();
		FBspNode& Node       = Model->Nodes[iNode];

		// Tell transaction tracking system that parent is about to be modified.
		FBspNode* Parent=NULL;
		if( NodePlace!=NODE_Root )
			Parent = &Model->Nodes[iParent];

		// Set node properties.
		Node.iSurf       	 = EdPoly->iLink;
		Node.NodeFlags   	 = NodeFlags;
		Node.iCollisionBound = INDEX_NONE;
		Node.Plane           = FPlane( EdPoly->Vertices[0], EdPoly->Normal );
		Node.iVertPool       = Model->Verts.AddUninitialized(EdPoly->Vertices.Num());
		Node.iFront		     = INDEX_NONE;
		Node.iBack		     = INDEX_NONE;
		Node.iPlane		     = INDEX_NONE;
		if( NodePlace==NODE_Root )
		{
			Node.iLeaf[0]	 = INDEX_NONE;
			Node.iLeaf[1] 	 = INDEX_NONE;
			Node.iZone[0]	 = 0;
			Node.iZone[1]	 = 0;
		}
		else if( NodePlace==NODE_Front || NodePlace==NODE_Back )
		{
			int32 ZoneFront=NodePlace==NODE_Front;
			Node.iLeaf[0]	 = Parent->iLeaf[ZoneFront];
			Node.iLeaf[1] 	 = Parent->iLeaf[ZoneFront];
			Node.iZone[0]	 = Parent->iZone[ZoneFront];
			Node.iZone[1]	 = Parent->iZone[ZoneFront];
		}
		else
		{
			int32 IsFlipped    = (Node.Plane|Parent->Plane)<0.0;
			Node.iLeaf[0]    = Parent->iLeaf[IsFlipped  ];
			Node.iLeaf[1]    = Parent->iLeaf[1-IsFlipped];
			Node.iZone[0]    = Parent->iZone[IsFlipped  ];
			Node.iZone[1]    = Parent->iZone[1-IsFlipped];
		}

		// Link parent to this node.
		if     ( NodePlace==NODE_Front ) Parent->iFront = iNode;
		else if( NodePlace==NODE_Back  ) Parent->iBack  = iNode;
		else if( NodePlace==NODE_Plane ) Parent->iPlane = iNode;

		// Add all points to point table, merging nearly-overlapping polygon points
		// with other points in the poly to prevent criscrossing vertices from
		// being generated.

		// Must maintain Node->NumVertices on the fly so that bspAddPoint is always
		// called with the Bsp in a clean state.
		Node.NumVertices = 0;
		FVert* VertPool	 = &Model->Verts[ Node.iVertPool ];
		for( uint8 i=0; i<EdPoly->Vertices.Num(); i++ )
		{
			int32 pVertex = bspAddPoint(Model,&EdPoly->Vertices[i],0);
			if( Node.NumVertices==0 || VertPool[Node.NumVertices-1].pVertex!=pVertex )
			{
				VertPool[Node.NumVertices].iSide   = INDEX_NONE;
				VertPool[Node.NumVertices].pVertex = pVertex;
				Node.NumVertices++;
			}
		}
		if( Node.NumVertices>=2 && VertPool[0].pVertex==VertPool[Node.NumVertices-1].pVertex )
		{
			Node.NumVertices--;
		}
		if( Node.NumVertices < 3 )
		{
			GErrors++;
// 			UE_LOG(LogBSPOps, Warning, TEXT("bspAddNode: Infinitesimal polygon %i (%i)"), Node.NumVertices, EdPoly->Vertices.Num() );
			Node.NumVertices = 0;
		}

		return iNode;
	}
}
예제 #25
0
//
// Recursively filter a set of polys defining a convex hull down the Bsp,
// splitting it into two halves at each node and adding in the appropriate
// face polys at splits.
//
static void FilterBound
(
	UModel*			Model,
	FBox*			ParentBound,
	int32				iNode,
	FPoly**			PolyList,
	int32				nPolys,
	int32				Outside
)
{
	FMemMark Mark(FMemStack::Get());
	FBspNode&	Node	= Model->Nodes  [iNode];
	FBspSurf&	Surf	= Model->Surfs  [Node.iSurf];
	FVector		Base = Surf.Plane * Surf.Plane.W;
	FVector&	Normal	= Model->Vectors[Surf.vNormal];
	FBox		Bound(0);

	Bound.Min.X = Bound.Min.Y = Bound.Min.Z = +WORLD_MAX;
	Bound.Max.X = Bound.Max.Y = Bound.Max.Z = -WORLD_MAX;

	// Split bound into front half and back half.
	FPoly** FrontList = new(FMemStack::Get(),nPolys*2+16)FPoly*; int32 nFront=0;
	FPoly** BackList  = new(FMemStack::Get(),nPolys*2+16)FPoly*; int32 nBack=0;

	// Keeping track of allocated FPoly structures to delete later on.
	TArray<FPoly*> AllocatedFPolys;

	FPoly* FrontPoly  = new FPoly;
	FPoly* BackPoly   = new FPoly;

	// Keep track of allocations.
	AllocatedFPolys.Add( FrontPoly );
	AllocatedFPolys.Add( BackPoly );

	for( int32 i=0; i<nPolys; i++ )
	{
		FPoly *Poly = PolyList[i];
		switch( Poly->SplitWithPlane( Base, Normal, FrontPoly, BackPoly, 0 ) )
		{
			case SP_Coplanar:
//				UE_LOG(LogBSPOps, Log,  TEXT("FilterBound: Got coplanar") );
				FrontList[nFront++] = Poly;
				BackList[nBack++] = Poly;
				break;
			
			case SP_Front:
				FrontList[nFront++] = Poly;
				break;
			
			case SP_Back:
				BackList[nBack++] = Poly;
				break;
			
			case SP_Split:
				FrontList[nFront++] = FrontPoly;
				BackList [nBack++] = BackPoly;

				FrontPoly = new FPoly;
				BackPoly  = new FPoly;

				// Keep track of allocations.
				AllocatedFPolys.Add( FrontPoly );
				AllocatedFPolys.Add( BackPoly );

				break;

			default:
				UE_LOG(LogBSPOps, Fatal, TEXT("FZoneFilter::FilterToLeaf: Unknown split code") );
		}
	}
	if( nFront && nBack )
	{
		// Add partitioner plane to front and back.
		FPoly InfiniteEdPoly = FBSPOps::BuildInfiniteFPoly( Model, iNode );
		InfiniteEdPoly.iBrushPoly = iNode;

		SplitPartitioner(Model,PolyList,FrontList,BackList,0,nPolys,nFront,nBack,InfiniteEdPoly,AllocatedFPolys);
	}
	else
	{
// 		if( !nFront ) UE_LOG(LogBSPOps, Log,  TEXT("FilterBound: Empty fronthull") );
// 		if( !nBack  ) UE_LOG(LogBSPOps, Log,  TEXT("FilterBound: Empty backhull") );
	}

	// Recursively update all our childrens' bounding volumes.
	if( nFront > 0 )
	{
		if( Node.iFront != INDEX_NONE )
			FilterBound( Model, &Bound, Node.iFront, FrontList, nFront, Outside || Node.IsCsg() );
		else if( Outside || Node.IsCsg() )
			UpdateBoundWithPolys( Bound, FrontList, nFront );
		else
			UpdateConvolutionWithPolys( Model, iNode, FrontList, nFront );
	}
	if( nBack > 0 )
	{
		if( Node.iBack != INDEX_NONE)
			FilterBound( Model, &Bound,Node.iBack, BackList, nBack, Outside && !Node.IsCsg() );
		else if( Outside && !Node.IsCsg() )
			UpdateBoundWithPolys( Bound, BackList, nBack );
		else
			UpdateConvolutionWithPolys( Model, iNode, BackList, nBack );
	}

	// Update parent bound to enclose this bound.
	if( ParentBound )
		*ParentBound += Bound;

	// Delete FPolys allocated above. We cannot use FMemStack::Get() for FPoly as the array data FPoly contains will be allocated in regular memory.
	for( int32 i=0; i<AllocatedFPolys.Num(); i++ )
	{
		FPoly* AllocatedFPoly = AllocatedFPolys[i];
		delete AllocatedFPoly;
	}

	Mark.Pop();
}
void FCompositionLighting::ProcessAfterLighting(FRHICommandListImmediate& RHICmdList, FViewInfo& View)
{
	check(IsInRenderingThread());
	FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList);

	
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ReflectiveShadowMapDiffuse);
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ReflectiveShadowMapNormal);
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ReflectiveShadowMapDepth);

	{
		FMemMark Mark(FMemStack::Get());
		FRenderingCompositePassContext CompositeContext(RHICmdList, View);
		FPostprocessContext Context(CompositeContext.Graph, View);
		FRenderingCompositeOutputRef AmbientOcclusion;

		// Screen Space Subsurface Scattering
		{
			float Radius = CVarSSSScale.GetValueOnRenderThread();

			bool bSimpleDynamicLighting = IsSimpleDynamicLightingEnabled();

			bool bScreenSpaceSubsurfacePassNeeded = (View.ShadingModelMaskInView & (1 << MSM_SubsurfaceProfile)) != 0;
			if (bScreenSpaceSubsurfacePassNeeded && Radius > 0 && !bSimpleDynamicLighting && View.Family->EngineShowFlags.SubsurfaceScattering &&
				//@todo-rco: Remove this when we fix the cross-compiler
				!IsOpenGLPlatform(View.GetShaderPlatform()))
			{
				// can be optimized out if we don't do split screen/stereo rendering (should be done after we some post process refactoring)
				FRenderingCompositePass* PassExtractSpecular = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceExtractSpecular());
				PassExtractSpecular->SetInput(ePId_Input0, Context.FinalOutput);

				FRenderingCompositePass* PassSetup = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceSetup(View));
				PassSetup->SetInput(ePId_Input0, Context.FinalOutput);

				FRenderingCompositePass* Pass0 = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurface(0));
				Pass0->SetInput(ePId_Input0, PassSetup);

				FRenderingCompositePass* Pass1 = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurface(1));
				Pass1->SetInput(ePId_Input0, Pass0);
				Pass1->SetInput(ePId_Input1, PassSetup);

				// full res composite pass, no blurring (Radius=0)
				FRenderingCompositePass* RecombinePass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessSubsurfaceRecombine());
				RecombinePass->SetInput(ePId_Input0, Pass1);
				RecombinePass->SetInput(ePId_Input1, PassExtractSpecular);
				
				SCOPED_DRAW_EVENT(RHICmdList, CompositionLighting_SSSSS);

				CompositeContext.Process(RecombinePass, TEXT("CompositionLighting_SSSSS"));
			}
		}

		// The graph setup should be finished before this line ----------------------------------------

		SCOPED_DRAW_EVENT(RHICmdList, CompositionAfterLighting);

		// we don't replace the final element with the scenecolor because this is what those passes should do by themself

		CompositeContext.Process(Context.FinalOutput.GetPass(), TEXT("CompositionLighting"));
	}

	// We only release the after the last view was processed (SplitScreen)
	if(View.Family->Views[View.Family->Views.Num() - 1] == &View)
	{
		// The RT should be released as early as possible to allow sharing of that memory for other purposes.
		// This becomes even more important with some limited VRam (XBoxOne).
		SceneContext.SetLightAttenuation(0);
	}
}
void FCompositionLighting::ProcessAfterBasePass(FRHICommandListImmediate& RHICmdList, FViewInfo& View)
{
	check(IsInRenderingThread());
	
	FSceneRenderTargets& SceneContext = FSceneRenderTargets::Get(RHICmdList);
	// might get renamed to refracted or ...WithAO
	SceneContext.GetSceneColor()->SetDebugName(TEXT("SceneColor"));
	// to be able to observe results with VisualizeTexture

	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GetSceneColor());
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferA);
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferB);
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferC);
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferD);
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferE);
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.GBufferVelocity);
	GRenderTargetPool.VisualizeTexture.SetCheckPoint(RHICmdList, SceneContext.ScreenSpaceAO);
	
	// so that the passes can register themselves to the graph
	{
		FMemMark Mark(FMemStack::Get());
		FRenderingCompositePassContext CompositeContext(RHICmdList, View);

		FPostprocessContext Context(CompositeContext.Graph, View);

		// Add the passes we want to add to the graph ----------
		
		if(Context.View.Family->EngineShowFlags.Decals && !Context.View.Family->EngineShowFlags.ShaderComplexity)
		{
			// DRS_AfterBasePass is for Volumetric decals which don't support ShaderComplexity yet
			FRenderingCompositePass* Pass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessDeferredDecals(DRS_AfterBasePass));
			Pass->SetInput(ePId_Input0, Context.FinalOutput);

			Context.FinalOutput = FRenderingCompositeOutputRef(Pass);
		}

		// decals are before AmbientOcclusion so the decal can output a normal that AO is affected by
		if( Context.View.Family->EngineShowFlags.Decals &&
			!Context.View.Family->EngineShowFlags.VisualizeLightCulling)		// decal are distracting when looking at LightCulling
		{
			FRenderingCompositePass* Pass = Context.Graph.RegisterPass(new(FMemStack::Get()) FRCPassPostProcessDeferredDecals(DRS_BeforeLighting));
			Pass->SetInput(ePId_Input0, Context.FinalOutput);

			Context.FinalOutput = FRenderingCompositeOutputRef(Pass);
		}

		FRenderingCompositeOutputRef AmbientOcclusion;

		if(uint32 Levels = ComputeAmbientOcclusionPassCount(Context))
		{
			AmbientOcclusion = AddPostProcessingAmbientOcclusion(RHICmdList, Context, Levels);
		}

		if(IsAmbientCubemapPassRequired(Context))
		{
			AddPostProcessingAmbientCubemap(Context, AmbientOcclusion);
		}

		// The graph setup should be finished before this line ----------------------------------------

		SCOPED_DRAW_EVENT(RHICmdList, LightCompositionTasks_PreLighting);

		TRefCountPtr<IPooledRenderTarget>& SceneColor = SceneContext.GetSceneColor();

		Context.FinalOutput.GetOutput()->RenderTargetDesc = SceneColor->GetDesc();
		Context.FinalOutput.GetOutput()->PooledRenderTarget = SceneColor;

		CompositeContext.Process(Context.FinalOutput.GetPass(), TEXT("CompositionLighting_AfterBasePass"));
	}
}
int FWindowsPlatformStackWalkExt::GetCallstacks()
{
	const int32 MAX_NAME_LENGHT = FProgramCounterSymbolInfo::MAX_NAME_LENGHT;
	int32 NumValidFunctionNames = 0;

	FCrashExceptionInfo& Exception = CrashInfo.Exception;

	FMemMark Mark(FMemStack::Get());

	//const float int int32 FString
	const int32 ContextSize = 4096;
	byte* Context = new(FMemStack::Get()) byte[ContextSize];
	ULONG DebugEvent = 0;
	ULONG ProcessID = 0;
	ULONG ThreadID = 0;
	ULONG ContextUsed = 0;

	// Get the context of the crashed thread
	HRESULT hr = Control->GetStoredEventInformation(&DebugEvent, &ProcessID, &ThreadID, Context, ContextSize, &ContextUsed, NULL, 0, 0);
	if( FAILED(hr) )
	{
		return NumValidFunctionNames;
	}

	// Some magic number checks
	if( ContextUsed == 716 )
	{
		UE_LOG( LogCrashDebugHelper, Log, TEXT( "Context size matches x86 sizeof( CONTEXT )" ) );
	}
	else if( ContextUsed == 1232 )
	{
		UE_LOG( LogCrashDebugHelper, Log, TEXT( "Context size matches x64 sizeof( CONTEXT )" ) );
	}

	// Get the entire stack trace
	const uint32 MaxFrames = 8192;
	const uint32 MaxFramesSize = MaxFrames * ContextUsed;

	DEBUG_STACK_FRAME* StackFrames = new(FMemStack::Get()) DEBUG_STACK_FRAME[MaxFrames];
	ULONG Count = 0;
	bool bFoundSourceFile = false;
	void* ContextData = FMemStack::Get().PushBytes( MaxFramesSize, 0 );
	FMemory::Memzero( ContextData, MaxFramesSize );
	HRESULT HR = Control->GetContextStackTrace( Context, ContextUsed, StackFrames, MaxFrames, ContextData, MaxFramesSize, ContextUsed, &Count );

	int32 AssertOrEnsureIndex = -1;

	for( uint32 StackIndex = 0; StackIndex < Count; StackIndex++ )
	{	
		const uint64 Offset = StackFrames[StackIndex].InstructionOffset;

		if( IsOffsetWithinModules( Offset ) )
		{
			// Get the module, function, and offset
			uint64 Displacement = 0;
			TCHAR NameByOffset[MAX_PATH] = {0};
			Symbol->GetNameByOffsetWide( Offset, NameByOffset, ARRAYSIZE( NameByOffset ) - 1, NULL, &Displacement );
			FString ModuleAndFunction = NameByOffset;

			// Don't care about any more entries higher than this
			if (ModuleAndFunction.Contains( TEXT( "tmainCRTStartup" ) ) || ModuleAndFunction.Contains( TEXT( "FRunnableThreadWin::GuardedRun" ) ))
			{
				break;
			}

			// Look for source file name and line number
			TCHAR SourceName[MAX_PATH] = { 0 };
			ULONG LineNumber = 0;
			Symbol->GetLineByOffsetWide( Offset, &LineNumber, SourceName, ARRAYSIZE( SourceName ) - 1, NULL, NULL );

			// Remember the top of the stack to locate in the source file
			if( !bFoundSourceFile && FCString::Strlen( SourceName ) > 0 && LineNumber > 0 )
			{
				CrashInfo.SourceFile = ExtractRelativePath( TEXT( "source" ), SourceName );
				CrashInfo.SourceLineNumber = LineNumber;
				bFoundSourceFile = true;
			}

			FString ModuleName;
			FString FunctionName;
			// According to MSDN, the symbol name will include an ! if the function name could be discovered, delimiting it from the module name
			// https://msdn.microsoft.com/en-us/library/windows/hardware/ff547186(v=vs.85).aspx
			if( ModuleAndFunction.Contains( TEXT( "!" ) ) )
			{
				NumValidFunctionNames++;
 
				ModuleAndFunction.Split( TEXT( "!" ), &ModuleName, &FunctionName );
				FunctionName += TEXT( "()" );
			}
			else
			{
				ModuleName = ModuleAndFunction;
			}

			// #YRX_Crash: 2015-07-24 Add for other platforms
			// If we find an assert, the actual source file we're interested in is the next one up, so reset the source file found flag
			if( FunctionName.Len() > 0 )
			{
				if( FunctionName.Contains( TEXT( "FDebug::" ), ESearchCase::CaseSensitive )
					|| FunctionName.Contains( TEXT( "NewReportEnsure" ), ESearchCase::CaseSensitive ) )
				{
					bFoundSourceFile = false;
					AssertOrEnsureIndex = FMath::Max( AssertOrEnsureIndex, (int32)StackIndex );
				}
			}

			// FString InModuleName, FString InFunctionName, FString InFilename, uint32 InLineNumber, uint64 InSymbolDisplacement, uint64 InOffsetInModule, uint64 InProgramCounter
			FProgramCounterSymbolInfoEx SymbolInfo( ModuleName, FunctionName, SourceName, LineNumber, Displacement, Offset, 0 );
			FString GenericFormattedCallstackLine;
			FGenericPlatformStackWalk::SymbolInfoToHumanReadableStringEx( SymbolInfo, GenericFormattedCallstackLine );
			Exception.CallStackString.Add( GenericFormattedCallstackLine );

			UE_LOG( LogCrashDebugHelper, Log, TEXT( "%3u: %s" ), StackIndex, *GenericFormattedCallstackLine );
		}
	}

	// Remove callstack entries below FDebug, we don't need them.
	if (AssertOrEnsureIndex > 0)
	{	
		Exception.CallStackString.RemoveAt( 0, AssertOrEnsureIndex );
		UE_LOG( LogCrashDebugHelper, Warning, TEXT( "Callstack trimmed to %i entries" ), Exception.CallStackString.Num() );
	}

	UE_LOG( LogCrashDebugHelper, Warning, TEXT( "Callstack generated with %i valid function names" ), NumValidFunctionNames );

	return NumValidFunctionNames;
}
FUniformBufferRHIRef FUniformExpressionSet::CreateUniformBuffer(const FMaterialRenderContext& MaterialRenderContext, FRHICommandList* CommandListIfLocalMode, struct FLocalUniformBuffer* OutLocalUniformBuffer) const
{
	check(UniformBufferStruct);
	check(IsInParallelRenderingThread());
	
	FUniformBufferRHIRef UniformBuffer;

	if (UniformBufferStruct->GetSize() > 0)
	{
		FMemMark Mark(FMemStack::Get());
		void* const TempBuffer = FMemStack::Get().PushBytes(UniformBufferStruct->GetSize(),UNIFORM_BUFFER_STRUCT_ALIGNMENT);

		FLinearColor* TempVectorBuffer = (FLinearColor*)TempBuffer;
		for(int32 VectorIndex = 0;VectorIndex < UniformVectorExpressions.Num();++VectorIndex)
		{
			TempVectorBuffer[VectorIndex] = FLinearColor(0,0,0,0);
			UniformVectorExpressions[VectorIndex]->GetNumberValue(MaterialRenderContext,TempVectorBuffer[VectorIndex]);
		}

		float* TempScalarBuffer = (float*)(TempVectorBuffer + UniformVectorExpressions.Num());
		for(int32 ScalarIndex = 0;ScalarIndex < UniformScalarExpressions.Num();++ScalarIndex)
		{
			FLinearColor VectorValue(0,0,0,0);
			UniformScalarExpressions[ScalarIndex]->GetNumberValue(MaterialRenderContext,VectorValue);
			TempScalarBuffer[ScalarIndex] = VectorValue.R;
		}

		void** ResourceTable = (void**)((uint8*)TempBuffer + UniformBufferStruct->GetLayout().ResourceOffset);
		check(((UPTRINT)ResourceTable & 0x7) == 0);

		check(UniformBufferStruct->GetLayout().Resources.Num() == Uniform2DTextureExpressions.Num() * 2 + UniformCubeTextureExpressions.Num() * 2 + 2);

		// Cache 2D texture uniform expressions.
		for(int32 ExpressionIndex = 0;ExpressionIndex < Uniform2DTextureExpressions.Num();ExpressionIndex++)
		{
			const UTexture* Value;
			ESamplerSourceMode SourceMode;
			Uniform2DTextureExpressions[ExpressionIndex]->GetTextureValue(MaterialRenderContext,MaterialRenderContext.Material,Value,SourceMode);
			if (Value && Value->Resource)
			{
				//@todo-rco: Help track down a invalid values
				checkf(Value->IsA(UTexture::StaticClass()), TEXT("Expecting a UTexture! Value='%s' class='%s'"), *Value->GetName(), *Value->GetClass()->GetName());

				// UMaterial / UMaterialInstance should have caused all dependent textures to be PostLoaded, which initializes their rendering resource
				checkf(Value->TextureReference.TextureReferenceRHI, TEXT("Texture %s of class %s had invalid texture reference"), *Value->GetName(), *Value->GetClass()->GetName());

				*ResourceTable++ = Value->TextureReference.TextureReferenceRHI;
				FSamplerStateRHIRef* SamplerSource = &Value->Resource->SamplerStateRHI;

				if (SourceMode == SSM_Wrap_WorldGroupSettings)
				{
					SamplerSource = &Wrap_WorldGroupSettings->SamplerStateRHI;
				}
				else if (SourceMode == SSM_Clamp_WorldGroupSettings)
				{
					SamplerSource = &Clamp_WorldGroupSettings->SamplerStateRHI;
				}

				*ResourceTable++ = *SamplerSource;
			}
			else
			{
				*ResourceTable++ = GWhiteTexture->TextureRHI;
				*ResourceTable++ = GWhiteTexture->SamplerStateRHI;
			}
		}

		// Cache cube texture uniform expressions.
		for(int32 ExpressionIndex = 0;ExpressionIndex < UniformCubeTextureExpressions.Num();ExpressionIndex++)
		{
			const UTexture* Value;
			ESamplerSourceMode SourceMode;
			UniformCubeTextureExpressions[ExpressionIndex]->GetTextureValue(MaterialRenderContext,MaterialRenderContext.Material,Value,SourceMode);
			if(Value && Value->Resource)
			{
				check(Value->TextureReference.TextureReferenceRHI);
				*ResourceTable++ = Value->TextureReference.TextureReferenceRHI;
				FSamplerStateRHIRef* SamplerSource = &Value->Resource->SamplerStateRHI;

				if (SourceMode == SSM_Wrap_WorldGroupSettings)
				{
					SamplerSource = &Wrap_WorldGroupSettings->SamplerStateRHI;
				}
				else if (SourceMode == SSM_Clamp_WorldGroupSettings)
				{
					SamplerSource = &Clamp_WorldGroupSettings->SamplerStateRHI;
				}

				*ResourceTable++ = *SamplerSource;
			}
			else
			{
				*ResourceTable++ = GWhiteTexture->TextureRHI;
				*ResourceTable++ = GWhiteTexture->SamplerStateRHI;
			}
		}

		*ResourceTable++ = Wrap_WorldGroupSettings->SamplerStateRHI;
		*ResourceTable++ = Clamp_WorldGroupSettings->SamplerStateRHI;

		if (CommandListIfLocalMode)
		{
			check(OutLocalUniformBuffer);
			*OutLocalUniformBuffer = CommandListIfLocalMode->BuildLocalUniformBuffer(TempBuffer, UniformBufferStruct->GetSize(), UniformBufferStruct->GetLayout());
			check(OutLocalUniformBuffer->IsValid());
		}
		else
		{
			UniformBuffer = RHICreateUniformBuffer(TempBuffer, UniformBufferStruct->GetLayout(), UniformBuffer_MultiFrame);
			check(!OutLocalUniformBuffer->IsValid());
		}
	}

	return UniformBuffer;
}
예제 #30
0
void FObjectReplicator::PostReceivedBunch()
{
	// Call PostNetReceive
	const bool bIsServer = (OwningChannel->Connection->Driver->ServerConnection == NULL);
	if (!bIsServer && bHasReplicatedProperties)
	{
		PostNetReceive();
		bHasReplicatedProperties = false;
	}

	// Check if PostNetReceive() destroyed Object
	UObject *Object = GetObject();
	if (Object == NULL || Object->IsPendingKill())
	{
		return;
	}

	RepLayout->CallRepNotifies( RepState, Object );

	// Call RepNotifies
	if ( RepNotifies.Num() > 0 )
	{
		for (int32 RepNotifyIdx = 0; RepNotifyIdx < RepNotifies.Num(); RepNotifyIdx++)
		{
			//UE_LOG(LogNet, Log,  TEXT("Calling Object->%s with %s"), *RepNotifies(RepNotifyIdx)->RepNotifyFunc.ToString(), *RepNotifies(RepNotifyIdx)->GetName()); 						
			UProperty* RepProperty = RepNotifies[RepNotifyIdx];
			UFunction* RepNotifyFunc = Object->FindFunctionChecked(RepProperty->RepNotifyFunc);
						
			if (RepNotifyFunc->NumParms == 0)
			{
				Object->ProcessEvent(RepNotifyFunc, NULL);
			}
			else if (RepNotifyFunc->NumParms == 1)
			{
				Object->ProcessEvent(RepNotifyFunc, RepProperty->ContainerPtrToValuePtr<uint8>(RepState->StaticBuffer.GetTypedData()) );
			}
			else if (RepNotifyFunc->NumParms == 2)
			{
				// Fixme: this isn't as safe as it could be. Right now we have two types of parameters: MetaData (a TArray<uint8>)
				// and the last local value (pointer into the Recent[] array).
				//
				// Arrays always expect MetaData. Everything else, including structs, expect last value.
				// This is enforced with UHT only. If a ::NetSerialize function ever starts producing a MetaData array thats not in UArrayProperty,
				// we have no static way of catching this and the replication system could pass the wrong thing into ProcessEvent here.
				//
				// But this is all sort of an edge case feature anyways, so its not worth tearing things up too much over.

				FMemMark Mark(FMemStack::Get());
				uint8* Parms = new(FMemStack::Get(),MEM_Zeroed,RepNotifyFunc->ParmsSize)uint8;
				
				TFieldIterator<UProperty> Itr(RepNotifyFunc);
				check(Itr);
				
				Itr->CopyCompleteValue( Itr->ContainerPtrToValuePtr<void>(Parms), RepProperty->ContainerPtrToValuePtr<uint8>(RepState->StaticBuffer.GetTypedData()) );
				++Itr;
				check(Itr);

				TArray<uint8> *NotifyMetaData = RepNotifyMetaData.Find(RepNotifies[RepNotifyIdx]);
				check(NotifyMetaData);
				Itr->CopyCompleteValue( Itr->ContainerPtrToValuePtr<void>(Parms), NotifyMetaData );
				
				Object->ProcessEvent(RepNotifyFunc, Parms );

				Mark.Pop();
			}
 						
 			if (Object == NULL || Object->IsPendingKill())
 			{
 				// script event destroyed Object
 				break;
 			}
		}
	}

	RepNotifies.Reset();
	RepNotifyMetaData.Empty();
}