|
1 // Copyright (c) 1998-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 #include <hal.h> |
|
17 #include <cdsb.h> |
|
18 #include <e32hal.h> |
|
19 |
|
20 |
|
21 #ifdef SYMBIAN_GRAPHICS_GCE |
|
22 #undef __WINS__ |
|
23 #include "../sgeneric/scdraw.h" |
|
24 #elif defined(__WINS__) |
|
25 #include "_WININC.H" |
|
26 #endif |
|
27 |
|
28 |
|
29 // |
|
30 // CGenericDirectScreenBitmap: Implementation of generic CDirectScreenBitmap class |
|
31 // |
|
32 NONSHARABLE_CLASS(CGenericDirectScreenBitmap) : public CDirectScreenBitmap |
|
33 { |
|
34 public: |
|
35 CGenericDirectScreenBitmap(); |
|
36 CGenericDirectScreenBitmap(TInt aScreenNo); |
|
37 ~CGenericDirectScreenBitmap(); |
|
38 |
|
39 public: |
|
40 // Pure virtual from CDirectScreenBitmap |
|
41 virtual TInt Create(const TRect& aScreenRect, TSettingsFlags aSettingsFlags); |
|
42 virtual TInt BeginUpdate(TAcceleratedBitmapInfo& aBitmapInfo); |
|
43 virtual void EndUpdate(TRequestStatus& aComplete); |
|
44 virtual void EndUpdate(const TRect& aScreenRect, TRequestStatus& aComplete); |
|
45 virtual void Close(); |
|
46 |
|
47 public: |
|
48 enum TDsbPanic |
|
49 { |
|
50 EPanicAlreadyCreated = 1, |
|
51 EPanicNotCreated = 2, |
|
52 EPanicInvalidMode = 3, |
|
53 EPanicOutOfBounds = 4, |
|
54 EPanicNotWordAligned = 5, |
|
55 EPanicInvalidRect = 6, |
|
56 EPanicIncompleteRequest = 7, |
|
57 EPanicHandleReturnedIncorrect = 8 |
|
58 }; |
|
59 static void Panic(TDsbPanic aPanic); |
|
60 |
|
61 private: |
|
62 TInt DoCreate(); |
|
63 |
|
64 #ifdef __WINS__ |
|
65 TRgb ExtractRgb(TUint8* aBuffer,TInt aPixelOffset) const; |
|
66 void WinsUpdate(const TRect& aScreenRect); |
|
67 #endif |
|
68 |
|
69 private: |
|
70 #ifndef __WINS__ |
|
71 TInt iVideoAddress; |
|
72 #endif |
|
73 #ifdef SYMBIAN_GRAPHICS_GCE |
|
74 CScreenDeviceHelper iSurfaceUpdater; |
|
75 TUidPixelFormat iPixelFormat; |
|
76 TBool iDsaBufferIsBusy; |
|
77 TRequestStatus iDsaBufferAvailable; |
|
78 #endif |
|
79 TAcceleratedBitmapInfo iBitmapInfo; |
|
80 TUint32 iSettingsFlags; |
|
81 TRect iUpdateRect; |
|
82 TInt iDisplayOffsetLines; |
|
83 TInt iBytesPerPixel; |
|
84 TInt iDisplayOffsetPixel; |
|
85 TBool iCreated; |
|
86 TInt iScreenNo; |
|
87 RChunk iChunk; |
|
88 TBool iHasChunk; |
|
89 }; |
|
90 |
|
91 // |
|
92 // Create a new instance of a DSB |
|
93 // The default screen (with number 0) will be used |
|
94 EXPORT_C CDirectScreenBitmap* CDirectScreenBitmap::NewL() |
|
95 { |
|
96 CGenericDirectScreenBitmap* pDsb=new(ELeave) CGenericDirectScreenBitmap; |
|
97 return(pDsb); |
|
98 } |
|
99 |
|
100 // |
|
101 // Create a new instance of a DSB |
|
102 // The screen with aScreenNo number will be used |
|
103 EXPORT_C CDirectScreenBitmap* CDirectScreenBitmap::NewL(TInt aScreenNo) |
|
104 { |
|
105 CGenericDirectScreenBitmap* pDsb = new (ELeave) CGenericDirectScreenBitmap(aScreenNo); |
|
106 return pDsb; |
|
107 } |
|
108 |
|
109 CGenericDirectScreenBitmap::CGenericDirectScreenBitmap() : |
|
110 #ifndef __WINS__ |
|
111 iVideoAddress(NULL), |
|
112 #endif |
|
113 #ifdef SYMBIAN_GRAPHICS_GCE |
|
114 iDsaBufferIsBusy(EFalse), |
|
115 #endif |
|
116 iBitmapInfo(), |
|
117 iSettingsFlags(ENone), |
|
118 iUpdateRect(), |
|
119 iDisplayOffsetLines(0), |
|
120 iBytesPerPixel(0), |
|
121 iDisplayOffsetPixel(0), |
|
122 iHasChunk(EFalse) |
|
123 { |
|
124 } |
|
125 |
|
126 CGenericDirectScreenBitmap::CGenericDirectScreenBitmap(TInt aScreenNo) : |
|
127 iScreenNo(aScreenNo) |
|
128 { |
|
129 } |
|
130 |
|
131 CGenericDirectScreenBitmap::~CGenericDirectScreenBitmap() |
|
132 { |
|
133 Close(); |
|
134 } |
|
135 |
|
136 // |
|
137 // Create a DSB object using a region of the screen previously |
|
138 // 'claimed' via the Window Servers Direct Screen Acceass API |
|
139 // |
|
140 TInt CGenericDirectScreenBitmap::Create(const TRect& aScreenRect, TSettingsFlags aSettingsFlags) |
|
141 { |
|
142 __ASSERT_ALWAYS(!iCreated, Panic(EPanicAlreadyCreated)); |
|
143 |
|
144 __ASSERT_ALWAYS((aSettingsFlags&(EDoubleBuffer|EIncrementalUpdate)) != |
|
145 (EDoubleBuffer|EIncrementalUpdate), Panic(EPanicInvalidMode)); |
|
146 |
|
147 //Initialize iScreenNo - its value occupies upper 5 bits of aSettingsFlags. |
|
148 //(32 - 1) is max allowed screen number |
|
149 iScreenNo = static_cast <TUint32> ((aSettingsFlags & 0xF8000000) >> 27); |
|
150 |
|
151 // Find the screen dimensions from the HAL and validate |
|
152 TInt screenWidth = 0; |
|
153 TInt screenHeight = 0; |
|
154 |
|
155 TInt r = HAL::Get(iScreenNo, HALData::EDisplayXPixels, screenWidth); |
|
156 if (r!=KErrNone) |
|
157 { |
|
158 return r; |
|
159 } |
|
160 |
|
161 r = HAL::Get(iScreenNo, HALData::EDisplayYPixels,screenHeight); |
|
162 if (r!=KErrNone) |
|
163 { |
|
164 return r; |
|
165 } |
|
166 |
|
167 __ASSERT_ALWAYS(aScreenRect.iTl.iX >= 0 && |
|
168 aScreenRect.iTl.iY >= 0 && |
|
169 aScreenRect.Width() <= screenWidth && |
|
170 aScreenRect.Height() <= screenHeight, Panic(EPanicOutOfBounds)); |
|
171 |
|
172 __ASSERT_ALWAYS(aScreenRect.Width() > 0 && |
|
173 aScreenRect.Height() > 0, Panic(EPanicInvalidRect)); |
|
174 |
|
175 iUpdateRect = aScreenRect; |
|
176 iSettingsFlags = aSettingsFlags; |
|
177 |
|
178 r = DoCreate(); |
|
179 if(r != KErrNone) |
|
180 { |
|
181 return r; |
|
182 } |
|
183 |
|
184 // Check that LHS is word-aligned |
|
185 const TUint pixelStartInBytes = aScreenRect.iTl.iX*iBytesPerPixel; |
|
186 const TUint pixelEndInBytes = aScreenRect.iBr.iX*iBytesPerPixel; |
|
187 |
|
188 // Check the alignment |
|
189 __ASSERT_ALWAYS(!(pixelStartInBytes & 0x03), Panic(EPanicNotWordAligned)); |
|
190 __ASSERT_ALWAYS(!(pixelEndInBytes & 0x03), Panic(EPanicNotWordAligned)); |
|
191 |
|
192 const TUint scanlineBytes = pixelEndInBytes-pixelStartInBytes; |
|
193 |
|
194 #ifndef __WINS__ |
|
195 iVideoAddress += pixelStartInBytes + // X Offset |
|
196 iUpdateRect.iTl.iY*iDisplayOffsetLines + // Y Offset |
|
197 iDisplayOffsetPixel; // Pixel (Palette) Offset |
|
198 #endif |
|
199 |
|
200 // Since this is a generic implementation, we only require one |
|
201 // buffer for both incremental and double buffered mode |
|
202 iBitmapInfo.iAddress = (TUint8*)User::Alloc(scanlineBytes * iUpdateRect.Height()); |
|
203 if(!iBitmapInfo.iAddress) |
|
204 return KErrNoMemory; |
|
205 |
|
206 iBitmapInfo.iSize = TSize(iUpdateRect.Width(), iUpdateRect.Height()); |
|
207 iBitmapInfo.iLinePitch = scanlineBytes; |
|
208 iBitmapInfo.iPhysicalAddress = 0; |
|
209 |
|
210 // All done |
|
211 iCreated = ETrue; |
|
212 |
|
213 return KErrNone; |
|
214 } |
|
215 |
|
216 #ifndef __WINS__ |
|
217 // |
|
218 // Attempt to initialise using the HAL |
|
219 // |
|
220 TInt CGenericDirectScreenBitmap::DoCreate() |
|
221 { |
|
222 // For GCE, if multiple modes are supported, only one needs to be returned. |
|
223 // On the emulator, what is returned via EDisplayMode can be set via ColorDepth setting in epoc.ini |
|
224 // On the hardware, 24/32bpp color mode is returned via EDisplayMode as pre-defined. |
|
225 TInt displayMode = 0; |
|
226 TInt r1 = HAL::Get(iScreenNo, HALData::EDisplayMode, displayMode); |
|
227 if (r1!=KErrNone) |
|
228 { |
|
229 return r1; |
|
230 } |
|
231 |
|
232 TInt bitsPerPixel = displayMode; |
|
233 |
|
234 r1 = HAL::Get(iScreenNo, HALData::EDisplayBitsPerPixel, bitsPerPixel); |
|
235 if (r1!=KErrNone) |
|
236 { |
|
237 return r1; |
|
238 } |
|
239 iBytesPerPixel = (bitsPerPixel+7) >> 3; |
|
240 |
|
241 // Store the important driver parameters to avoid HAL calls when drawing |
|
242 iDisplayOffsetPixel = displayMode; |
|
243 r1 = HAL::Get(iScreenNo, HALData::EDisplayOffsetToFirstPixel, iDisplayOffsetPixel); |
|
244 if (r1!=KErrNone) |
|
245 { |
|
246 return r1; |
|
247 } |
|
248 iDisplayOffsetLines = displayMode; |
|
249 r1 = HAL::Get(iScreenNo, HALData::EDisplayOffsetBetweenLines, iDisplayOffsetLines); |
|
250 if (r1!=KErrNone) |
|
251 { |
|
252 return r1; |
|
253 } |
|
254 |
|
255 TInt val = 0; |
|
256 r1 = HAL::Get(iScreenNo, HALData::EDisplayMemoryHandle,val); |
|
257 if (r1 == KErrNotSupported) |
|
258 { |
|
259 // EDisplayMemoryHandle is not supported, use the address instead |
|
260 r1 = HAL::Get(iScreenNo, HALData::EDisplayMemoryAddress, iVideoAddress); |
|
261 if (r1!=KErrNone) |
|
262 { |
|
263 return r1; |
|
264 } |
|
265 } |
|
266 else if (r1 == KErrNone) |
|
267 { |
|
268 // EDisplayMemoryHandle is supported, use the handle base address |
|
269 __ASSERT_ALWAYS(val != 0, Panic(EPanicHandleReturnedIncorrect)); |
|
270 RChunk chunk; |
|
271 r1 = chunk.SetReturnedHandle(val); |
|
272 if (r1 != KErrNone) |
|
273 { |
|
274 return r1; |
|
275 } |
|
276 iChunk = chunk; |
|
277 r1 = iChunk.Duplicate(RThread(), EOwnerProcess); |
|
278 chunk.Close(); |
|
279 if (r1 != KErrNone) |
|
280 { |
|
281 return r1; |
|
282 } |
|
283 iVideoAddress = (TInt)iChunk.Base(); |
|
284 iHasChunk = ETrue; |
|
285 } |
|
286 else |
|
287 { |
|
288 return r1; |
|
289 } |
|
290 |
|
291 // The HAL doesn't specify explicit dislpay modes, so we need |
|
292 // to calculate the mode using bitsPerPixel and isMono |
|
293 TBool isMono = displayMode; |
|
294 r1 = HAL::Get(iScreenNo, HALData::EDisplayIsMono, isMono); |
|
295 if (r1!=KErrNone) |
|
296 { |
|
297 return r1; |
|
298 } |
|
299 switch(bitsPerPixel) |
|
300 { |
|
301 // EGray2, EGray4, EGray16, EColor16 not supported on the hardware |
|
302 // The generic scdv support EGray2, EGray4, EGray16, EColor16 on the emulator |
|
303 // However, the low display modes should not be used. |
|
304 case 1: |
|
305 iBitmapInfo.iPixelShift = 0; |
|
306 iBitmapInfo.iDisplayMode = EGray2; |
|
307 iBytesPerPixel = 2; |
|
308 #ifdef SYMBIAN_GRAPHICS_GCE |
|
309 iPixelFormat = EUidPixelFormatUnknown; |
|
310 #endif |
|
311 break; |
|
312 case 2: |
|
313 iBitmapInfo.iPixelShift = 1; |
|
314 iBitmapInfo.iDisplayMode = EGray4; |
|
315 iBytesPerPixel = 2; |
|
316 #ifdef SYMBIAN_GRAPHICS_GCE |
|
317 iPixelFormat = EUidPixelFormatUnknown; |
|
318 #endif |
|
319 break; |
|
320 case 4: |
|
321 iBitmapInfo.iPixelShift = 2; |
|
322 iBitmapInfo.iDisplayMode = isMono ? EGray16 : EColor16; |
|
323 iBytesPerPixel = 2; |
|
324 #ifdef SYMBIAN_GRAPHICS_GCE |
|
325 iPixelFormat = EUidPixelFormatUnknown; |
|
326 #endif |
|
327 break; |
|
328 case 8: |
|
329 iBitmapInfo.iPixelShift = 3; |
|
330 iBitmapInfo.iDisplayMode = isMono ? EGray256 : EColor256; |
|
331 iBytesPerPixel = 2; |
|
332 #ifdef SYMBIAN_GRAPHICS_GCE |
|
333 iPixelFormat = EUidPixelFormatUnknown; |
|
334 #endif |
|
335 break; |
|
336 case 12: |
|
337 iBitmapInfo.iPixelShift = 4; |
|
338 iBitmapInfo.iDisplayMode = EColor4K; |
|
339 #ifdef SYMBIAN_GRAPHICS_GCE |
|
340 iPixelFormat = EUidPixelFormatXRGB_4444; |
|
341 #endif |
|
342 break; |
|
343 case 16: |
|
344 iBitmapInfo.iPixelShift = 4; |
|
345 iBitmapInfo.iDisplayMode = EColor64K; |
|
346 #ifdef SYMBIAN_GRAPHICS_GCE |
|
347 iPixelFormat = EUidPixelFormatRGB_565; |
|
348 #endif |
|
349 break; |
|
350 case 24: |
|
351 case 32: |
|
352 iBitmapInfo.iPixelShift = 5; |
|
353 iBitmapInfo.iDisplayMode = EColor16MAP; |
|
354 #ifdef SYMBIAN_GRAPHICS_GCE |
|
355 iPixelFormat = EUidPixelFormatARGB_8888_PRE; |
|
356 iBytesPerPixel = 4; |
|
357 #endif |
|
358 break; |
|
359 default: |
|
360 return KErrNotSupported; |
|
361 } |
|
362 |
|
363 #ifdef SYMBIAN_GRAPHICS_GCE |
|
364 TInt ret = iSurfaceUpdater.Construct(iScreenNo,iPixelFormat,displayMode); |
|
365 if (ret != KErrNone) |
|
366 { |
|
367 return ret; |
|
368 } |
|
369 #endif |
|
370 |
|
371 return KErrNone; |
|
372 } |
|
373 #endif |
|
374 |
|
375 #ifdef __WINS__ |
|
376 // |
|
377 // Attempt to initialise for WINS |
|
378 // This is intended for use if HAL initialisation fails. |
|
379 // |
|
380 TInt CGenericDirectScreenBitmap::DoCreate() |
|
381 { |
|
382 RWindows* window = ::WindowHandler(iScreenNo); |
|
383 if(window) |
|
384 { |
|
385 iBitmapInfo.iDisplayMode = window->iDisplayMode; |
|
386 iDisplayOffsetLines = window->iEpocBitmapLinePitch; |
|
387 iDisplayOffsetPixel = 0; |
|
388 |
|
389 switch(iBitmapInfo.iDisplayMode) |
|
390 { |
|
391 case EGray2: |
|
392 iBitmapInfo.iPixelShift = 0; |
|
393 iBytesPerPixel = 1; |
|
394 break; |
|
395 case EGray4: |
|
396 iBitmapInfo.iPixelShift = 1; |
|
397 iBytesPerPixel = 1; |
|
398 break; |
|
399 case EGray16: |
|
400 case EColor16: |
|
401 iBitmapInfo.iPixelShift = 2; |
|
402 iBytesPerPixel = 1; |
|
403 break; |
|
404 case EGray256: |
|
405 case EColor256: |
|
406 iBitmapInfo.iPixelShift = 3; |
|
407 iBytesPerPixel = 1; |
|
408 break; |
|
409 case EColor4K: |
|
410 case EColor64K: |
|
411 iBitmapInfo.iPixelShift = 4; |
|
412 iBytesPerPixel = 2; |
|
413 break; |
|
414 case EColor16M: |
|
415 iBitmapInfo.iPixelShift = 5; |
|
416 iBytesPerPixel = 3; |
|
417 break; |
|
418 case ERgb: |
|
419 case EColor16MU: |
|
420 case EColor16MA: |
|
421 case EColor16MAP: |
|
422 iBitmapInfo.iPixelShift = 5; |
|
423 iBytesPerPixel = 4; |
|
424 break; |
|
425 default: |
|
426 return KErrNotSupported; |
|
427 } |
|
428 |
|
429 return KErrNone; |
|
430 } |
|
431 else |
|
432 { |
|
433 return KErrNoMemory; |
|
434 } |
|
435 } |
|
436 #endif |
|
437 |
|
438 // |
|
439 // Begin update - aBitmapinfo returns the current bitmap |
|
440 // |
|
441 TInt CGenericDirectScreenBitmap::BeginUpdate(TAcceleratedBitmapInfo& aBitmapInfo) |
|
442 { |
|
443 __ASSERT_ALWAYS(iCreated, Panic(EPanicNotCreated)); |
|
444 aBitmapInfo = iBitmapInfo; |
|
445 return KErrNone; |
|
446 } |
|
447 |
|
448 |
|
449 #ifdef __WINS__ |
|
450 |
|
451 void CGenericDirectScreenBitmap::WinsUpdate(const TRect& aScreenRect) |
|
452 { |
|
453 const TUint dS = iBitmapInfo.iLinePitch; |
|
454 const TUint offY = aScreenRect.iTl.iY - iUpdateRect.iTl.iY; |
|
455 TUint8* pS = iBitmapInfo.iAddress + (offY*dS); |
|
456 RWindows* window = ::WindowHandler(iScreenNo); |
|
457 TInt orientation=window->Orientation(); |
|
458 TRect orientedRect; |
|
459 TSize orientedSize; |
|
460 |
|
461 orientedSize = window->GetOrientedSize(); |
|
462 orientedRect = window->GetOrientedRect(aScreenRect); |
|
463 |
|
464 TInt BrX = iUpdateRect.iBr.iX-1; |
|
465 TInt BrY = iUpdateRect.iBr.iY-1; |
|
466 |
|
467 for(TInt y=aScreenRect.iTl.iY; y < aScreenRect.iBr.iY; y++) |
|
468 { |
|
469 |
|
470 TRgb pixelColor; |
|
471 |
|
472 TInt xSource = aScreenRect.iTl.iX-iUpdateRect.iTl.iX; |
|
473 |
|
474 for(TInt x = aScreenRect.iTl.iX; x < aScreenRect.iBr.iX; x++) |
|
475 { |
|
476 TUint8* pD; |
|
477 |
|
478 switch(orientation) |
|
479 { |
|
480 case 0: |
|
481 pD = window->PixelAddress(x, y); |
|
482 break; |
|
483 case 1: |
|
484 pD = window->PixelAddress(y, BrX-x); |
|
485 break; |
|
486 case 2: |
|
487 pD = window->PixelAddress(BrX-x, BrY-y); |
|
488 break; |
|
489 case 3: |
|
490 pD = window->PixelAddress(BrY-y, x); |
|
491 break; |
|
492 default: |
|
493 break; |
|
494 } |
|
495 |
|
496 // Convert the user colour to RGB, as required by the WINS Emulator |
|
497 pixelColor = ExtractRgb(pS, xSource++); |
|
498 |
|
499 pD[0] = TUint8(pixelColor.Blue()); |
|
500 pD[1] = TUint8(pixelColor.Green()); |
|
501 pD[2] = TUint8(pixelColor.Red()); |
|
502 |
|
503 } |
|
504 pS += dS; |
|
505 } |
|
506 |
|
507 RRegion region; |
|
508 region.AddRect(orientedRect); |
|
509 window->Update(region,orientedSize); |
|
510 region.Close(); |
|
511 } |
|
512 |
|
513 #endif |
|
514 |
|
515 // |
|
516 // End Update - Commit changes to the Frame Buffer |
|
517 // |
|
518 void CGenericDirectScreenBitmap::EndUpdate(TRequestStatus& aComplete) |
|
519 { |
|
520 __ASSERT_ALWAYS(iCreated, Panic(EPanicNotCreated)); |
|
521 |
|
522 TUint8* pS = iBitmapInfo.iAddress; |
|
523 const TUint dS = iBitmapInfo.iLinePitch; |
|
524 |
|
525 #ifdef __WINS__ |
|
526 |
|
527 WinsUpdate(iUpdateRect); |
|
528 |
|
529 #else |
|
530 TUint8* pD = (TUint8*)iVideoAddress; |
|
531 const TUint dD = iDisplayOffsetLines; |
|
532 #ifdef SYMBIAN_GRAPHICS_GCE |
|
533 if (iDsaBufferIsBusy) |
|
534 { |
|
535 User::WaitForRequest(iDsaBufferAvailable); |
|
536 __ASSERT_DEBUG(iDsaBufferAvailable != KRequestPending, Panic(EPanicIncompleteRequest)); |
|
537 iDsaBufferIsBusy=EFalse; |
|
538 } |
|
539 #endif |
|
540 for(TInt y=iUpdateRect.Height(); y>0; y--) |
|
541 { |
|
542 Mem::Move((void *)pD, (void *)pS, dS); |
|
543 pS += dS; |
|
544 pD += dD; |
|
545 } |
|
546 #endif |
|
547 |
|
548 #ifdef SYMBIAN_GRAPHICS_GCE |
|
549 iDsaBufferIsBusy=ETrue; |
|
550 iSurfaceUpdater.UpdateRegion(iUpdateRect); |
|
551 iDsaBufferAvailable = KRequestPending; |
|
552 iSurfaceUpdater.NotifyWhenAvailable(iDsaBufferAvailable); |
|
553 iSurfaceUpdater.Update(); |
|
554 #endif |
|
555 // In the generic implementation, complete the request immediately to allow the client |
|
556 // to render to the back buffer |
|
557 TRequestStatus* pComplete=&aComplete; |
|
558 |
|
559 User::RequestComplete(pComplete,KErrNone); |
|
560 } |
|
561 |
|
562 // |
|
563 // End Update - Commit changes within the given area to the Frame Buffer |
|
564 // |
|
565 void CGenericDirectScreenBitmap::EndUpdate(const TRect& aScreenRect, TRequestStatus& aComplete) |
|
566 { |
|
567 __ASSERT_ALWAYS(iCreated, Panic(EPanicNotCreated)); |
|
568 |
|
569 __ASSERT_ALWAYS(aScreenRect.iTl.iX >= iUpdateRect.iTl.iX && |
|
570 aScreenRect.iTl.iY >= iUpdateRect.iTl.iY && |
|
571 aScreenRect.iBr.iX <= iUpdateRect.iBr.iX && |
|
572 aScreenRect.iBr.iY <= iUpdateRect.iBr.iY, Panic(EPanicOutOfBounds)); |
|
573 |
|
574 __ASSERT_ALWAYS(aScreenRect.Width() > 0 && |
|
575 aScreenRect.Height() > 0, Panic(EPanicInvalidRect)); |
|
576 |
|
577 // We can only use this functionality in Incremental Update mode |
|
578 __ASSERT_ALWAYS(iSettingsFlags == CDirectScreenBitmap::EIncrementalUpdate, Panic(EPanicInvalidMode)); |
|
579 |
|
580 const TUint offY = aScreenRect.iTl.iY - iUpdateRect.iTl.iY; |
|
581 |
|
582 const TUint dS = iBitmapInfo.iLinePitch; |
|
583 |
|
584 #ifdef __WINS__ |
|
585 |
|
586 WinsUpdate(aScreenRect); |
|
587 |
|
588 #else |
|
589 |
|
590 TInt xLeft = aScreenRect.iTl.iX*iBytesPerPixel; |
|
591 TInt xRight = aScreenRect.iBr.iX*iBytesPerPixel; |
|
592 |
|
593 // We have already tested the limits against iUpdateRect, which is |
|
594 // word aligned, so we are safe to perform a round up/down here |
|
595 // without fear of overrunning the buffer. |
|
596 |
|
597 xLeft &= ~0x03; |
|
598 xRight = (xRight+0x03)&~0x03; |
|
599 |
|
600 const TUint offX = xLeft - iUpdateRect.iTl.iX*iBytesPerPixel; |
|
601 |
|
602 const TUint bytesToCopy = xRight-xLeft; |
|
603 |
|
604 const TUint dD = iDisplayOffsetLines; |
|
605 |
|
606 TUint8* pS = iBitmapInfo.iAddress + offX + (offY*dS); |
|
607 TUint8* pD = (TUint8*)iVideoAddress + offX + (offY*dD); |
|
608 |
|
609 #ifdef SYMBIAN_GRAPHICS_GCE |
|
610 if (iDsaBufferIsBusy) |
|
611 { |
|
612 User::WaitForRequest(iDsaBufferAvailable); |
|
613 __ASSERT_DEBUG(iDsaBufferAvailable != KRequestPending, Panic(EPanicIncompleteRequest)); |
|
614 iDsaBufferIsBusy=EFalse; |
|
615 } |
|
616 #endif |
|
617 |
|
618 for(TInt y=aScreenRect.Height(); y>0; y--) |
|
619 { |
|
620 Mem::Move((void *)pD, (void *)pS, bytesToCopy); |
|
621 pS += dS; |
|
622 pD += dD; |
|
623 } |
|
624 #endif |
|
625 |
|
626 #ifdef SYMBIAN_GRAPHICS_GCE |
|
627 iDsaBufferIsBusy=ETrue; |
|
628 iSurfaceUpdater.UpdateRegion(iUpdateRect); |
|
629 iDsaBufferAvailable = KRequestPending; |
|
630 iSurfaceUpdater.NotifyWhenAvailable(iDsaBufferAvailable); |
|
631 iSurfaceUpdater.Update(); |
|
632 #endif |
|
633 // In the generic implementation, complete the request immediately. |
|
634 TRequestStatus* pComplete=&aComplete; |
|
635 |
|
636 User::RequestComplete(pComplete,KErrNone); |
|
637 } |
|
638 |
|
639 #ifdef __WINS__ |
|
640 // |
|
641 // Extracts the RGB value of the specidied pixel from the buffer |
|
642 // |
|
643 TRgb CGenericDirectScreenBitmap::ExtractRgb(TUint8* aBuffer,TInt aPixelOffset) const |
|
644 { |
|
645 switch (iBitmapInfo.iDisplayMode) |
|
646 { |
|
647 case EGray2: |
|
648 { |
|
649 TUint8 byte = *(aBuffer + (aPixelOffset >> 3)); |
|
650 if (byte & (1 << (aPixelOffset & 7))) |
|
651 return KRgbWhite; |
|
652 return KRgbBlack; |
|
653 } |
|
654 case EGray4: |
|
655 { |
|
656 TUint8 byte = *(aBuffer + (aPixelOffset >> 2)); |
|
657 byte >>= ((aPixelOffset & 3) << 1); |
|
658 return TRgb::_Gray4(byte & 3); |
|
659 } |
|
660 case EGray16: |
|
661 { |
|
662 TUint8 byte = *(aBuffer + (aPixelOffset >> 1)); |
|
663 if (aPixelOffset & 1) |
|
664 byte >>= 4; |
|
665 return TRgb::_Gray16(byte & 0xf); |
|
666 } |
|
667 case EGray256: |
|
668 return TRgb::_Gray256(*(aBuffer + aPixelOffset)); |
|
669 case EColor16: |
|
670 { |
|
671 TUint8 byte = *(aBuffer + (aPixelOffset >> 1)); |
|
672 if (aPixelOffset & 1) |
|
673 byte >>= 4; |
|
674 return TRgb::Color16(byte & 0xf); |
|
675 } |
|
676 case EColor256: |
|
677 return TRgb::Color256(*(aBuffer + aPixelOffset)); |
|
678 case EColor4K: |
|
679 { |
|
680 TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset); |
|
681 return TRgb::_Color4K(doubleByte & 0xfff); |
|
682 } |
|
683 case EColor64K: |
|
684 { |
|
685 TUint16 doubleByte = *(((TUint16*)aBuffer) + aPixelOffset); |
|
686 return TRgb::_Color64K(doubleByte); |
|
687 } |
|
688 case EColor16M: |
|
689 { |
|
690 aBuffer += aPixelOffset * 3; |
|
691 TInt value = *aBuffer++; |
|
692 value |= *aBuffer++ << 8; |
|
693 value |= *aBuffer << 16; |
|
694 return TRgb::_Color16M(value); |
|
695 } |
|
696 case ERgb: |
|
697 return *(((TRgb*)aBuffer) + aPixelOffset); |
|
698 case EColor16MU: |
|
699 { |
|
700 aBuffer += aPixelOffset * 4; |
|
701 TInt value = *aBuffer++; |
|
702 value |= *aBuffer++ << 8; |
|
703 value |= *aBuffer << 16; |
|
704 return TRgb::_Color16MU(value); |
|
705 } |
|
706 case EColor16MA: |
|
707 { |
|
708 aBuffer += aPixelOffset * 4; |
|
709 TInt value = *aBuffer++; |
|
710 value |= *aBuffer++ << 8; |
|
711 value |= *aBuffer++ << 16; |
|
712 value |= *aBuffer << 24; |
|
713 return TRgb::_Color16MA(value); |
|
714 } |
|
715 case EColor16MAP: |
|
716 { |
|
717 aBuffer += aPixelOffset * 4; |
|
718 TInt value = *aBuffer++; |
|
719 value |= *aBuffer++ << 8; |
|
720 value |= *aBuffer++ << 16; |
|
721 value |= *aBuffer << 24; |
|
722 return TRgb::_Color16MAP(value); |
|
723 } |
|
724 default: |
|
725 break; |
|
726 }; |
|
727 return KRgbBlack; |
|
728 } |
|
729 #endif |
|
730 |
|
731 // |
|
732 // Close - Deallocate resources and cancel outstanding updates |
|
733 // |
|
734 void CGenericDirectScreenBitmap::Close() |
|
735 { |
|
736 if(iCreated) |
|
737 { |
|
738 User::Free(iBitmapInfo.iAddress); |
|
739 iBitmapInfo.iAddress = NULL; |
|
740 iCreated = EFalse; |
|
741 } |
|
742 if (iHasChunk) |
|
743 { |
|
744 iChunk.Close(); |
|
745 } |
|
746 } |
|
747 |
|
748 // |
|
749 // Panic the user if a serious error occurs |
|
750 // |
|
751 void CGenericDirectScreenBitmap::Panic(TDsbPanic aPanic) |
|
752 { |
|
753 _LIT( KPanicString, "CGenericDirectScreenBitmap" ); |
|
754 User::Panic( KPanicString, aPanic ); |
|
755 } |
|
756 |
|
757 |