os/graphics/graphicscomposition/surfaceupdate/tsrc/tsurfaceupdateinteg.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) 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 <e32std.h>
sl@0
    17
#include <hal.h>
sl@0
    18
#include <u32hal.h>
sl@0
    19
#include <limits.h>
sl@0
    20
#include <e32const.h>
sl@0
    21
#include <graphics/surfaceupdateclient.h>
sl@0
    22
#include <graphics/suerror.h>
sl@0
    23
#include <graphics/wstestscreencapture.h>
sl@0
    24
#include <graphics/testscreencapture.h>
sl@0
    25
#include "surfaceupdatetest.h"
sl@0
    26
#include "tsurfaceupdateinteg.h"
sl@0
    27
#include "twindows.h"
sl@0
    28
#include "tredrawhandler.h"
sl@0
    29
#include "tsurfacehelper.h"
sl@0
    30
sl@0
    31
const TSize windowSize(160, 100);
sl@0
    32
const TSize windowHalfSize(windowSize.iWidth / 2, 100);
sl@0
    33
const TPoint windowTopLeft(10,10);
sl@0
    34
const TPoint windowTopMiddle(windowTopLeft.iX + windowSize.iWidth / 2, windowTopLeft.iY);
sl@0
    35
sl@0
    36
sl@0
    37
CTSurfaceUpdateInteg::CTSurfaceUpdateInteg(CTestStep* aStep) :
sl@0
    38
	CTGraphicsBase(aStep)
sl@0
    39
	{
sl@0
    40
	}
sl@0
    41
sl@0
    42
CTSurfaceUpdateInteg::~CTSurfaceUpdateInteg()
sl@0
    43
	{
sl@0
    44
	iWindows.ResetAndDestroy();
sl@0
    45
	iGroups.ResetAndDestroy();
sl@0
    46
sl@0
    47
	iWsDevs.ResetAndDestroy();
sl@0
    48
	iGcs.ResetAndDestroy();
sl@0
    49
	
sl@0
    50
	delete iRedrawHandler;
sl@0
    51
	iSurfaceUpdate.Close();
sl@0
    52
	delete iSurfaceHelper;
sl@0
    53
	iBitmaps.ResetAndDestroy();
sl@0
    54
sl@0
    55
	delete iGraphicsContext;
sl@0
    56
	delete iBitmapDevice;
sl@0
    57
	delete iRefBitmap;
sl@0
    58
	
sl@0
    59
	iWs.Close();
sl@0
    60
	}
sl@0
    61
sl@0
    62
/**
sl@0
    63
 * Create a screen device, drawing context and a window for each screen.
sl@0
    64
 * Create surfaces, open connection to the SUS.
sl@0
    65
 */
sl@0
    66
void CTSurfaceUpdateInteg::ConstructL()
sl@0
    67
	{
sl@0
    68
	INFO_PRINTF1(_L("Test case construction"));
sl@0
    69
	User::LeaveIfError(iWs.Connect());
sl@0
    70
	iNumOfScreens = iWs.NumberOfScreens();
sl@0
    71
	iSurfaceHelper = CSurfaceHelper::NewL();
sl@0
    72
	const TInt stride = windowSize.iWidth * 4;
sl@0
    73
	const TInt stride1 = windowHalfSize.iWidth * 4;
sl@0
    74
	iSurface = iSurfaceHelper->CreateSurfaceL(windowSize, EUidPixelFormatXRGB_8888, stride,1);
sl@0
    75
	iSurfaceDoubleBuffered = iSurfaceHelper->CreateSurfaceL(windowSize, EUidPixelFormatXRGB_8888, stride,2);
sl@0
    76
	iSurfaceAbove = iSurfaceHelper->CreateSurfaceL(windowHalfSize, EUidPixelFormatXRGB_8888, stride1, 1);
sl@0
    77
	iSurfaceAbove1 = iSurfaceHelper->CreateSurfaceL(windowSize, EUidPixelFormatXRGB_8888, stride, 1);
sl@0
    78
	INFO_PRINTF1(_L("The surfaces have been created"));
sl@0
    79
sl@0
    80
	iRefBitmap = new (ELeave)CFbsBitmap();
sl@0
    81
	User::LeaveIfError(iRefBitmap->Create(windowSize,EColor16MU));
sl@0
    82
	iBitmapDevice = CFbsBitmapDevice::NewL(iRefBitmap);
sl@0
    83
	User::LeaveIfError(iBitmapDevice->CreateContext(iGraphicsContext));
sl@0
    84
sl@0
    85
	//fill the whole surfaces with different color
sl@0
    86
	iSurfaceHelper->FillRectangleL(iSurfaceAbove, TPoint(), windowHalfSize, KRgbYellow);
sl@0
    87
	iSurfaceHelper->FillRectangleL(iSurfaceAbove1, TPoint(), windowSize, KRgbYellow);
sl@0
    88
	iSurfaceHelper->FillRectangleL(iSurface, TPoint(), windowSize, KRgbGreen);
sl@0
    89
	iSurfaceHelper->FillRectangleL(iSurfaceDoubleBuffered, TPoint(), windowSize, KRgbCyan);
sl@0
    90
	FillRefBitmap(KRgbGreen);
sl@0
    91
	INFO_PRINTF1(_L("The surfaces and a reference bitmap have been filled with color"));
sl@0
    92
	
sl@0
    93
	User::LeaveIfError(iSurfaceUpdate.Connect());
sl@0
    94
	
sl@0
    95
	iRedrawHandler = new (ELeave) CTRedrawHandler(iWs); //will deal with all redrawing command
sl@0
    96
	iRedrawHandler->Start();
sl@0
    97
sl@0
    98
	//create windows and assign surfaces to them
sl@0
    99
	for(TInt ii = 0; ii < 2; ii++)
sl@0
   100
		{
sl@0
   101
		CWsScreenDevice* wsDev = new (ELeave) CWsScreenDevice(iWs);
sl@0
   102
		iWsDevs.AppendL(wsDev);
sl@0
   103
		User::LeaveIfError(wsDev->Construct(ii));
sl@0
   104
		CWindowGc* gc = NULL;
sl@0
   105
		User::LeaveIfError(wsDev->CreateContext(gc));
sl@0
   106
		iGcs.AppendL(gc);
sl@0
   107
sl@0
   108
		CTWindowGroup* defaultGroup = CreateGroupL(wsDev);
sl@0
   109
		CTWindow* windowSingle = CTWindow::NewL(iWs, *defaultGroup, *gc);
sl@0
   110
		RegisterWindowL(windowSingle);
sl@0
   111
		windowSingle->Window()->SetExtent(windowTopLeft, windowSize);
sl@0
   112
		windowSingle->Window()->SetBackgroundSurface(iSurface);
sl@0
   113
		windowSingle->Window()->Activate();
sl@0
   114
		
sl@0
   115
		CTWindow* windowDouble = CTWindow::NewL(iWs, *defaultGroup, *gc);
sl@0
   116
		RegisterWindowL(windowDouble);
sl@0
   117
		windowDouble->Window()->SetExtent(windowTopLeft, windowSize);
sl@0
   118
		windowDouble->Window()->SetBackgroundSurface(iSurfaceDoubleBuffered);
sl@0
   119
		windowDouble->Window()->SetVisible(EFalse);
sl@0
   120
		windowDouble->Window()->Activate();
sl@0
   121
sl@0
   122
		CTWindow* windowAbove = CTWindow::NewL(iWs, *iGroups[ii], *iGcs[ii]);
sl@0
   123
		RegisterWindowL(windowAbove);
sl@0
   124
		windowAbove->Window()->SetExtent(windowTopLeft, windowHalfSize);
sl@0
   125
		windowAbove->Window()->SetBackgroundSurface(iSurfaceAbove);
sl@0
   126
		windowAbove->Window()->SetVisible(EFalse);
sl@0
   127
		windowAbove->Window()->Activate();
sl@0
   128
		if(ii == 0)
sl@0
   129
			{
sl@0
   130
			iWindowAbove11 = CTWindow::NewL(iWs, *iGroups[ii], *iGcs[ii]);
sl@0
   131
			RegisterWindowL(iWindowAbove11);
sl@0
   132
			iWindowAbove11->Window()->SetExtent(windowTopLeft, windowSize);
sl@0
   133
			iWindowAbove11->Window()->SetBackgroundSurface(iSurfaceAbove1);
sl@0
   134
			iWindowAbove11->Window()->SetVisible(EFalse);
sl@0
   135
			iWindowAbove11->Window()->Activate();
sl@0
   136
sl@0
   137
			iWindowAbove1 = windowAbove;
sl@0
   138
			iWindowSingleBuffured1 = windowSingle;
sl@0
   139
			iWindowDoubleBuffured1 = windowDouble;
sl@0
   140
			}
sl@0
   141
		else
sl@0
   142
			{
sl@0
   143
			iWindowAbove2 = windowAbove;
sl@0
   144
			iWindowSingleBuffured2 = windowSingle;
sl@0
   145
			iWindowDoubleBuffured2 = windowDouble;
sl@0
   146
			}
sl@0
   147
sl@0
   148
	    TPixelsTwipsAndRotation sizeAndRotation;
sl@0
   149
	    iWsDevs[ii]->GetDefaultScreenSizeAndRotation(sizeAndRotation);
sl@0
   150
	    CFbsBitmap* bitmap = new (ELeave)CFbsBitmap();
sl@0
   151
	    iBitmaps.AppendL(bitmap);
sl@0
   152
	    User::LeaveIfError(bitmap->Create(sizeAndRotation.iPixelSize, EColor16MU));
sl@0
   153
        INFO_PRINTF4(_L("Bitmap with size: %d, %d was created to match the size of the screen %d"), sizeAndRotation.iPixelSize.iWidth, sizeAndRotation.iPixelSize.iHeight, ii);
sl@0
   154
		}
sl@0
   155
	INFO_PRINTF1(_L("The windows have been created"));
sl@0
   156
	
sl@0
   157
	iWs.Finish();
sl@0
   158
	}
sl@0
   159
sl@0
   160
/**
sl@0
   161
 * Create the window group for the given screen device and put it into the list.
sl@0
   162
 */
sl@0
   163
CTWindowGroup* CTSurfaceUpdateInteg::CreateGroupL(CWsScreenDevice* aScreenDevice)
sl@0
   164
	{
sl@0
   165
	CTWindowGroup* group = CTWindowGroup::NewL(iWs, aScreenDevice);
sl@0
   166
	CleanupStack::PushL(group);
sl@0
   167
	iGroups.AppendL(group);
sl@0
   168
	CleanupStack::Pop();
sl@0
   169
	return group;
sl@0
   170
	}
sl@0
   171
sl@0
   172
/**
sl@0
   173
 * Append a window into the list for retrawing it and destroying in the future.
sl@0
   174
 */
sl@0
   175
void CTSurfaceUpdateInteg::RegisterWindowL(CTWindowTreeNode* aWindow)
sl@0
   176
	{
sl@0
   177
	CleanupStack::PushL(aWindow);
sl@0
   178
	iWindows.AppendL(aWindow);
sl@0
   179
	CleanupStack::Pop(aWindow);
sl@0
   180
	}
sl@0
   181
sl@0
   182
/**
sl@0
   183
 * Go through all screens and compare the whole surface area with the reference bitmap.
sl@0
   184
 * 
sl@0
   185
 * @return ETrue, if the surface is exactly the same as the reference bitmap or EFalse otherwise. 
sl@0
   186
 */
sl@0
   187
TBool CTSurfaceUpdateInteg::CompareAllScreens()
sl@0
   188
	{
sl@0
   189
	TBool res = ETrue;
sl@0
   190
	TRect rc(windowTopLeft, windowSize);
sl@0
   191
	for(TInt ii = 0; (ii < iNumOfScreens) && res; ii++)
sl@0
   192
		{
sl@0
   193
		res = Compare(ii, rc, iRefBitmap);
sl@0
   194
		}
sl@0
   195
	return res;
sl@0
   196
	}
sl@0
   197
sl@0
   198
/**
sl@0
   199
 * Compare part of the screen with the reference bitmap.
sl@0
   200
 * 
sl@0
   201
 * @param aScreenNumber Screen number.
sl@0
   202
 * @param aRectSrc The area of the screen to be compared.
sl@0
   203
 * @param aRefBitmap Bitmap for comparison.
sl@0
   204
 * @return ETrue, if given part of the screen is exactly the same as the reference bitmap or EFalse otherwise. 
sl@0
   205
 */
sl@0
   206
TBool CTSurfaceUpdateInteg::Compare(TInt aScreenNumber, const TRect& aRectSrc, CFbsBitmap* aRefBitmap)
sl@0
   207
	{
sl@0
   208
	MTestScreenCapture* csc = static_cast<MTestScreenCapture*> (iWsDevs[aScreenNumber]->GetInterface(MTestScreenCapture::KUidTestScreenCaptureIf));
sl@0
   209
	if(!csc) //shouldn't happen, as we have checked this before
sl@0
   210
		{
sl@0
   211
		return EFalse;
sl@0
   212
		}
sl@0
   213
	
sl@0
   214
	TBool res = ETrue;
sl@0
   215
	TInt ret = csc->ComposeScreen(*(iBitmaps[aScreenNumber]));
sl@0
   216
	if(ret != KErrNone)
sl@0
   217
		{
sl@0
   218
		INFO_PRINTF2(_L("Composition screen failure, err = %d"), ret);
sl@0
   219
		res = EFalse;
sl@0
   220
		}
sl@0
   221
	//Go through all pixels in screen bitmap for specified area and check that they are 
sl@0
   222
	//identical to corresponding pixels in reference bitmap
sl@0
   223
	for(TInt ii = 0; (ii < aRectSrc.Height()) && res; ii++)
sl@0
   224
		{
sl@0
   225
		for(TInt jj = 0; (jj < aRectSrc.Width()) && res; jj++)
sl@0
   226
			{
sl@0
   227
			TRgb refCol;
sl@0
   228
			aRefBitmap->GetPixel(refCol, TPoint(jj, ii));
sl@0
   229
			TRgb col;
sl@0
   230
			(iBitmaps[aScreenNumber])->GetPixel(col, TPoint(jj, ii) + aRectSrc.iTl);
sl@0
   231
			if(refCol != col)
sl@0
   232
				{
sl@0
   233
				res = EFalse;
sl@0
   234
				}
sl@0
   235
			}
sl@0
   236
		}
sl@0
   237
	//useful for debugging
sl@0
   238
#ifdef TEST_COMPARE_PARTLY_UPDATED_SCREEN 	
sl@0
   239
	if(!res)
sl@0
   240
		{
sl@0
   241
		iBitmap->Save(_L("c:\\bitmap.mbm"));
sl@0
   242
		aRefBitmap->Save(_L("c:\\ref.mbm"));
sl@0
   243
		}
sl@0
   244
#endif
sl@0
   245
	
sl@0
   246
	return res;
sl@0
   247
	}
sl@0
   248
sl@0
   249
/**
sl@0
   250
 * Fill reference bitmap with color specified.
sl@0
   251
 * 
sl@0
   252
 */
sl@0
   253
void CTSurfaceUpdateInteg::FillRefBitmap(TRgb aColor)
sl@0
   254
	{
sl@0
   255
	TRect rect = TRect(iRefBitmap->SizeInPixels());
sl@0
   256
	iGraphicsContext->SetBrushColor(aColor);
sl@0
   257
	iGraphicsContext->SetPenColor(aColor);
sl@0
   258
	iGraphicsContext->SetBrushStyle(CGraphicsContext::ESolidBrush);
sl@0
   259
	iGraphicsContext->DrawRect(rect);
sl@0
   260
	}
sl@0
   261
sl@0
   262
/**
sl@0
   263
  @SYMTestCaseID  GRAPHIC-SURFACEUPDATE-0026
sl@0
   264
  	
sl@0
   265
  @SYMCR CR1650
sl@0
   266
sl@0
   267
  @SYMREQ REQ11596
sl@0
   268
sl@0
   269
  @SYMTestCaseDesc 
sl@0
   270
  	SubmitUpdate() to cope with Global Updates with surface on various 
sl@0
   271
  	screens when the dirty region to update may not be visible on all screens
sl@0
   272
sl@0
   273
  @SYMTestPriority High
sl@0
   274
sl@0
   275
  @SYMTestStatus Implemented
sl@0
   276
	
sl@0
   277
  @SYMTestActions The test consists of a single surface, visible on 
sl@0
   278
  screens A (master), B.
sl@0
   279
	1.	Submit a global update for the surface, passing a null dirty region.
sl@0
   280
	2.	Submit a global update for the surface, passing a dirty region 
sl@0
   281
	that is only visible on screens A  (that particular region for the 
sl@0
   282
	surface is not visible on B).
sl@0
   283
	3.	Submit a global update for the surface, passing a dirty region 
sl@0
   284
	that is only visible on screens B (that particular region for the 
sl@0
   285
	surface is not visible on A).
sl@0
   286
	4.	Submit a global update for the surface, passing a dirty 
sl@0
   287
	region that is not visible on any of the screens.
sl@0
   288
  
sl@0
   289
  @SYMTestExpectedResults 
sl@0
   290
  	1.	TRequestStatus signals KErrNone in all cases. Timestamps must 
sl@0
   291
  	be valid. The surface gets updated on all screens.
sl@0
   292
	2.	TRequestStatus signals KErrNone in all cases. Timestamps must 
sl@0
   293
	be valid. The surface gets updated only on screens A. Screen B is unchanged.
sl@0
   294
	3.	TRequestStatus signals KErrNone in all cases. Timestamps must 
sl@0
   295
	be valid. The surface gets updated only on screens B. 
sl@0
   296
	Screen A is unchanged.
sl@0
   297
	4.	SubmitUpdate() returns KErrNone.
sl@0
   298
*/
sl@0
   299
void CTSurfaceUpdateInteg::TestCase1L()
sl@0
   300
	{
sl@0
   301
	INFO_PRINTF1(_L("Global Submit Update with/without update region supplied"));
sl@0
   302
	
sl@0
   303
	const TInt bufferNumber = 0; 
sl@0
   304
	TRequestStatus status = KRequestPending;
sl@0
   305
	TRequestStatus status1 = KRequestPending;
sl@0
   306
	TRequestStatus status2 = KRequestPending;
sl@0
   307
	TUint64 timestampComposition = 0;
sl@0
   308
	TTimeStamp timeStamp; 
sl@0
   309
	
sl@0
   310
	//Fill the surface to different colour, submit update for the whole surface 
sl@0
   311
	//and check that screen is updated correctly
sl@0
   312
	INFO_PRINTF1(_L("Fill the surface with the blue color"));
sl@0
   313
	iSurfaceHelper->FillRectangleL(iSurface, TPoint(), windowSize, KRgbBlue);
sl@0
   314
	FillRefBitmap(KRgbBlue);
sl@0
   315
	
sl@0
   316
	INFO_PRINTF1(_L("Updating the whole area of the surface"));
sl@0
   317
	TUint64 timestampBefore = User::FastCounter();
sl@0
   318
	iSurfaceUpdate.NotifyWhenAvailable(status);	
sl@0
   319
	iSurfaceUpdate.NotifyWhenDisplayed(status1, timeStamp);	
sl@0
   320
	iSurfaceUpdate.NotifyWhenDisplayedXTimes(10, status2);
sl@0
   321
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, bufferNumber);
sl@0
   322
	User::WaitForRequest(status);
sl@0
   323
	User::WaitForRequest(status1);
sl@0
   324
	User::WaitForRequest(status2);
sl@0
   325
	User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   326
sl@0
   327
	TUint64 timestampAfter = User::FastCounter();
sl@0
   328
	if(timestampAfter < timestampBefore)
sl@0
   329
		{
sl@0
   330
		timestampAfter += UINT_MAX;
sl@0
   331
		}
sl@0
   332
	timestampComposition = timeStamp();
sl@0
   333
	if(timestampComposition < timestampBefore)
sl@0
   334
		{
sl@0
   335
		timestampComposition += UINT_MAX;
sl@0
   336
		}
sl@0
   337
	
sl@0
   338
	TEST(status == KErrNone);
sl@0
   339
	TEST(status1 == KErrNone);
sl@0
   340
	TEST(status2 == KErrNone);
sl@0
   341
	TEST(timestampComposition != 0);
sl@0
   342
	TEST(timestampAfter >= timestampComposition);
sl@0
   343
	TEST(timestampBefore <= timestampComposition);
sl@0
   344
	TEST(CompareAllScreens());
sl@0
   345
sl@0
   346
	//Fill the surface to different colour; hide the part of the surface on 
sl@0
   347
	//the screen which is not a master, submit update for the area of the surface 
sl@0
   348
	//which is only visible on the master. Check that only master screen gets updated.
sl@0
   349
	INFO_PRINTF1(_L("Hide the part of the surface on the second screen"));
sl@0
   350
	iWindowAbove1->Window()->SetVisible(EFalse);
sl@0
   351
	iWindowAbove2->Window()->SetVisible(ETrue);
sl@0
   352
	iWs.Finish();
sl@0
   353
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, bufferNumber);
sl@0
   354
	User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   355
	
sl@0
   356
	INFO_PRINTF1(_L("Fill the surface with the green color"));
sl@0
   357
	iSurfaceHelper->FillRectangleL(iSurface, TPoint(), windowSize, KRgbGreen);
sl@0
   358
	
sl@0
   359
	TRect rc(windowHalfSize);
sl@0
   360
	rc.Shrink(10, 10);
sl@0
   361
	RRegion region(1, &rc); //this area is hidden if the window above is visible
sl@0
   362
	timestampBefore = User::FastCounter();
sl@0
   363
	iSurfaceUpdate.NotifyWhenAvailable(status);	
sl@0
   364
	iSurfaceUpdate.NotifyWhenDisplayed(status1, timeStamp);	
sl@0
   365
	iSurfaceUpdate.NotifyWhenDisplayedXTimes(10, status2);
sl@0
   366
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, bufferNumber, &region);
sl@0
   367
	User::WaitForRequest(status);
sl@0
   368
	User::WaitForRequest(status1);
sl@0
   369
	User::WaitForRequest(status2);
sl@0
   370
	User::After(TTimeIntervalMicroSeconds32(1000000)); //useful for visual checking
sl@0
   371
sl@0
   372
	timestampAfter = User::FastCounter();
sl@0
   373
	if(timestampAfter < timestampBefore)
sl@0
   374
		{
sl@0
   375
		timestampAfter += UINT_MAX;
sl@0
   376
		}
sl@0
   377
	timestampComposition = timeStamp();
sl@0
   378
	if(timestampComposition < timestampBefore)
sl@0
   379
		{
sl@0
   380
		timestampComposition += UINT_MAX;
sl@0
   381
		}
sl@0
   382
	
sl@0
   383
	TEST(status == KErrNone);
sl@0
   384
	TEST(status1 == KErrNone);
sl@0
   385
	TEST(status2 == KErrNone);
sl@0
   386
	TEST(timestampComposition != 0);
sl@0
   387
	TEST(timestampAfter >= timestampComposition);
sl@0
   388
	TEST(timestampBefore <= timestampComposition);
sl@0
   389
	User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   390
sl@0
   391
	//first screen should be updated, as the surface is visible here
sl@0
   392
	TRect rectSrc = rc;
sl@0
   393
	rectSrc.Move(windowTopLeft);
sl@0
   394
	FillRefBitmap(KRgbGreen);
sl@0
   395
	TEST(Compare(0, rectSrc, iRefBitmap));
sl@0
   396
	//check that second screen doesn't update visible part of the surface 
sl@0
   397
	FillRefBitmap(KRgbYellow);
sl@0
   398
	TEST(Compare(1, rectSrc, iRefBitmap));
sl@0
   399
sl@0
   400
	//Fill the surface to different colour; hide the part of the surface 
sl@0
   401
	//on the master screen, submit update for the area of the surface 
sl@0
   402
	//which is only visible on non-master. Check that only non-master screen gets updated.
sl@0
   403
	INFO_PRINTF1(_L("Hide the part of the surface on the first screen"));
sl@0
   404
	iWindowAbove1->Window()->SetVisible(ETrue);
sl@0
   405
	iWindowAbove2->Window()->SetVisible(EFalse);
sl@0
   406
	iWs.Finish();
sl@0
   407
	User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   408
	
sl@0
   409
	INFO_PRINTF1(_L("Fill the surface with the blue color"));
sl@0
   410
	iSurfaceHelper->FillRectangleL(iSurface, TPoint(), windowSize, KRgbBlue);
sl@0
   411
	
sl@0
   412
	timestampBefore = User::FastCounter();
sl@0
   413
	iSurfaceUpdate.NotifyWhenAvailable(status);	
sl@0
   414
	iSurfaceUpdate.NotifyWhenDisplayed(status1, timeStamp);	
sl@0
   415
	iSurfaceUpdate.NotifyWhenDisplayedXTimes(10, status2);
sl@0
   416
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, bufferNumber, &region);
sl@0
   417
	User::WaitForRequest(status);
sl@0
   418
	User::WaitForRequest(status1);
sl@0
   419
	User::WaitForRequest(status2);
sl@0
   420
	User::After(TTimeIntervalMicroSeconds32(1000000)); //useful for visual checking
sl@0
   421
sl@0
   422
	timestampAfter = User::FastCounter();
sl@0
   423
	if(timestampAfter < timestampBefore)
sl@0
   424
		{
sl@0
   425
		timestampAfter += UINT_MAX;
sl@0
   426
		}
sl@0
   427
	timestampComposition = timeStamp();
sl@0
   428
	if(timestampComposition < timestampBefore)
sl@0
   429
		{
sl@0
   430
		timestampComposition += UINT_MAX;
sl@0
   431
		}
sl@0
   432
	
sl@0
   433
	TEST(status == KErrNone);
sl@0
   434
	TEST(status1 == KErrNone);
sl@0
   435
	TEST(status2 == KErrNone);
sl@0
   436
	TEST(timestampComposition != 0);
sl@0
   437
	TEST(timestampAfter >= timestampComposition);
sl@0
   438
	TEST(timestampBefore <= timestampComposition);
sl@0
   439
sl@0
   440
	//check that first screen doesn't update visible part of the surface 
sl@0
   441
	FillRefBitmap(KRgbYellow);
sl@0
   442
	TEST(Compare(0, rectSrc, iRefBitmap));
sl@0
   443
	//second screen should be updated, as the surface is visible here
sl@0
   444
	FillRefBitmap(KRgbBlue);
sl@0
   445
	TEST(Compare(1, rectSrc, iRefBitmap));
sl@0
   446
	
sl@0
   447
	//Fill the surface to different colour; hide the part of the surface on the master screen, 
sl@0
   448
	//submit update for the area of the surface which is not visible on any screen. 
sl@0
   449
	//Check that all screens have not been updated.
sl@0
   450
	INFO_PRINTF1(_L("Hide partly the surface on two screens"));
sl@0
   451
	iWindowAbove1->Window()->SetVisible(ETrue);
sl@0
   452
	iWindowAbove2->Window()->SetVisible(ETrue);
sl@0
   453
	iWs.Finish();
sl@0
   454
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, bufferNumber);
sl@0
   455
	User::After(TTimeIntervalMicroSeconds32(1000000)); //useful for visual checking
sl@0
   456
	
sl@0
   457
	INFO_PRINTF1(_L("Fill the surface with the green color"));
sl@0
   458
	iSurfaceHelper->FillRectangleL(iSurface, TPoint(), windowSize, KRgbGreen);
sl@0
   459
	FillRefBitmap(KRgbGreen);
sl@0
   460
	
sl@0
   461
	timestampBefore = User::FastCounter();
sl@0
   462
	iSurfaceUpdate.NotifyWhenAvailable(status);	
sl@0
   463
	iSurfaceUpdate.NotifyWhenDisplayed(status1, timeStamp);	
sl@0
   464
	iSurfaceUpdate.NotifyWhenDisplayedXTimes(10, status2);
sl@0
   465
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, bufferNumber, &region);
sl@0
   466
	User::WaitForRequest(status);
sl@0
   467
	User::WaitForRequest(status1);
sl@0
   468
	User::WaitForRequest(status2);
sl@0
   469
	User::After(TTimeIntervalMicroSeconds32(1000000)); //useful for visual checking
sl@0
   470
sl@0
   471
	timestampAfter = User::FastCounter();
sl@0
   472
	if(timestampAfter < timestampBefore)
sl@0
   473
		{
sl@0
   474
		timestampAfter += UINT_MAX;
sl@0
   475
		}
sl@0
   476
	timestampComposition = timeStamp();
sl@0
   477
	if(timestampComposition < timestampBefore)
sl@0
   478
		{
sl@0
   479
		timestampComposition += UINT_MAX;
sl@0
   480
		}
sl@0
   481
	
sl@0
   482
	TEST(status == KErrNone);
sl@0
   483
	TEST(status1 == KErrNone);
sl@0
   484
	TEST(status2 == KErrNone);
sl@0
   485
	TEST(timestampComposition != 0);
sl@0
   486
	TEST(timestampAfter >= timestampComposition);
sl@0
   487
	TEST(timestampBefore <= timestampComposition);
sl@0
   488
	User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   489
	
sl@0
   490
	//both first and second screen shouldn't be updated, as the surface is not visible here
sl@0
   491
	FillRefBitmap(KRgbYellow);
sl@0
   492
	TEST(Compare(0, rectSrc, iRefBitmap));
sl@0
   493
	TEST(Compare(1, rectSrc, iRefBitmap));
sl@0
   494
sl@0
   495
	INFO_PRINTF1(_L("Return to the initial state"));
sl@0
   496
	iWindowAbove1->Window()->SetVisible(EFalse);
sl@0
   497
	iWindowAbove2->Window()->SetVisible(EFalse);
sl@0
   498
	iWs.Finish();
sl@0
   499
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, bufferNumber);
sl@0
   500
	User::After(TTimeIntervalMicroSeconds32(1000000)); //useful for visual checking
sl@0
   501
	
sl@0
   502
	FillRefBitmap(KRgbGreen);
sl@0
   503
	TEST(CompareAllScreens());
sl@0
   504
	}
sl@0
   505
sl@0
   506
/**
sl@0
   507
  @SYMTestCaseID GRAPHIC-SURFACEUPDATE-0031
sl@0
   508
sl@0
   509
  @SYMCR CR1650
sl@0
   510
sl@0
   511
  @SYMREQ REQ11598
sl@0
   512
sl@0
   513
  @SYMTestCaseDesc NotifyWhenAvailable() to deal with global updates and be signalled 
sl@0
   514
 	correctly when screen is unplugged.
sl@0
   515
 	
sl@0
   516
  @SYMTestPriority 	High
sl@0
   517
sl@0
   518
  @SYMTestStatus Implemented
sl@0
   519
	
sl@0
   520
  @SYMTestActions 
sl@0
   521
 	The test consists of a double-buffered surface, visible on screens A 
sl@0
   522
 	(master) and B,
sl@0
   523
	1	Make global submit update with notify when available for the buffer 1.
sl@0
   524
	2	Unplug screen A (notification is still in a progress )
sl@0
   525
	3	Make global submit update with notify when available for the 
sl@0
   526
	buffer 2 to trigger notification.
sl@0
   527
	4	Make global submit update with notify when available for the 
sl@0
   528
	buffer 1.
sl@0
   529
	5	Plug in screen A. (notification is still in a progress )
sl@0
   530
	6	Make global submit update with notify when available for 
sl@0
   531
	the buffer 2.
sl@0
   532
  
sl@0
   533
  @SYMTestExpectedResults 
sl@0
   534
  	After step 3, notification is received with KErrNone (this is 
sl@0
   535
  	triggered by the Receiver for screen B).
sl@0
   536
	After step 6, notification is received with KErrNone (this is 
sl@0
   537
	triggered by the Receiver for screen A).
sl@0
   538
*/
sl@0
   539
void CTSurfaceUpdateInteg::TestCase2L()
sl@0
   540
	{
sl@0
   541
	INFO_PRINTF1(_L("Exercising NotifyWhenAvailable while some screens are disconnected."));
sl@0
   542
sl@0
   543
	//hide single-buffered surface and show a double buffered-surface
sl@0
   544
	iWindowSingleBuffured1->Window()->SetVisible(EFalse);
sl@0
   545
	iWindowSingleBuffured2->Window()->SetVisible(EFalse);
sl@0
   546
	iWindowDoubleBuffured1->Window()->SetVisible(ETrue);
sl@0
   547
	iWindowDoubleBuffured2->Window()->SetVisible(ETrue);
sl@0
   548
	iWs.Finish();
sl@0
   549
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, 0);
sl@0
   550
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceDoubleBuffered, 0);
sl@0
   551
	FillRefBitmap(KRgbCyan);
sl@0
   552
	TEST(CompareAllScreens());
sl@0
   553
	User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   554
	
sl@0
   555
	INFO_PRINTF1(_L("Fill the surface with the blue color"));
sl@0
   556
	iSurfaceHelper->FillRectangleL(iSurfaceDoubleBuffered, TPoint(), windowSize, KRgbBlue);
sl@0
   557
	
sl@0
   558
	INFO_PRINTF1(_L("Disconnect the screen while notify when available request is still in a progress")); 
sl@0
   559
	TRequestStatus status;
sl@0
   560
	TSwitchDisplayAndReleaseBuffer param;
sl@0
   561
	param.iBuffer = 0;
sl@0
   562
	param.iScreen = 0;
sl@0
   563
	param.iSurfaceId=iSurfaceDoubleBuffered;
sl@0
   564
	CCommandDispatcher commandDispatcher(CCommandDispatcher::EDisconnectDisplayAndReleaseBuffer, &param);
sl@0
   565
	
sl@0
   566
	//Command dispatcher will be running in the separate thread. 
sl@0
   567
	//The requirement for this caused by the fact that for dubble-buffered surfaces 
sl@0
   568
	//the content update receiver will postpone completion of the request for availability until 
sl@0
   569
	//client sends SubmitUpdate for another buffer. 
sl@0
   570
	iSurfaceUpdate.NotifyWhenAvailable(status);	
sl@0
   571
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceDoubleBuffered, 1);
sl@0
   572
	TInt res = commandDispatcher.Start();  //kickoff another thread, which SubmitUpdate 
sl@0
   573
											//for buffer 1 and disconnects the first screen
sl@0
   574
	TEST(res == KErrNone);
sl@0
   575
	User::WaitForRequest(status);//At that point we are blocked until command dispatcher sends SubmitUpdate for the buffer number 1
sl@0
   576
	TEST(status == KErrNone);
sl@0
   577
	
sl@0
   578
	//connect the screen
sl@0
   579
	INFO_PRINTF1(_L("Connect the screen while notify when available request is still in a progress")); 
sl@0
   580
	CCommandDispatcher commandDispatcher1(CCommandDispatcher::EConnectDisplayAndReleaseBuffer, &param);
sl@0
   581
	iSurfaceUpdate.NotifyWhenAvailable(status);	
sl@0
   582
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceDoubleBuffered, 0);
sl@0
   583
	res = commandDispatcher.Start();//kickoff another thread, which SubmitUpdate 
sl@0
   584
										//for buffer 1 and connects the first screen
sl@0
   585
sl@0
   586
	TEST(res == KErrNone);
sl@0
   587
	User::WaitForRequest(status);
sl@0
   588
	TEST(status == KErrNone);
sl@0
   589
sl@0
   590
	//restore the original state
sl@0
   591
	iWindowSingleBuffured1->Window()->SetVisible(ETrue);
sl@0
   592
	iWindowSingleBuffured2->Window()->SetVisible(ETrue);
sl@0
   593
	iWindowDoubleBuffured1->Window()->SetVisible(EFalse);
sl@0
   594
	iWindowDoubleBuffured2->Window()->SetVisible(EFalse);
sl@0
   595
	iWs.Finish();
sl@0
   596
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, 0);
sl@0
   597
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceDoubleBuffered, 0);
sl@0
   598
	FillRefBitmap(KRgbGreen);
sl@0
   599
	TEST(CompareAllScreens());
sl@0
   600
	}
sl@0
   601
sl@0
   602
/**
sl@0
   603
  @SYMTestCaseID GRAPHIC-SURFACEUPDATE-0032
sl@0
   604
  	
sl@0
   605
  @SYMCR CR1650
sl@0
   606
sl@0
   607
  @SYMREQ REQ11599, REQ11600, REQ11601
sl@0
   608
sl@0
   609
  @SYMTestCaseDesc NotifyWhenDisplayedXTimes() to deal with global 
sl@0
   610
  updates and be signalled correctly when screen is unplugged.
sl@0
   611
	
sl@0
   612
  @SYMTestPriority 	High
sl@0
   613
sl@0
   614
  @SYMTestStatus Implemented
sl@0
   615
	
sl@0
   616
  @SYMTestActions 
sl@0
   617
  	The test consists of a single-buffered surface, S1, visible on 
sl@0
   618
  	screens A (master) and B.
sl@0
   619
sl@0
   620
	Screens are ordered in the following priority: A > B
sl@0
   621
		1	Make global submit update for surface S1 with notify 
sl@0
   622
		when notify when displayed X times. X should be approximately 10 
sl@0
   623
		seconds.
sl@0
   624
		2	Unplug screen A while display XTimes is still in progress.
sl@0
   625
		3	After receiving notification, plug in screen A
sl@0
   626
		4	Make global submit update with notify when displayed X times. 
sl@0
   627
		X should be approximately 10 seconds.
sl@0
   628
		5	Make global submit update for surface S1, with notify when 
sl@0
   629
		displayed X times. X should be approximately 10 seconds.
sl@0
   630
		6	Unplug screen B while display XTimes is still in progress.
sl@0
   631
        7   Make global submit update for surface S1, with notify when 
sl@0
   632
        displayed X times. X should be approximately 10 seconds.		
sl@0
   633
		8	Unplug screen A as well whilst display XTimes is still in progress.
sl@0
   634
		9   Reconnect both screens
sl@0
   635
  	
sl@0
   636
  @SYMTestExpectedResults
sl@0
   637
  	After the 10 seconds have elapsed from step 1, notification is 
sl@0
   638
  	received (step 3) with KErrNone (this is triggered by the Receiver 
sl@0
   639
  	for screen B).
sl@0
   640
	After 10 seconds have elapsed from step 4, notification is received 
sl@0
   641
	with KErrNone (this is triggered by the Receiver for screen A).
sl@0
   642
	After step 8 (which must occur before 10 seconds) notification will 
sl@0
   643
	be received with KErrNotVisible (ie. The surface is not visible on 
sl@0
   644
	any screen).
sl@0
   645
*/
sl@0
   646
void CTSurfaceUpdateInteg::TestCase3()
sl@0
   647
	{
sl@0
   648
	INFO_PRINTF1(_L("Exercising NotifyWhenDisplayedXTimes while some screen is disconnected."));
sl@0
   649
sl@0
   650
	TRequestStatus status;
sl@0
   651
	TInt count = 100 * 2; 
sl@0
   652
	iSurfaceUpdate.NotifyWhenDisplayedXTimes(count, status);	
sl@0
   653
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, 0);
sl@0
   654
	
sl@0
   655
	INFO_PRINTF1(_L("Disconnect the screen when notification when displayed X times request is still in a progress")); 
sl@0
   656
	TInt displayState = EDisconnect;
sl@0
   657
	TInt disconnectedScreenNo = 0;
sl@0
   658
	TInt res = UserSvr::HalFunction(EHalGroupDisplay | (disconnectedScreenNo<<16), EDisplayHalSetDisplayState, &displayState, NULL);
sl@0
   659
	TEST(res == KErrNone);
sl@0
   660
	User::WaitForRequest(status); //The content update receiver will complete notification when “count” number of display refreshes has occurred.  
sl@0
   661
									//We are not blocked here indefinitely, so there is no point to use a command dispatcher
sl@0
   662
	TEST(status == KErrNone);
sl@0
   663
sl@0
   664
	//restore the first screen 
sl@0
   665
	INFO_PRINTF1(_L("Connect the screen when notification when displayed X times request is still in a progress")); 
sl@0
   666
	displayState = ENormalResolution;
sl@0
   667
	res = UserSvr::HalFunction(EHalGroupDisplay | (disconnectedScreenNo<<16), EDisplayHalSetDisplayState, &displayState, NULL);
sl@0
   668
	TEST(res == KErrNone);
sl@0
   669
sl@0
   670
	iSurfaceUpdate.NotifyWhenDisplayedXTimes(count, status);	
sl@0
   671
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, 0);
sl@0
   672
	User::WaitForRequest(status);
sl@0
   673
	TEST(status == KErrNone);
sl@0
   674
	
sl@0
   675
	// Make sure other surface is not visible
sl@0
   676
	iWindowAbove11->Window()->SetVisible(EFalse);
sl@0
   677
	iWs.Finish();
sl@0
   678
	User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   679
	
sl@0
   680
	// above1 surface should not be visible because window is not visible
sl@0
   681
	TTimeStamp timeStamp; 
sl@0
   682
	iSurfaceUpdate.NotifyWhenDisplayed(status, timeStamp);	
sl@0
   683
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceAbove1, 0);
sl@0
   684
	User::WaitForRequest(status);
sl@0
   685
	TEST(status == KErrNotVisible);
sl@0
   686
	
sl@0
   687
	//disconnect the secondary screen - surface still visible on primary
sl@0
   688
	INFO_PRINTF1(_L("Disconnect the secondary screen - surface still visible on primary")); 
sl@0
   689
	displayState = EDisconnect;
sl@0
   690
	disconnectedScreenNo = 1;
sl@0
   691
	iSurfaceUpdate.NotifyWhenDisplayedXTimes(count, status);	
sl@0
   692
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, 0);
sl@0
   693
	
sl@0
   694
	res = UserSvr::HalFunction(EHalGroupDisplay | (disconnectedScreenNo<<16), EDisplayHalSetDisplayState, &displayState, NULL);
sl@0
   695
	TEST(res == KErrNone);
sl@0
   696
	User::WaitForRequest(status);
sl@0
   697
	TEST(status == KErrNone);
sl@0
   698
	User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   699
sl@0
   700
   //disconnect the primary screen - surface now not visible on any screen
sl@0
   701
    INFO_PRINTF1(_L("Disconnect the primary screen - surface not visible on any screen")); 
sl@0
   702
    displayState = EDisconnect;
sl@0
   703
    disconnectedScreenNo = 0;
sl@0
   704
    iSurfaceUpdate.NotifyWhenDisplayedXTimes(count, status);    
sl@0
   705
    iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, 0);
sl@0
   706
    
sl@0
   707
    res = UserSvr::HalFunction(EHalGroupDisplay | (disconnectedScreenNo<<16), EDisplayHalSetDisplayState, &displayState, NULL);
sl@0
   708
    TEST(res == KErrNone);
sl@0
   709
    User::WaitForRequest(status);
sl@0
   710
    TEST(status == KErrNotVisible); // not visible raised if primary is disconnected
sl@0
   711
    User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   712
        
sl@0
   713
sl@0
   714
    //restore initial state 
sl@0
   715
    disconnectedScreenNo = 0;
sl@0
   716
    displayState = ENormalResolution;
sl@0
   717
    res = UserSvr::HalFunction(EHalGroupDisplay | (disconnectedScreenNo<<16), EDisplayHalSetDisplayState, &displayState, NULL);
sl@0
   718
    TEST(res == KErrNone);
sl@0
   719
    disconnectedScreenNo = 1;
sl@0
   720
    res = UserSvr::HalFunction(EHalGroupDisplay | (disconnectedScreenNo<<16), EDisplayHalSetDisplayState, &displayState, NULL);
sl@0
   721
    TEST(res == KErrNone);
sl@0
   722
sl@0
   723
    
sl@0
   724
	iWs.Finish();	
sl@0
   725
	iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurface, 0);
sl@0
   726
	User::After(TTimeIntervalMicroSeconds32(100000)); //useful for visual checking
sl@0
   727
	TEST(CompareAllScreens());
sl@0
   728
	}
sl@0
   729
sl@0
   730
void CTSurfaceUpdateInteg::RunTestCaseL(TInt aCurTestCase)
sl@0
   731
	{
sl@0
   732
	((CTSurfaceUpdateIntegStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName);
sl@0
   733
	switch(aCurTestCase)
sl@0
   734
		{
sl@0
   735
	case 1:
sl@0
   736
		{
sl@0
   737
		
sl@0
   738
		if((static_cast <CTSurfaceUpdateIntegStep*> (iStep)) -> IsScreenCaptureSupported()  && (iNumOfScreens > 1))
sl@0
   739
			{
sl@0
   740
			((CTSurfaceUpdateIntegStep*)iStep)->SetTestStepID(_L("GRAPHIC-SURFACEUPDATE-0026"));
sl@0
   741
			INFO_PRINTF1(_L("TestCase1"));
sl@0
   742
			TestCase1L();
sl@0
   743
			}
sl@0
   744
		else
sl@0
   745
			{
sl@0
   746
			((CTSurfaceUpdateIntegStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
sl@0
   747
			INFO_PRINTF3(_L("The test will be skipped as the environment is not ready: Number of screen : %d, Is screen capture supported: %d"), 
sl@0
   748
					iNumOfScreens, (static_cast <CTSurfaceUpdateIntegStep*> (iStep)) -> IsScreenCaptureSupported());
sl@0
   749
			TestComplete();		
sl@0
   750
			}	
sl@0
   751
		break;
sl@0
   752
		}
sl@0
   753
#ifdef __WINS__
sl@0
   754
	case 2:
sl@0
   755
		{
sl@0
   756
		((CTSurfaceUpdateIntegStep*)iStep)->SetTestStepID(_L("GRAPHIC-SURFACEUPDATE-0031"));
sl@0
   757
		INFO_PRINTF1(_L("TestCase2"));
sl@0
   758
		TestCase2L();
sl@0
   759
		break;
sl@0
   760
		}
sl@0
   761
	case 3:
sl@0
   762
		{
sl@0
   763
		((CTSurfaceUpdateIntegStep*)iStep)->SetTestStepID(_L("GRAPHIC-SURFACEUPDATE-0032"));
sl@0
   764
		INFO_PRINTF1(_L("TestCase3"));
sl@0
   765
		TestCase3();
sl@0
   766
		break;
sl@0
   767
		}
sl@0
   768
#endif		
sl@0
   769
	default:
sl@0
   770
		((CTSurfaceUpdateIntegStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName);
sl@0
   771
		((CTSurfaceUpdateIntegStep*)iStep)->CloseTMSGraphicsStep();
sl@0
   772
		TestComplete();		
sl@0
   773
		break;
sl@0
   774
		}
sl@0
   775
	((CTSurfaceUpdateIntegStep*)iStep)->RecordTestResultL();
sl@0
   776
	}
sl@0
   777
//--------------
sl@0
   778
_LIT(KCommandDispatcher, "CommandDispatcher");
sl@0
   779
const TUint KDefaultHeapSize=0x10000;
sl@0
   780
sl@0
   781
/**
sl@0
   782
 * Launch the command thread.
sl@0
   783
 */
sl@0
   784
TInt CCommandDispatcher::Start()
sl@0
   785
	{
sl@0
   786
	RThread commandThread;
sl@0
   787
	TInt res = KErrGeneral;
sl@0
   788
	TBuf<64> commandThreadName;
sl@0
   789
	TBuf<64> commandThreaMask;
sl@0
   790
	
sl@0
   791
	// Guarantee uniqueness of thread name by using timestamp
sl@0
   792
	TTime tm;
sl@0
   793
	TBuf<32> timeStamp;
sl@0
   794
	tm.UniversalTime();
sl@0
   795
	TRAP(res, tm.FormatL(timeStamp, _L("_%H%T%S%C")));
sl@0
   796
	if(res != KErrNone)
sl@0
   797
		{
sl@0
   798
		return res;
sl@0
   799
		}
sl@0
   800
sl@0
   801
	commandThreadName.Append(KCommandDispatcher);
sl@0
   802
	commandThreadName.Append(timeStamp);
sl@0
   803
	commandThreaMask = commandThreadName;
sl@0
   804
	commandThreaMask.Insert(0, _L("*"));
sl@0
   805
	TFindThread findThread(commandThreaMask);
sl@0
   806
	TFullName name;
sl@0
   807
	  // Need to check that the thread exists.
sl@0
   808
	if (findThread.Next(name)!=KErrNone)
sl@0
   809
		{
sl@0
   810
		  // Create the thread for the server.
sl@0
   811
		res = commandThread.Create(commandThreadName,
sl@0
   812
			CCommandDispatcher::ThreadFunction,
sl@0
   813
			KDefaultStackSize,
sl@0
   814
			KDefaultHeapSize,
sl@0
   815
			KDefaultHeapSize,
sl@0
   816
			this
sl@0
   817
			);
sl@0
   818
			
sl@0
   819
          // The thread has been created OK so get it started - however
sl@0
   820
          // we need to make sure that it has started before we continue.
sl@0
   821
		if (res==KErrNone)
sl@0
   822
			{
sl@0
   823
			TRequestStatus rendezvousStatus;
sl@0
   824
			commandThread.SetPriority(EPriorityNormal);
sl@0
   825
			commandThread.Rendezvous(rendezvousStatus);
sl@0
   826
			commandThread.Resume();
sl@0
   827
			}
sl@0
   828
		}
sl@0
   829
	commandThread.Close();
sl@0
   830
	return res;
sl@0
   831
	}
sl@0
   832
sl@0
   833
TInt CCommandDispatcher::ThreadFunction(TAny* aAny)
sl@0
   834
	{
sl@0
   835
	  // get clean-up stack
sl@0
   836
	CTrapCleanup* cleanup=CTrapCleanup::New();
sl@0
   837
	CCommandDispatcher* commandDispatcher = (CCommandDispatcher*) aAny;
sl@0
   838
	TRAPD(res, commandDispatcher->ExecuteCommandL());
sl@0
   839
	delete cleanup; 
sl@0
   840
	return res;
sl@0
   841
	}
sl@0
   842
sl@0
   843
/**
sl@0
   844
 * Run commands in a thread different to the thread where the instance 
sl@0
   845
 * of the class was initialized.
sl@0
   846
 */
sl@0
   847
void CCommandDispatcher::ExecuteCommandL()
sl@0
   848
	{
sl@0
   849
	switch(iCommandName)
sl@0
   850
		{
sl@0
   851
	case EDisconnectDisplayAndReleaseBuffer:
sl@0
   852
		{
sl@0
   853
		RSurfaceUpdateSession surfaceUpdate;
sl@0
   854
		User::LeaveIfError(surfaceUpdate.Connect());
sl@0
   855
		CleanupClosePushL(surfaceUpdate);
sl@0
   856
		TSwitchDisplayAndReleaseBuffer* param = static_cast<TSwitchDisplayAndReleaseBuffer*>(iParam); 
sl@0
   857
		if(!param)
sl@0
   858
			{
sl@0
   859
			User::Leave(KErrArgument);
sl@0
   860
			}
sl@0
   861
		TInt displayState = EDisconnect;
sl@0
   862
		TInt screenNumber = param->iScreen;
sl@0
   863
		TInt bufferNumber = param->iBuffer;
sl@0
   864
		User::LeaveIfError(UserSvr::HalFunction(EHalGroupDisplay | (screenNumber<<16), EDisplayHalSetDisplayState, &displayState, NULL));
sl@0
   865
		//Submit Update to unblock the main client thread 
sl@0
   866
		User::LeaveIfError(surfaceUpdate.SubmitUpdate(KAllScreens, param->iSurfaceId, bufferNumber));
sl@0
   867
		CleanupStack::PopAndDestroy(&surfaceUpdate);
sl@0
   868
		break;
sl@0
   869
		}
sl@0
   870
	case EConnectDisplayAndReleaseBuffer:
sl@0
   871
		{
sl@0
   872
		RSurfaceUpdateSession surfaceUpdate;
sl@0
   873
		User::LeaveIfError(surfaceUpdate.Connect());
sl@0
   874
		CleanupClosePushL(surfaceUpdate);
sl@0
   875
		TSwitchDisplayAndReleaseBuffer* param = static_cast<TSwitchDisplayAndReleaseBuffer*>(iParam); 
sl@0
   876
		if(!param)
sl@0
   877
			{
sl@0
   878
			User::Leave(KErrArgument);
sl@0
   879
			}
sl@0
   880
		TInt displayState = ENormalResolution;
sl@0
   881
		TInt screenNumber = param->iScreen;
sl@0
   882
		TInt bufferNumber = param->iBuffer;
sl@0
   883
		User::LeaveIfError(UserSvr::HalFunction(EHalGroupDisplay | (screenNumber<<16), EDisplayHalSetDisplayState, &displayState, NULL));
sl@0
   884
		//Submit Update to unblock the main client thread 
sl@0
   885
		User::LeaveIfError(surfaceUpdate.SubmitUpdate(KAllScreens, param->iSurfaceId, bufferNumber));
sl@0
   886
		CleanupStack::PopAndDestroy(&surfaceUpdate);
sl@0
   887
		break;
sl@0
   888
		}
sl@0
   889
	default:
sl@0
   890
		User::Leave(KErrNotSupported);
sl@0
   891
		break;
sl@0
   892
		}
sl@0
   893
	}
sl@0
   894
sl@0
   895
//--------------
sl@0
   896
__CONSTRUCT_STEP__(SurfaceUpdateInteg)
sl@0
   897
sl@0
   898
/**
sl@0
   899
 * Retrieve screen capturing plug-in, if succeed set a flag.
sl@0
   900
 */
sl@0
   901
void CTSurfaceUpdateIntegStep::TestSetupL()
sl@0
   902
	{
sl@0
   903
//	check if the screen capture plug-in presents in the system
sl@0
   904
	RWsSession ws;
sl@0
   905
	User::LeaveIfError(ws.Connect());
sl@0
   906
	CleanupClosePushL(ws);
sl@0
   907
sl@0
   908
	TInt numOfScreens = ws.NumberOfScreens();
sl@0
   909
	if(numOfScreens < 2)
sl@0
   910
		{
sl@0
   911
		ERR_PRINTF2(_L("Environment is not ready, the number of the screens in the system for this test should be 2 or more, the current number is: %d"), numOfScreens);
sl@0
   912
		User::Leave(KErrNotReady);
sl@0
   913
		}
sl@0
   914
	
sl@0
   915
	CWsScreenDevice* wsDev = new (ELeave) CWsScreenDevice(ws);
sl@0
   916
	CleanupStack::PushL(wsDev);
sl@0
   917
	User::LeaveIfError(wsDev->Construct(0));
sl@0
   918
	TDisplayMode dispMode = wsDev->DisplayMode();
sl@0
   919
	INFO_PRINTF2(_L("Screen device display mode is: %d."), dispMode);
sl@0
   920
	
sl@0
   921
	MTestScreenCapture* csc = static_cast<MTestScreenCapture*> (wsDev->GetInterface(MTestScreenCapture::KUidTestScreenCaptureIf));
sl@0
   922
	if(csc)
sl@0
   923
		{
sl@0
   924
		INFO_PRINTF1(_L("Screen capture plug-in presents in the system."));
sl@0
   925
		iScreenCapture = ETrue;
sl@0
   926
		}
sl@0
   927
	else
sl@0
   928
		{
sl@0
   929
		INFO_PRINTF1(_L("Screen capture plug-in is not installed in the system, to make automated checking screen capture rendering stage is required, \
sl@0
   930
see graphics\\wserv_std_plugins\\screencapture"));
sl@0
   931
		}
sl@0
   932
	
sl@0
   933
	CleanupStack::PopAndDestroy(2, &ws); //ws, wsDev
sl@0
   934
	}
sl@0
   935
	
sl@0
   936
void CTSurfaceUpdateIntegStep::TestClose()
sl@0
   937
	{
sl@0
   938
	}
sl@0
   939