void Image::flipVertically()
{
  if (depth)
    return;
    
  GLubyte *newDataBuffer = new GLubyte[width*height*components];
  int      counterDown   = 0,
                           counterUp     = 0;
                           
  if (components == 3)
  {
    for (int y = 0, y1 = height - 1; y < height; y++, y1--)
      for (int x = 0; x < width; x++)
      {
        counterUp   = (x + y1 * width) * 3;
        counterDown = (x +  y * width) * 3;
        newDataBuffer[counterUp + 0]   = dataBuffer[counterDown + 0];
        newDataBuffer[counterUp + 1]   = dataBuffer[counterDown + 1];
        newDataBuffer[counterUp + 2]   = dataBuffer[counterDown + 2];
      }
  }
  
  if (components == 4)
  {
    for (int y = 0, y1 = height - 1; y < height; y++, y1--)
      for (int x = 0; x < width; x++)
      {
        counterUp   = (x + y1 * width) * components;
        counterDown = (x +  y * width) * components;
        newDataBuffer[counterUp + 0]   = dataBuffer[counterDown + 0];
        newDataBuffer[counterUp + 1]   = dataBuffer[counterDown + 1];
        newDataBuffer[counterUp + 2]   = dataBuffer[counterDown + 2];
        newDataBuffer[counterUp + 3]   = dataBuffer[counterDown + 3];
      }
  }
  
  if (components == 1)
  {
    for (int y = 0, y1 = height - 1; y < height; y++, y1--)
      for (int x = 0; x < width; x++)
      {
        counterUp   = x + y1 * width;
        counterDown = x +  y * width;
        newDataBuffer[counterUp + 0]   = dataBuffer[counterDown + 0];
      }
  }
  
  setDataBuffer(newDataBuffer);
  deleteArray(newDataBuffer);
}
Image &Image::operator=(const Image & copy)
{
  if (this != &copy)
  {
    internalFormat = copy.internalFormat;
    components     = copy.components;
    format         = copy.format;
    height         = copy.height;
    width          = copy.width;
    depth          = copy.depth;
    path           = copy.path;
    
    setDataBuffer(copy.dataBuffer);
  }
  return *this;
}
Exemple #3
0
/* QWinSound */
QWinSound::QWinSound(plCreatable* pCre, QWidget* parent)
         : QCreatable(pCre, kSound, parent)
{
    plSound* obj = plSound::Convert(fCreatable);

    fSynchObjLink = new QCreatableLink(this, false);
    fSynchObjLink->setCreatable(obj, tr("Synch Flags"));
    fSynchObjLink->setForceType(kSynchedObject);

    fTime = new QFloatEdit(this);
    fMaxFalloff = new QIntEdit(this);
    fMinFalloff = new QIntEdit(this);
    fCurrVolume = new QFloatEdit(this);
    fDesiredVolume = new QFloatEdit(this);
    fSoundType = new QComboBox(this);
    fSoundType->addItems(QStringList() << "Sound FX" << "Ambience"
                         << "Background Music" << "GUI Sound" << "NPC Voices");
    fOuterVol = new QIntEdit(this);
    fInnerCone = new QIntEdit(this);
    fOuterCone = new QIntEdit(this);
    fFadedVolume = new QFloatEdit(this);
    fPriority = new QIntEdit(this);
    fPriority->setRange(0, 0xFF);
    fPlaying = new QCheckBox(tr("Playing"), this);
    fSubtitleId = new QLineEdit(this);

    fTime->setValue(obj->getTime());
    fMaxFalloff->setValue(obj->getMaxFalloff());
    fMinFalloff->setValue(obj->getMinFalloff());
    fCurrVolume->setValue(obj->getCurrVolume());
    fDesiredVolume->setValue(obj->getDesiredVolume());
    fSoundType->setCurrentIndex(obj->getType());
    fOuterVol->setValue(obj->getOuterVol());
    fInnerCone->setValue(obj->getInnerCone());
    fOuterCone->setValue(obj->getOuterCone());
    fFadedVolume->setValue(obj->getFadedVolume());
    fPriority->setValue(obj->getPriority());
    fPlaying->setChecked(obj->isPlaying());
    fSubtitleId->setText(st2qstr(obj->getSubtitleId()));

    QGroupBox* grpProperties = new QGroupBox(tr("Properties"), this);
    QGridLayout* layProperties = new QGridLayout(grpProperties);
    layProperties->setVerticalSpacing(0);
    layProperties->setHorizontalSpacing(8);
    fProperties[kPropIs3DSound] = new QCheckBox(tr("Is 3D Sound"), grpProperties);
    fProperties[kPropDisableLOD] = new QCheckBox(tr("Disable LOD"), grpProperties);
    fProperties[kPropLooping] = new QCheckBox(tr("Looping"), grpProperties);
    fProperties[kPropAutoStart] = new QCheckBox(tr("Auto Start"), grpProperties);
    fProperties[kPropLocalOnly] = new QCheckBox(tr("Local Only"), grpProperties);
    fProperties[kPropLoadOnlyOnCall] = new QCheckBox(tr("Load Only on Call"), grpProperties);
    fProperties[kPropFullyDisabled] = new QCheckBox(tr("Fully Disabled"), grpProperties);
    fProperties[kPropDontFade] = new QCheckBox(tr("Don't Fade"), grpProperties);
    fProperties[kPropIncidental] = new QCheckBox(tr("Incidental"), grpProperties);
    fProperties[kPropIs3DSound]->setChecked((obj->getProperties() & plSound::kPropIs3DSound) != 0);
    fProperties[kPropDisableLOD]->setChecked((obj->getProperties() & plSound::kPropDisableLOD) != 0);
    fProperties[kPropLooping]->setChecked((obj->getProperties() & plSound::kPropLooping) != 0);
    fProperties[kPropAutoStart]->setChecked((obj->getProperties() & plSound::kPropAutoStart) != 0);
    fProperties[kPropLocalOnly]->setChecked((obj->getProperties() & plSound::kPropLocalOnly) != 0);
    fProperties[kPropLoadOnlyOnCall]->setChecked((obj->getProperties() & plSound::kPropLoadOnlyOnCall) != 0);
    fProperties[kPropFullyDisabled]->setChecked((obj->getProperties() & plSound::kPropFullyDisabled) != 0);
    fProperties[kPropDontFade]->setChecked((obj->getProperties() & plSound::kPropDontFade) != 0);
    fProperties[kPropIncidental]->setChecked((obj->getProperties() & plSound::kPropIncidental) != 0);
    layProperties->addWidget(fProperties[kPropIs3DSound], 0, 0);
    layProperties->addWidget(fProperties[kPropDisableLOD], 1, 0);
    layProperties->addWidget(fProperties[kPropLooping], 2, 0);
    layProperties->addWidget(fProperties[kPropAutoStart], 0, 1);
    layProperties->addWidget(fProperties[kPropLocalOnly], 1, 1);
    layProperties->addWidget(fProperties[kPropLoadOnlyOnCall], 2, 1);
    layProperties->addWidget(fProperties[kPropFullyDisabled], 0, 2);
    layProperties->addWidget(fProperties[kPropDontFade], 1, 2);
    layProperties->addWidget(fProperties[kPropIncidental], 2, 2);

    QGroupBox* grpFadeIn = new QGroupBox(tr("Fade In Parameters"), this);
    QGridLayout* layFadeIn = new QGridLayout(grpFadeIn);
    layFadeIn->setVerticalSpacing(4);
    layFadeIn->setHorizontalSpacing(8);
    fFadeInParams.fLength = new QFloatEdit(grpFadeIn);
    fFadeInParams.fVolStart = new QFloatEdit(grpFadeIn);
    fFadeInParams.fVolEnd = new QFloatEdit(grpFadeIn);
    fFadeInParams.fType = new QComboBox(grpFadeIn);
    fFadeInParams.fCurrTime = new QFloatEdit(grpFadeIn);
    fFadeInParams.fStopWhenDone = new QCheckBox(tr("Stop When Done"), grpFadeIn);
    fFadeInParams.fFadeSoftVol = new QCheckBox(tr("Fade Soft Volume"), grpFadeIn);
    fFadeInParams.fType->addItems(QStringList() << "Linear" << "Logarithmic" << "Exponential");
    fFadeInParams.fLength->setValue(obj->getFadeInParams().fLengthInSecs);
    fFadeInParams.fVolStart->setValue(obj->getFadeInParams().fVolStart);
    fFadeInParams.fVolEnd->setValue(obj->getFadeInParams().fVolEnd);
    fFadeInParams.fType->setCurrentIndex(obj->getFadeInParams().fType);
    fFadeInParams.fCurrTime->setValue(obj->getFadeInParams().fCurrTime);
    fFadeInParams.fStopWhenDone->setChecked(obj->getFadeInParams().fStopWhenDone);
    fFadeInParams.fFadeSoftVol->setChecked(obj->getFadeInParams().fFadeSoftVol);
    layFadeIn->addWidget(new QLabel(tr("Length (Secs):"), grpFadeIn), 0, 0);
    layFadeIn->addWidget(fFadeInParams.fLength, 0, 1);
    layFadeIn->addWidget(new QLabel(tr("Volume Start:"), grpFadeIn), 1, 0);
    layFadeIn->addWidget(fFadeInParams.fVolStart, 1, 1);
    layFadeIn->addWidget(new QLabel(tr("Volume End:"), grpFadeIn), 2, 0);
    layFadeIn->addWidget(fFadeInParams.fVolEnd, 2, 1);
    layFadeIn->addWidget(new QLabel(tr("Type:"), grpFadeIn), 3, 0);
    layFadeIn->addWidget(fFadeInParams.fType, 3, 1);
    layFadeIn->addWidget(new QLabel(tr("Current Time:"), grpFadeIn), 4, 0);
    layFadeIn->addWidget(fFadeInParams.fCurrTime, 4, 1);
    layFadeIn->addWidget(fFadeInParams.fStopWhenDone, 5, 0, 1, 2);
    layFadeIn->addWidget(fFadeInParams.fFadeSoftVol, 6, 0, 1, 2);

    QGroupBox* grpFadeOut = new QGroupBox(tr("Fade Out Parameters"), this);
    QGridLayout* layFadeOut = new QGridLayout(grpFadeOut);
    layFadeOut->setVerticalSpacing(4);
    layFadeOut->setHorizontalSpacing(8);
    fFadeOutParams.fLength = new QFloatEdit(grpFadeOut);
    fFadeOutParams.fVolStart = new QFloatEdit(grpFadeOut);
    fFadeOutParams.fVolEnd = new QFloatEdit(grpFadeOut);
    fFadeOutParams.fType = new QComboBox(grpFadeOut);
    fFadeOutParams.fCurrTime = new QFloatEdit(grpFadeOut);
    fFadeOutParams.fStopWhenDone = new QCheckBox(tr("Stop When Done"), grpFadeOut);
    fFadeOutParams.fFadeSoftVol = new QCheckBox(tr("Fade Soft Volume"), grpFadeOut);
    fFadeOutParams.fType->addItems(QStringList() << "Linear" << "Logarithmic" << "Exponential");
    fFadeOutParams.fLength->setValue(obj->getFadeOutParams().fLengthInSecs);
    fFadeOutParams.fVolStart->setValue(obj->getFadeOutParams().fVolStart);
    fFadeOutParams.fVolEnd->setValue(obj->getFadeOutParams().fVolEnd);
    fFadeOutParams.fType->setCurrentIndex(obj->getFadeOutParams().fType);
    fFadeOutParams.fCurrTime->setValue(obj->getFadeOutParams().fCurrTime);
    fFadeOutParams.fStopWhenDone->setChecked(obj->getFadeOutParams().fStopWhenDone);
    fFadeOutParams.fFadeSoftVol->setChecked(obj->getFadeOutParams().fFadeSoftVol);
    layFadeOut->addWidget(new QLabel(tr("Length (Secs):"), grpFadeOut), 0, 0);
    layFadeOut->addWidget(fFadeOutParams.fLength, 0, 1);
    layFadeOut->addWidget(new QLabel(tr("Volume Start:"), grpFadeOut), 1, 0);
    layFadeOut->addWidget(fFadeOutParams.fVolStart, 1, 1);
    layFadeOut->addWidget(new QLabel(tr("Volume End:"), grpFadeOut), 2, 0);
    layFadeOut->addWidget(fFadeOutParams.fVolEnd, 2, 1);
    layFadeOut->addWidget(new QLabel(tr("Type:"), grpFadeOut), 3, 0);
    layFadeOut->addWidget(fFadeOutParams.fType, 3, 1);
    layFadeOut->addWidget(new QLabel(tr("Current Time:"), grpFadeOut), 4, 0);
    layFadeOut->addWidget(fFadeOutParams.fCurrTime, 4, 1);
    layFadeOut->addWidget(fFadeOutParams.fStopWhenDone, 5, 0, 1, 2);
    layFadeOut->addWidget(fFadeOutParams.fFadeSoftVol, 6, 0, 1, 2);

    fSoftRegion = new QCreatableLink(this);
    fSoftRegion->setKey(obj->getSoftRegion());

    fDataBuffer = new QCreatableLink(this);
    fDataBuffer->setKey(obj->getDataBuffer());

    fSoftOcclusionRegion = new QCreatableLink(this);
    fSoftOcclusionRegion->setKey(obj->getSoftOcclusionRegion());

    QWidget* eaxWidget = new QWidget(this);
    QHBoxLayout* eaxLayout = new QHBoxLayout(eaxWidget);
    eaxLayout->setContentsMargins(0, 0, 0, 0);
    eaxLayout->setSpacing(4);
    QLinkLabel* linkEaxSettings = new QLinkLabel(eaxWidget);
    linkEaxSettings->setText(tr("EAX Settings"));
    eaxLayout->addWidget(linkEaxSettings);
    eaxLayout->addStretch();
    connect(linkEaxSettings, SIGNAL(activated()), this, SLOT(editEaxSettings()));

    QGridLayout* layout = new QGridLayout(this);
    layout->setContentsMargins(8, 8, 8, 8);
    layout->addWidget(fSynchObjLink, 0, 0, 1, 4);
    layout->addWidget(new QLabel(tr("Time:"), this), 1, 0);
    layout->addWidget(fTime, 1, 1);
    layout->addWidget(new QLabel(tr("Max Falloff:"), this), 2, 0);
    layout->addWidget(fMaxFalloff, 2, 1);
    layout->addWidget(new QLabel(tr("Min Falloff:"), this), 3, 0);
    layout->addWidget(fMinFalloff, 3, 1);
    layout->addWidget(new QLabel(tr("Current Vol:"), this), 4, 0);
    layout->addWidget(fCurrVolume, 4, 1);
    layout->addWidget(new QLabel(tr("Desired Vol:"), this), 5, 0);
    layout->addWidget(fDesiredVolume, 5, 1);
    layout->addWidget(new QLabel(tr("Type:"), this), 6, 0);
    layout->addWidget(fSoundType, 6, 1);
    layout->addWidget(new QLabel(tr("Outer Volume:"), this), 1, 2);
    layout->addWidget(fOuterVol, 1, 3);
    layout->addWidget(new QLabel(tr("Inner Cone:"), this), 2, 2);
    layout->addWidget(fInnerCone, 2, 3);
    layout->addWidget(new QLabel(tr("Outer Cone:"), this), 3, 2);
    layout->addWidget(fOuterCone, 3, 3);
    layout->addWidget(new QLabel(tr("Faded Volume:"), this), 4, 2);
    layout->addWidget(fFadedVolume, 4, 3);
    layout->addWidget(new QLabel(tr("Priority:"), this), 5, 2);
    layout->addWidget(fPriority, 5, 3);
    layout->addWidget(fPlaying, 6, 2, 1, 2, Qt::AlignRight);
    layout->addWidget(new QLabel(tr("Subtitle ID:"), this), 7, 0);
    layout->addWidget(fSubtitleId, 7, 1, 1, 3);
    layout->addWidget(grpProperties, 8, 0, 1, 4);
    layout->addWidget(grpFadeIn, 9, 0, 1, 2);
    layout->addWidget(grpFadeOut, 9, 2, 1, 2);
    layout->addWidget(new QLabel(tr("Soft Region:"), this), 10, 0);
    layout->addWidget(fSoftRegion, 10, 1, 1, 3);
    layout->addWidget(new QLabel(tr("Data Buffer:"), this), 11, 0);
    layout->addWidget(fDataBuffer, 11, 1, 1, 3);
    layout->addWidget(new QLabel(tr("Soft Occlusion:"), this), 12, 0);
    layout->addWidget(fSoftOcclusionRegion, 12, 1, 1, 3);
    layout->addWidget(eaxWidget, 13, 0, 1, 4);

    connect(fSoftRegion, SIGNAL(addObject()), this, SLOT(setSoftRegion()));
    connect(fSoftRegion, SIGNAL(delObject()), this, SLOT(unsetSoftRegion()));
    connect(fDataBuffer, SIGNAL(addObject()), this, SLOT(setDataBuffer()));
    connect(fDataBuffer, SIGNAL(delObject()), this, SLOT(unsetDataBuffer()));
    connect(fSoftOcclusionRegion, SIGNAL(addObject()), this, SLOT(setSoftOcclusionRegion()));
    connect(fSoftOcclusionRegion, SIGNAL(delObject()), this, SLOT(unsetSoftOcclusionRegion()));
}
int main(int argc, char * argv[])
{
    int numPointsPerDimension;
    int verbose = 0;
    double omega;
    double epsilon;
    double * * points;
    struct timeval startTime;
    struct timeval endTime;
    double duration;
    double breakdown = 0;
    int numIterations;
    double maxDiff, tmpMaxDiff;

    int numProcesses;
    int workingProcesses;
    int myRank;
    MPI_Status status;
    MPI_Request requestUpSend, requestUpRecv;
    MPI_Request requestDownSend, requestDownRecv;
    int partitions;
    int remainder;
    int width;
    int i, k;
    int buffSize;
    int startRow;

    double * upPointsSend, * upPointsRecv;
    double * downPointsSend, * downPointsRecv;

    int upperProc, lowerProc;
    struct timeval startInterval;
    struct timeval endInterval;

    if (argc < 2)
    {
        fprintf(stderr, "ERROR: Too few arguments!\n");
        printUsage(argv[0]);
        exit(1);
    }
    else if (argc > 3)
    {
        fprintf(stderr, "ERROR: Too many arguments!\n");
        printUsage(argv[0]);
        exit(1);
    }
    else
    {
        int argIdx = 1;
        if (argc == 3)
        {
            if (strncmp(argv[argIdx], OPTION_VERBOSE, strlen(OPTION_VERBOSE)) != 0)
            {
                fprintf(stderr, "ERROR: Unexpected option '%s'!\n", argv[argIdx]);
                printUsage(argv[0]);
                exit(1);
            }
            verbose = 1;
            ++argIdx;
        }
        numPointsPerDimension = atoi(argv[argIdx]);
        if (numPointsPerDimension < 2)
        {
            fprintf(stderr, "ERROR: The number of points, '%s', should be "
                "a numeric value greater than or equal to 2!\n", argv[argIdx]);
            printUsage(argv[0]);
            exit(1);
        }
    }
    
    MPI_Init(&argc, &argv);

    /* get info about how may processes are running 
     * and what is your rank number */
    MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
    MPI_Comm_rank(MPI_COMM_WORLD, &myRank);

    /* calculate nominal size of data per each process */
    partitions = numPointsPerDimension / numProcesses;

    /* calculate number of processes with the additional row of data */
    remainder = numPointsPerDimension % numProcesses;

    /* according to myRank, set the width of the table */
    width = (myRank < remainder) ? partitions + 1 : partitions;
    
    /* decide how many processes are required to do the calculation */
    workingProcesses = (numProcesses > numPointsPerDimension) ? numPointsPerDimension : numProcesses;

    /* terminate processes that won't be used */
    /* start of copied part of code */
    MPI_Comm MY_WORLD = MPI_COMM_WORLD;
    if(workingProcesses < numProcesses)
    {
        MPI_Group world_group;
        MPI_Comm_group(MPI_COMM_WORLD, &world_group);
        
        // Remove all unnecessary ranks
        MPI_Group new_group;
        int ranges[1][3] = {{workingProcesses, (numProcesses - 1), 1}};
        MPI_Group_range_excl(world_group, 1, ranges, &new_group);

        // Create a new communicator
        MPI_Comm_create(MPI_COMM_WORLD, new_group, &MY_WORLD);

        if (MY_WORLD == MPI_COMM_NULL)
        {
            // Bye bye cruel world
            MPI_Finalize();
            exit(0);
        }
    }
    /* end of copied part of code */
    /* source: http://stackoverflow.com/questions/13774968/mpi-kill-unwanted-processes */


    /* set the calculation parameters */
    omega = getOmega(numPointsPerDimension);
    epsilon = getEpsilon(numPointsPerDimension);
    
    /* allocate points table for each process */
    points = allocatePoints(numPointsPerDimension, width, numProcesses);
    if (points == NULL)
    {
        freePoints(points, width, myRank);
        fprintf(stderr, "ERROR: Malloc failed!\n");
        exit(1);
    }
    
    /* size of the table to send per each iteration */
    buffSize = numPointsPerDimension / 2 + numPointsPerDimension % 2 ;
    
    /* initialize additional buffers for communication */
    upPointsSend = initializeBuffer(buffSize);
    upPointsRecv = initializeBuffer(buffSize);
    downPointsSend = initializeBuffer(buffSize);
    downPointsRecv = initializeBuffer(buffSize);
    
    /* process #0 sends to others separate parts of the table
     * others wait for incoming data */
    if (myRank == 0)
    { 
        startRow = numPointsPerDimension;
        for(k = workingProcesses - 1; k >= 0 ; --k)
        {
            width = (k < remainder) ? partitions + 1 : partitions;
            
            /* initialize points */
            initializePoints(points, startRow - width, width, numPointsPerDimension);
        
            /* send table to k-th process */
            if(k != 0)
            {
                for(i = 0; i < width; ++i)
                {
                    MPI_Send(points[i], numPointsPerDimension, MPI_DOUBLE, k, 123, MY_WORLD);
                }
            }
            startRow -= width;
        }        
    } 
    else 
    {
        if(myRank < workingProcesses)
        {
            for(i = 0; i < width; ++i)
            {
                MPI_Recv(points[i], numPointsPerDimension, MPI_DOUBLE, 0, 123, MY_WORLD, &status);
            }
        }
    }

    /* remember with which processes you comunicate */ 
    upperProc = myRank == 0 ? MPI_PROC_NULL : myRank - 1;
    lowerProc = myRank == workingProcesses - 1 ? MPI_PROC_NULL : myRank + 1;
    
    /* here each process has it's own data set for computations */

    if(remainder > 0)
    {
        startRow = (myRank < remainder) ? myRank * (partitions + 1) : myRank * partitions + remainder;
    }
    else 
    {
        startRow = myRank * partitions;
    }

    if(gettimeofday(&startTime, NULL))
    {
        freePoints(points, width, myRank);
        fprintf(stderr, "ERROR: Gettimeofday failed!\n");
        exit(1);
    }
    
    /* Start of computations. */
    
    numIterations = 0;
    do
    {
        int i, j, color;
        maxDiff = 0.0;
        for (color = 0; color < 2; ++color)
        {

            /* fill downPointsSend with the last row of points data */
            setDataBuffer(downPointsSend, points, width - 1, 1 + ((startRow + width) % 2 == color ? 1 : 0), numPointsPerDimension);

            if(gettimeofday(&startInterval, NULL))
		    {
		        freePoints(points, width, myRank);
		        fprintf(stderr, "ERROR: Gettimeofday failed!\n");
		        exit(1);
	        }
            
            MPI_Isend(downPointsSend, buffSize, MPI_DOUBLE, lowerProc, color, MY_WORLD, &requestDownSend);
            MPI_Irecv(downPointsRecv, buffSize, MPI_DOUBLE, lowerProc, color, MY_WORLD, &requestDownRecv);
            
            if(gettimeofday(&endInterval, NULL))
		    {
		        freePoints(points, width, myRank);
		        fprintf(stderr, "ERROR: Gettimeofday failed!\n");
		        exit(1);
		    }
	
		    breakdown += ((double)endInterval.tv_sec + ((double)endInterval.tv_usec / 1000000.0)) - 
	                     ((double)startInterval.tv_sec + ((double)startInterval.tv_usec / 1000000.0));

            /* fill upPointsSend with the last row of points data */
            setDataBuffer(upPointsSend, points, 0, 1 + ((startRow - 1) % 2 == color ? 1 : 0), numPointsPerDimension);

		    if(gettimeofday(&startInterval, NULL))
		    {
		        freePoints(points, width, myRank);
		        fprintf(stderr, "ERROR: Gettimeofday failed!\n");
		        exit(1);
		    }

		    MPI_Isend(upPointsSend, buffSize, MPI_DOUBLE, upperProc, color, MY_WORLD, &requestUpSend);
            MPI_Irecv(upPointsRecv, buffSize, MPI_DOUBLE, upperProc, color, MY_WORLD, &requestUpRecv);
			
		    if(gettimeofday(&endInterval, NULL))
		    {
		        freePoints(points, width, myRank);
		        fprintf(stderr, "ERROR: Gettimeofday failed!\n");
		        exit(1);
		    }
		
		    breakdown += ((double)endInterval.tv_sec + ((double)endInterval.tv_usec / 1000000.0)) - 
        	             ((double)startInterval.tv_sec + ((double)startInterval.tv_usec / 1000000.0));

            /* computations of the first row requires data that has to be recieved from other process */
            MPI_Wait(&requestUpRecv, &status);

            for (i = 0; i < width; ++i)
            {
 
                /* before computing the last row of its data, 
                 * process has to be sure that it has required
                 * row from process rank+1 */
		        if(i == width - 1)
                {
                	MPI_Wait(&requestDownRecv, &status);
                }

                for (j = 1 + ((startRow+i) % 2 == color ? 1 : 0); j < numPointsPerDimension - 1; j += 2)
                {
                    if( (myRank != 0 || i != 0 ) && (myRank != workingProcesses - 1 || i != width - 1) )
                    {
                        
                        double tmp, diff;
                        double down, up;
                        int jIdx = (j - 1 - ((startRow + i) % 2 == color ? 1 : 0))/ 2;
                        
                        /* decide if up or down value should be taken from additional buffers */
                        up = (i == 0) ? upPointsRecv[jIdx] : points[i-1][j];
                        down = (i == width - 1) ? downPointsRecv[jIdx] : points[i+1][j];
                        
                        /* calculate final value */
                        tmp = (up + down + points[i][j - 1] + points[i][j + 1]) / 4.0;
                        diff = points[i][j];
                        points[i][j] = (1.0 - omega) * points[i][j] + omega * tmp;
                        
                        diff = fabs(diff - points[i][j]);
                        if (diff > maxDiff)
                        {
                            maxDiff = diff;
                        }
                    }
                }
            }
            MPI_Barrier(MY_WORLD);
        }
    	
        if(gettimeofday(&startInterval, NULL))
        {
            freePoints(points, width, myRank);
            fprintf(stderr, "ERROR: Gettimeofday failed!\n");
            exit(1);
        }
        
        /* find new maxDiff among all processes */
        MPI_Allreduce(&maxDiff, &tmpMaxDiff, 1, MPI_DOUBLE, MPI_MAX, MY_WORLD );
        maxDiff = tmpMaxDiff;

        if(gettimeofday(&endInterval, NULL))
        {
            freePoints(points, width, myRank);
            fprintf(stderr, "ERROR: Gettimeofday failed!\n");
                exit(1);
        }
        
        breakdown += ((double)endInterval.tv_sec + ((double)endInterval.tv_usec / 1000000.0)) - 
                     ((double)startInterval.tv_sec + ((double)startInterval.tv_usec / 1000000.0));

        ++numIterations;
    }
    while (maxDiff > epsilon);

    /* End of computations. */
 
    if(gettimeofday(&endTime, NULL))
    {
        freePoints(points, width, myRank);
        fprintf(stderr, "ERROR: Gettimeofday failed!\n");
        exit(1);
    }

    /* calculate how long did the computation lasted */
    duration =
        ((double)endTime.tv_sec + ((double)endTime.tv_usec / 1000000.0)) - 
        ((double)startTime.tv_sec + ((double)startTime.tv_usec / 1000000.0));

    /* we choose the process whose execution lasted for the longest time */     
    double maxDuration;
    MPI_Allreduce(&duration, &maxDuration, 1, MPI_DOUBLE, MPI_MAX, MY_WORLD);
   
    if(myRank==0)
    {
        fprintf(stderr,
            "Statistics: duration(s)=%.10f breakdown=%.10f #iters=%d diff=%.10f epsilon=%.10f\n",
            maxDuration, breakdown, numIterations, maxDiff, epsilon);
    }
  
    if (verbose) {
        
        MPI_Barrier(MY_WORLD);
    
        /* process #0 is responsible for printing results of computation 
         * others send their data straight to it */
        if(myRank != 0 && myRank < workingProcesses) 
        {
            for(k = 0; k < width ; ++k)
            {
                MPI_Send(points[k], numPointsPerDimension, MPI_DOUBLE, 0, 123, MY_WORLD);
            }
        }
        else if(myRank == 0)
        {
            printPoints(points, width, numPointsPerDimension);
            for(i = 1; i < workingProcesses; ++i)
            {
                width = (i < remainder) ? partitions + 1 : partitions;
                
                for (k = 0 ; k < width ; ++k)
                {
                    MPI_Recv(points[k], numPointsPerDimension, MPI_DOUBLE, i, 123, MY_WORLD, &status);
                }

                printPoints(points, width, numPointsPerDimension);
            }
        }
    }
    
    /* free all the memory that was allocated */
    freePoints(points, width, myRank);
    free(downPointsSend);
    free(upPointsSend);
    free(downPointsRecv);
    free(upPointsRecv);
     
    MPI_Finalize();
    
    return 0;
}
bool DisplayPlane::setDataBuffer(uint32_t handle)
{
    DataBuffer *buffer;
    BufferMapper *mapper;
    ssize_t index;
    bool ret;
    bool isCompression;
    BufferManager *bm = Hwcomposer::getInstance().getBufferManager();

    RETURN_FALSE_IF_NOT_INIT();
    ALOGTRACE("handle = %#x", handle);

    if (!handle) {
        WLOGTRACE("invalid buffer handle");
        return false;
    }

    // do not need to update the buffer handle
    if (mCurrentDataBuffer != handle)
        mUpdateMasks |= PLANE_BUFFER_CHANGED;

    // if no update then do Not need set data buffer
    if (!mUpdateMasks)
        return true;

    buffer = bm->lockDataBuffer(handle);
    if (!buffer) {
        ELOGTRACE("failed to get buffer");
        return false;
    }

    mIsProtectedBuffer = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
    isCompression = GraphicBuffer::isCompressionBuffer((GraphicBuffer*)buffer);

    // map buffer if it's not in cache
    index = mDataBuffers.indexOfKey(buffer->getKey());
    if (index < 0) {
        VLOGTRACE("unmapped buffer, mapping...");
        mapper = mapBuffer(buffer);
        if (!mapper) {
            ELOGTRACE("failed to map buffer %#x", handle);
            bm->unlockDataBuffer(buffer);
            return false;
        }
    } else {
        VLOGTRACE("got mapper in saved data buffers and update source Crop");
        mapper = mDataBuffers.valueAt(index);
    }

    // always update source crop to mapper
    mapper->setCrop(mSrcCrop.x, mSrcCrop.y, mSrcCrop.w, mSrcCrop.h);

    mapper->setIsCompression(isCompression);

    // unlock buffer after getting mapper
    bm->unlockDataBuffer(buffer);
    buffer = NULL;

    ret = setDataBuffer(*mapper);
    if (ret) {
        mCurrentDataBuffer = handle;
        // update active buffers
        updateActiveBuffers(mapper);
    }
    return ret;
}