sl@0: // Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @test sl@0: @internalComponent - Internal Symbian test code sl@0: */ sl@0: sl@0: sl@0: #ifndef __EGLTEST_ENDPOINT_ENGINE_H__ sl@0: #define __EGLTEST_ENDPOINT_ENGINE_H__ sl@0: sl@0: #include "localtestbase.h" sl@0: #include "remotetestbase.h" sl@0: #include "egltest_surface.h" sl@0: #include "egltest_endpoint_engine_types.h" sl@0: #include "egltest_endpoint_images.h" sl@0: sl@0: #define ENGINE_ASSERT(x) DoEngineAssert((x) != 0, #x, __FILE__, __LINE__) sl@0: sl@0: static inline void DoEngineAssert(TInt aX, const char *aXStr, sl@0: const char *aFile, TInt aLine) sl@0: { sl@0: if (!aX) sl@0: { sl@0: RDebug::Printf("EGL_ENDPOINT_TEST_ENGINE ASSERT(%s) failed (value %d) at %s:%d\n", sl@0: aXStr, aX, aFile, aLine); sl@0: User::Panic(_L("ENGINE_ASSERT"), aLine); sl@0: } sl@0: } sl@0: sl@0: sl@0: // This could be wrapped in #if/#else to allow us to generate non-unicode text content. sl@0: #define TESTIDS(x) _S(x) sl@0: #define CASETITLE(x) _S(x) sl@0: sl@0: sl@0: // SurfaceType lists. sl@0: // We use macros so that we get an automatic comment as to what the fields are, sl@0: // rather than just listing enums in an array. sl@0: #define SurfaceTypes1(type1) 1, { type1 } sl@0: #define SurfaceTypes2(type1, type2) 2, { type1, type2 } sl@0: #define SurfaceTypes3(type1, type2, type3) 3, { type1, type2, type3 } sl@0: #define SurfaceTypes4(type1, type2, type3, type4) 4, { type1, type2, type3, type4 } sl@0: sl@0: // Macro used for building a TTestCases entry. sl@0: #define TestCase(x) { x, sizeof(x) / sizeof(x[0]) } sl@0: sl@0: // Forward declare this class. sl@0: class CEgltest_Local_Engine_Exec; sl@0: sl@0: // The object passed back from the exec thread to the sl@0: // controller thread. sl@0: class TExecResult sl@0: { sl@0: public: sl@0: TExecResult(); sl@0: sl@0: //Constructor for sending result info. sl@0: TExecResult(TVerdict aVerdict, TEngineCases aCase); sl@0: sl@0: // Constructor for sending result of buffer count paramters. sl@0: TExecResult(TVerdict aBufferCountVerdict, TVerdict aVerdict, TEngineCases aCase); sl@0: sl@0: public: sl@0: //Result message. sl@0: TVerdict iVerdict; sl@0: // Checking buffer count. sl@0: TVerdict iBufferCountVerdict; sl@0: // Get Surface parameter reply. sl@0: TSurfaceParamsRemote iSurfaceParams; sl@0: // To check that we are in sync - it should match the request. sl@0: TEngineCases iCase; sl@0: }; sl@0: sl@0: const TInt KMaxLoadThreads = 4; sl@0: sl@0: NONSHARABLE_CLASS(CEgltest_Local_Engine): public CLocalTestStepBase sl@0: { sl@0: private: sl@0: enum TExecState sl@0: { sl@0: EExecStateNone = 0, sl@0: EExecStateRemote, sl@0: EExecStateLocal sl@0: }; sl@0: public: sl@0: CEgltest_Local_Engine(const TTestCases *aTestCases, TInt aNumCases); sl@0: virtual ~CEgltest_Local_Engine(); sl@0: virtual TVerdict doTestStepL(); sl@0: virtual void DoPreambleL(); sl@0: virtual void DoPostambleL(); sl@0: void SetTestCasesL(const TTestCases * const aTestCases, TInt aNumCases); sl@0: sl@0: private: sl@0: void RunTestCase(const TTestCases &aTestCase); sl@0: void RunOneTestCase(const TTestCase& aTestCase, TSurfaceType aSurfType); sl@0: void SendLocalTestCase(const TRemoteTestParams &aParams); sl@0: void RunLocalTestCase(TEngineCases aCase); sl@0: void DoSyncToLocal(); sl@0: void GetLocalResult(TExecResult& aResult, TEngineCases aCase); sl@0: void DoMonitorThreadEntry(); sl@0: void ForwardPanic(RThread& aThread, RThread& aOtherThread, TRequestStatus &aStatus); sl@0: static TInt MonitorThreadEntry(TAny *aParam); sl@0: void RunControllerLocalAndRemoteL(const TEngineTestCase&, const TRemoteTestParams& params); sl@0: sl@0: protected: sl@0: void RunLocalTestCase(const TRemoteTestParams& aMessageIn, TExecResult& aResult); sl@0: TVerdict RunRemoteTestCase(TInt aTestCase, const TRemoteTestParams& aMessageIn); sl@0: void RunSingleCaseL(const TTestCase& aTestCase, TSurfaceType aSurfType); sl@0: void CommonPreambleL(); sl@0: CEgltest_Local_Engine(); sl@0: // The StartThread and EndThread needs to be overridden in the sl@0: // implementation to provide a good functionality. sl@0: virtual void StartThreadL(TInt aThreadNumber); sl@0: virtual void EndThread(TInt aThreadNumber); sl@0: sl@0: protected: sl@0: const TTestCases* iTestCases; sl@0: TInt iNumCases; sl@0: RThread iExecThread; sl@0: RThread iMonitorThread; sl@0: RThread iControllerThread; // Controller thread sl@0: RMsgQueue iExecResultOutQueue; sl@0: RMsgQueue iExecParamsInQueue; sl@0: TExecState iExecState; sl@0: TBool iLogging; sl@0: }; sl@0: sl@0: sl@0: struct TRemoteTestArgs sl@0: { sl@0: EGLDisplay iDisplay; sl@0: EGLEndpointNOK iEndpoint; sl@0: EGLImageKHR iImage; sl@0: }; sl@0: sl@0: sl@0: struct TAvailableMemory sl@0: { sl@0: TInt iHeapMemAvailable; sl@0: TInt iGpuMemAvailable; sl@0: }; sl@0: sl@0: // Base class that allows "script" style exectution of testcases. sl@0: NONSHARABLE_CLASS(CEgltest_Remote_Engine): public CRemoteTestStepBase sl@0: { sl@0: public: sl@0: CEgltest_Remote_Engine(); sl@0: virtual ~CEgltest_Remote_Engine(); sl@0: virtual TRemoteTestVerdict DoStartRemoteTestStepL(const TRemoteTestParams& aParams); sl@0: virtual TRemoteTestVerdict DoEndRemoteTestStepL(const TRemoteTestParams& aParams); sl@0: virtual TRemoteTestVerdict DoRunRemoteTestCaseL(TInt aTestCase, const TRemoteTestParams& aParams); sl@0: private: sl@0: void LogDump(const TEngineTestCase& aCase); sl@0: EGLDisplay GetDisplay(TInt aFlags); sl@0: EGLEndpointNOK GetEndpoint(TInt aIndex, TInt aFlags); sl@0: EGLImageKHR GetImage(TInt aIndex, TInt aFlags); sl@0: EGLenum GetEndpointType(TInt aFlags); sl@0: EGLenum GetSourceType(TInt aFlags); sl@0: const TSurfaceId GetSurfaceId(TInt aFlags, const TSurfaceId& aSurfaceId); sl@0: void CheckReturn(TInt aRetval, const TEngineTestCase& aStreamItem, TInt aFailValue, sl@0: const TText* aFailSymbol, const TText* aFunction); sl@0: void RunCaseL(TInt aTestCase, const TRemoteTestParams &aParams, const TRemoteTestArgs& aArgs); sl@0: void CreateEndpointCaseL(const TRemoteTestParams& aParams, const TRemoteTestArgs& aArgs); sl@0: void ReleaseImageCaseL(const TRemoteTestParams& aParams, const TRemoteTestArgs& aArgs); sl@0: void ActivateVgContextL(); sl@0: void RequestNotificationL(const TRemoteTestParams& aParams, const TRemoteTestArgs& aArgs); sl@0: void GetEndpointDirtyAreaL(const TRemoteTestParams& aParams, const TRemoteTestArgs& aArgs); sl@0: void DoCheckRectsL(EGLint *aActualRects, EGLint aRectCount, EGLint aMaxRects, sl@0: TInt aRectsIndex, const TRect aSurfacRect); sl@0: void CheckForMemoryLeaks(); sl@0: void CheckForMemoryLeaksFinish(); sl@0: sl@0: TInt FillGpuMemory(); sl@0: TInt CalculateAvailableGPUMemory(); sl@0: TInt CalculateAvailableHeapMemory(); sl@0: sl@0: // Thread entry points for "load" threads. sl@0: static TInt LoadHeapMemory(TAny *); sl@0: void LoadHeapMemoryL(); sl@0: static TInt LoadGpuMemory(TAny *); sl@0: void LoadGpuMemoryL(); sl@0: sl@0: void StartThreadL(TInt aThreadNumber); sl@0: void EndThread(TInt aThreadNumber); sl@0: TThreadFunction GetThreadFunction(TInt aThreadNumber); sl@0: sl@0: private: sl@0: EGLEndpointNOK iEndpoints[KMaxEndpoints]; sl@0: EGLImageKHR iEglImage[KMaxEndpoints]; sl@0: CTestVgEglImage* iVgImage[KMaxEndpoints]; sl@0: TRequestStatus iRequestStatus[KMaxEndpoints]; sl@0: TRemoteTestVerdict iTestVerdict; sl@0: TBool iLogging; sl@0: CEglWindowSurface *iSurface; sl@0: // when this flag is set, errors discovered during a test-step is logged. sl@0: // This is normally true, but for stress tests [etc], it can be turned sl@0: // off so that when a test is set up to run 1000 times, but only succeeds sl@0: // X times, we don't get "error, something failed", when we really didn't sl@0: // get an error. sl@0: TBool iLogErrors; sl@0: sl@0: // Tracking memory available. sl@0: RArray iMemoryStats; sl@0: sl@0: // Variables to keep track of load-threads. sl@0: RThread iLoadThread[KMaxLoadThreads]; sl@0: TBool iStopThreadFlag[KMaxLoadThreads]; sl@0: sl@0: RHeap* iMainThreadHeap; sl@0: PFNEGLQUERYPROFILINGDATANOKPROC ipfnEglQueryProfilingDataNOK; sl@0: }; sl@0: sl@0: sl@0: #define CASE(x) case x: caseName=_S(#x); break sl@0: sl@0: static inline const TText* EngineCaseName(TEngineCases aCase) sl@0: { sl@0: const TText* caseName = _S("Unknown Engine Case"); sl@0: switch (aCase) sl@0: { sl@0: CASE(ECreateEndpointCase); sl@0: CASE(EBeginStreamingCase); sl@0: CASE(EAcquireImageCase); sl@0: CASE(EReleaseImageCase); sl@0: CASE(EEndStreamingCase); sl@0: CASE(EContentUpdateCase); sl@0: CASE(EDestroyEndpointCase); sl@0: CASE(EInitializeCase); sl@0: CASE(ETerminateCase); sl@0: CASE(EGetAttribCase); sl@0: CASE(ESetAttribCase); sl@0: CASE(ECreateSurfaceCase); sl@0: CASE(EDrawContentCase); sl@0: CASE(ECompareImageCase); sl@0: CASE(EWaitForCase); sl@0: CASE(ENotifyWhenCase); sl@0: CASE(ETestVgImageValidCase); sl@0: CASE(EDestroyVgImageCase); sl@0: CASE(EDestroyEglImageCase); sl@0: CASE(ETimeStampCase); sl@0: CASE(ERequestNotificationCase); sl@0: CASE(EWaitForNotificationCase); sl@0: CASE(ECancelNotificationCase); sl@0: CASE(EBreakPointCase); sl@0: CASE(ELogEnableCase); sl@0: CASE(EIllegalCase); sl@0: CASE(EPanicCase); sl@0: CASE(EGetEndpointDirtyAreaCase); sl@0: CASE(ESyncLocalCase); sl@0: CASE(EGetSurfaceParamsCase); sl@0: CASE(EFinishedCase); sl@0: CASE(ECreateVgImageCase); sl@0: CASE(EDestroySurfaceCase); sl@0: CASE(EStartLoadThreadCase); sl@0: CASE(EEndLoadThreadCase); sl@0: CASE(ECheckForMemoryLeaks); sl@0: CASE(ECheckForMemoryLeaksFinish); sl@0: } sl@0: return caseName; sl@0: } sl@0: sl@0: #undef CASE sl@0: sl@0: sl@0: inline void LogDump(CTestExecuteLogger &aLogger, const TEngineTestCase& aCase) sl@0: { sl@0: const TText *caseName = EngineCaseName(aCase.iCase); sl@0: aLogger.LogExtra(((TText8*)__FILE__), __LINE__, ESevrInfo, sl@0: _L("Performing subcase %d (%s), with flags=%d, err=%04x endpointidx=%d, image=%d, args=(%d, %d)"), sl@0: aCase.iCase, sl@0: caseName, sl@0: aCase.iFlags, sl@0: aCase.iErrorExpected, sl@0: aCase.iEndpointIndex, sl@0: aCase.iImageIndex, sl@0: aCase.iArg1, aCase.iArg2); sl@0: } sl@0: sl@0: sl@0: #endif // __EGLTEST_ENDPOINT_ENGINE_H__