os/graphics/egl/egltest/src/egltest_stress_sgimage.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 /**
    17  @file
    18  @test
    19 */
    20 
    21 #include <s32file.h>
    22 #include <test/t_simload.h>
    23 #include <test/tefunit.h>    //ASSERT_TRUE
    24 #include "egltest_stress_sgimage.h"
    25 
    26 TVerdict CEglTest_Stress::doTestStepL()
    27     {
    28     INFO_PRINTF1(_L("CEglTest_Stress:doTestStepL()"));
    29     
    30     TBuf<100> testCaseId;
    31     TestCaseName(testCaseId);
    32     SetTestStepID(testCaseId);
    33 
    34 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
    35     __UHEAP_MARK;
    36     
    37     //File server is used to generate simload ini file
    38     User::LeaveIfError(iFs.Connect());
    39   
    40     TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
    41     if(!ret)
    42         {
    43         // The extension is not supported
    44         RecordTestResultL();
    45         CloseTMSGraphicsStep();
    46         return TestStepResult();
    47         }
    48 
    49     //Create a config file and launch the simulated load app
    50     ReadIniValuesL();
    51     PrintConfigDataL();
    52     CreateSimLoadAppL();
    53 
    54     INFO_PRINTF1(_L("Creating a Semaphore to signal all child processes at once"));
    55     RSemaphore sem;
    56     User::LeaveIfError(sem.CreateGlobal(KEglStressTest(), iNumberChildProcesses));
    57     CleanupClosePushL(sem);
    58 
    59     //Information to be passed to the child process
    60     TSgImageInfo info;
    61     TSize size(iRSgImageWidth, iRSgImageHeight);
    62     info.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
    63     info.iPixelFormat = iFormat;
    64     info.iSizeInPixels = size;
    65 
    66     //Utilise egl helper functions
    67     CreateEglSessionL();
    68     
    69     //Create a display and initialise it
    70     GetDisplayL();
    71     iEglSess->InitializeL();
    72     
    73     //Open RSGImage driver    
    74     iEglSess->OpenSgDriverL();
    75     
    76     EGL_LEAVE_ERROR(eglBindAPI(EGL_OPENVG_API));
    77  
    78     EGLContext context;
    79     for(TInt i=0; i<iNumberRSgImages; i++)
    80         {
    81         RSgImage image;
    82         iSgImageArray.InsertL(image, i);
    83         User::LeaveIfError(iSgImageArray[i].Create(info, NULL, NULL));
    84 
    85         EGLConfig config;
    86         if(i == 0)
    87             {
    88             //Only need to determine a matching configuration once
    89             ChooseConfigAndCreateContextL(iDisplay, context, config, iSgImageArray[i], KStressTestMainAppPanic, iAlphaPre);
    90             }
    91  
    92         EGLSurface surface = EGL_NO_SURFACE; //remove arm warning
    93         EGL_LEAVE_NULL(surface, CreatePixmapSurfaceL(iDisplay, config, iSgImageArray[i], iAlphaPre));
    94 
    95         EGL_LEAVE_ERROR(eglMakeCurrent(iDisplay, surface, surface, context));
    96          
    97         PaintSurfaceL(iDisplay, surface, context);
    98         EGL_LEAVE_ERROR(eglSwapBuffers(iDisplay, surface));
    99 
   100         if(iTestType == EStressVGImage)
   101             {
   102             EGL_LEAVE_ERROR(eglMakeCurrent(iDisplay, surface, surface, context));
   103             
   104             EGLImageKHR eglImage = 0; //removes arm compiler warning
   105             VGImage vgImage;
   106 
   107             EGL_LEAVE_NULL(eglImage, iEglSess->eglCreateImageKhrL(iDisplay, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, &iSgImageArray[i], (int*)KEglImageAttribsPreservedTrue));
   108             EGL_LEAVE_NULL(vgImage, iEglSess->vgCreateImageTargetKHR(eglImage));
   109 
   110             //Close the EGLImage
   111             EGL_LEAVE_ERROR(iEglSess->DestroyEGLImage(iDisplay, eglImage));
   112                         
   113             User::LeaveIfError(iVGImageArray.Insert(vgImage, i));
   114             }
   115 
   116         User::LeaveIfError(iSurfaceArray.Insert(surface, i));
   117         }
   118 
   119     /* Create and install the active scheduler */
   120     CActiveScheduler* sched = new(ELeave) CActiveScheduler;
   121     CActiveScheduler::Install(sched);
   122     CleanupStack::PushL(sched);
   123 
   124     TInt exitCounter = iNumberMainImages;
   125     TBool testResult = ETrue;
   126 
   127     //Create an active object for each RSgImage accessed in the main process
   128     CTReadWriteMain* painter = 0;
   129     for(TInt i=0; i<iNumberMainImages; i++)
   130         {
   131         if(iTestType == EStressVGImage)
   132             {
   133             painter = CTReadWriteMain::NewL(iDisplay, iSurfaceArray[i], context, iRSgImageWidth, iRSgImageHeight, iByteSize, iVgFormat, testResult, exitCounter, iTestType, iVGImageArray[i]);
   134             }
   135         else
   136             {
   137             painter = CTReadWriteMain::NewL(iDisplay, iSurfaceArray[i], context, iRSgImageWidth, iRSgImageHeight, iByteSize, iVgFormat, testResult, exitCounter, iTestType);            
   138             }
   139             
   140         CleanupStack::PushL(painter);
   141         painter->After(TTimeIntervalMicroSeconds32(0));
   142         }
   143 
   144     CreateChildProcessesL();
   145 
   146     INFO_PRINTF1(_L("Signaling all child processes at once - starts data access in the child processes"));
   147     sem.Signal(iNumberChildProcesses);
   148 
   149     //Start the active scheduler - starts data access in the main process
   150     sched->Start();
   151 
   152     if(testResult == EFalse)
   153         {
   154 		if (iTestType == EStressReadWriteSingleImage || iTestType == EStressReadWriteMultiImage)
   155 			{
   156 			// For GRAPHICS-EGL-0428 and GRAPHICS-EGL-0437 data integrity cannot be guaranteed on 
   157 			// all implementations, so the pixel value checking aspects of these tests are regarded as optional   
   158 			WARN_PRINTF1(_L("Unexpected pixel colour"));
   159 			}
   160 		else
   161 			{
   162 			ERR_PRINTF1(_L("Unexpected pixel colour"));
   163 			SetTestStepResult(EFail);
   164 			}
   165         }
   166 
   167     //Check that each child process has completed without error
   168     for(TInt i=0; i<iNumberChildProcesses; i++)
   169        {
   170        TRequestStatus status;
   171        iProcessArray[i].Logon(status);
   172        User::WaitForRequest(status);
   173 
   174        if(status != KErrNone)
   175            {
   176 		   if (status == KTestStressUnexpectedPixelError && (iTestType == EStressReadWriteSingleImage || iTestType == EStressReadWriteMultiImage))
   177 			   {
   178 			   // For GRAPHICS-EGL-0428 and GRAPHICS-EGL-0437 data integrity cannot be guaranteed on 
   179 			   // all implementations, so the pixel value checking aspects of these tests are regarded as optional
   180 			   // So check that if it fails, it fails for the expected reason of no matching pixel.
   181 			   WARN_PRINTF2(_L("Child Process completed with code %d, expected KErrNone"), status.Int());
   182 			   }
   183 		   else
   184 			   {
   185 			   ERR_PRINTF2(_L("Child Process completed with code %d, expected KErrNone"), status.Int());
   186 			   SetTestStepResult(EFail);
   187 			   }
   188            }
   189        }
   190 
   191     DestroySimLoadProcess();
   192     DeleteConfigData();
   193     ClearDownArraysL(iDisplay);
   194     EGL_LEAVE_ERROR(eglDestroyContext(iDisplay, context));
   195 
   196     CleanupStack::PopAndDestroy(iNumberMainImages + 2, &sem); //(iNumberMainImages + 1) active objects, sched, sem
   197     iEglSess->CloseSgDriver();
   198     
   199     CleanAll();
   200     iFs.Close();
   201 
   202     __UHEAP_MARKEND;
   203 
   204 #else
   205     INFO_PRINTF2(_L("%S can only be run with SgImage-Lite"), &testCaseId);
   206 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
   207     
   208     //Comply with the terrific TMS
   209     RecordTestResultL();
   210     CloseTMSGraphicsStep();
   211 
   212     return TestStepResult();
   213     }
   214 
   215 CEglTest_Stress::~CEglTest_Stress()
   216     {
   217     //Free memory and close handles in case of panic in the doTestStepL()
   218     delete iEglSess;
   219     
   220     iFs.Close();
   221     iSurfaceArray.Close();
   222     iProcessArray.Close();
   223     iSgImageArray.Close();
   224     iVGImageArray.Close();
   225     }
   226 
   227 void CEglTest_Stress::PaintSurfaceL(EGLDisplay aDisplay, EGLSurface aSurface, EGLContext aContext)
   228     {
   229     //Clear surface background, format of the constant is ARGB
   230     //Match the colour to that of the defined constant
   231     VGfloat red = 0.0;
   232     VGfloat green = 0.0;
   233     VGfloat blue = 0.0;
   234     VGfloat alpha = 0.0;
   235     
   236     //Care taken to avoid fixed width -> floating point -> fixed width rounding errors
   237     if(iByteSize == 4)
   238         {
   239         red = 1.0 * ((KColourInitial32 & 0x00FF0000) >> 16)/255;
   240         green = 1.0 * ((KColourInitial32 & 0x0000FF00) >> 8)/255;
   241         blue = 1.0 * (KColourInitial32 & 0x000000FF)/255;
   242         alpha = 1.0 * ((KColourInitial32 & 0xFF000000) >> 24)/255;        
   243         }
   244     else //iByteSize == 2
   245         {
   246         red = 1.0 * ((KColourInitial16 & 0x7C00) >> 11)/31;
   247         green = 1.0 * ((KColourInitial16 & 0x0480) >> 5)/63;
   248         blue = 1.0 * (KColourInitial16 & 0x001F)/31;
   249         }
   250 
   251     //Format of the constant is RGBA (32 bit) 
   252     VGfloat bgColor[] = {red, green, blue, alpha};
   253 
   254     EGL_LEAVE_ERROR(eglMakeCurrent(aDisplay, aSurface, aSurface, aContext));
   255  
   256     vgSetfv(VG_CLEAR_COLOR, 4, bgColor);
   257     ASSERT_VG_TRUE(vgGetError() == VG_NO_ERROR);
   258     vgClear(0, 0, iRSgImageWidth, iRSgImageHeight);
   259     ASSERT_VG_TRUE(vgGetError() == VG_NO_ERROR);
   260     }
   261 
   262 void CEglTest_Stress::CreateChildProcessL(TInt aProcessNumber, TTestType aTestType, TSgDrawableId aDrawableId)
   263     {
   264     TRequestStatus status;
   265     RProcess client;
   266     User::LeaveIfError(client.Create(KStressTestClientApp, KNullDesC));
   267 
   268     //Pass image and test information to the child process
   269     TStressProcessInfo info;
   270     info.iTestType = aTestType;
   271     info.iSgId = aDrawableId;
   272     info.iByteSize = iByteSize;
   273     info.iAlphaPre = iAlphaPre;
   274 
   275     TPckg<TStressProcessInfo> pckgInfo(info);
   276     User::LeaveIfError((client.SetParameter(KMultiProcessSlot, pckgInfo)));
   277 
   278     client.Rendezvous(status);
   279     client.Resume();
   280     User::WaitForRequest(status);
   281     TEST(status == KErrNone);
   282 
   283     //Store image handle for cleanup
   284     iProcessArray.InsertL(client, aProcessNumber);
   285     }
   286 
   287 void CEglTest_Stress::CreateChildProcessesL()
   288     {
   289     for(TInt i=0; i<iNumberChildProcesses; i++)
   290         {
   291         switch(iTestType)
   292             {
   293             case EStressReadWriteMultiImage:
   294             case EStressPixmapSurface:
   295                 {
   296                 //Each child process accesses one SgImage
   297                 CreateChildProcessL(i, iTestType, iSgImageArray[i].Id());
   298                 break;
   299                 }
   300             case EStressRead:
   301             case EStressReadWriteSingleImage:
   302             case EStressVGImage:
   303                 {
   304                 //All child processes access the same SgImage
   305                 CreateChildProcessL(i, iTestType, iSgImageArray[0].Id());
   306                 break;
   307                 }
   308             default:
   309                 User::Panic(KStressTestMainAppPanic, KErrNotFound);
   310                 break;
   311             }
   312         }
   313     }
   314 
   315 void CEglTest_Stress::ClearDownArraysL(EGLDisplay aDisplay)
   316     {
   317     for(TInt i=0; i<iSurfaceArray.Count(); i++)
   318         {
   319         ASSERT_EGL_TRUE(eglDestroySurface(aDisplay, iSurfaceArray[i]));
   320         }
   321     
   322     for(TInt i=0; i<iVGImageArray.Count(); i++)
   323         {
   324         vgDestroyImage(iVGImageArray[i]);
   325         ASSERT_VG_TRUE(vgGetError() == VG_NO_ERROR);
   326         }
   327     
   328     for(TInt i=0; i<iProcessArray.Count(); i++)
   329         {
   330         iProcessArray[i].Close();
   331         }
   332 
   333     for(TInt i=0; i<iSgImageArray.Count(); i++)
   334         {
   335         iSgImageArray[i].Close();
   336         }
   337     
   338     iSurfaceArray.Close();
   339     iProcessArray.Close();
   340     iSgImageArray.Close();
   341     iVGImageArray.Close();
   342     }
   343 
   344 void CEglTest_Stress::CreateSimLoadAppL()
   345     {
   346     TInt index = 1;
   347     TBuf<100> tempStore;
   348 
   349     //Three simload processes need to be launched t_simloadapp1.exe - t_simloadapp3.exe
   350     while(index <= KNumSimLoadApps)
   351         {
   352         tempStore.Format(KSimLoadApp, index++);
   353         CreateSimLoadProcessL(tempStore);
   354         }
   355     }
   356 
   357 void CEglTest_Stress::CreateSimLoadProcessL(const TDesC& aApp)
   358     {
   359     INFO_PRINTF2(_L("Starting App: %S"), &aApp);
   360 
   361     RProcess process;
   362     User::LeaveIfError(process.Create(aApp, KNullDesC));
   363 
   364     //Give the simulated load high priority to be sure it does its job
   365     process.SetPriority(EPriorityHigh);
   366     TEST(process.Priority() == EPriorityHigh);
   367     INFO_PRINTF3(_L("Process Priority: Actual: %d, Expected: %d"), process.Priority(), EPriorityHigh);
   368     process.Resume();
   369     
   370     iProcessList.AppendL(process);
   371     }
   372 
   373 void CEglTest_Stress::DestroySimLoadProcess()
   374     {
   375     for (TInt index = 0; index < iProcessList.Count(); index++)
   376         {
   377         // check process
   378         INFO_PRINTF3(_L("Process Check: Actual: %d, Expected: %d"), iProcessList[index].ExitReason(), KErrNone);
   379         TEST(iProcessList[index].ExitReason( )== KErrNone);
   380 
   381         // kill process
   382         iProcessList[index].Kill(KErrGeneral);
   383         INFO_PRINTF3(_L("Process Exit Reason: Actual: %d, Expected: %d"), iProcessList[index].ExitReason(), KErrGeneral);
   384         TEST(iProcessList[index].ExitReason() == KErrGeneral);
   385 
   386         iProcessList[index].Close();
   387         }
   388 
   389     iProcessList.Close();
   390     }
   391 
   392 void CEglTest_Stress::ReadIniValueL(const TDesC& aSectName, const TDesC& aKeyName, TInt& aResult)
   393     {
   394     if(!GetIntFromConfig(aSectName, aKeyName, aResult))
   395         {
   396         ERR_PRINTF2(_L("Error reading %S value from ini file"), &aKeyName);
   397         User::Leave(KErrNotFound);
   398         }
   399 
   400     INFO_PRINTF3(_L("Ini file value %S = %d"), &aKeyName, aResult);
   401     }
   402 
   403 void CEglTest_Stress::ReadIniValuesL()
   404     {
   405     ReadIniValueL(ConfigSection(), KNumberRSgImages, iNumberRSgImages);
   406     ReadIniValueL(ConfigSection(), KNumberMainImages, iNumberMainImages);
   407     ReadIniValueL(ConfigSection(), KNumberChildProcesses, iNumberChildProcesses);
   408     ReadIniValueL(ConfigSection(), KRSgImageWidth, iRSgImageWidth);
   409     ReadIniValueL(ConfigSection(), KRSgImageHeight, iRSgImageHeight);
   410     ReadIniValueL(ConfigSection(), KConfigSimLoadValue, iSimLoadValue);
   411     
   412     //Check for erroneous ini values
   413     ASSERT_TRUE(iNumberChildProcesses <= iNumberRSgImages);
   414     ASSERT_TRUE(iNumberMainImages <= iNumberRSgImages);
   415     ASSERT_TRUE(iRSgImageWidth >= 0);
   416     ASSERT_TRUE(iRSgImageHeight >= 0);
   417     ASSERT_TRUE(iSimLoadValue >= 0);
   418     ASSERT_TRUE(iSimLoadValue <= 100);
   419     
   420     TBuf16<100> buffer;
   421     TPtrC16 ptrBuffer(buffer);
   422     if(!GetStringFromConfig(ConfigSection(), KPixelFormat, ptrBuffer))
   423         {
   424         ERR_PRINTF2(_L("Error reading %S value from ini file"), &KPixelFormat);
   425         User::Leave(KErrNotFound);
   426         }
   427 
   428     INFO_PRINTF3(_L("Ini file value %S = %S"), &KPixelFormat, &ptrBuffer);
   429 
   430     //Derive information from the pixel format
   431     if(ptrBuffer == KUidPixelFormatARGB_8888)
   432         {
   433         iFormat = EUidPixelFormatARGB_8888;
   434         iVgFormat = VG_sARGB_8888;
   435         iAlphaPre = EFalse;
   436         iByteSize = 4;
   437         }
   438     else if(ptrBuffer == KUidPixelFormatARGB_8888_PRE)
   439         {
   440         iFormat = EUidPixelFormatARGB_8888_PRE;
   441         iVgFormat = VG_sARGB_8888_PRE;
   442         iAlphaPre = ETrue;
   443         iByteSize = 4;
   444         }
   445     else if(ptrBuffer == KUidPixelFormatRGB_565)
   446         {
   447         iFormat = EUidPixelFormatRGB_565;
   448         iVgFormat = VG_sRGB_565;
   449         iAlphaPre = EFalse;
   450         iByteSize = 2;
   451         }
   452     else
   453         {
   454         ERR_PRINTF2(_L("Unsupported pixel format %S"), &ptrBuffer);
   455         User::Leave(KErrNotFound);
   456         }
   457 
   458      //Determine the test type from the ini file section name
   459      if(ConfigSection().Find(KStressReadOnly) != KErrNotFound)
   460          {
   461          iTestType = EStressRead;
   462          }
   463      else if(ConfigSection().Find(KEStressReadWriteSingleImage) != KErrNotFound)
   464          {
   465          iTestType = EStressReadWriteSingleImage;
   466          }
   467      else if(ConfigSection().Find(KStressReadWriteMultiImage) != KErrNotFound)
   468          {
   469          iTestType = EStressReadWriteMultiImage;
   470          }
   471      else if(ConfigSection().Find(KStressVGImage) != KErrNotFound)
   472          {
   473          iTestType = EStressVGImage;
   474          }
   475      else if(ConfigSection().Find(KStressPixmapSurface) != KErrNotFound)
   476          {
   477          iTestType = EStressPixmapSurface;
   478          }
   479      else
   480          {
   481          ERR_PRINTF2(_L("Unknown test case %S"), &ptrBuffer);
   482          User::Leave(KErrNotFound);
   483          }
   484     }
   485 
   486 /** 
   487  *   This function generates an ini file for the simulated load application
   488  *   containing two lines to determine
   489  *   1. The type of load (static or spiked, in this case always static)
   490  *   2. The simulated load level
   491  */
   492 void CEglTest_Stress::PrintConfigDataL()
   493     {
   494     RFileWriteStream writer;
   495     writer.PushL();
   496 
   497     TInt err = iFs.MkDirAll(KSimLoadConfigFile);
   498     TEST(err == KErrNone || err == KErrAlreadyExists);
   499     INFO_PRINTF2(_L("Create Config File: %S"), &KSimLoadConfigFile);
   500     User::LeaveIfError(writer.Replace(iFs, KSimLoadConfigFile, EFileStreamText|EFileWrite));
   501     writer.CommitL();
   502 
   503     CleanupStack::PopAndDestroy(&writer);
   504 
   505     CIniData* data=CIniData::NewL(KSimLoadConfigFile);
   506     CleanupStack::PushL(data);
   507 
   508     INFO_PRINTF3(_L("Config Name: %S, \t\tConfig Data: %S"), &KConfigSimLoadType, &KConfigSimLoadStatic);
   509     err = data->AddValue(KDefaultSectionName, KConfigSimLoadType, KConfigSimLoadStatic);
   510     INFO_PRINTF3(_L("AddValue - Expected: %d, Actual: %d"), KErrNone, err);
   511     TEST(err == KErrNone);
   512 
   513     TBuf16<100> buffer;
   514     TPtrC16 ptrBuffer(buffer);
   515     User::LeaveIfError(GetStringFromConfig(ConfigSection(), KConfigSimLoadValue, ptrBuffer));
   516 
   517     INFO_PRINTF3(_L("Config Name: %S, \t\tConfig Data: %S"), &KConfigSimLoadValue, &ptrBuffer);
   518     err = data->AddValue(KDefaultSectionName, KConfigSimLoadValue, ptrBuffer);
   519 
   520     INFO_PRINTF3(_L("AddValue - Expected: %d, Actual: %d"), KErrNone, err);
   521     TEST(err == KErrNone);
   522 
   523     data->WriteToFileL();
   524     CleanupStack::PopAndDestroy(data);
   525     }
   526 
   527 void CEglTest_Stress::DeleteConfigData()
   528     {
   529     INFO_PRINTF2(_L("Deleting Config File Name: %S"), &KSimLoadConfigFile);
   530     TInt err = iFs.Delete(KSimLoadConfigFile);
   531     TEST(err==KErrNone);
   532     }
   533 
   534 /**
   535  *    class CTReadWriteMain
   536  *    A Child of CTReadWrite which contains member data not included in the base class and 
   537  *    implementations of pure virtual functions.
   538  *    a) One for each particular test case
   539  *    b) Support functions MakeCurrentL() and IsFinished()
   540  *    
   541  *    The base class is an active object and the implemented virtual functions are invoked
   542  *    indirectly from the RunL() function
   543  */
   544 CTReadWriteMain::CTReadWriteMain(EGLDisplay aDisplay, EGLSurface aSurface, EGLContext aContext, TInt aWidth, TInt aHeight, TInt aByteSize, VGImageFormat aFormat, TBool& aTestPass, TInt& aFinishedCounter, const TTestType& aTestType)
   545 : CTReadWrite(aWidth, aHeight, aByteSize, aFormat, aTestType, aTestPass),
   546     iDisplay(aDisplay),
   547     iSurface(aSurface),
   548     iContext(aContext),
   549     iFinishedCounter(aFinishedCounter)
   550     {
   551     }
   552 
   553 CTReadWriteMain* CTReadWriteMain::NewL(EGLDisplay aDisplay, EGLSurface aSurface, EGLContext aContext, TInt aWidth, TInt aHeight, TInt aByteSize, VGImageFormat aFormat, TBool& aTestPass, TInt& aFinishedCounter, const TTestType& aTestType, VGImage aVGImage)
   554     {
   555     CTReadWriteMain* self = new (ELeave) CTReadWriteMain(aDisplay, aSurface, aContext, aWidth, aHeight, aByteSize, aFormat, aTestPass, aFinishedCounter, aTestType);
   556     CleanupStack::PushL(self);
   557     self->ConstructL(aVGImage);
   558     CleanupStack::Pop(self);
   559     return self;
   560     }
   561 
   562 void CTReadWriteMain::ConstructL(VGImage aVGImage)
   563     {
   564     //NULL values indicate a programming error
   565     if( (iDisplay == EGL_NO_DISPLAY) || (iSurface == EGL_NO_SURFACE) || (iContext == EGL_NO_CONTEXT) || (iFinishedCounter == 0) || ((iTestType == EStressVGImage) && (aVGImage == NULL)) )
   566         {
   567         User::Leave(KErrArgument);
   568         }
   569     
   570     iVGImage = aVGImage;
   571     
   572     //Call base class function to complete construction
   573      CTReadWrite::ConstructL();
   574     }
   575 
   576 void CTReadWriteMain::MakeCurrentL() const
   577     {
   578     EGL_LEAVE_ERROR(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
   579     }
   580 
   581 void CTReadWriteMain::ReadImageFuncL()
   582     {
   583     vgReadPixels(iData, iWidth*iByteSize, iFormat, 0, 0, iWidth, iHeight);
   584     VgLeaveIfErrorL();
   585     }
   586 
   587 void CTReadWriteMain::ReadFuncL()
   588     {
   589     ReadImageFuncL();
   590     }
   591 
   592 void CTReadWriteMain::WriteImageFuncL()
   593     {
   594     vgWritePixels(iData, iWidth*iByteSize, iFormat, 0, 0, iWidth, iHeight);
   595     VgLeaveIfErrorL();
   596     }
   597 
   598 TBool CTReadWriteMain::IsFinished()
   599     {
   600     iFinishedCounter--;
   601 
   602     if(iFinishedCounter <= 0)
   603         {
   604         return ETrue;
   605         }
   606 
   607     return EFalse;
   608     }
   609 
   610 void CTReadWriteMain::VgImageFuncL()
   611     {
   612     //Alter the image data, actual pixel values are not important
   613     for(TInt i=0; i<iBufferSize; i++)
   614         {
   615         const TUint32 temp = iBufferSize % iFrameNumber;
   616         iData[i] = temp + (temp << 8) + (temp << 16) + (temp << 24);
   617         }
   618     
   619     //Currently panics as context->scanlinebuffer is NULL
   620     vgImageSubData(iVGImage, iData, iWidth*iByteSize, iFormat, 0, 0, iWidth, iHeight);
   621     VgLeaveIfErrorL();
   622     
   623     EGL_LEAVE_ERROR(eglSwapBuffers(iDisplay, iSurface));
   624     }
   625 
   626 void CTReadWriteMain::PixmapSurfaceFuncL()
   627     {
   628     // clear surface background to an arbitrary colour
   629     VGfloat arbitraryColour = (1.0*iFrameNumber)/KNumberOfFrames;
   630     VGfloat backgroundColour[] = {1.0 - arbitraryColour/2, arbitraryColour/2, 1.0 - arbitraryColour, arbitraryColour};
   631     vgSetfv(VG_CLEAR_COLOR, 4, backgroundColour);
   632     VgLeaveIfErrorL();
   633     vgClear(0, 0, iWidth, iHeight);
   634     VgLeaveIfErrorL();
   635 
   636     EGL_LEAVE_ERROR(eglSwapBuffers(iDisplay, iSurface));
   637     }