|
1 // Copyright (c) 2007-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". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @test |
|
19 @internalComponent - Internal Symbian test code |
|
20 */ |
|
21 |
|
22 |
|
23 #include "egltest_surface.h" |
|
24 #include "egltest_endpoint_images.h" |
|
25 #include <graphics/surfaceconfiguration.h> |
|
26 |
|
27 #define SURF_ASSERT(x) { if (!(x)) { RDebug::Printf("ASSERT(%s) failed at %s:%d", #x, __FILE__, __LINE__); User::Panic(_L("ASSERT SURF"), __LINE__); }} |
|
28 |
|
29 // Macros for indicating what is what. |
|
30 #define SIZE(x, y) x, y |
|
31 #define Buffers(x) x |
|
32 #define DefaultAlignment 32 // Pick some value that is valid. |
|
33 #define Alignment(x) x |
|
34 #define Stride(x) x |
|
35 #define DefaultStride 0 |
|
36 // Note: Offset to first buffer. |
|
37 #define Offset(x) x |
|
38 #define WindowPos(x, y) x, y |
|
39 #define WindowMode(m) m |
|
40 |
|
41 static const TSurfaceParamsCommon KSurfaceParams[] = |
|
42 { |
|
43 { |
|
44 EStandardSurface, |
|
45 SIZE(100, 100), |
|
46 Buffers(2), |
|
47 DefaultAlignment, |
|
48 DefaultStride, |
|
49 Offset(0), |
|
50 EUidPixelFormatARGB_8888_PRE, |
|
51 EFalse, |
|
52 { 0 }, |
|
53 WindowPos(0, 0), |
|
54 WindowMode(EColor16MAP) |
|
55 }, |
|
56 { |
|
57 EBadAttribSurface, |
|
58 SIZE(100, 100), |
|
59 Buffers(2), |
|
60 DefaultAlignment, |
|
61 DefaultStride, |
|
62 Offset(0), |
|
63 EUidPixelFormatARGB_8888_PRE, |
|
64 ETrue, |
|
65 { 1, 1, EGL_NONE }, |
|
66 WindowPos(0, 0), |
|
67 WindowMode(EColor16MAP) |
|
68 }, |
|
69 { |
|
70 EEmptyAttribSurface, |
|
71 SIZE(100, 100), |
|
72 Buffers(2), |
|
73 DefaultAlignment, |
|
74 DefaultStride, |
|
75 Offset(0), |
|
76 EUidPixelFormatARGB_8888_PRE, |
|
77 ETrue, |
|
78 { EGL_NONE }, |
|
79 WindowPos(0, 0), |
|
80 WindowMode(EColor16MAP) |
|
81 }, |
|
82 { |
|
83 EStandard128sqSurface, |
|
84 SIZE(128, 128), |
|
85 Buffers(3), |
|
86 DefaultAlignment, |
|
87 DefaultStride, |
|
88 Offset(0), |
|
89 EUidPixelFormatARGB_8888_PRE, |
|
90 EFalse, |
|
91 { 0 }, |
|
92 WindowPos(20, 20), |
|
93 WindowMode(EColor16MAP) |
|
94 }, |
|
95 { |
|
96 EUnusualStrideSurface, |
|
97 SIZE(167,263), |
|
98 Buffers(2), |
|
99 Alignment(8), |
|
100 Stride(167*4+64), |
|
101 Offset(200), |
|
102 EUidPixelFormatARGB_8888_PRE, |
|
103 EFalse, |
|
104 { 0 }, |
|
105 WindowPos(0, 0), |
|
106 WindowMode(EColor16MAP) |
|
107 }, |
|
108 { |
|
109 EUnalignedPixelSizeSurface, |
|
110 SIZE(103, 107), |
|
111 Buffers(2), |
|
112 Alignment(8), |
|
113 Stride(103*4), |
|
114 Offset(0), |
|
115 EUidPixelFormatARGB_8888_PRE, |
|
116 EFalse, |
|
117 { 0 }, |
|
118 WindowPos(0, 0), |
|
119 WindowMode(EColor16MAP) |
|
120 }, |
|
121 { |
|
122 ELargeSurface, |
|
123 SIZE(800, 600), |
|
124 Buffers(2), |
|
125 DefaultAlignment, |
|
126 DefaultStride, |
|
127 Offset(0), |
|
128 EUidPixelFormatARGB_8888_PRE, |
|
129 EFalse, |
|
130 { 0 }, |
|
131 WindowPos(0, 0), |
|
132 WindowMode(EColor16MAP) |
|
133 }, |
|
134 }; |
|
135 |
|
136 |
|
137 TInt KSurfaceMaxIndex = sizeof(KSurfaceParams) / sizeof(KSurfaceParams[0]); |
|
138 |
|
139 CRawSurface* CRawSurface::NewL() |
|
140 { |
|
141 CRawSurface* obj = new (ELeave) CRawSurface(); |
|
142 CleanupStack::PushL(obj); |
|
143 obj->ConstructL(); |
|
144 CleanupStack::Pop(obj); |
|
145 return obj; |
|
146 } |
|
147 |
|
148 |
|
149 CRawSurface::CRawSurface() : iDrawBuffer(0), iBuffers(0) |
|
150 { |
|
151 } |
|
152 |
|
153 |
|
154 void CRawSurface::ConstructL() |
|
155 { |
|
156 iSurfaceId = TSurfaceId::CreateNullId(); |
|
157 User::LeaveIfError(iSurfaceManager.Open()); |
|
158 User::LeaveIfError(iSurfaceUpdate.Connect(5)); |
|
159 } |
|
160 |
|
161 |
|
162 CRawSurface::~CRawSurface() |
|
163 { |
|
164 iSurfaceUpdate.Close(); |
|
165 if(!iSurfaceId.IsNull()) |
|
166 { |
|
167 iSurfaceManager.CloseSurface(iSurfaceId); |
|
168 } |
|
169 iSurfaceManager.Close(); |
|
170 } |
|
171 |
|
172 |
|
173 TInt CRawSurface::PixelSize(TUidPixelFormat aPixelFormat) |
|
174 { |
|
175 switch(aPixelFormat) |
|
176 { |
|
177 case EUidPixelFormatARGB_8888_PRE: |
|
178 case EUidPixelFormatARGB_8888: |
|
179 case EUidPixelFormatABGR_8888: |
|
180 case EUidPixelFormatABGR_8888_PRE: |
|
181 return 4; |
|
182 |
|
183 case EUidPixelFormatARGB_4444: |
|
184 case EUidPixelFormatRGB_565: |
|
185 return 2; |
|
186 |
|
187 default: |
|
188 SURF_ASSERT(0); |
|
189 break; |
|
190 } |
|
191 return 0; // Make sure no compiler moans about "not all paths return a value". |
|
192 } |
|
193 |
|
194 |
|
195 void CRawSurface::GetSurfAttribs(RSurfaceManager::TSurfaceCreationAttributesBuf &aSurfaceAttribs, TInt aIndex) |
|
196 { |
|
197 SURF_ASSERT(aIndex < KSurfaceMaxIndex); |
|
198 SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex); |
|
199 iParamIndex = aIndex; |
|
200 aSurfaceAttribs().iSize = TSize(KSurfaceParams[aIndex].iXSize, KSurfaceParams[aIndex].iYSize); |
|
201 iBuffers = KSurfaceParams[aIndex].iBuffers; |
|
202 aSurfaceAttribs().iBuffers = iBuffers; |
|
203 aSurfaceAttribs().iPixelFormat = KSurfaceParams[aIndex].iPixelFormat; |
|
204 TInt stride = KSurfaceParams[aIndex].iStrideInBytes; |
|
205 if (stride == 0) |
|
206 { |
|
207 stride = KSurfaceParams[aIndex].iXSize * PixelSize(KSurfaceParams[aIndex].iPixelFormat); |
|
208 } |
|
209 aSurfaceAttribs().iStride = stride; |
|
210 aSurfaceAttribs().iOffsetToFirstBuffer = KSurfaceParams[aIndex].iOffsetToFirstBuffer; |
|
211 aSurfaceAttribs().iAlignment = KSurfaceParams[aIndex].iAlignment; |
|
212 aSurfaceAttribs().iContiguous = EFalse; |
|
213 aSurfaceAttribs().iCacheAttrib = RSurfaceManager::ECached; |
|
214 aSurfaceAttribs().iOffsetBetweenBuffers = 0; |
|
215 aSurfaceAttribs().iSurfaceHints = NULL; |
|
216 aSurfaceAttribs().iHintCount = 0; |
|
217 aSurfaceAttribs().iMappable = ETrue; |
|
218 } |
|
219 |
|
220 |
|
221 //From CSurface. |
|
222 void CRawSurface::CreateL(TInt aIndex) |
|
223 { |
|
224 RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs; |
|
225 |
|
226 GetSurfAttribs(surfaceAttribs, aIndex); |
|
227 TInt err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId); |
|
228 User::LeaveIfError(err); |
|
229 } |
|
230 |
|
231 |
|
232 TUint8* CRawSurface::MapSurfaceAndGetInfoLC(RSurfaceManager::TSurfaceInfoV01& aInfo) |
|
233 { |
|
234 SURF_ASSERT(!iSurfaceId.IsNull()); |
|
235 User::LeaveIfError(iSurfaceManager.MapSurface(iSurfaceId, iSurfaceChunk)); |
|
236 CleanupClosePushL(iSurfaceChunk); |
|
237 RSurfaceManager::TInfoBuf infoBuf; |
|
238 User::LeaveIfError(iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf)); |
|
239 aInfo = infoBuf(); |
|
240 TInt offset = -1000; // So we hopefully detect when it goes horribly wrong. |
|
241 User::LeaveIfError(iSurfaceManager.GetBufferOffset(iSurfaceId, iDrawBuffer, offset)); |
|
242 return iSurfaceChunk.Base() + offset; |
|
243 } |
|
244 |
|
245 |
|
246 void CRawSurface::DrawContentL(TInt aImageIndex) |
|
247 { |
|
248 CTestCFbsImage *image = CTestCFbsImage::NewL(aImageIndex); |
|
249 CleanupStack::PushL(image); |
|
250 |
|
251 RSurfaceManager::TSurfaceInfoV01 info; |
|
252 TUint8 *dataAddress = MapSurfaceAndGetInfoLC(info); |
|
253 TInt stride = info.iStride; |
|
254 |
|
255 CFbsBitmap *bitmap = image->Bitmap(); |
|
256 TDisplayMode displaymode = bitmap->DisplayMode(); |
|
257 TInt pixelStride = stride / CFbsBitmap::ScanLineLength(1, displaymode); |
|
258 for(TInt y = 0; y < image->Size().iHeight; y++) |
|
259 { |
|
260 TPtr8 buf(dataAddress + y * stride, stride); |
|
261 |
|
262 // TODO: We need to check that the bitsperpixel matches between the surface and bitmap. |
|
263 bitmap->GetScanLine(buf, TPoint(0, y), pixelStride, displaymode); |
|
264 } |
|
265 |
|
266 CleanupStack::PopAndDestroy(2, image); |
|
267 } |
|
268 |
|
269 |
|
270 void CRawSurface::DrawContentL(const TRgb& aColour) |
|
271 { |
|
272 //Map the surface and get its info. |
|
273 RSurfaceManager::TSurfaceInfoV01 surfaceInfo; |
|
274 TUint32* buffer = (TUint32*)MapSurfaceAndGetInfoLC(surfaceInfo); |
|
275 |
|
276 //Currently this function only supports drawing into ARGB_8888_PRE surfaces. |
|
277 //This is because the only test that uses this function uses this type of surface. |
|
278 //If this functionallity needs expanding, you must correctly convert the TRgb colour |
|
279 //and pack it into the surface buffer correctly. |
|
280 SURF_ASSERT(surfaceInfo.iPixelFormat == EUidPixelFormatARGB_8888_PRE); |
|
281 |
|
282 TUint32 fillColour = aColour._Color16MAP(); |
|
283 |
|
284 //Loop over each pixel in the surface and colour it. |
|
285 //This is deliberately slow since it is only used for the tearing test |
|
286 //and we want to spend most of our time drawing so that the chances of the other thread |
|
287 //picking up a buffer in the middle of drawing is increased. |
|
288 for(TInt y=0; y < surfaceInfo.iSize.iHeight; ++y) |
|
289 { |
|
290 for(TInt x=0; x < surfaceInfo.iSize.iWidth; ++x) |
|
291 { |
|
292 buffer[x] = fillColour; |
|
293 } |
|
294 buffer += surfaceInfo.iStride >> 2; |
|
295 } |
|
296 |
|
297 CleanupStack::PopAndDestroy(); |
|
298 } |
|
299 |
|
300 |
|
301 void CRawSurface::SubmitContentL(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */) |
|
302 { |
|
303 TRequestStatus displayNotify = KRequestPending; |
|
304 TTimeStamp timeStamp; |
|
305 |
|
306 if(aShouldWaitForDisplay) |
|
307 { |
|
308 Notify(ENotifyWhenDisplayed, displayNotify, 0); |
|
309 } |
|
310 |
|
311 TInt err = iSurfaceUpdate.SubmitUpdate(KAllScreens, iSurfaceId, iDrawBuffer, NULL); |
|
312 User::LeaveIfError(err); |
|
313 iDrawBuffer = (iDrawBuffer + 1) % iBuffers; |
|
314 |
|
315 if(aShouldWaitForDisplay) |
|
316 { |
|
317 TUint32 dummy; |
|
318 TInt err = WaitFor(ENotifyWhenDisplayed, displayNotify, 100 * 1000, dummy); |
|
319 if (err != KErrNone && err != KErrNotVisible && err != KErrOverflow) |
|
320 { |
|
321 RDebug::Printf("%s:%d: NotifyWhenDisplayed gave unexpected error %d", __FILE__, __LINE__, err); |
|
322 User::Leave(err); |
|
323 } |
|
324 } |
|
325 } |
|
326 |
|
327 |
|
328 TSurfaceId CRawSurface::SurfaceId() const |
|
329 { |
|
330 return iSurfaceId; |
|
331 } |
|
332 |
|
333 |
|
334 void CRawSurface::GetSurfaceParamsL(TSurfaceParamsRemote &aParams) |
|
335 { |
|
336 aParams.iCommonParams = KSurfaceParams[iParamIndex]; |
|
337 aParams.iCommonParams.iBuffers = iBuffers; // May have been changed if it's a single buffered surface... |
|
338 aParams.iSurfaceId = SurfaceId(); |
|
339 } |
|
340 |
|
341 const TText *CRawSurface::GetSurfaceTypeStr() const |
|
342 { |
|
343 return _S("CRawSurface"); |
|
344 } |
|
345 |
|
346 TInt CRawSurface::Notify(TNotification aWhen, TRequestStatus& aStatus, TUint32 aXTimes) |
|
347 { |
|
348 aStatus = KRequestPending; |
|
349 switch(aWhen) |
|
350 { |
|
351 case ENotifyWhenAvailable: |
|
352 iSurfaceUpdate.NotifyWhenAvailable(aStatus); |
|
353 break; |
|
354 case ENotifyWhenDisplayed: |
|
355 iSurfaceUpdate.NotifyWhenDisplayed(aStatus, iTimeStamp); |
|
356 break; |
|
357 case ENotifyWhenDispXTimes: |
|
358 iSurfaceUpdate.NotifyWhenDisplayedXTimes(aXTimes, aStatus); |
|
359 break; |
|
360 default: |
|
361 RDebug::Printf("%s:%d: Invalid notification: %d. Panicking...", __FILE__, __LINE__, aWhen); |
|
362 User::Panic(_L("CRawSurface::Notify()"), __LINE__); |
|
363 break; |
|
364 } |
|
365 return KErrNone; |
|
366 } |
|
367 |
|
368 |
|
369 TInt CRawSurface::WaitFor(TNotification aWhen, TRequestStatus& aStatus, TInt aTimeoutInMicroSeconds, TUint32& aTimeStamp) |
|
370 { |
|
371 RTimer timer; |
|
372 TInt err = timer.CreateLocal(); |
|
373 if (err != KErrNone) |
|
374 { |
|
375 return err; |
|
376 } |
|
377 TRequestStatus timerStatus = KRequestPending; |
|
378 #if __WINS__ |
|
379 // Windows timer isn't very precise - add some "fuzz" to the timeout to ensure we do not wait "too little". |
|
380 const TInt KTimeOutExtra = 20000; |
|
381 #else |
|
382 // On hardware, we should be able to run with less "fuzz". |
|
383 const TInt KTimeOutExtra = 10000; |
|
384 #endif |
|
385 timer.HighRes(timerStatus, aTimeoutInMicroSeconds + KTimeOutExtra); |
|
386 User::WaitForRequest(timerStatus, aStatus); |
|
387 if (aStatus == KRequestPending) |
|
388 { |
|
389 if (aWhen == ENotifyWhenDisplayed) |
|
390 { |
|
391 aTimeStamp = User::FastCounter(); |
|
392 } |
|
393 return KErrTimedOut; |
|
394 } |
|
395 if (aWhen == ENotifyWhenDisplayed) |
|
396 { |
|
397 aTimeStamp = iTimeStamp(); |
|
398 } |
|
399 timer.Cancel(); |
|
400 timer.Close(); |
|
401 TInt result = aStatus.Int(); |
|
402 aStatus = KRequestPending; |
|
403 return result; |
|
404 } |
|
405 |
|
406 |
|
407 |
|
408 const TText *CRawSingleBufferSurface::GetSurfaceTypeStr() const |
|
409 { |
|
410 return _S("CRawSingleBufferedSurface"); |
|
411 } |
|
412 |
|
413 CRawSingleBufferSurface *CRawSingleBufferSurface::NewL() |
|
414 { |
|
415 CRawSingleBufferSurface* obj = new (ELeave) CRawSingleBufferSurface(); |
|
416 CleanupStack::PushL(obj); |
|
417 obj->ConstructL(); |
|
418 CleanupStack::Pop(obj); |
|
419 return obj; |
|
420 } |
|
421 |
|
422 |
|
423 void CRawSingleBufferSurface::CreateL(TInt aIndex) |
|
424 { |
|
425 RSurfaceManager::TSurfaceCreationAttributesBuf surfaceAttribs; |
|
426 |
|
427 GetSurfAttribs(surfaceAttribs, aIndex); |
|
428 |
|
429 iBuffers = 1; |
|
430 surfaceAttribs().iBuffers = 1; |
|
431 |
|
432 TInt err = iSurfaceManager.CreateSurface(surfaceAttribs, iSurfaceId); |
|
433 User::LeaveIfError(err); |
|
434 } |
|
435 |
|
436 CRawSingleBufferSurface::~CRawSingleBufferSurface() |
|
437 { |
|
438 } |
|
439 |
|
440 class CWindow: public CBase |
|
441 { |
|
442 public: |
|
443 static CWindow *NewL(TInt aIndex); |
|
444 RWindow& Window(); |
|
445 ~CWindow(); |
|
446 private: |
|
447 void ConstructL(TInt aIndex); |
|
448 CWindow(); |
|
449 |
|
450 private: |
|
451 RWindow iWindow; |
|
452 RWindowGroup iWindowGroup; |
|
453 RWsSession iWsSession; |
|
454 }; |
|
455 |
|
456 |
|
457 CWindow* CWindow::NewL(TInt aIndex) |
|
458 { |
|
459 CWindow *self = new (ELeave) CWindow; |
|
460 CleanupStack::PushL(self); |
|
461 self->ConstructL(aIndex); |
|
462 CleanupStack::Pop(self); |
|
463 return self; |
|
464 } |
|
465 |
|
466 |
|
467 void CWindow::ConstructL(TInt aIndex) |
|
468 { |
|
469 RFbsSession::Connect(); |
|
470 if (aIndex >= KSurfaceMaxIndex) |
|
471 { |
|
472 User::Leave(KErrOverflow); |
|
473 } |
|
474 User::LeaveIfError(iWsSession.Connect()); |
|
475 iWindowGroup = RWindowGroup(iWsSession); |
|
476 User::LeaveIfError(iWindowGroup.Construct((TUint32)this)); |
|
477 iWindow = RWindow(iWsSession); |
|
478 User::LeaveIfError(iWindow.Construct(iWindowGroup, -1U)); |
|
479 const TSurfaceParamsCommon& winAttrib = KSurfaceParams[aIndex]; |
|
480 iWindow.SetExtent(TPoint(winAttrib.iXPos, winAttrib.iYPos), TSize(winAttrib.iXSize, winAttrib.iYSize)); |
|
481 iWindow.SetRequiredDisplayMode(winAttrib.iDisplayMode); |
|
482 iWindow.Activate(); |
|
483 } |
|
484 |
|
485 |
|
486 CWindow::~CWindow() |
|
487 { |
|
488 iWindow.Close(); |
|
489 iWindowGroup.Close(); |
|
490 iWsSession.Close(); |
|
491 RFbsSession::Disconnect(); |
|
492 } |
|
493 |
|
494 |
|
495 CWindow::CWindow() |
|
496 { |
|
497 } |
|
498 |
|
499 |
|
500 RWindow& CWindow::Window() |
|
501 { |
|
502 return iWindow; |
|
503 } |
|
504 |
|
505 |
|
506 CEglWindowSurface* CEglWindowSurface::NewL() |
|
507 { |
|
508 CEglWindowSurface* self = new (ELeave) CEglWindowSurface; |
|
509 CleanupStack::PushL(self); |
|
510 self->ConstructL(); |
|
511 CleanupStack::Pop(self); |
|
512 return self; |
|
513 } |
|
514 |
|
515 |
|
516 void CEglWindowSurface::ConstructL() |
|
517 { |
|
518 } |
|
519 |
|
520 |
|
521 CEglWindowSurface::CEglWindowSurface() |
|
522 { |
|
523 } |
|
524 |
|
525 |
|
526 void CEglWindowSurface::CreateL(TInt aIndex) |
|
527 { |
|
528 SURF_ASSERT(aIndex < KSurfaceMaxIndex); |
|
529 SURF_ASSERT(aIndex == KSurfaceParams[aIndex].iIndex); |
|
530 iParamIndex = aIndex; |
|
531 iWindow = CWindow::NewL(aIndex); |
|
532 iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
|
533 EGLint err; |
|
534 if (iDisplay == EGL_NO_DISPLAY) |
|
535 { |
|
536 err = eglGetError(); |
|
537 RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err); |
|
538 User::Leave(KErrNotSupported); |
|
539 } |
|
540 |
|
541 EGLConfig config; |
|
542 EGLint nConfigs = 0; |
|
543 |
|
544 // TODO: Need to use differnet config attribs based on aIndex. |
|
545 static const EGLint KConfigAttribs[] = |
|
546 { |
|
547 EGL_BUFFER_SIZE, 32, |
|
548 EGL_RED_SIZE, 8, |
|
549 EGL_GREEN_SIZE, 8, |
|
550 EGL_BLUE_SIZE, 8, |
|
551 EGL_ALPHA_SIZE, 8, |
|
552 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, |
|
553 EGL_RENDERABLE_TYPE,EGL_OPENVG_BIT, |
|
554 EGL_NONE |
|
555 }; |
|
556 |
|
557 // Need some way to configure the attribs ... |
|
558 eglChooseConfig(iDisplay, KConfigAttribs, &config, 1, &nConfigs); |
|
559 if (!nConfigs) |
|
560 { |
|
561 err = eglGetError(); |
|
562 RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err); |
|
563 User::Leave(KErrNotSupported); |
|
564 } |
|
565 |
|
566 if (!eglBindAPI(EGL_OPENVG_API)) |
|
567 { |
|
568 err = eglGetError(); |
|
569 RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err); |
|
570 User::Leave(KErrNotSupported); |
|
571 } |
|
572 iContext = eglCreateContext(iDisplay, config, 0, NULL); |
|
573 if (iContext == EGL_NO_CONTEXT) |
|
574 { |
|
575 err = eglGetError(); |
|
576 RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err); |
|
577 User::Leave(KErrNotSupported); |
|
578 } |
|
579 |
|
580 iSurface = eglCreateWindowSurface(iDisplay, config, &iWindow->Window(), NULL); |
|
581 if (iSurface == EGL_NO_SURFACE) |
|
582 { |
|
583 err = eglGetError(); |
|
584 RDebug::Printf("%s:%d: err = %d", __FILE__, __LINE__, err); |
|
585 User::Leave(KErrNotSupported); |
|
586 } |
|
587 } |
|
588 |
|
589 void CEglWindowSurface::SubmitContentL(TBool aShouldWaitForDisplay, TInt /* aRectsIndex */) |
|
590 { |
|
591 ActivateL(); |
|
592 if (!eglSwapBuffers(iDisplay, iSurface)) |
|
593 { |
|
594 User::Leave(KErrBadHandle); |
|
595 } |
|
596 if (aShouldWaitForDisplay) |
|
597 { |
|
598 // We are cheating: We just wait for a bit to ensure that the swapbuffer is actually finished. |
|
599 // There is no way to determine how long this takes, so we just grab a number that should be |
|
600 // large enough... |
|
601 User::After(100 * 1000); // Wait 100ms. |
|
602 } |
|
603 } |
|
604 |
|
605 void CEglWindowSurface::ActivateL() |
|
606 { |
|
607 if (!eglMakeCurrent(iDisplay, iSurface, iSurface, iContext)) |
|
608 { |
|
609 User::Leave(KErrBadHandle); |
|
610 } |
|
611 } |
|
612 |
|
613 CEglWindowSurface::~CEglWindowSurface() |
|
614 { |
|
615 eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); |
|
616 if (iSurface != EGL_NO_SURFACE) |
|
617 { |
|
618 eglDestroySurface(iDisplay, iSurface); |
|
619 iSurface = EGL_NO_SURFACE; |
|
620 } |
|
621 |
|
622 if (iDisplay != EGL_NO_DISPLAY) |
|
623 { |
|
624 eglDestroyContext(iDisplay, iContext); |
|
625 } |
|
626 |
|
627 delete iWindow; |
|
628 } |
|
629 |
|
630 TSurfaceId CEglWindowSurface::SurfaceId() const |
|
631 { |
|
632 // Default constructor for id sets it to a NULL-value, so if no window is created, we get |
|
633 // a defined surface id value that is invalid. |
|
634 TSurfaceId id; |
|
635 if (iWindow) |
|
636 { |
|
637 TSurfaceConfiguration surfConfig; |
|
638 iWindow->Window().GetBackgroundSurface(surfConfig); |
|
639 surfConfig.GetSurfaceId(id); |
|
640 } |
|
641 return id; |
|
642 } |
|
643 |
|
644 |
|
645 void CEglWindowSurface::DrawContentL(const TRgb& aColour) |
|
646 { |
|
647 ActivateL(); |
|
648 |
|
649 TSize size; |
|
650 eglQuerySurface(iDisplay, iSurface, EGL_WIDTH, &size.iWidth); |
|
651 eglQuerySurface(iDisplay, iSurface, EGL_HEIGHT, &size.iHeight); |
|
652 |
|
653 VGfloat fillColour[4]; |
|
654 fillColour[0] = (VGfloat)aColour.Red() / 255.0f; |
|
655 fillColour[1] = (VGfloat)aColour.Green() / 255.0f; |
|
656 fillColour[2] = (VGfloat)aColour.Blue() / 255.0f; |
|
657 fillColour[3] = (VGfloat)aColour.Alpha() / 255.0f; |
|
658 |
|
659 vgSetfv(VG_CLEAR_COLOR, 4, fillColour); |
|
660 vgClear(0, 0, size.iWidth, size.iHeight); |
|
661 } |
|
662 |
|
663 |
|
664 void CEglWindowSurface::DrawContentL(TInt aIndex) |
|
665 { |
|
666 ActivateL(); |
|
667 CTestVgImage *vgImage = CTestVgImage::NewL(aIndex); |
|
668 CleanupStack::PushL(vgImage); |
|
669 vgDrawImage(vgImage->VGImage()); |
|
670 CleanupStack::PopAndDestroy(vgImage); |
|
671 } |
|
672 |
|
673 void CEglWindowSurface::GetSurfaceParamsL(TSurfaceParamsRemote &aParams) |
|
674 { |
|
675 RSurfaceManager surfaceManager; |
|
676 User::LeaveIfError(surfaceManager.Open()); |
|
677 RSurfaceManager::TInfoBuf infoBuf; |
|
678 TInt err = surfaceManager.SurfaceInfo(SurfaceId(), infoBuf); |
|
679 User::LeaveIfError(err); |
|
680 surfaceManager.Close(); |
|
681 RSurfaceManager::TSurfaceInfoV01& info = infoBuf(); |
|
682 aParams.iSurfaceId = SurfaceId(); |
|
683 aParams.iCommonParams.iAlignment = -1; // N/A |
|
684 aParams.iCommonParams.iBuffers = info.iBuffers; |
|
685 aParams.iCommonParams.iOffsetToFirstBuffer = -1; |
|
686 aParams.iCommonParams.iPixelFormat = info.iPixelFormat; |
|
687 aParams.iCommonParams.iStrideInBytes = info.iStride; |
|
688 aParams.iCommonParams.iXSize = info.iSize.iWidth; |
|
689 aParams.iCommonParams.iYSize = info.iSize.iHeight; |
|
690 aParams.iCommonParams.iUseAttribList = KSurfaceParams[iParamIndex].iUseAttribList; |
|
691 for(TInt i = 0; i < KNumAttribs; i++) |
|
692 { |
|
693 aParams.iCommonParams.iAttribs[i] = KSurfaceParams[iParamIndex].iAttribs[i]; |
|
694 } |
|
695 } |
|
696 |
|
697 const TText *CEglWindowSurface::GetSurfaceTypeStr() const |
|
698 { |
|
699 return _S("CEglWindowSurface"); |
|
700 } |
|
701 |
|
702 TInt CEglWindowSurface::Notify(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/, TUint32 /*aXTImes*/) |
|
703 { |
|
704 return KErrNotSupported; |
|
705 } |
|
706 |
|
707 TInt CEglWindowSurface::WaitFor(TNotification /*aWhen*/, TRequestStatus& /*aStatus*/, |
|
708 TInt /*aTimeoutinMicroseconds*/, TUint32 & /*aTimeStamp*/) |
|
709 { |
|
710 return KErrNotSupported; |
|
711 } |
|
712 |
|
713 |
|
714 // Factory function. |
|
715 CSurface *CSurface::SurfaceFactoryL(TSurfaceType aSurfaceType) |
|
716 { |
|
717 switch(aSurfaceType) |
|
718 { |
|
719 case ESurfTypeRaw: |
|
720 return CRawSurface::NewL(); |
|
721 case ESurfTypeEglWindow: |
|
722 return CEglWindowSurface::NewL(); |
|
723 case ESurfTypeRawSingleBuffered: |
|
724 return CRawSingleBufferSurface::NewL(); |
|
725 default: |
|
726 SURF_ASSERT(0); |
|
727 return NULL; |
|
728 } |
|
729 } |
|
730 |