os/graphics/graphicsdeviceinterface/directgdi/test/tdirectgdieglcontent_server.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "tdirectgdieglcontent_server.h"
sl@0
    17
#include "tdirectgdieglcontent_cube.h"
sl@0
    18
#include "tdirectgdieglcontent_clientserver.h"
sl@0
    19
#include "tdisplaymode_mapping.h"
sl@0
    20
#include <e32debug.h>
sl@0
    21
#include <fbs.h>
sl@0
    22
#include <graphics/sgimage_sw.h>
sl@0
    23
sl@0
    24
/**
sl@0
    25
Static constructor.
sl@0
    26
*/
sl@0
    27
CEglContent* CEglContent::NewL()
sl@0
    28
	{
sl@0
    29
	CEglContent* self = NewLC();
sl@0
    30
	CleanupStack::Pop(self);
sl@0
    31
	return self;
sl@0
    32
	}
sl@0
    33
sl@0
    34
CEglContent* CEglContent::NewLC()
sl@0
    35
	{
sl@0
    36
	CEglContent* self = new(ELeave) CEglContent();
sl@0
    37
	CleanupStack::PushL(self);
sl@0
    38
	self->ConstructL();
sl@0
    39
	return self;
sl@0
    40
	}
sl@0
    41
sl@0
    42
/**
sl@0
    43
1st phase constructor
sl@0
    44
*/
sl@0
    45
CEglContent::CEglContent() : CTimer(CActive::EPriorityStandard), iMode(ESync)
sl@0
    46
	{
sl@0
    47
	CActiveScheduler::Add(this);
sl@0
    48
	}
sl@0
    49
sl@0
    50
/**
sl@0
    51
2nd phase constructor
sl@0
    52
*/
sl@0
    53
void CEglContent::ConstructL()
sl@0
    54
	{
sl@0
    55
	CTimer::ConstructL();
sl@0
    56
sl@0
    57
	iCube = CGLCube::NewL(EUidPixelFormatXRGB_8888, TSize(200, 200));
sl@0
    58
	}
sl@0
    59
sl@0
    60
/**
sl@0
    61
Destructor
sl@0
    62
*/
sl@0
    63
CEglContent::~CEglContent()
sl@0
    64
	{
sl@0
    65
	Cancel();
sl@0
    66
sl@0
    67
	delete iCube;
sl@0
    68
	}
sl@0
    69
sl@0
    70
/**
sl@0
    71
Handles an active object's request completion event.
sl@0
    72
*/
sl@0
    73
void CEglContent::RunL()
sl@0
    74
	{
sl@0
    75
	if(iStatus.Int() == KErrNone)
sl@0
    76
		{
sl@0
    77
		RenderNextFrame();
sl@0
    78
		iFrame = iFrame % KEglContentAsyncMaxFrames;
sl@0
    79
sl@0
    80
		if(iMode == EAsync)
sl@0
    81
			{
sl@0
    82
			// issue request for next frame
sl@0
    83
			After(KEglContentDelay);
sl@0
    84
			}
sl@0
    85
		}
sl@0
    86
	}
sl@0
    87
sl@0
    88
/**
sl@0
    89
Render next frame of animation.
sl@0
    90
Function returns when rendering is finished. Animation is set to next frame.
sl@0
    91
*/
sl@0
    92
void CEglContent::RenderNextFrame()
sl@0
    93
	{
sl@0
    94
	iCube->Render(iFrame);
sl@0
    95
	iLastFrame = iFrame;
sl@0
    96
	iFrame++;
sl@0
    97
	}
sl@0
    98
sl@0
    99
/**
sl@0
   100
Set rendering mode to synchronous or asynchronous
sl@0
   101
@param aMode Rendering mode to set.
sl@0
   102
*/
sl@0
   103
void CEglContent::SetMode(TMode aMode)
sl@0
   104
	{
sl@0
   105
	if(aMode == iMode)
sl@0
   106
		return;
sl@0
   107
sl@0
   108
	iMode = aMode;
sl@0
   109
sl@0
   110
	// reset mode
sl@0
   111
	if(aMode == ESync)
sl@0
   112
		{
sl@0
   113
		// cancel request for next frame
sl@0
   114
		Cancel();
sl@0
   115
		iFrame = 0;
sl@0
   116
		}
sl@0
   117
	else if(aMode == EAsync)
sl@0
   118
		{
sl@0
   119
		// render init frame
sl@0
   120
		iFrame = 0;
sl@0
   121
		RenderNextFrame();
sl@0
   122
		// issue request for next frame
sl@0
   123
		After(KEglContentDelay);
sl@0
   124
		}
sl@0
   125
	else // EAsyncDebug
sl@0
   126
		{
sl@0
   127
		// render init frame
sl@0
   128
		iFrame = 0;
sl@0
   129
		RenderNextFrame();
sl@0
   130
		}
sl@0
   131
	}
sl@0
   132
sl@0
   133
/**
sl@0
   134
Get image id of current frame. Current image to render is switch to next.
sl@0
   135
@param aId Reference to drawable id class to store image id.
sl@0
   136
@return number of frame stored in image
sl@0
   137
*/
sl@0
   138
TInt CEglContent::GetImage(TSgDrawableId& aId)
sl@0
   139
	{
sl@0
   140
	if(iMode == ESync)
sl@0
   141
		{
sl@0
   142
		// if rendering mode is synchrounous, we need to render current frame
sl@0
   143
		RenderNextFrame();
sl@0
   144
		}
sl@0
   145
sl@0
   146
	iCube->GetImage(aId);
sl@0
   147
sl@0
   148
	if(iMode == EAsyncDebug)
sl@0
   149
		{	
sl@0
   150
		// Added this as a panic can occur if After() is called while the server is active. 
sl@0
   151
		// Before this was added the server could get stuck in an active state
sl@0
   152
		// occasionally when running the tests in SW mode.
sl@0
   153
		if (IsActive())					
sl@0
   154
			Cancel();
sl@0
   155
					
sl@0
   156
		// if rendering mode is asynchrounous debug, we start rendering next frame (only one) immediately
sl@0
   157
		After(0);
sl@0
   158
		}
sl@0
   159
sl@0
   160
	return iLastFrame;
sl@0
   161
	}
sl@0
   162
sl@0
   163
/**
sl@0
   164
Static constructor
sl@0
   165
*/
sl@0
   166
CServer2* CEglContentServer::NewLC()
sl@0
   167
	{
sl@0
   168
	CEglContentServer* self = new(ELeave) CEglContentServer;
sl@0
   169
	CleanupStack::PushL(self);
sl@0
   170
	self->ConstructL();
sl@0
   171
	return self;
sl@0
   172
	}
sl@0
   173
sl@0
   174
/**
sl@0
   175
1st phase constructor
sl@0
   176
*/
sl@0
   177
CEglContentServer::CEglContentServer() : CServer2(0, ESharableSessions)
sl@0
   178
	{
sl@0
   179
	}
sl@0
   180
sl@0
   181
/**
sl@0
   182
2nd phase construction - ensure the content renderer and server objects are running
sl@0
   183
*/
sl@0
   184
void CEglContentServer::ConstructL()
sl@0
   185
	{
sl@0
   186
	StartL(KEglContentServerName);
sl@0
   187
	iContent = CEglContent::NewL();
sl@0
   188
	}
sl@0
   189
sl@0
   190
/**
sl@0
   191
Destructor.
sl@0
   192
*/
sl@0
   193
CEglContentServer::~CEglContentServer()
sl@0
   194
	{
sl@0
   195
	delete iContent;
sl@0
   196
	}
sl@0
   197
sl@0
   198
/**
sl@0
   199
Cretae a new client session.
sl@0
   200
*/
sl@0
   201
CSession2* CEglContentServer::NewSessionL(const TVersion&, const RMessage2&) const
sl@0
   202
	{
sl@0
   203
	return new(ELeave) CEglContentSession();
sl@0
   204
	}
sl@0
   205
sl@0
   206
/*
sl@0
   207
A new session is being created
sl@0
   208
*/
sl@0
   209
void CEglContentServer::AddSession()
sl@0
   210
	{
sl@0
   211
	++iSessionCount;
sl@0
   212
	}
sl@0
   213
sl@0
   214
/*
sl@0
   215
A session is being destroyed
sl@0
   216
*/
sl@0
   217
void CEglContentServer::DropSession()
sl@0
   218
	{
sl@0
   219
	--iSessionCount;
sl@0
   220
	}
sl@0
   221
sl@0
   222
/**
sl@0
   223
Get image in synchronous mode.
sl@0
   224
@param aId Reference to drawable id class to store image id.
sl@0
   225
*/
sl@0
   226
void CEglContentServer::GetSyncImage(TSgDrawableId& aId)
sl@0
   227
	{
sl@0
   228
	if(iContent)
sl@0
   229
		{
sl@0
   230
		iContent->SetMode(CEglContent::ESync);
sl@0
   231
		iContent->GetImage(aId);
sl@0
   232
		}
sl@0
   233
	}
sl@0
   234
sl@0
   235
/**
sl@0
   236
Get image in asynchronous mode.
sl@0
   237
@param aId Reference to drawable id class to store image id.
sl@0
   238
@return number of frame stored in image
sl@0
   239
*/
sl@0
   240
TInt CEglContentServer::GetAsyncImage(TSgDrawableId& aId)
sl@0
   241
	{
sl@0
   242
	if(iContent)
sl@0
   243
		{
sl@0
   244
		iContent->SetMode(CEglContent::EAsync);
sl@0
   245
		return iContent->GetImage(aId);
sl@0
   246
		}
sl@0
   247
	return -1;
sl@0
   248
	}
sl@0
   249
sl@0
   250
/**
sl@0
   251
Get image in asynchronous debug mode.
sl@0
   252
@param aId Reference to drawable id class to store image id.
sl@0
   253
@return number of frame stored in image
sl@0
   254
*/
sl@0
   255
TInt CEglContentServer::GetAsyncImageDebug(TSgDrawableId& aId)
sl@0
   256
	{
sl@0
   257
	if(iContent)
sl@0
   258
		{
sl@0
   259
		iContent->SetMode(CEglContent::EAsyncDebug);
sl@0
   260
		return iContent->GetImage(aId);
sl@0
   261
		}
sl@0
   262
	return -1;
sl@0
   263
	}
sl@0
   264
sl@0
   265
/**
sl@0
   266
1st phase constructor
sl@0
   267
*/
sl@0
   268
CEglContentSession::CEglContentSession()
sl@0
   269
	{
sl@0
   270
	}
sl@0
   271
sl@0
   272
/**
sl@0
   273
2nd phase construct for sessions - called by the CServer framework
sl@0
   274
*/
sl@0
   275
void CEglContentSession::Create()
sl@0
   276
	{
sl@0
   277
	Server().AddSession();
sl@0
   278
	}
sl@0
   279
sl@0
   280
/**
sl@0
   281
Destructor.
sl@0
   282
*/
sl@0
   283
CEglContentSession::~CEglContentSession()
sl@0
   284
	{
sl@0
   285
	Server().DropSession();
sl@0
   286
	}
sl@0
   287
sl@0
   288
/**
sl@0
   289
Get server object.
sl@0
   290
@return a reference to server object
sl@0
   291
*/
sl@0
   292
CEglContentServer& CEglContentSession::Server()
sl@0
   293
	{
sl@0
   294
	return *static_cast<CEglContentServer*>(const_cast<CServer2*>(CSession2::Server()));
sl@0
   295
	}
sl@0
   296
sl@0
   297
/**
sl@0
   298
Handle a client request.
sl@0
   299
Leaving is handled by CEglContentSession::ServiceError() which reports
sl@0
   300
the error code to the client
sl@0
   301
*/
sl@0
   302
void CEglContentSession::ServiceL(const RMessage2& aMessage)
sl@0
   303
	{
sl@0
   304
	switch(aMessage.Function())
sl@0
   305
		{
sl@0
   306
		case ETerminateServer:
sl@0
   307
			{
sl@0
   308
			aMessage.Complete(KErrNone);
sl@0
   309
			CActiveScheduler::Stop();
sl@0
   310
			break;
sl@0
   311
			}
sl@0
   312
		case EGetSyncImage:
sl@0
   313
			{
sl@0
   314
			// Get the current image synchronously, the frame
sl@0
   315
			// number is not returned as the client will already know the frame number
sl@0
   316
			// as it controls when a frame is drawn
sl@0
   317
			TSgDrawableId id;
sl@0
   318
			Server().GetSyncImage(id);
sl@0
   319
			TPckg<TSgDrawableId> idPckg(id);
sl@0
   320
			aMessage.Write(0, idPckg);
sl@0
   321
			aMessage.Complete(KErrNone);
sl@0
   322
			break;
sl@0
   323
			}
sl@0
   324
		case EGetAsyncImage:
sl@0
   325
			{
sl@0
   326
			// Get the current image and it's frame number, the drawing is
sl@0
   327
			// asynchronous so the client needs to know which one this as it cannot tell otherwise
sl@0
   328
			TSgDrawableId id;
sl@0
   329
			TInt fnum = Server().GetAsyncImage(id);
sl@0
   330
			TPckg<TSgDrawableId> idPckg(id);
sl@0
   331
			aMessage.Write(0, idPckg);
sl@0
   332
			TPckg<TInt> fnumPckg(fnum);
sl@0
   333
			aMessage.Write(1, fnumPckg);
sl@0
   334
			aMessage.Complete(KErrNone);
sl@0
   335
			break;
sl@0
   336
			}
sl@0
   337
		case EGetAsyncImageDebug:
sl@0
   338
			{
sl@0
   339
			// Get the current image and it's frame number, the drawing is
sl@0
   340
			// asynchronous so the client needs to know which one this as it cannot tell otherwise
sl@0
   341
			TSgDrawableId id;
sl@0
   342
			TInt fnum = Server().GetAsyncImageDebug(id);			
sl@0
   343
			TPckg<TSgDrawableId> idPckg(id);
sl@0
   344
			aMessage.Write(0, idPckg);
sl@0
   345
			TPckg<TInt> fnumPckg(fnum);
sl@0
   346
			aMessage.Write(1, fnumPckg);
sl@0
   347
			aMessage.Complete(KErrNone);
sl@0
   348
			break;
sl@0
   349
			}
sl@0
   350
		default:
sl@0
   351
			{
sl@0
   352
			PanicClient(aMessage, EPanicIllegalFunction);
sl@0
   353
			}
sl@0
   354
		}
sl@0
   355
	}
sl@0
   356
sl@0
   357
/**
sl@0
   358
Handle an error from CEglContentSession::ServiceL()
sl@0
   359
*/
sl@0
   360
void CEglContentSession::ServiceError(const RMessage2& aMessage, TInt aError)
sl@0
   361
	{
sl@0
   362
	if(aError == KErrBadDescriptor)
sl@0
   363
		PanicClient(aMessage, EPanicBadDescriptor);
sl@0
   364
	CSession2::ServiceError(aMessage, aError);
sl@0
   365
	}
sl@0
   366
sl@0
   367
sl@0
   368
/**
sl@0
   369
RMessage::Panic() also completes the message.
sl@0
   370
*/
sl@0
   371
void PanicClient(const RMessagePtr2& aMessage, TEglContentPanic aPanic)
sl@0
   372
	{
sl@0
   373
	aMessage.Panic(KEglContentServerName, aPanic);
sl@0
   374
	}
sl@0
   375
sl@0
   376
/**
sl@0
   377
Perform all server initialisation, in particular creation of the
sl@0
   378
scheduler and server and then run the scheduler
sl@0
   379
*/
sl@0
   380
static void RunServerL()
sl@0
   381
	{
sl@0
   382
	// naming the server thread after the server helps to debug panics
sl@0
   383
	User::LeaveIfError(RThread::RenameMe(KEglContentServerName));
sl@0
   384
	//
sl@0
   385
	// create and install the active scheduler we need
sl@0
   386
	CActiveScheduler* s = new(ELeave) CActiveScheduler;
sl@0
   387
	CleanupStack::PushL(s);
sl@0
   388
	CActiveScheduler::Install(s);
sl@0
   389
	//
sl@0
   390
	// create the server (leave it on the cleanup stack)
sl@0
   391
	CEglContentServer::NewLC();
sl@0
   392
	//
sl@0
   393
	// Initialisation complete, now signal the client
sl@0
   394
	RProcess::Rendezvous(KErrNone);
sl@0
   395
	//
sl@0
   396
	// Ready to run
sl@0
   397
	CActiveScheduler::Start();
sl@0
   398
	//
sl@0
   399
	// Cleanup the server and scheduler
sl@0
   400
	CleanupStack::PopAndDestroy(2);
sl@0
   401
	}
sl@0
   402
sl@0
   403
/**
sl@0
   404
Entry point of server executable.
sl@0
   405
*/
sl@0
   406
GLDEF_C TInt E32Main()
sl@0
   407
	{
sl@0
   408
	__UHEAP_MARK;
sl@0
   409
	RDebug::Print(_L("%S started"), &KEglContentServerName);
sl@0
   410
	CTrapCleanup* cleanup = CTrapCleanup::New();
sl@0
   411
	TInt r = KErrNoMemory;
sl@0
   412
	if(cleanup)
sl@0
   413
		{
sl@0
   414
		TRAP(r, RunServerL());
sl@0
   415
		delete cleanup;
sl@0
   416
		}
sl@0
   417
	RDebug::Print(_L("%S terminated"), &KEglContentServerName);
sl@0
   418
	__UHEAP_MARKEND;
sl@0
   419
	return r;
sl@0
   420
	}