# HG changeset patch # User Faisal Memon # Date 1285868586 -3600 # Node ID bbf967b65d9e5a96ffe2e21e3066d637a74b2997 # Parent 790dbf92bc7e76e1bce142352d6c154ae1d4b1ac Add a bringup test program. Rom build is: buildrom syborg minigui_simulator eglbringuptest.iby The command to run is called ebt. See mmp file for documentation. diff -r 790dbf92bc7e -r bbf967b65d9e bug235.pkgdef.xml --- a/bug235.pkgdef.xml Thu Sep 30 13:10:25 2010 +0100 +++ b/bug235.pkgdef.xml Thu Sep 30 18:43:06 2010 +0100 @@ -96,6 +96,11 @@ + + + + + diff -r 790dbf92bc7e -r bbf967b65d9e egl/sfegltest/group/bld.inf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/egl/sfegltest/group/bld.inf Thu Sep 30 18:43:06 2010 +0100 @@ -0,0 +1,20 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: + + +PRJ_TESTMMPFILES +eglbringuptest.mmp + +PRJ_TESTEXPORTS +eglbringuptest.iby /epoc32/rom/include/eglbringuptest.iby diff -r 790dbf92bc7e -r bbf967b65d9e egl/sfegltest/group/eglbringuptest.iby --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/egl/sfegltest/group/eglbringuptest.iby Thu Sep 30 18:43:06 2010 +0100 @@ -0,0 +1,20 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#if !defined(__EGLBRINGUPTEST_IBY__) +#define __EGLBRINGUPTEST_IBY__ + +file=ABI_DIR\udeb\eglbringuptest.exe sys\bin\ebt.exe +#endif diff -r 790dbf92bc7e -r bbf967b65d9e egl/sfegltest/group/eglbringuptest.mmp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/egl/sfegltest/group/eglbringuptest.mmp Thu Sep 30 18:43:06 2010 +0100 @@ -0,0 +1,61 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// This test program is designed for a Mini GUI environment (no middleware) +// for the purpose of testing the bring-up of a new EGL implementation. +// It differs from egltest component in so far as it does not need the +// Test Execution Framework version 1, which is not present in the Symbian +// Foundation (since it uses the newer STIF framework instead). +// +// A new EGL implementation must implement EGL Sync Objects in order for the +// system to boot, since OpenWF needs this for initialisation. +// +// Once EGL sync objects support is present, this utility program known as +// ebt (EGL bringup test) can be used from the EShell command prompt. +// +// ebt can take an argument to specific which screen to test. By default +// screen zero is tested. +// ebt aims to provide comprehensive logging to allow confirmation of the +// setup of appropriate EGL objects, and subsequent rendering using OpenVG + + +target eglbringuptest.exe +targettype exe + +userinclude . +userinclude ../inc/ +systeminclude /epoc32/include +systeminclude /epoc32/include/stdapis +systeminclude /epoc32/include/platform + +library libegl.lib // EGL +library libopenvg.lib // OpenVG +library libopenvgu.lib // OpenVGU + +library euser.lib +library libc.lib +library fbscli.lib +library ws32.lib +library gdi.lib +library bitgdi.lib +library hal.lib +library efsrv.lib +library fntstr.lib + +sourcepath ../src +source main.cpp +source eglrendering.cpp + +epocheapsize 0x1000 0x800000 + +smpsafe diff -r 790dbf92bc7e -r bbf967b65d9e egl/sfegltest/inc/eglrendering.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/egl/sfegltest/inc/eglrendering.h Thu Sep 30 18:43:06 2010 +0100 @@ -0,0 +1,60 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: + +#ifndef __EGLRENDERING_H__ +#define __EGLRENDERING_H__ + + +#include +#include +#include +#include +#include + +class CEGLRendering : public CBase + { +public: + static CEGLRendering* NewL(RWindow& aWindow, TBool); + static CEGLRendering* NewLC(RWindow& aWindow,TBool); + + ~CEGLRendering(); + + void Start(); + void Stop(); + + static void EGLCheckError(); + static void EGLCheckReturnError(EGLBoolean aBool); + static void VGCheckError(); + void UpdateDisplay(); + static TInt TimerCallBack(TAny* aDemo); + +private: + CEGLRendering(RWindow& aWindow); + void ConstructL(TBool); + +private: + RWindow& iWindow; + + CPeriodic* iTimer; + + CFbsBitmap* iBitmap; + TInt iCount; + + EGLDisplay iDisplay; + EGLSurface iSurface; + EGLContext iContextVG; + }; + + +#endif diff -r 790dbf92bc7e -r bbf967b65d9e egl/sfegltest/inc/openvgengine.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/egl/sfegltest/inc/openvgengine.h Thu Sep 30 18:43:06 2010 +0100 @@ -0,0 +1,34 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: + +#ifndef OPENVGENGINE_H_ +#define OPENVGENGINE_H_ + +#include +#include + +// image Height/Width +const TInt KImageSize = 128; + +//KMaxCoversExample3 refers to the number of album covers visible on the screen at any given point +const TInt KMaxDisplayCoversExample3 = 40; +const TInt KMaxDisplayLeftExample3 = -3; +const TInt KMaxDisplayRightExample3 = 3; + + +// the max number of covers you can store +const TInt KMaxCoversExample3 = 40; + + +#endif diff -r 790dbf92bc7e -r bbf967b65d9e egl/sfegltest/src/eglrendering.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/egl/sfegltest/src/eglrendering.cpp Thu Sep 30 18:43:06 2010 +0100 @@ -0,0 +1,229 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: + +#include +#include "eglrendering.h" +#include "openvgengine.h" +#include + +const TInt KTimerDelay = 0; + + +/** Attributes to be passed into eglChooseConfig */ +const EGLint KColorRGB565AttribList[] = + { + EGL_RED_SIZE, 5, + EGL_GREEN_SIZE, 6, + EGL_BLUE_SIZE, 5, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT, + EGL_NONE + }; + + +CEGLRendering* CEGLRendering::NewL(RWindow& aWindow, TBool aQhd) + { + CEGLRendering* self = CEGLRendering::NewLC(aWindow, aQhd); + CleanupStack::Pop(self); + return self; + } + + +CEGLRendering* CEGLRendering::NewLC(RWindow& aWindow, TBool aQhd) + { + CEGLRendering* self = new(ELeave) CEGLRendering(aWindow); + CleanupStack::PushL(self); + self->ConstructL(aQhd); + return self; + } + +CEGLRendering::~CEGLRendering() + { + Stop(); + + delete iTimer; + + if (iContextVG!=EGL_NO_CONTEXT) + { + EGLCheckReturnError(eglDestroyContext(iDisplay,iContextVG)); + } + + if (iSurface!=EGL_NO_SURFACE) + { + EGLCheckReturnError(eglDestroySurface(iDisplay,iSurface)); + } + + // Call eglMakeCurrent() to ensure the surfaces and contexts are truly destroyed. + EGLCheckReturnError(eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); + + EGLCheckReturnError(eglTerminate(iDisplay)); + EGLCheckReturnError(eglReleaseThread()); + + delete iBitmap; + } + +void CEGLRendering::Start() + { + // Start drawing the screen periodically + iTimer->Start(0, KTimerDelay, TCallBack(TimerCallBack,this)); + } + +void CEGLRendering::Stop() + { + if(iTimer) + { + iTimer->Cancel(); + } + } + +void CEGLRendering::EGLCheckError() + { + EGLint error = eglGetError(); + if(error != EGL_SUCCESS) + { + User::Panic(_L("EGL error"), error); + } + } + +void CEGLRendering::VGCheckError() + { + VGint error = vgGetError(); + if(error != VG_NO_ERROR) + { + User::Panic(_L("OpenVG error"), error); + } + } + +void CEGLRendering::EGLCheckReturnError(EGLBoolean aBool) + { + if (!aBool) + { + User::Panic(_L("EGL return error"),eglGetError()); + } + } + + +CEGLRendering::CEGLRendering(RWindow& aWindow) + : iWindow(aWindow),iCount(0) + { + } + +/* + * Construct EGL objects, and OpenVG binding. + * + * Here we collaborate with EGL to associate a session, pick and configuration, assign + * it to the window we have, and then bind the OpenVG rendering API to our newly created + * context. + * + * In bring up terms, here is where the first EGL code entry points are called from. Its + * the natural point where an EGL bringup starts debugging from, assuming the core EGL + * works in terms of supporting EGL sync objects (needed for boot before we get to the + * ESHELL command prompt). + */ +void CEGLRendering::ConstructL(TBool aQhd) + { + RDebug::Printf("CEGLRendering::ConstructL"); + + // Refresh timer + iTimer = CPeriodic::NewL(CActive::EPriorityIdle); + + const TDisplayMode dispMode = iWindow.DisplayMode(); + const TSize windowSize(iWindow.Size()); + + // Create display object + iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + RDebug::Printf("CEGLRendering::ConstructL 1"); + EGLCheckError(); + + // Initialize display object + EGLCheckReturnError(eglInitialize(iDisplay, NULL, NULL)); + RDebug::Printf("CEGLRendering::ConstructL 2"); + + RDebug::Printf("Vendor string %s", eglQueryString(iDisplay, EGL_VENDOR)); + RDebug::Printf("Version string %s", eglQueryString(iDisplay, EGL_VERSION)); + RDebug::Printf("Version string %s", eglQueryString(iDisplay, EGL_EXTENSIONS)); + + + // Check that EGL provides the capabilities for this app. + TInt error = KErrNone; + if ( NULL == strstr(eglQueryString(iDisplay, EGL_CLIENT_APIS), "OpenVG") ) + { + RDebug::Printf("OpenVG not listed in supported client APIs %s", eglQueryString(iDisplay, EGL_CLIENT_APIS)); + error = KErrNotSupported; + } + + + if ( NULL == strstr(eglQueryString(iDisplay, EGL_EXTENSIONS), "EGL_SYMBIAN_COMPOSITION") ) + { + RDebug::Printf("EGL_SYMBIAN_COMPOSITION not listed in extension string %s", eglQueryString(iDisplay, EGL_EXTENSIONS)); + error = KErrNotSupported; + } + if (error != KErrNone) + { + User::Leave(error); + } + + EGLint numConfigs; + EGLConfig chosenConfig = 0; + + // Choose the config to use + EGLCheckReturnError(eglChooseConfig(iDisplay, KColorRGB565AttribList, &chosenConfig, 1, &numConfigs)); + RDebug::Printf("CEGLRendering::ConstructL 3"); + if (numConfigs == 0) + { + RDebug::Printf("No matching configs found", eglQueryString(iDisplay, EGL_EXTENSIONS)); + User::Leave(KErrNotSupported); + } + + // Create window surface to draw direct to. + EGLCheckReturnError(eglBindAPI(EGL_OPENVG_API)); + RDebug::Printf("CEGLRendering::ConstructL 4"); + iSurface = eglCreateWindowSurface(iDisplay, chosenConfig, &iWindow, NULL); + RDebug::Printf("CEGLRendering::ConstructL 5"); + EGLCheckError(); + + TInt redSize, greenSize, blueSize, alphaSize; + + EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_ALPHA_SIZE, &alphaSize)); + EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_RED_SIZE, &redSize)); + EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_GREEN_SIZE, &greenSize)); + EGLCheckReturnError(eglGetConfigAttrib(iDisplay, chosenConfig, EGL_BLUE_SIZE, &blueSize)); + RDebug::Print(_L("EGLConfig id:%d alpha:%d red:%d green:%d blue:%d"), chosenConfig, + alphaSize, redSize, greenSize, blueSize); + RDebug::Printf("CEGLRendering::ConstructL 6"); + + // Create context to store surface settings + iContextVG = eglCreateContext(iDisplay, chosenConfig, EGL_NO_CONTEXT, NULL); + RDebug::Printf("CEGLRendering::ConstructL 7"); + EGLCheckError(); + + CEGLRendering::EGLCheckReturnError(eglMakeCurrent(iDisplay, iSurface, iSurface, iContextVG)); + RDebug::Printf("CEGLRendering::ConstructL 8"); + } + + +/** Update the display */ +void CEGLRendering::UpdateDisplay() + { + // Flush colour buffer to the window surface + CEGLRendering::EGLCheckReturnError(eglSwapBuffers(iDisplay, iSurface)); + } + +/** Callback called by refresh timer */ +TInt CEGLRendering::TimerCallBack(TAny* aDemo) + { + + static_cast(aDemo)->UpdateDisplay(); + return KErrNone; + } diff -r 790dbf92bc7e -r bbf967b65d9e egl/sfegltest/src/main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/egl/sfegltest/src/main.cpp Thu Sep 30 18:43:06 2010 +0100 @@ -0,0 +1,351 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: + +#include +#include +#include +#include +#include "eglrendering.h" + +#define KDefaultScreenNo 0 + +class CWsRedrawHandler; + +class CWsCanvas: public CBase +{ +public: + static CWsCanvas* NewL(TInt, const TPoint&); + ~CWsCanvas(); + + void DrawNow(); + void Redraw(); + void Draw(const TRect&); + + RWsSession& Session() {return iWs;} + RWindow& Window() {return iWin;} + RWindowGroup& Group() {return iGrp;} + CWindowGc* Gc() {return iGc;} + CWsScreenDevice* Screen() {return iScr;} + inline TSize ScreenSize() const; + +private: + CWsCanvas(TInt, const TPoint&); + void ConstructL(); + +private: + TInt iScrId; + TPoint iPos; + TSize iSz; + RWsSession iWs; + RWindowGroup iGrp; + RWindow iWin; + CWsScreenDevice* iScr; + CWindowGc* iGc; + CWsRedrawHandler* iRedrawHandler; +}; + +class CWsRedrawHandler: public CActive +{ +public: + CWsRedrawHandler(CWsCanvas&); + ~CWsRedrawHandler(); + + void RunL(); + void DoCancel(); + +private: + CWsCanvas& iCanvas; +}; + +class CWsApp: public CBase + { +public: + static CWsApp* NewL(); + ~CWsApp(); + void Start(); + void Stop(); + +private: + CWsApp(); + void ConstructL(); + + CWsCanvas* iAppView; + CEGLRendering* iDemo; + TBool iCallWindow; + + TPoint iQvgaPos; + TPoint iQhdPos; + TBool iQhd; + TPoint iPos; + TSize iSz; + TInt iScrId; + }; + +/** + * Create a canvas to draw to. + * + * @param aScrId Screen number to use + * @param aPos Position on screen to use + */ +CWsCanvas* CWsCanvas::NewL(TInt aScrId, const TPoint& aPos) + { + CWsCanvas* c = new(ELeave) CWsCanvas(aScrId, aPos); + CleanupStack::PushL(c); + c->ConstructL(); + CleanupStack::Pop(c); + + return c; + } + +CWsCanvas::CWsCanvas(TInt aScrId, const TPoint& aPos): + iScrId(aScrId), iPos(aPos) + { + } + +CWsCanvas::~CWsCanvas() + { + delete iGc; + delete iScr; + iGrp.Close(); + iWin.Close(); + delete iRedrawHandler; + iWs.Close(); + } + +/** + * Construct the application canvas. + * + * Here we setup the collaboration with the Window Server. We want to get a window + * on the appropriate screen, and setup a redraw handler so we can re-paint our window + * when the Window Server wants us to. + */ +void CWsCanvas::ConstructL() + { + TInt err = iWs.Connect(); + User::LeaveIfError(err); + + iScr = new(ELeave) CWsScreenDevice(iWs); + err = iScr->Construct(iScrId); + User::LeaveIfError(err); + + err = iScr->CreateContext(iGc); + User::LeaveIfError(err); + + iGrp = RWindowGroup(iWs); + err = iGrp.Construct(0xbadf00d, ETrue, iScr); + User::LeaveIfError(err); + + iWin = RWindow(iWs); + err = iWin.Construct(iGrp, (TUint32)this); + User::LeaveIfError(err); + + iSz = iScr->SizeInPixels(); + iWin.SetExtent(iPos, iSz); + iWin.SetBackgroundColor(); + iWin.Activate(); + + iWs.Flush(); + + iRedrawHandler = new(ELeave) CWsRedrawHandler(*this); + iWs.SetFocusScreen(iScrId); + } + +void CWsCanvas::DrawNow() + { + iWin.Invalidate(); + Redraw(); + } + +void CWsCanvas::Redraw() + { + iWin.BeginRedraw(); + iGc->Activate(iWin); + Draw(TRect(TPoint(), iSz)); + iGc->Deactivate(); + iWin.EndRedraw(); + + iWs.Flush(); + } + +void CWsCanvas::Draw(const TRect& /*aRect*/) + { + } + +inline TSize CWsCanvas::ScreenSize() const + { + return iSz; + } + +CWsRedrawHandler::CWsRedrawHandler(CWsCanvas& aCanvas): + CActive(CActive::EPriorityStandard), + iCanvas(aCanvas) + { + CActiveScheduler::Add(this); + + iStatus = KRequestPending; + iCanvas.Session().RedrawReady(&iStatus); + SetActive(); + } + +CWsRedrawHandler::~CWsRedrawHandler() + { + Cancel(); + } + +void CWsRedrawHandler::RunL() + { + TWsRedrawEvent e; + iCanvas.Session().GetRedraw(e); + if (e.Handle() == (TInt) &iCanvas) + { + iCanvas.Redraw(); + } + + iStatus = KRequestPending; + iCanvas.Session().RedrawReady(&iStatus); + SetActive(); + } + +void CWsRedrawHandler::DoCancel() + { + iCanvas.Session().RedrawReadyCancel(); + } + + +CWsApp::CWsApp(): + iQvgaPos(160,60), + iQhdPos(0,0), + iQhd(ETrue) + { + } + +CWsApp* CWsApp::NewL() + { + RDebug::Printf("CWsApp::NewL()"); + CWsApp* app = new(ELeave) CWsApp; + CleanupStack::PushL(app); + app->ConstructL(); + CleanupStack::Pop(app); + + return app; + } + +/** + * Constructor for CWsApp + * + * @note This constructor looks at the command line argument, if any, supplied when + * launching the application. If specified, its used as the screen number to + * target the output of the program. By default, screen 0 is used. + */ +void CWsApp::ConstructL() + { + RDebug::Printf("CWsApp::ConstructL()"); + iPos = iQhd? iQhdPos : iQvgaPos; + + iScrId = KDefaultScreenNo; + if (User::CommandLineLength() > 0) + { + TBuf<1> arg; + User::CommandLine(arg); + iScrId = (TInt)(arg[0]-'0'); + } + RDebug::Printf("CWsApp::ConstructL() 1"); + iAppView = CWsCanvas::NewL(iScrId, iPos); + RDebug::Printf("CWsApp::ConstructL() 2"); + iDemo = CEGLRendering::NewL(iAppView->Window(), iQhd); + RDebug::Printf("CWsApp::ConstructL() 3"); + iDemo->Start(); + RDebug::Printf("CWsApp::ConstructL() 4"); + + iSz = iAppView->ScreenSize(); + RDebug::Printf("CWsApp::ConstructL() 5"); + + //Connstruct dialog Box + // Get a 212x76 pixel box in the centre of the window. + TRect rcDialog(TRect(iPos, iSz)); + +#ifdef PORTRAIT_MODE + rcDialog.Shrink((rcDialog.Width() - 76) / 2, (rcDialog.Height() - 212) / 2); +#else + rcDialog.Shrink((rcDialog.Width() - 212) / 2, (rcDialog.Height() - 76) / 2); +#endif + + iCallWindow = EFalse; + } + +void CWsApp::Start() + { + RDebug::Printf("CWsApp::Start"); + CActiveScheduler::Start(); + } + +void CWsApp::Stop() + { + CActiveScheduler::Stop(); + } + +CWsApp::~CWsApp() + { + delete iDemo; + delete iAppView; + } + +/** + * Application second level entry point. + * + * Launches the application specific class CWsApp and calls Start() on it. + * + * @pre Active scheduler established. + */ +void MainL() + { + RDebug::Printf("ebt ::MainL"); + CWsApp* app = CWsApp::NewL(); + CleanupStack::PushL(app); + + app->Start(); + + CleanupStack::PopAndDestroy(1, app); + } + +/** + * Application entry point. + * + * This sets up the application environment active scheduler and runs MainL under a trap + * harness. + */ +GLDEF_C TInt E32Main() + { + RDebug::Printf("ebt ::E32Main"); + + CTrapCleanup* tc = CTrapCleanup::New(); + if (!tc) + { + return KErrNoMemory; + } + + CActiveScheduler* as = new CActiveScheduler; + if (!as) + { + delete tc; + return KErrNoMemory; + } + + CActiveScheduler::Install(as); + TRAPD(err, MainL()); + + delete as; + delete tc; + return err; + }