Update contrib.
1 // Copyright (c) 2008-2009 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 "tmultithread.h"
23 #include <graphics/directgdicontext.h>
25 const TUint KMinTestThreadHeapSize = 0x00000100;
26 const TUint KMaxTestThreadheapSize = 0x00100000;
28 CTMultiThread::CTMultiThread()
30 SetTestStepName(KTMultiThreadStep);
33 CTMultiThread::~CTMultiThread()
40 Override of base class virtual
41 @leave Gets system wide error code
42 @return - TVerdict code
44 TVerdict CTMultiThread::doTestStepPreambleL()
46 CTDirectGdiStepBase::doTestStepPreambleL();
47 return TestStepResult();
51 Override of base class pure virtual
52 Our implementation only gets called if the base class doTestStepPreambleL() did
53 not leave. That being the case, the current test result value will be EPass.
54 @leave Gets system wide error code
57 TVerdict CTMultiThread::doTestStepL()
62 // No framework OOM tests are run for the multithreaded tests as OOM testing only checks the
63 // heap in the current thread and these tests use multiple threads. Some heap checking is
64 // performed within the tests themselves.
68 INFO_PRINTF1(_L("Test skipped under BitGDI.\n"));
70 CloseTMSGraphicsStep();
71 return TestStepResult();
75 Override of base class pure virtual
76 Lists the tests to be run
78 void CTMultiThread::RunTestsL()
80 SetTestStepID(_L("GRAPHICS-DIRECTGDI-MULTITHREAD-0001"));
81 TestDirectGdiMultipleThreadIndependenceL();
83 SetTestStepID(_L("GRAPHICS-DIRECTGDI-MULTITHREAD-0002"));
84 TestShareEGLImageBetweenSources_MultithreadedL();
90 GRAPHICS-DIRECTGDI-MULTITHREAD-0001
105 Ensure multi-threaded use of DirectGDI is truly independent.
114 The following sequence should be legal:
115 1: (thread 1) initialise DirectGDI by calling ThreadOneStart()
116 2: (thread 2) initialise DirectGDI by calling ThreadTwoStart()
117 3: (thread 1) close DirectGDI
118 4: (thread 2) render using DirectGDI
120 @SYMTestExpectedResults
121 There should be no panics.
123 void CTMultiThread::TestDirectGdiMultipleThreadIndependenceL()
125 INFO_PRINTF1(_L("Multithread_MultipleThreadIndependence"));
126 // Create a semaphore
128 TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
129 CleanupClosePushL(sem);
132 User::LeaveIfError(iThread1.Create(KNameThreadOne, ThreadOneStart, KDefaultStackSize, KMinTestThreadHeapSize, KMaxTestThreadheapSize, NULL));
133 User::LeaveIfError(iThread2.Create(KNameThreadTwo, ThreadTwoStart, KDefaultStackSize, KMinTestThreadHeapSize, KMaxTestThreadheapSize, NULL));
136 TRequestStatus thread1Status;
137 iThread1.Logon(thread1Status);
138 iThread1.SetPriority(EPriorityLess);
144 TRequestStatus thread2Status;
145 iThread2.Logon(thread2Status);
146 iThread2.SetPriority(EPriorityLess);
153 User::WaitForRequest(thread1Status);
157 User::WaitForRequest(thread2Status);
159 TESTNOERROR(iThread1.ExitReason());
160 TESTNOERROR(iThread2.ExitReason());
164 CleanupStack::PopAndDestroy(&sem);
168 Function for initializing DirectGdi, used by TestDirectGdiMultipleThreadIndependenceL().
169 @see TestDirectGdiMultipleThreadIndependenceL()
170 @param aInfo Not used
171 @return KErrNone if successful, one of the system wide error codes otherwise
173 TInt CTMultiThread::ThreadOneStart(TAny* /*aInfo*/)
175 TInt procHandles1 =0;
176 TInt threadHandles1=0;
177 RThread().HandleCount(procHandles1, threadHandles1);
181 TInt ret = sem.OpenGlobal(KMultiThreadSemaphore);
187 //initialize graphics resource driver
188 ret = SgDriver::Open();
194 //initialise DirectGDI
195 ret = CDirectGdiDriver::Open();
201 CDirectGdiDriver* dgdiDriver = CDirectGdiDriver::Static();
202 if(dgdiDriver == NULL)
214 TInt procHandles2 =0;
215 TInt threadHandles2=0;
216 RThread().HandleCount(procHandles2,threadHandles2);
217 if (threadHandles1 != threadHandles2)
219 ret = KErrGeneral; // Thread-owned handles not closed
225 Function for initializing DirectGdi then activating a target and drawing on it,
226 used by TestDirectGdiMultipleThreadIndependenceL().
227 @see TestDirectGdiMultipleThreadIndependenceL()
228 @param aInfo Not used
229 @return KErrNone if successful, one of the system wide error codes otherwise
231 TInt CTMultiThread::ThreadTwoStart(TAny* /*aInfo*/)
233 TInt procHandles1 =0;
234 TInt threadHandles1=0;
235 RThread().HandleCount(procHandles1, threadHandles1);
237 CTrapCleanup* cleanupStack=CTrapCleanup::New();
238 if (cleanupStack==NULL)
244 TInt ret = sem.OpenGlobal(KMultiThreadSemaphore);
250 //initialize graphics resource driver
251 ret = SgDriver::Open();
257 //initialise DirectGDI
258 ret = CDirectGdiDriver::Open();
264 CDirectGdiDriver* dgdiDriver = CDirectGdiDriver::Static();
265 if(dgdiDriver == NULL)
272 //render using DirectGDI
273 CDirectGdiContext* gc = NULL;
274 TRAPD(err, gc=CDirectGdiContext::NewL(*dgdiDriver));
281 TSgImageInfo imageInfo;
282 imageInfo.iSizeInPixels = TSize (320, 240);
283 imageInfo.iPixelFormat = EUidPixelFormatRGB_565;
284 imageInfo.iUsage = ESgUsageDirectGdiTarget;
285 ret = rsgImage.Create(imageInfo, NULL,0);
290 RDirectGdiImageTarget dgdiImageTarget(*dgdiDriver);
291 ret = dgdiImageTarget.Create(rsgImage);
296 gc->Activate(dgdiImageTarget);
297 gc->SetPenColor(TRgb(100,100,100));
298 gc->DrawRect(TRect(0,0,30,30));
301 dgdiImageTarget.Close();
308 TInt procHandles2 =0;
309 TInt threadHandles2=0;
310 RThread().HandleCount(procHandles2,threadHandles2);
311 if (threadHandles1 != threadHandles2)
313 ret = KErrGeneral; // Thread-owned handles not closed
320 GRAPHICS-DIRECTGDI-MULTITHREAD-0002
341 Create two CDirectGdiImageSource objects from the same RSgImage, but in different threads.
344 Test the use case where we:
346 Create two CDirectGdiImageSource objects, one in the current thread, and one in a new thread.
347 The CDirectGdiImageSource objects should share the EGL image created from the RSgImage in the
348 current thread as only one EGL image can be created per RSgImage per process.
349 If the EGL image sharing is not working an error will occur when creating the
350 second CDirectGdiImageSource object in the new thread.
352 void CTMultiThread::TestShareEGLImageBetweenSources_MultithreadedL()
354 INFO_PRINTF1(_L("Multithread_ShareEGLImageBetweenSources"));
356 TUidPixelFormat pixelFormat = EUidPixelFormatXRGB_8888;
357 SetTargetL(pixelFormat);
359 // Initialize graphics resource driver
360 TInt res = SgDriver::Open();
363 res = CDirectGdiDriver::Open();
366 CDirectGdiDriver* dgdiDriver = CDirectGdiDriver::Static();
367 TESTL(dgdiDriver != NULL);
368 CleanupClosePushL(*dgdiDriver);
371 CDirectGdiContext* gc = CDirectGdiContext::NewL(*dgdiDriver);
373 CleanupStack::PushL(gc);
375 // Create a CFbsBitmap
376 TSize patternSize(90,50);
377 TRect rect(0,0,90,50);
378 CFbsBitmap* bitmap = CreateCheckedBoardBitmapL(pixelFormat, patternSize);
379 TESTL(NULL != bitmap);
380 CleanupStack::PushL(bitmap);
382 // Create an RSgImage from the CFbsBitmap
383 TSgImageInfo imageInfo;
384 imageInfo.iSizeInPixels = patternSize;
385 imageInfo.iPixelFormat = pixelFormat;
386 imageInfo.iUsage = ESgUsageDirectGdiSource;
388 res = sgImage.Create(imageInfo, bitmap->DataAddress(), bitmap->DataStride());
390 CleanupClosePushL(sgImage);
392 // Create a RDirectGdiDrawableSource from the RSgImage
393 RDirectGdiDrawableSource dgdiImageSource(*dgdiDriver);
394 res = dgdiImageSource.Create(sgImage);
396 CleanupClosePushL(dgdiImageSource);
398 // Create a semaphore
400 TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0));
401 CleanupClosePushL(sem);
403 // Create the thread that will create a source from the RSgImage above
404 TSgDrawableId sgImageId = sgImage.Id();
405 User::LeaveIfError(iThread1.Create(KNameThreadOne, ThreadEGLImageStart, KDefaultStackSize, KMinTestThreadHeapSize, KMaxTestThreadheapSize, &sgImageId));
408 TRequestStatus threadStatus;
409 iThread1.Logon(threadStatus);
410 iThread1.SetPriority(EPriorityLess);
417 User::WaitForRequest(threadStatus);
419 TESTNOERROR(iThread1.ExitReason());
423 CleanupStack::PopAndDestroy(6, dgdiDriver);
427 Function use by TestShareEGLImageBetweenSources_MultithreadedL() when testing
428 creation of a target in a separate thread.
429 @see TestShareEGLImageBetweenSources_MultithreadedL()
430 @param aInfo Not used
431 @return KErrNone if successful, one of the system wide error codes otherwise
433 TInt CTMultiThread::ThreadEGLImageStart(TAny* aInfo)
435 TInt procHandles1 = 0;
436 TInt threadHandles1 = 0;
437 RThread().HandleCount(procHandles1, threadHandles1);
439 CTrapCleanup* cleanupStack=CTrapCleanup::New();
440 if (cleanupStack==NULL)
446 TInt ret = sem.OpenGlobal(KMultiThreadSemaphore);
450 // Initialize graphics resource driver
451 ret = SgDriver::Open();
455 // Initialise DirectGDI
456 ret = CDirectGdiDriver::Open();
460 CDirectGdiDriver* dgdiDriver = CDirectGdiDriver::Static();
461 if(dgdiDriver == NULL)
466 TSgDrawableId* sgImageId = reinterpret_cast<TSgDrawableId*>(aInfo);
467 RSgImage sgImageSource;
468 ret = sgImageSource.Open(*sgImageId);
472 // Create a RDirectGdiDrawableSource from the RSgImage
473 RDirectGdiDrawableSource dgdiImageSource(*dgdiDriver);
474 ret = dgdiImageSource.Create(sgImageSource);
480 // Render using DirectGDI
481 CDirectGdiContext* gc = NULL;
482 TRAPD(err, gc=CDirectGdiContext::NewL(*dgdiDriver));
489 TSgImageInfo imageInfo;
490 imageInfo.iSizeInPixels = TSize (320, 240);
491 imageInfo.iPixelFormat = EUidPixelFormatRGB_565;
492 imageInfo.iUsage = ESgUsageDirectGdiTarget;
493 ret = rsgImage.Create(imageInfo, NULL,0);
498 RDirectGdiImageTarget dgdiImageTarget(*dgdiDriver);
499 ret = dgdiImageTarget.Create(rsgImage);
504 gc->Activate(dgdiImageTarget);
505 gc->SetPenColor(TRgb(100,100,100));
506 gc->DrawRect(TRect(0,0,30,30));
508 dgdiImageSource.Close();
509 sgImageSource.Close();
511 dgdiImageTarget.Close();
518 TInt procHandles2 =0;
519 TInt threadHandles2=0;
520 RThread().HandleCount(procHandles2,threadHandles2);
521 if (threadHandles1 != threadHandles2)
523 ret = KErrGeneral; // Thread-owned handles not closed