Commit 5ec94e91 authored by hrchilds's avatar hrchilds

Update from November 3, 2005

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@563 18c085ea-50e0-402c-830e-de6fd14e8384
parent 68957dc2
......@@ -281,15 +281,18 @@ TimingsManager::OutputAllTimings(void)
// Jeremy Meredith, Fri Oct 4 16:47:47 PDT 2002
// Added number of current timings.
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added ability to force acquisition of timing info even if we're not
// logging timings to files
// ****************************************************************************
int
TimingsManager::StartTimer(void)
TimingsManager::StartTimer(bool forced)
{
//
// Return if timings disabled.
//
if (!enabled)
if (!enabled && !forced)
{
return -1;
}
......@@ -327,14 +330,17 @@ TimingsManager::StartTimer(void)
// Jeremy Meredith, Fri Oct 4 16:47:47 PDT 2002
// Added number of current timings and indentation based on it.
//
// Mark C. Miller, Wed Nov 2 09:07:05 PST 2005
// Added code to force return of timing info even if logging is not enabled
//
// ****************************************************************************
double
TimingsManager::StopTimer(int index, const std::string &summary)
TimingsManager::StopTimer(int index, const std::string &summary, bool forced)
{
double t = 0.;
if (enabled)
if (enabled || forced)
{
if (index < 0 || index >= numTimings)
{
......@@ -347,9 +353,12 @@ TimingsManager::StopTimer(int index, const std::string &summary)
t = PlatformStopTimer(index);
times.push_back(t);
char indented[1000];
sprintf(indented, "%*s%s", 3*numCurrentTimings, " ", summary.c_str());
summaries.push_back(indented);
if (enabled)
{
char indented[1000];
sprintf(indented, "%*s%s", 3*numCurrentTimings, " ", summary.c_str());
summaries.push_back(indented);
}
}
}
......
......@@ -58,6 +58,10 @@
// I added static methods, TimeSinceLastArrival, DiffTime
// I defined the TIMEINFO macro and restructured code to use it
//
// Mark C. Miller, Wed Nov 2 09:07:05 PST 2005
// Added optional force argument to Start/Stop methods to permit
// getting timer info in return value even if not logging to file
//
// ****************************************************************************
class MISC_API TimingsManager
......@@ -73,9 +77,10 @@ class MISC_API TimingsManager
void Enable(void);
void Disable(void);
bool Enabled() const {return enabled;};
int StartTimer(void);
double StopTimer(int, const std::string &);
int StartTimer(bool force=false);
double StopTimer(int, const std::string &, bool force=false);
static double DiffTime();
......
This diff is collapsed.
......@@ -15,7 +15,7 @@
// Notes: Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation: Thu Jun 30 14:31:44 PST 2005
// Creation: Thu Nov 3 11:33:54 PDT 2005
//
// Modifications:
//
......@@ -78,6 +78,7 @@ public:
void SetSpecularColor(const ColorAttribute &specularColor_);
void SetDoShadowing(bool doShadowing_);
void SetShadowStrength(double shadowStrength_);
void SetCompressionActivationMode(TriStateMode compressionActivationMode_);
// Property getting methods
bool GetAntialiasing() const;
......@@ -95,6 +96,7 @@ public:
ColorAttribute &GetSpecularColor();
bool GetDoShadowing() const;
double GetShadowStrength() const;
TriStateMode GetCompressionActivationMode() const;
// Persistence methods
virtual bool CreateNode(DataNode *node, bool completeSave, bool forceAdd);
......@@ -140,6 +142,7 @@ private:
ColorAttribute specularColor;
bool doShadowing;
double shadowStrength;
int compressionActivationMode;
};
#endif
......@@ -61,6 +61,9 @@
<Field name="shadowStrength" label="Shadow Strength" type="double">
0.500000
</Field>
<Field name="compressionActivationMode" label="compressionActivationMode" type="enum" subtype="TriStateMode">
Never
</Field>
<Function name="GetEffectiveScalableThreshold" user="true" member="true">
</Function>
<Constant name="DEFAULT_SCALABLE_AUTO_THRESHOLD" member="false">
......
......@@ -63,6 +63,8 @@ class PIPELINE_API avtImage : public avtDataObject
virtual void ReleaseData(void);
avtImageRepresentation &GetImage(void);
virtual void GetSize(int *width, int *height) const;
virtual float GetCompressionRatio() const
{return image.GetCompressionRatio(); };
protected:
avtImageRepresentation image;
......
// ************************************************************************* //
// avtImageRepresentation.C //
// ************************************************************************* //
#include <visit-config.h>
#include <vtkCharArray.h>
#include <vtkFloatArray.h>
......@@ -14,6 +15,12 @@
#include <NoInputException.h>
#include <ImproperUseException.h>
#ifdef HAVE_LIBBZ2
#include <bzlib.h>
#include <TimingsManager.h>
#include <DebugStream.h>
#endif
//
// Function Prototypes
......@@ -184,6 +191,7 @@ avtImageRepresentation::Initialize(void)
asCharRef = NULL;
rowOrigin = 0;
colOrigin = 0;
compressionRatio = -1.0;
}
......@@ -312,6 +320,40 @@ avtImageRepresentation::Valid(void)
}
// ****************************************************************************
// Method: avtImageRepresentation::GetImageString
//
// Purpose: Public interface to GetImageString
//
// Programmer: Mark C. Miller
// Creation: October 24, 2005
//
// ****************************************************************************
unsigned char *
avtImageRepresentation::GetImageString(int &length)
{
const bool useCompression = false;
return GetImageString(length, useCompression);
}
// ****************************************************************************
// Method: avtImageRepresentation::GetCompressedImageString
//
// Purpose: Public interface to GetImageString
//
// Programmer: Mark C. Miller
// Creation: October 24, 2005
//
// ****************************************************************************
unsigned char *
avtImageRepresentation::GetCompressedImageString(int &length)
{
const bool useCompression = true;
return GetImageString(length, useCompression);
}
// ****************************************************************************
// Method: avtImageRepresentation::GetImageString
//
......@@ -321,10 +363,14 @@ avtImageRepresentation::Valid(void)
// Programmer: Hank Childs
// Creation: November 21, 2000
//
// Modifications:
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added compression
// ****************************************************************************
unsigned char *
avtImageRepresentation::GetImageString(int &length)
avtImageRepresentation::GetImageString(int &length, bool compress)
{
if (asChar == NULL)
{
......@@ -337,6 +383,46 @@ avtImageRepresentation::GetImageString(int &length)
asCharRef = new int(1);
}
#ifdef HAVE_LIBBZ2
if (compress)
{
// shoot for >=2:1 compression ratio. Fall back to no compression
// if can't achieve it
unsigned int asCharLengthTMP = asCharLength;
unsigned int asCharLengthBZ2 = asCharLength / 2;
unsigned char *asCharBZ2 = new unsigned char [asCharLengthBZ2+10];
int startCompress = debug5_real ? visitTimer->StartTimer(true) : 0;
if (BZ2_bzBuffToBuffCompress((char*)asCharBZ2, &asCharLengthBZ2,
(char*)asChar, asCharLengthTMP,
1, 0, 250) != BZ_OK)
{
double dummy = debug5_real ?
visitTimer->StopTimer(startCompress,
"Compressing image", true)
: 0.0;
delete [] asCharBZ2;
}
else
{
double timeToCompress = debug5_real ?
visitTimer->StopTimer(startCompress,
"Compressing image",
true)
: 0.0;
debug5 << "Compressed image "
<< (float) asCharLength / (float) asCharLengthBZ2
<< ":1 in " << timeToCompress << " seconds" << endl;
sprintf((char*) &asCharBZ2[asCharLengthBZ2], "%10d", asCharLength);
delete [] asChar;
asChar = asCharBZ2;
asCharLength = asCharLengthBZ2+10;
compressionRatio = (float) asCharLength / (float) asCharLengthBZ2;
}
}
#endif
length = asCharLength;
return asChar;
}
......@@ -605,11 +691,58 @@ CreateStringFromVTKInput(vtkImageData *img, unsigned char *&str, int &len)
// Mark C. Miller, 22Jul03
// Re-wrote to avoid use of memcpy.
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added compression support
// ****************************************************************************
void avtImageRepresentation::GetImageFromString(unsigned char *str,
int strLength, vtkImageData *&img, float *&zbuffer)
{
#ifdef HAVE_LIBBZ2
//
// Handle a possibly compressed input string
//
if (str[0] == 'B' && str[1] == 'Z' && str[2] == 'h')
{
unsigned int strLengthTMP = strLength;
unsigned int strLengthOrig;
sscanf((char*) &str[strLength-10], "%10d", &strLengthOrig);
unsigned char *strOrig = new unsigned char[strLengthOrig];
int startDecompress = debug5_real ? visitTimer->StartTimer(true) : 0;
if (BZ2_bzBuffToBuffDecompress((char*) strOrig, &strLengthOrig,
(char*) str, strLengthTMP, 0, 0) != BZ_OK)
{
double dummy = debug5_real ?
visitTimer->StopTimer(startDecompress,
"Decompressing image", true)
: 0.0;
debug5 << "Found 3 character \"BZh\" header in image string "
<< "but failed to decompress. Assuming coincidence." << endl;
}
else
{
double timeToDecompress = debug5_real ?
visitTimer->StopTimer(startDecompress,
"Decompressing image",
true)
: 0.0;
debug5 << "Uncompressed image 1:"
<< (float) strLengthOrig / (float) strLength
<< " in " << timeToDecompress << " seconds" << endl;
delete [] str;
str = strOrig;
strLength = strLengthOrig;
// update the object, too
asChar = strOrig;
asCharLength = strLengthOrig;
compressionRatio = (float) strLengthOrig / (float) strLength;
}
}
#endif
// read the string assuming its just an image
vtkStructuredPointsReader *reader = vtkStructuredPointsReader::New();
vtkCharArray *charArray = vtkCharArray::New();
......@@ -740,3 +873,22 @@ avtImageRepresentation::GetNumberOfCells(bool polysOnly) const
return asVTK->GetNumberOfCells();
}
}
float
avtImageRepresentation::GetCompressionRatio() const
{
if (compressionRatio != -1.0)
return compressionRatio;
if (asChar != NULL)
{
if (asChar[0] == 'B' && asChar[1] == 'Z' && asChar[2] == 'h')
{
unsigned int asCharLengthOrig;
sscanf((char*) &asChar[asCharLength-10], "%10d", &asCharLengthOrig);
return (float) asCharLengthOrig / (float) asCharLength;
}
}
return compressionRatio;
}
......@@ -35,6 +35,9 @@ class vtkImageData;
// used by VTK. Since I don't plan to use this feature of a vtkImageData
// object, I have captured knowledge of row/col offset here in AVT.
//
// Mark C. Miller, Mon Oct 31 18:12:49 PST 2005
// Added code to support compression of data object string
//
// ****************************************************************************
class PIPELINE_API avtImageRepresentation
......@@ -56,11 +59,13 @@ class PIPELINE_API avtImageRepresentation
float *GetZBuffer(void);
unsigned char *GetRGBBuffer(void);
unsigned char *GetImageString(int &);
unsigned char *GetCompressedImageString(int &);
void GetSize(int *rowSize, int *colSize);
void SetOrigin(const int rowOrigin, const int colOrigin);
void GetOrigin(int *rowOrigin, int *colOrigin) const;
virtual int GetNumberOfCells(bool polysOnly = false) const;
float GetCompressionRatio() const;
bool Valid(void);
void ReleaseData(void);
......@@ -77,6 +82,7 @@ class PIPELINE_API avtImageRepresentation
int rowOrigin;
int colOrigin;
float compressionRatio;
void Copy(const avtImageRepresentation &);
void DestructSelf(void);
......@@ -85,6 +91,7 @@ class PIPELINE_API avtImageRepresentation
private:
void GetImageFromString(unsigned char *, int,
vtkImageData *&, float *&);
unsigned char *GetImageString(int &, bool);
};
inline
......
......@@ -46,6 +46,9 @@ class avtDataObjectString;
// Moved inlined destructor definition to .C file because certain compilers
// have problems with them.
//
// Mark C. Miller, Mon Oct 31 18:12:49 PST 2005
// Added code to support compression of data object string
//
// ****************************************************************************
class PIPELINE_API avtDataObjectWriter : virtual public avtOriginatingSink
......@@ -57,6 +60,7 @@ class PIPELINE_API avtDataObjectWriter : virtual public avtOriginatingSink
void Write(avtDataObjectString &);
void SetDestinationFormat(const TypeRepresentation&);
void SetUseCompression(bool val) { useCompression = val; };
void WriteInt(avtDataObjectString &, int) const;
void WriteFloat(avtDataObjectString &, float) const;
......@@ -73,6 +77,7 @@ class PIPELINE_API avtDataObjectWriter : virtual public avtOriginatingSink
protected:
TypeRepresentation sourceFormat;
TypeRepresentation destinationFormat;
bool useCompression;
virtual void DataObjectWrite(avtDataObjectString &) = 0;
};
......
......@@ -67,6 +67,9 @@ avtImageWriter::~avtImageWriter()
// Hank Childs, Mon Oct 1 09:31:50 PDT 2001
// Renamed to DataObjectWrite.
//
// Mark C. Miller, Mon Oct 31 18:12:49 PST 2005
// Added code to support compression of data object string
//
// ****************************************************************************
void
......@@ -74,7 +77,9 @@ avtImageWriter::DataObjectWrite(avtDataObjectString &str)
{
avtImageRepresentation &image = GetImageRep();
int length;
unsigned char *imagestr = image.GetImageString(length);
unsigned char *imagestr = useCompression ?
image.GetCompressedImageString(length) :
image.GetImageString(length);
//
// Write out how long the image string is.
......
......@@ -101,6 +101,8 @@ bool VisWinRendering::stereoEnabled = false;
// Replaced scalableThreshold member with scalableAutoThreshold
// Added scalableActivationMode member
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added initialization for 3 most recent rendering times
// ****************************************************************************
VisWinRendering::VisWinRendering(VisWindowColleagueProxy &p)
......@@ -113,6 +115,9 @@ VisWinRendering::VisWinRendering(VisWindowColleagueProxy &p)
summedRenderTime = 0.;
maxRenderTime = 0.;
minRenderTime = 1.e6;
curRenderTimes[0] = 0.0;
curRenderTimes[1] = 0.0;
curRenderTimes[2] = 0.0;
stereo = false;
stereoType = 2;
displayListMode = 2; // Auto
......@@ -524,13 +529,18 @@ VisWinRendering::EnableUpdates(void)
// Brad Whitlock, Thu Sep 19 17:04:58 PST 2002
// I added code to send the rendering time back to the client.
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added args to Start/Stop timer to force acquisition of timing information
// even if timings were not enabled on the command-line.
// Added 3 most recent rendering times to set of times returned
// ****************************************************************************
void
VisWinRendering::Render()
{
int timingsIndex = visitTimer->StartTimer();
bool timingEnabled = (timingsIndex != -1);
const bool forceTiming = true;
const bool timingEnabled = visitTimer->Enabled();
const int timingsIndex = visitTimer->StartTimer(forceTiming);
float rt = 0.;
if (realized)
......@@ -544,28 +554,23 @@ VisWinRendering::Render()
}
// Determine the time taken to render the image.
rt = (float)visitTimer->StopTimer(timingsIndex, "Render one frame", forceTiming);
if(timingEnabled)
{
// VisIt's timer is going so use its return value.
rt = (float)visitTimer->StopTimer(timingsIndex, "Render one frame");
// Dump the timings to the timings file.
visitTimer->DumpTimings();
}
else
{
// The timer is not going, use the render time for all of the
// renderers.
rt = background->GetLastRenderTimeInSeconds() +
canvas->GetLastRenderTimeInSeconds() +
foreground->GetLastRenderTimeInSeconds();
}
// Update the render times and call the renderer information callback
// if we need to.
summedRenderTime += (rt >= 0.) ? rt : 0.;
++nRenders;
minRenderTime = (rt < minRenderTime) ? rt : minRenderTime;
maxRenderTime = (rt > maxRenderTime) ? rt : maxRenderTime;
curRenderTimes[2] = curRenderTimes[1];
curRenderTimes[1] = curRenderTimes[0];
curRenderTimes[0] = (rt >= 0.) ? rt : 0.;
++nRenders;
// Call the rendering information callback
if(notifyForEachRender && !inMotion && renderInfo != 0)
......@@ -586,6 +591,8 @@ VisWinRendering::Render()
//
// Modifications:
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added reseting of 3 most recent rendering times
// ****************************************************************************
void
......@@ -595,6 +602,9 @@ VisWinRendering::ResetCounters()
summedRenderTime = 0.;
maxRenderTime = 0.;
minRenderTime = 1.e6;
curRenderTimes[0] = 0.0;
curRenderTimes[1] = 0.0;
curRenderTimes[2] = 0.0;
}
// ****************************************************************************
......@@ -1448,14 +1458,19 @@ VisWinRendering::SetAntialiasing(bool enabled)
//
// Modifications:
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added 3 most recent rendering times to set of times returned
// ****************************************************************************
void
VisWinRendering::GetRenderTimes(float times[3]) const
VisWinRendering::GetRenderTimes(float times[6]) const
{
times[0] = minRenderTime;
times[1] = (nRenders > 0) ? (summedRenderTime / float(nRenders)) : 0.;
times[2] = maxRenderTime;
times[3] = curRenderTimes[0];
times[4] = curRenderTimes[1];
times[5] = curRenderTimes[2];
}
// ****************************************************************************
......
......@@ -142,6 +142,9 @@ class VisWindowColleagueProxy;
// Mark C. Miller, Fri Mar 4 13:05:02 PST 2005
// Changed name of GetNumTriangles to GetNumPrimitives
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added 3 most recent rendering times to set of times returned by
// GetRenderTimes. Added supporting data members
// ****************************************************************************
class VISWINDOW_API VisWinRendering : public VisWinColleague
......@@ -211,7 +214,7 @@ class VISWINDOW_API VisWinRendering : public VisWinColleague
void SetAntialiasing(bool enabled);
bool GetAntialiasing() const
{ return antialiasing; };
void GetRenderTimes(float times[3]) const;
void GetRenderTimes(float times[6]) const;
void SetStereoRendering(bool enabled, int type);
bool GetStereo() const
{ return stereo; };
......@@ -282,6 +285,7 @@ class VISWINDOW_API VisWinRendering : public VisWinColleague
float maxRenderTime;
float summedRenderTime;
float nRenders;
float curRenderTimes[3];
// stereo option
static bool stereoEnabled;
......
......@@ -4581,11 +4581,14 @@ VisWindow::GetAntialiasing() const
// Creation: Mon Sep 23 14:07:40 PST 2002
//
// Modifications:
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added 3 most recent rendering times to set of times returned
//
// ****************************************************************************
void
VisWindow::GetRenderTimes(float times[3]) const
VisWindow::GetRenderTimes(float times[6]) const
{
rendering->GetRenderTimes(times);
}
......
......@@ -311,6 +311,9 @@ class VisitInteractor;
// Kathleen Bonnell, Mon Jun 27 14:54:36 PDT 2005
// Added GetMaxPlotZShift.
//
// Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
// Added 3 most recent rendering times to set of times returned
// by GetRenderTimes
// ****************************************************************************
class VISWINDOW_API VisWindow
......@@ -474,7 +477,7 @@ public:
void SetRenderInfoCallback(VisCallback *cb, void *data);
void SetAntialiasing(bool enabled);
bool GetAntialiasing() const;
void GetRenderTimes(float times[3]) const;
void GetRenderTimes(float times[6]) const;
void SetStereoRendering(bool enabled, int type);
bool GetStereo() const;
int GetStereoType() const;
......
......@@ -5502,6 +5502,69 @@ if test $ac_cv_lib_m_main = yes; then
LIBS="-lm $LIBS"
fi
echo "$as_me:$LINENO: checking for BZ2_bzBuffToBuffCompress in -lbz2" >&5
echo $ECHO_N "checking for BZ2_bzBuffToBuffCompress in -lbz2... $ECHO_C" >&6
if test "${ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lbz2 $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char BZ2_bzBuffToBuffCompress ();
int
main ()
{
BZ2_bzBuffToBuffCompress ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress" >&5
echo "${ECHO_T}$ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress" >&6
if test $ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress = yes; then
LIBS="-lbz2 $LIBS"
cat >>confdefs.h <<\_ACEOF
#define HAVE_LIBBZ2 1
_ACEOF
fi
saved_CPPFLAGS="$CPPFLAGS"
......@@ -9372,6 +9435,7 @@ else
fi
COMPONENT_CPPFLAGS="$COMPONENT_CPPFLAGS -I$""(TOPDIR)/include "
COMPONENT_CPPFLAGS="$COMPONENT_CPPFLAGS -I$""(TOPDIR)/include/visit "
COMPONENT_CPPFLAGS="$COMPONENT_CPPFLAGS $VTK_INCLUDES "
......
......@@ -572,6 +572,11 @@ dnl Jeremy Meredith, Thu Oct 13 13:55:32 PDT 2005
dnl Added cqscore, the tool for scoring tickets. Also forced a make on
dnl the bin directory before exiting configure.
dnl
dnl Mark C. Miller, Thu Nov 3 16:59:41 PST 2005
dnl I added code to check for libbz2 (bzip2)
dnl I also added -I$(TOPDIR)/include to COMPONENT_CPPFLAGS so that
dnl components could include visit-config.h
dnl
dnl --------------------------------------------------------------------------
dnl
......@@ -1414,6 +1419,9 @@ AC_TRY_COMPILE([#include <sys/types.h>
# are needed. The libraries are added to the beginning of `LIBS'.
#
AC_CHECK_LIB(m, main, LIBS="-lm $LIBS")
AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress, LIBS="-lbz2 $LIBS"
AC_DEFINE(HAVE_LIBBZ2)
)
dnl Is zlib present?
dnl
......@@ -2474,6 +2482,7 @@ else
fi
AC_SUBST(PREPROCESSOR_PARALLEL_SRC)