Update contrib.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
22 #include <test/t_simload.h>
23 #include <test/tefunit.h> //ASSERT_TRUE
24 #include "egltest_stress_sgimage.h"
26 TVerdict CEglTest_Stress::doTestStepL()
28 INFO_PRINTF1(_L("CEglTest_Stress:doTestStepL()"));
31 TestCaseName(testCaseId);
32 SetTestStepID(testCaseId);
34 #ifdef SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
37 //File server is used to generate simload ini file
38 User::LeaveIfError(iFs.Connect());
40 TBool ret = CheckForExtensionL(KEGL_RSgimage | KEGL_KHR_image_base | KVG_KHR_EGL_image | KEGL_KHR_image_pixmap);
43 // The extension is not supported
45 CloseTMSGraphicsStep();
46 return TestStepResult();
49 //Create a config file and launch the simulated load app
54 INFO_PRINTF1(_L("Creating a Semaphore to signal all child processes at once"));
56 User::LeaveIfError(sem.CreateGlobal(KEglStressTest(), iNumberChildProcesses));
57 CleanupClosePushL(sem);
59 //Information to be passed to the child process
61 TSize size(iRSgImageWidth, iRSgImageHeight);
62 info.iUsage = ESgUsageBitOpenVgImage | ESgUsageBitOpenVgSurface;
63 info.iPixelFormat = iFormat;
64 info.iSizeInPixels = size;
66 //Utilise egl helper functions
69 //Create a display and initialise it
71 iEglSess->InitializeL();
73 //Open RSGImage driver
74 iEglSess->OpenSgDriverL();
76 EGL_LEAVE_ERROR(eglBindAPI(EGL_OPENVG_API));
79 for(TInt i=0; i<iNumberRSgImages; i++)
82 iSgImageArray.InsertL(image, i);
83 User::LeaveIfError(iSgImageArray[i].Create(info, NULL, NULL));
88 //Only need to determine a matching configuration once
89 ChooseConfigAndCreateContextL(iDisplay, context, config, iSgImageArray[i], KStressTestMainAppPanic, iAlphaPre);
92 EGLSurface surface = EGL_NO_SURFACE; //remove arm warning
93 EGL_LEAVE_NULL(surface, CreatePixmapSurfaceL(iDisplay, config, iSgImageArray[i], iAlphaPre));
95 EGL_LEAVE_ERROR(eglMakeCurrent(iDisplay, surface, surface, context));
97 PaintSurfaceL(iDisplay, surface, context);
98 EGL_LEAVE_ERROR(eglSwapBuffers(iDisplay, surface));
100 if(iTestType == EStressVGImage)
102 EGL_LEAVE_ERROR(eglMakeCurrent(iDisplay, surface, surface, context));
104 EGLImageKHR eglImage = 0; //removes arm compiler warning
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));
111 EGL_LEAVE_ERROR(iEglSess->DestroyEGLImage(iDisplay, eglImage));
113 User::LeaveIfError(iVGImageArray.Insert(vgImage, i));
116 User::LeaveIfError(iSurfaceArray.Insert(surface, i));
119 /* Create and install the active scheduler */
120 CActiveScheduler* sched = new(ELeave) CActiveScheduler;
121 CActiveScheduler::Install(sched);
122 CleanupStack::PushL(sched);
124 TInt exitCounter = iNumberMainImages;
125 TBool testResult = ETrue;
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++)
131 if(iTestType == EStressVGImage)
133 painter = CTReadWriteMain::NewL(iDisplay, iSurfaceArray[i], context, iRSgImageWidth, iRSgImageHeight, iByteSize, iVgFormat, testResult, exitCounter, iTestType, iVGImageArray[i]);
137 painter = CTReadWriteMain::NewL(iDisplay, iSurfaceArray[i], context, iRSgImageWidth, iRSgImageHeight, iByteSize, iVgFormat, testResult, exitCounter, iTestType);
140 CleanupStack::PushL(painter);
141 painter->After(TTimeIntervalMicroSeconds32(0));
144 CreateChildProcessesL();
146 INFO_PRINTF1(_L("Signaling all child processes at once - starts data access in the child processes"));
147 sem.Signal(iNumberChildProcesses);
149 //Start the active scheduler - starts data access in the main process
152 if(testResult == EFalse)
154 if (iTestType == EStressReadWriteSingleImage || iTestType == EStressReadWriteMultiImage)
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"));
162 ERR_PRINTF1(_L("Unexpected pixel colour"));
163 SetTestStepResult(EFail);
167 //Check that each child process has completed without error
168 for(TInt i=0; i<iNumberChildProcesses; i++)
170 TRequestStatus status;
171 iProcessArray[i].Logon(status);
172 User::WaitForRequest(status);
174 if(status != KErrNone)
176 if (status == KTestStressUnexpectedPixelError && (iTestType == EStressReadWriteSingleImage || iTestType == EStressReadWriteMultiImage))
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());
185 ERR_PRINTF2(_L("Child Process completed with code %d, expected KErrNone"), status.Int());
186 SetTestStepResult(EFail);
191 DestroySimLoadProcess();
193 ClearDownArraysL(iDisplay);
194 EGL_LEAVE_ERROR(eglDestroyContext(iDisplay, context));
196 CleanupStack::PopAndDestroy(iNumberMainImages + 2, &sem); //(iNumberMainImages + 1) active objects, sched, sem
197 iEglSess->CloseSgDriver();
205 INFO_PRINTF2(_L("%S can only be run with SgImage-Lite"), &testCaseId);
206 #endif //SYMBIAN_GRAPHICS_EGL_SGIMAGELITE
208 //Comply with the terrific TMS
210 CloseTMSGraphicsStep();
212 return TestStepResult();
215 CEglTest_Stress::~CEglTest_Stress()
217 //Free memory and close handles in case of panic in the doTestStepL()
221 iSurfaceArray.Close();
222 iProcessArray.Close();
223 iSgImageArray.Close();
224 iVGImageArray.Close();
227 void CEglTest_Stress::PaintSurfaceL(EGLDisplay aDisplay, EGLSurface aSurface, EGLContext aContext)
229 //Clear surface background, format of the constant is ARGB
230 //Match the colour to that of the defined constant
236 //Care taken to avoid fixed width -> floating point -> fixed width rounding errors
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;
244 else //iByteSize == 2
246 red = 1.0 * ((KColourInitial16 & 0x7C00) >> 11)/31;
247 green = 1.0 * ((KColourInitial16 & 0x0480) >> 5)/63;
248 blue = 1.0 * (KColourInitial16 & 0x001F)/31;
251 //Format of the constant is RGBA (32 bit)
252 VGfloat bgColor[] = {red, green, blue, alpha};
254 EGL_LEAVE_ERROR(eglMakeCurrent(aDisplay, aSurface, aSurface, aContext));
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);
262 void CEglTest_Stress::CreateChildProcessL(TInt aProcessNumber, TTestType aTestType, TSgDrawableId aDrawableId)
264 TRequestStatus status;
266 User::LeaveIfError(client.Create(KStressTestClientApp, KNullDesC));
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;
275 TPckg<TStressProcessInfo> pckgInfo(info);
276 User::LeaveIfError((client.SetParameter(KMultiProcessSlot, pckgInfo)));
278 client.Rendezvous(status);
280 User::WaitForRequest(status);
281 TEST(status == KErrNone);
283 //Store image handle for cleanup
284 iProcessArray.InsertL(client, aProcessNumber);
287 void CEglTest_Stress::CreateChildProcessesL()
289 for(TInt i=0; i<iNumberChildProcesses; i++)
293 case EStressReadWriteMultiImage:
294 case EStressPixmapSurface:
296 //Each child process accesses one SgImage
297 CreateChildProcessL(i, iTestType, iSgImageArray[i].Id());
301 case EStressReadWriteSingleImage:
304 //All child processes access the same SgImage
305 CreateChildProcessL(i, iTestType, iSgImageArray[0].Id());
309 User::Panic(KStressTestMainAppPanic, KErrNotFound);
315 void CEglTest_Stress::ClearDownArraysL(EGLDisplay aDisplay)
317 for(TInt i=0; i<iSurfaceArray.Count(); i++)
319 ASSERT_EGL_TRUE(eglDestroySurface(aDisplay, iSurfaceArray[i]));
322 for(TInt i=0; i<iVGImageArray.Count(); i++)
324 vgDestroyImage(iVGImageArray[i]);
325 ASSERT_VG_TRUE(vgGetError() == VG_NO_ERROR);
328 for(TInt i=0; i<iProcessArray.Count(); i++)
330 iProcessArray[i].Close();
333 for(TInt i=0; i<iSgImageArray.Count(); i++)
335 iSgImageArray[i].Close();
338 iSurfaceArray.Close();
339 iProcessArray.Close();
340 iSgImageArray.Close();
341 iVGImageArray.Close();
344 void CEglTest_Stress::CreateSimLoadAppL()
349 //Three simload processes need to be launched t_simloadapp1.exe - t_simloadapp3.exe
350 while(index <= KNumSimLoadApps)
352 tempStore.Format(KSimLoadApp, index++);
353 CreateSimLoadProcessL(tempStore);
357 void CEglTest_Stress::CreateSimLoadProcessL(const TDesC& aApp)
359 INFO_PRINTF2(_L("Starting App: %S"), &aApp);
362 User::LeaveIfError(process.Create(aApp, KNullDesC));
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);
370 iProcessList.AppendL(process);
373 void CEglTest_Stress::DestroySimLoadProcess()
375 for (TInt index = 0; index < iProcessList.Count(); index++)
378 INFO_PRINTF3(_L("Process Check: Actual: %d, Expected: %d"), iProcessList[index].ExitReason(), KErrNone);
379 TEST(iProcessList[index].ExitReason( )== KErrNone);
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);
386 iProcessList[index].Close();
389 iProcessList.Close();
392 void CEglTest_Stress::ReadIniValueL(const TDesC& aSectName, const TDesC& aKeyName, TInt& aResult)
394 if(!GetIntFromConfig(aSectName, aKeyName, aResult))
396 ERR_PRINTF2(_L("Error reading %S value from ini file"), &aKeyName);
397 User::Leave(KErrNotFound);
400 INFO_PRINTF3(_L("Ini file value %S = %d"), &aKeyName, aResult);
403 void CEglTest_Stress::ReadIniValuesL()
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);
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);
421 TPtrC16 ptrBuffer(buffer);
422 if(!GetStringFromConfig(ConfigSection(), KPixelFormat, ptrBuffer))
424 ERR_PRINTF2(_L("Error reading %S value from ini file"), &KPixelFormat);
425 User::Leave(KErrNotFound);
428 INFO_PRINTF3(_L("Ini file value %S = %S"), &KPixelFormat, &ptrBuffer);
430 //Derive information from the pixel format
431 if(ptrBuffer == KUidPixelFormatARGB_8888)
433 iFormat = EUidPixelFormatARGB_8888;
434 iVgFormat = VG_sARGB_8888;
438 else if(ptrBuffer == KUidPixelFormatARGB_8888_PRE)
440 iFormat = EUidPixelFormatARGB_8888_PRE;
441 iVgFormat = VG_sARGB_8888_PRE;
445 else if(ptrBuffer == KUidPixelFormatRGB_565)
447 iFormat = EUidPixelFormatRGB_565;
448 iVgFormat = VG_sRGB_565;
454 ERR_PRINTF2(_L("Unsupported pixel format %S"), &ptrBuffer);
455 User::Leave(KErrNotFound);
458 //Determine the test type from the ini file section name
459 if(ConfigSection().Find(KStressReadOnly) != KErrNotFound)
461 iTestType = EStressRead;
463 else if(ConfigSection().Find(KEStressReadWriteSingleImage) != KErrNotFound)
465 iTestType = EStressReadWriteSingleImage;
467 else if(ConfigSection().Find(KStressReadWriteMultiImage) != KErrNotFound)
469 iTestType = EStressReadWriteMultiImage;
471 else if(ConfigSection().Find(KStressVGImage) != KErrNotFound)
473 iTestType = EStressVGImage;
475 else if(ConfigSection().Find(KStressPixmapSurface) != KErrNotFound)
477 iTestType = EStressPixmapSurface;
481 ERR_PRINTF2(_L("Unknown test case %S"), &ptrBuffer);
482 User::Leave(KErrNotFound);
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
492 void CEglTest_Stress::PrintConfigDataL()
494 RFileWriteStream writer;
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));
503 CleanupStack::PopAndDestroy(&writer);
505 CIniData* data=CIniData::NewL(KSimLoadConfigFile);
506 CleanupStack::PushL(data);
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);
514 TPtrC16 ptrBuffer(buffer);
515 User::LeaveIfError(GetStringFromConfig(ConfigSection(), KConfigSimLoadValue, ptrBuffer));
517 INFO_PRINTF3(_L("Config Name: %S, \t\tConfig Data: %S"), &KConfigSimLoadValue, &ptrBuffer);
518 err = data->AddValue(KDefaultSectionName, KConfigSimLoadValue, ptrBuffer);
520 INFO_PRINTF3(_L("AddValue - Expected: %d, Actual: %d"), KErrNone, err);
521 TEST(err == KErrNone);
523 data->WriteToFileL();
524 CleanupStack::PopAndDestroy(data);
527 void CEglTest_Stress::DeleteConfigData()
529 INFO_PRINTF2(_L("Deleting Config File Name: %S"), &KSimLoadConfigFile);
530 TInt err = iFs.Delete(KSimLoadConfigFile);
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()
541 * The base class is an active object and the implemented virtual functions are invoked
542 * indirectly from the RunL() function
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),
549 iFinishedCounter(aFinishedCounter)
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)
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);
562 void CTReadWriteMain::ConstructL(VGImage aVGImage)
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)) )
567 User::Leave(KErrArgument);
572 //Call base class function to complete construction
573 CTReadWrite::ConstructL();
576 void CTReadWriteMain::MakeCurrentL() const
578 EGL_LEAVE_ERROR(eglMakeCurrent(iDisplay, iSurface, iSurface, iContext));
581 void CTReadWriteMain::ReadImageFuncL()
583 vgReadPixels(iData, iWidth*iByteSize, iFormat, 0, 0, iWidth, iHeight);
587 void CTReadWriteMain::ReadFuncL()
592 void CTReadWriteMain::WriteImageFuncL()
594 vgWritePixels(iData, iWidth*iByteSize, iFormat, 0, 0, iWidth, iHeight);
598 TBool CTReadWriteMain::IsFinished()
602 if(iFinishedCounter <= 0)
610 void CTReadWriteMain::VgImageFuncL()
612 //Alter the image data, actual pixel values are not important
613 for(TInt i=0; i<iBufferSize; i++)
615 const TUint32 temp = iBufferSize % iFrameNumber;
616 iData[i] = temp + (temp << 8) + (temp << 16) + (temp << 24);
619 //Currently panics as context->scanlinebuffer is NULL
620 vgImageSubData(iVGImage, iData, iWidth*iByteSize, iFormat, 0, 0, iWidth, iHeight);
623 EGL_LEAVE_ERROR(eglSwapBuffers(iDisplay, iSurface));
626 void CTReadWriteMain::PixmapSurfaceFuncL()
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);
633 vgClear(0, 0, iWidth, iHeight);
636 EGL_LEAVE_ERROR(eglSwapBuffers(iDisplay, iSurface));