PCMContext.cpp

Go to the documentation of this file.
00001 
00002 //
00003 // This source file is a part of ParCompMark
00004 // Parallel Compositing Benchmark Framework
00005 //
00006 // for latest info see http://parcompmark.sourceforge.net
00007 
00008 //
00009 // Copyright (C) 2006 IT2 ParCompMark Dev. Team
00010 // 
00011 // This program is free software; you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License
00013 // as published by the Free Software Foundation; either version 2
00014 // of the License, or (at your option) any later version.
00015 // 
00016 // This program is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 // GNU General Public License for more details.
00020 // 
00021 // You should have received a copy of the GNU General Public License
00022 // along with this program; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00024 
00025 //
00026 // Inner includes
00027 //
00028 
00029 #include "../include/PCMContext.h"
00030 
00031 #include "../include/PCMProcess.h"
00032 
00033 #include "../include/PCMXDisplay.h"
00034 
00035 #include "../include/PCMHost.h"
00036 
00037 #include "../include/PCMStringConverter.h"
00038 
00039 namespace ParCompMark
00040 {
00041 
00042   //
00043   // Constructors & destructor
00044   //
00045 
00046   Context::Context()
00047         // You have to initialize the following attributes:
00048         // - mID
00049         // - mUseGLFrameletEXT
00050         // - mContextType
00051         // - mFrameID
00052         // - mFrameWidth
00053         // - mFrameHeight
00054         // - mColourFormat
00055         // - mDepthFormat
00056         // - mPixelFormat
00057         // - mCompositeType
00058         // - mCompressionHint
00059         // - mRetainOutputCount
00060         // - mVolatileFrameletCount
00061         // - mOutputDepth
00062         // - mProcesses
00063         // - mProcessCount
00064         // - mProcessIndex
00065         // - mHostIndex
00066         // - mNetworkID
00067         // - mContext
00068         // - mParent
00069         // - mInitialized
00070   {
00071         Except(INVALID_OPERATION_ERROR, "Context::Context()",
00072            "Default constructor for Squirrel compatibility. Calling this constructor always raises an exception.");
00073   }
00074 
00075  /*----------------------------------------------------------------------*/
00076 
00077   Context::Context(Process * parent):
00078         // Initialize parent 
00079    mParent(parent               /* Parent process */
00080         )
00081         // You have to initialize the following attributes:
00082         // - mID
00083         // - mUseGLFrameletEXT
00084         // - mContextType
00085         // - mFrameID
00086         // - mFrameWidth
00087         // - mFrameHeight
00088         // - mColourFormat
00089         // - mDepthFormat
00090         // - mPixelFormat
00091         // - mCompositeType
00092         // - mCompressionHint
00093         // - mRetainOutputCount
00094         // - mVolatileFrameletCount
00095         // - mOutputDepth
00096         // - mProcesses
00097         // - mProcessCount
00098         // - mProcessIndex
00099         // - mHostIndex
00100         // - mNetworkID
00101         // - mContext
00102         // - mParent
00103         // - mInitialized
00104   {
00105         Assert(parent, NULL_POINTER_ERROR, "Context::Context()");
00106 
00107         mUseGLFrameletEXT = true;
00108         mContextType = SLAVE;
00109         mFrameID = 0;
00110         mFrameWidth = 256;
00111         mFrameHeight = 256;
00112         mColourFormat = PC_PF_BGRA8;
00113         mDepthFormat = PC_PF_Z32I;
00114         mPixelFormat = mColourFormat | mDepthFormat;
00115         mCompositeType = PC_COMP_DEPTH;
00116         mCompressionHint = PC_COMPRESSION_NONE;
00117         mRetainOutputCount = 1;
00118         mVolatileFrameletCount = 0;
00119         mOutputDepth = true;
00120         mProcesses = 0;
00121         mProcessCount = -1;
00122         mHostIndex = -1;
00123         mNetworkID = PC_ID_DEFAULT;
00124         mContext = 0;
00125         mInitialized = false;
00126 
00127         Logger::getInstance()->log(Logger::NOTICE,
00128                                  "Context has been created for process `" + mParent->getName() + "\'");
00129   }
00130 
00131  /*----------------------------------------------------------------------*/
00132 
00133   Context::~Context()
00134   {
00135         // Deallocate name buffers
00136 
00137         if(mInitialized)
00138         {
00139          finalize();
00140         }
00141 
00142         if(mProcesses)
00143         {
00144          for(int i = 0; i < mProcessCount; i++)
00145                 if(mProcesses[i])
00146                  delete mProcesses[i];
00147 
00148          delete mProcesses;
00149         }
00150 
00151         Logger::getInstance()->log(Logger::NOTICE,
00152                                  "Context has been destroyed for process `" + mParent->getName() + "\'");
00153   }
00154 
00155  /*----------------------------------------------------------------------*/
00156 
00157   //
00158   // Methods
00159   //
00160 
00161   void Context::setProcesses(const char *processList)
00162   {
00163         std::string processListStr(processList);
00164 
00165         // Get number of processes
00166         std::string::size_type index = 0, i = 0;
00167         mProcessCount = 1;
00168 
00169         while((index = processListStr.find(";", index)) != std::string::npos)
00170         {
00171          mProcessCount++;
00172          index++;
00173         }
00174         mProcesses = new PCstring[mProcessCount + 1];
00175 
00176         // Get name of processes in format host:localid
00177         while((index = processListStr.find(";")) != std::string::npos)
00178         {
00179          std::string processName = processListStr.substr(0, index);
00180          mProcesses[i] = strdup(processName.c_str());
00181 
00182          processListStr = processListStr.substr(++index);
00183          i++;
00184         }
00185         mProcesses[i] = strdup(processListStr.c_str());
00186 
00187         mProcesses[mProcessCount] = 0;
00188   }
00189 
00190  /*----------------------------------------------------------------------*/
00191 
00192   void Context::initialize()
00193   {
00194         Assert(!mInitialized, INVALID_OPERATION_ERROR, "Context::initialize()");
00195 
00196         const int max = 64;
00197 
00198         if(mUseGLFrameletEXT)
00199         {
00200          // Query extension in the interface
00201 #ifndef PC_EXT_CUR_GFX_CTX
00202          Except(INTERNAL_ERROR, "Context::initialize()",
00203                  "PC_EXT_CUR_GFX_CTX extension is not present in your PC interface.");
00204 #endif
00205          // TODO what is the extension name 
00206 
00212         }
00213 
00214         switch (mContextType)
00215         {
00216                 //
00217                 // Master context initialization
00218                 //
00219          case MASTER:
00220                 {
00221 
00222                  // set attributes i:attribute i+1:attribute value
00223                  int i = 0;
00224                  PCint attribs[max];
00225 
00226                  attribs[i++] = PC_FRAME_WIDTH;
00227                  attribs[i++] = mFrameWidth;
00228                  attribs[i++] = PC_FRAME_HEIGHT;
00229                  attribs[i++] = mFrameHeight;
00230                  attribs[i++] = PC_COMPOSITE_TYPE;
00231                  attribs[i++] = mCompositeType;
00232                  attribs[i++] = PC_PIXEL_FORMAT;
00233                  // PC bug? cannot pass depth format when alpha compositing
00234                  attribs[i++] = (mCompositeType == PC_COMP_ALPHA_SORT ? mColourFormat : mPixelFormat);
00235                  attribs[i++] = PC_COMPRESSION_HINT;
00236                  attribs[i++] = mCompressionHint;
00237                  attribs[i++] = PC_NETWORK_ID;
00238                  attribs[i++] = mNetworkID;
00239                  attribs[i++] = PC_OUTPUT_DEPTH;
00240                  attribs[i++] = (PCint) (mOutputDepth ? 1 : 0);
00241                  attribs[i++] = PC_RETAIN_OUTPUT;
00242                  attribs[i++] = mRetainOutputCount;
00243                  attribs[i++] = PC_VOLATILE_FRAMELET;
00244                  attribs[i++] = mVolatileFrameletCount;
00245                  attribs[i++] = PC_PROPERTY_END;
00246 
00252                  if(PCerr err =
00253                    pcContextCreateMaster(attribs, mProcesses, mProcesses[mProcessIndex], &mContext) != PC_NO_ERROR)
00254                  {
00255                         //std::cerr << "[M] Error: " << mProcesses[mProcessIndex] << std::endl;
00256                         Except(INTERNAL_ERROR, "Context::initialize()", pcGetErrorString(err));
00257                  }
00258                 }
00259 
00260                 //std::cerr << "[M] Ok: " << mProcesses[mProcessIndex] << std::endl;
00261 
00262                 break;
00263 
00264                 //
00265                 // Slave context initialization
00266                 //
00267          case SLAVE:
00268                 {
00269 
00270                  //std::cerr << "[S] Process: " << mProcesses[mProcessIndex] << std::endl;
00271 
00272                  if(PCerr err = pcContextCreate(mNetworkID, mProcesses[mProcessIndex], &mContext) != PC_NO_ERROR)
00273                  {
00274                         //std::cerr << "[S] Error: " << mProcesses[mProcessIndex] << std::endl;
00275                         Except(INTERNAL_ERROR, "Context::initialize()", pcGetErrorString(err));
00276                  }
00277                  //std::cerr << "[S] Ok: " << mProcesses[mProcessIndex] << std::endl;
00278                  //int retval = 0; pthread_exit(&retval);
00279 
00280                  Logger::getInstance()->log(Logger::NOTICE,
00281                                            "Slave PC context has been initialized for process `" +
00282                                            mParent->getName() + "\'");
00283                 }
00284         }
00285 
00286         //int retval = 0; pthread_exit(&retval);
00287 
00288         // Synchronize context and set starting time of the process
00289         if(PCerr err = pcContextSync(mContext) != PC_NO_ERROR)
00290          Except(INTERNAL_ERROR, "Context::initialize()", pcGetErrorString(err));
00291         mParent->setStartTime(Timer::getSystemTime());
00292 
00293         // Get host index
00294         if(PCerr err = pcContextGetInteger(mContext, PC_HOSTINDEX, PC_LOCALHOST_INDEX, &mHostIndex) != PC_NO_ERROR)
00295          Except(INTERNAL_ERROR, "Context::initialize()", pcGetErrorString(err));
00296 
00297         // Get attributes for slave node
00298         if(mContextType == SLAVE)
00299         {
00300          if(PCerr err = pcContextGetInteger(mContext, PC_NUM_HOSTS, PC_ID_DEFAULT, &mProcessCount) != PC_NO_ERROR)
00301                 Except(INTERNAL_ERROR, "Context::initialize()", pcGetErrorString(err));
00302 
00303          if(PCerr err = pcContextGetInteger(mContext, PC_FRAME_WIDTH, PC_ID_DEFAULT, &mFrameWidth) != PC_NO_ERROR)
00304                 Except(INTERNAL_ERROR, "Context::initialize()", pcGetErrorString(err));
00305 
00306          if(PCerr err = pcContextGetInteger(mContext, PC_FRAME_HEIGHT, PC_ID_DEFAULT, &mFrameHeight) != PC_NO_ERROR)
00307                 Except(INTERNAL_ERROR, "Context::initialize()", pcGetErrorString(err));
00308 
00309          if(PCerr err = pcContextGetInteger(mContext, PC_PIXEL_FORMAT, PC_ID_DEFAULT, &mPixelFormat) != PC_NO_ERROR)
00310                 Except(INTERNAL_ERROR, "Context::initialize()", pcGetErrorString(err));
00311         }
00312 
00313         mInitialized = true;
00314 
00315         // Log starting of the benchmark
00316         Logger::getInstance()->log(Logger::NOTICE,
00317                                  "Benchmark timer started at " + StringConverter::toString(mParent->getStartTime()) +
00318                                  " for process " + mParent->getName());
00319   }
00320 
00321  /*----------------------------------------------------------------------*/
00322 
00323   void Context::finalize()
00324   {
00325         Assert(mInitialized, INVALID_OPERATION_ERROR, "Context::finalize()");
00326 
00327         if(PCerr err = pcContextDestroy(mContext) != PC_NO_ERROR)
00328          Except(INTERNAL_ERROR, "Context::finalize()", pcGetErrorString(err));
00329 
00330         mInitialized = false;
00331 
00332         Logger::getInstance()->log(Logger::DEBUG,
00333                                  "PC context has been finalized for process `" + mParent->getName() + "\'");
00334 
00335   }
00336 
00337  /*----------------------------------------------------------------------*/
00338 
00339 }