|
1 /* |
|
2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Handles serializing of data and sending it to alf streamer server. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // Maybe... |
|
21 // - EAlfCancelClippingRect is many times followed by EAlfSetClippingRect. Could the EAlfCancelClippingRect be ignored? |
|
22 // - EAlfSetBrushStyle (etc. other non drawing commands) are followed by AlfReset and no drawing is done. Could the Set |
|
23 // commands be ignored. |
|
24 // Can ignoring be done faster than executing useless commands? |
|
25 |
|
26 #include <barsread.h> |
|
27 #include <barsc.h> |
|
28 #include <e32std.h> |
|
29 #include <alfstreamerconsts.h> |
|
30 #include <huiwscanvascommands.h> |
|
31 #include <uiacceltk/HuiUtil.h> |
|
32 |
|
33 #include <alfdecoderserverclient.h> |
|
34 #include <alflogger.h> |
|
35 #include "alf/alfcompositionclient.h" |
|
36 #include "alfrssendbuffer.h" |
|
37 #include "alfrenderstage.h" |
|
38 #include "alfcommanddebug.h" |
|
39 #include <alfnonsupportedwscommands.rsg> |
|
40 |
|
41 #include <data_caging_path_literals.hrh> |
|
42 |
|
43 _LIT( KRendererSupportedCommands,"alfnonsupportedwscommands.rsc" ); |
|
44 |
|
45 const TInt KFrameHeaderSizeWhenCacheChunks = 500; |
|
46 const TInt KFrameHeaderSize = 5000; |
|
47 const TInt KFrameOffsetTemplate = 12345678; |
|
48 const TInt KCacheChunkMinSize = 50000; |
|
49 const TUint8 KDivisibleByX = 8; |
|
50 const TInt KWindowFrameHeader1 = 6; // bytes |
|
51 const TInt KWindowFrameHeader2 = 18 + 10; // bytes // TP +10 |
|
52 |
|
53 const TInt KAllRenderersMask = 63; |
|
54 const TInt KPossiblePerformanceProblemInWindow = 64; |
|
55 const TInt KPossiblePerformanceProblemInWindowThreshold = 1000; |
|
56 |
|
57 |
|
58 enum TPatternSearchStates |
|
59 { |
|
60 ESeekSetClippingRegion = 0, |
|
61 ESeekBitBlit = 1, |
|
62 ESeekResetClipping = 2, |
|
63 ESeekBrushStyle1 = 3, |
|
64 ESeekBrushStyle2 = 4 |
|
65 }; |
|
66 |
|
67 |
|
68 #ifdef _OPTIMIZE_WS_COMMANDS_ADVANCED_ |
|
69 const TInt TSearchPatternBitBlit[2][3] = { |
|
70 // Search command // state // alternative command in this state |
|
71 { EAlfSetClippingRegion, ESeekSetClippingRegion, KErrNotFound }, |
|
72 { EAlfBitBltMasked, ESeekBitBlit, EAlfBitBltRect }}; |
|
73 #else |
|
74 const TInt TSearchPatternBitBlit[5][3] = { |
|
75 // Search command // state // alternative command in this state |
|
76 { EAlfSetClippingRegion, ESeekSetClippingRegion, KErrNotFound }, |
|
77 { EAlfBitBltMasked, ESeekBitBlit, EAlfBitBltRect }, |
|
78 { EAlfResetClippingRegion, ESeekResetClipping, KErrNotFound }, |
|
79 { EAlfSetBrushStyle, ESeekBrushStyle1, KErrNotFound }, |
|
80 { EAlfSetBrushStyle, ESeekBrushStyle2, EAlfSetPenStyle} }; |
|
81 #endif |
|
82 |
|
83 |
|
84 // --------------------------------------------------------------------------- |
|
85 // class CAlfObserver |
|
86 // --------------------------------------------------------------------------- |
|
87 // |
|
88 |
|
89 NONSHARABLE_CLASS(CAlfObserver):public CActive |
|
90 { |
|
91 public: |
|
92 |
|
93 // --------------------------------------------------------------------------- |
|
94 // SetL |
|
95 // --------------------------------------------------------------------------- |
|
96 // |
|
97 static void SetL(CAlfRsSendBuffer* aHost, TBool aStartServer ) |
|
98 { |
|
99 CAlfObserver* me = new (ELeave) CAlfObserver(aHost, aStartServer); |
|
100 me->SetActive(); |
|
101 // breahe one cycle to allow wserv kick its server object alive |
|
102 TRequestStatus* status = &me->iStatus; |
|
103 User::RequestComplete(status, KErrNone); |
|
104 } |
|
105 |
|
106 // --------------------------------------------------------------------------- |
|
107 // NewL |
|
108 // --------------------------------------------------------------------------- |
|
109 // |
|
110 CAlfObserver(CAlfRsSendBuffer* aHost, TBool aStartServer):CActive(2*EPriorityHigh), |
|
111 iHost(aHost), iStartServer(aStartServer), iBreathe(ETrue) |
|
112 { |
|
113 CActiveScheduler::Add(this); |
|
114 iTimer.CreateLocal(); |
|
115 } |
|
116 |
|
117 // --------------------------------------------------------------------------- |
|
118 // RunL |
|
119 // --------------------------------------------------------------------------- |
|
120 // |
|
121 void RunL() |
|
122 { |
|
123 if (iBreathe && iStartServer) |
|
124 { |
|
125 iBreathe = EFalse; |
|
126 SetActive(); |
|
127 TRAPD(err, AlfServerStarter::StartL(iStatus, EFalse)); |
|
128 if (err) |
|
129 { |
|
130 // Important, and thus enabled even in release builds. Other option would be letting leave to fall through |
|
131 // render stage stack and let window server panic the boot |
|
132 RDebug::Print(_L("********* Error occurred when starting alf: %d"),err); |
|
133 } |
|
134 else |
|
135 { |
|
136 return; |
|
137 } |
|
138 } |
|
139 else |
|
140 { |
|
141 if( !iHost->ConnectL() ) // if connecting fails, try again a bit later |
|
142 { |
|
143 SetActive(); |
|
144 if( iStartServer ) |
|
145 { |
|
146 iTimer.After( iStatus, 250000); // primary display is more important |
|
147 } |
|
148 else |
|
149 { |
|
150 iTimer.After( iStatus, 1000000); |
|
151 } |
|
152 } |
|
153 else |
|
154 { |
|
155 __ALFLOGSTRING("********************FLUSHING WSERV"); |
|
156 TRAP_IGNORE(iHost->PrepareBufferL()); |
|
157 TRAP_IGNORE(iHost->SendL( NULL )); |
|
158 iTimer.Close(); |
|
159 delete this; |
|
160 } |
|
161 } |
|
162 } |
|
163 |
|
164 // --------------------------------------------------------------------------- |
|
165 // DoCancel |
|
166 // --------------------------------------------------------------------------- |
|
167 // |
|
168 void DoCancel() |
|
169 { |
|
170 // not applicable atm |
|
171 } |
|
172 |
|
173 private: // Data |
|
174 |
|
175 CAlfRsSendBuffer* iHost; |
|
176 TBool iStartServer; |
|
177 TBool iBreathe; |
|
178 RTimer iTimer; |
|
179 }; |
|
180 |
|
181 // --------------------------------------------------------------------------- |
|
182 // doFlushBuffer |
|
183 // Local function |
|
184 // --------------------------------------------------------------------------- |
|
185 // |
|
186 TInt doFlushBuffer( TAny* aPtr ) |
|
187 { |
|
188 ((CAlfRsSendBuffer*)aPtr)->FlushBuffer(); |
|
189 return 0; // must return something |
|
190 } |
|
191 |
|
192 |
|
193 // --------------------------------------------------------------------------- |
|
194 // NewL |
|
195 // --------------------------------------------------------------------------- |
|
196 // |
|
197 CAlfRsSendBuffer* CAlfRsSendBuffer::NewL(CAlfRenderStage& aParent, TInt aScreenNumber ) |
|
198 { |
|
199 CAlfRsSendBuffer* self = new(ELeave) CAlfRsSendBuffer( aParent, aScreenNumber ); |
|
200 CleanupStack::PushL(self); |
|
201 self->ConstructL(); |
|
202 CleanupStack::Pop(self); |
|
203 return self; |
|
204 } |
|
205 |
|
206 // --------------------------------------------------------------------------- |
|
207 // Destructor |
|
208 // --------------------------------------------------------------------------- |
|
209 // |
|
210 CAlfRsSendBuffer::~CAlfRsSendBuffer() |
|
211 { |
|
212 if ( iAlfBridgerClient ) |
|
213 { |
|
214 iAlfBridgerClient->Close(); |
|
215 delete iAlfBridgerClient; |
|
216 iAlfBridgerClient = NULL; |
|
217 delete iAlfCompositionCntrlClient; |
|
218 } |
|
219 #ifdef _OLD_STREAM |
|
220 if ( iBufStream ) |
|
221 { |
|
222 iBufStream->Close(); |
|
223 delete iBufStream; |
|
224 iBufStream = NULL; |
|
225 } |
|
226 #endif |
|
227 iChunk.Close(); |
|
228 } |
|
229 |
|
230 // --------------------------------------------------------------------------- |
|
231 // ConstructL |
|
232 // --------------------------------------------------------------------------- |
|
233 // |
|
234 void CAlfRsSendBuffer::ConstructL() |
|
235 { |
|
236 // If this is not the primary screen (0) do not send any commands to Alf server |
|
237 iDisabled = (iScreenNumber != 0); |
|
238 |
|
239 ReadNonSupportedCommandsL(); |
|
240 iChunkInUse = 0; |
|
241 iBooting = ETrue; |
|
242 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
243 iLog = 0; |
|
244 iCommandDebugger = CAlfCommandDebug::NewL(); |
|
245 #endif |
|
246 |
|
247 TBool runInsideWserv = ETrue; // EFalse; |
|
248 if( runInsideWserv ) |
|
249 { |
|
250 TBool startServer = ETrue; |
|
251 if (iScreenNumber != 0) // we need one instance only |
|
252 { |
|
253 startServer = EFalse; |
|
254 } |
|
255 CAlfObserver::SetL(this, startServer); |
|
256 } |
|
257 else |
|
258 { |
|
259 CAlfObserver::SetL(this, EFalse); |
|
260 } |
|
261 |
|
262 MAlfCompositionController* compcntrl = (MAlfCompositionController*)iParent.ResolveObjectInterface(KAlfCompositionControllerIfUid); |
|
263 if (compcntrl) |
|
264 { |
|
265 compcntrl->AlfBridgeCallback(MAlfBridge::EAlfBridgeCreated, (MAlfBridge*)this); |
|
266 } |
|
267 } |
|
268 |
|
269 // --------------------------------------------------------------------------- |
|
270 // ReadNonSupportedCommandsL |
|
271 // --------------------------------------------------------------------------- |
|
272 // |
|
273 void CAlfRsSendBuffer::ReadNonSupportedCommandsL() |
|
274 { |
|
275 RFs fs; |
|
276 User::LeaveIfError(fs.Connect()); |
|
277 CleanupClosePushL(fs); |
|
278 RResourceFile resFile; |
|
279 TInt result; |
|
280 // resolve the absolute path |
|
281 // Read unsupported command resource |
|
282 TFileName resourceFileName; |
|
283 TPtrC driveLetter = TParsePtrC( RProcess().FileName() ).Drive(); |
|
284 resourceFileName.Copy( driveLetter ); |
|
285 resourceFileName.Append( KDC_ECOM_RESOURCE_DIR ); |
|
286 resourceFileName.Append( KRendererSupportedCommands ); |
|
287 |
|
288 TRAP( result, resFile.OpenL(fs,resourceFileName); ); |
|
289 if ( result == KErrNone ) |
|
290 { |
|
291 CleanupClosePushL(resFile); |
|
292 resFile.ConfirmSignatureL(0); // offset value. |
|
293 |
|
294 TInt resId = R_ALF_NON_SUPPORTED_COMMANDS_ARRAY; |
|
295 |
|
296 HBufC8* readData = resFile.AllocReadL(resId); |
|
297 // now first get rid of RResourceFile and RFs as they are not needed any more |
|
298 CleanupStack::PopAndDestroy(); // resFile |
|
299 CleanupStack::PopAndDestroy(); // fs |
|
300 CleanupStack::PushL(readData); |
|
301 |
|
302 // now parse it and store the values in cmdTextArray |
|
303 TResourceReader reader; |
|
304 reader.SetBuffer(readData); |
|
305 const TInt count = reader.ReadInt16(); |
|
306 TInt8 command; |
|
307 |
|
308 TInt8 value; |
|
309 TInt nonSupportedParameterCount = 0; |
|
310 // resource file contains only non supported commands by renderers. Patch them to the iSupportedCommands |
|
311 TInt supportedParameterIndex = 0; |
|
312 for ( TInt i = 0; i < count ; i++ ) |
|
313 { |
|
314 command = reader.ReadInt8(); |
|
315 value = ConvertToBitsL( 7, &reader ); |
|
316 |
|
317 nonSupportedParameterCount = reader.ReadInt16(); |
|
318 if ( nonSupportedParameterCount > 0 ) |
|
319 { |
|
320 iSupportedCommandParameters[command][0] = supportedParameterIndex; |
|
321 for ( TInt l = 0 ; l < nonSupportedParameterCount ; l ++ ) |
|
322 { |
|
323 TInt8 parameterValue = reader.ReadInt8(); |
|
324 iSupportedParameters[supportedParameterIndex][0] = parameterValue; |
|
325 TInt8 value2 = ConvertToBitsL( 6, &reader ); |
|
326 iSupportedParameters[supportedParameterIndex][1] = value2; |
|
327 supportedParameterIndex++; |
|
328 } |
|
329 iSupportedCommandParameters[command][1] = supportedParameterIndex; |
|
330 } |
|
331 iNonSupportedCommands[command] = value; |
|
332 } |
|
333 CleanupStack::PopAndDestroy(readData); |
|
334 } |
|
335 else |
|
336 { |
|
337 __ALFLOGSTRING1("CAlfRsSendBuffer::ConstructL - WARNING! Failed to read unsupported commands from resource file: %S! Error code:st %d.", &resourceFileName ); |
|
338 CleanupStack::PopAndDestroy(); // fs |
|
339 } |
|
340 } |
|
341 |
|
342 // --------------------------------------------------------------------------- |
|
343 // ConvertToBitsL |
|
344 // --------------------------------------------------------------------------- |
|
345 // |
|
346 TUint8 CAlfRsSendBuffer::ConvertToBitsL( TInt aCount, TResourceReader* aReader ) |
|
347 { |
|
348 #ifdef _DEBUG |
|
349 if ( aCount > 7 ) |
|
350 { |
|
351 __ALFLOGSTRING("CAlfRsSendBuffer::ConvertToBitsL - Can convert only 7 sequantial bytes to one byte"); |
|
352 USER_INVARIANT(); // |
|
353 } |
|
354 #endif |
|
355 TInt8 value = 0; |
|
356 TInt8 notSupported[7]; |
|
357 aReader->Read( notSupported, aCount ); |
|
358 TUint8 mask = 1; |
|
359 for (TInt j = 0; j < aCount ; j ++) |
|
360 { |
|
361 if ( notSupported[j] ){ value |= mask ; } |
|
362 mask = mask << 1; |
|
363 } |
|
364 return value; |
|
365 } |
|
366 |
|
367 // --------------------------------------------------------------------------- |
|
368 // RunL |
|
369 // --------------------------------------------------------------------------- |
|
370 // |
|
371 void CAlfRsSendBuffer::RunL() |
|
372 { |
|
373 switch( iState ) |
|
374 { |
|
375 case EWaitingAck: |
|
376 { |
|
377 if ( iStatus == EAlfBridgerAsyncronousData || iStatus < 0 ) |
|
378 { |
|
379 TInt chunkIndex = 0; |
|
380 // The following is written to the last created chunk. |
|
381 TInt cacheChunkCount = iCacheChunks.Count(); |
|
382 |
|
383 if ( cacheChunkCount > 0 ) |
|
384 { |
|
385 // request destruction of all temporary chunks |
|
386 while ( chunkIndex < cacheChunkCount ) |
|
387 { |
|
388 WriteInt8L( EAlfDestroyChunk ); |
|
389 WriteInt8L( 0 ); // screen number, not used. |
|
390 WriteInt32L( iCacheChunks[chunkIndex].Handle() ); |
|
391 WriteInt8L( EAlfCommandEndMarker ); |
|
392 |
|
393 chunkIndex++; |
|
394 } |
|
395 if ( !iBooting ) |
|
396 { |
|
397 // This is not necessary in the first boot, because jump |
|
398 // request has been already created in PrepareBufferL |
|
399 |
|
400 JumpToAnotherChunkL( 0, iPrimaryChunkMaxSize ); |
|
401 OpenPrimaryChunkForWritingL(); |
|
402 SeekL(0); // rewind stream to the beginning |
|
403 WriteInt8L( EAlfCommandEndMarker ); |
|
404 CommitL(); |
|
405 FlushBuffer(); |
|
406 } |
|
407 // destroy renderstage side handles to the chunk. alfhierarchy |
|
408 // has still open handles for a while. |
|
409 while( iCacheChunks.Count() ) |
|
410 { |
|
411 iCacheChunks[ 0 ].Close(); |
|
412 iCacheChunks.Remove( 0 ); |
|
413 } |
|
414 } |
|
415 iUsedChunkMaxSize = iPrimaryChunkMaxSize - sizeof( TChunkHeader); |
|
416 iChunkInUse = 0; |
|
417 iBooting = EFalse; // alf has acknowledged the first frame |
|
418 iParent.EndCallBack( iQuedStatus ); |
|
419 iState = EIdle; |
|
420 } |
|
421 break; |
|
422 } |
|
423 case EWaitingHandle: |
|
424 { |
|
425 break; |
|
426 } |
|
427 case EIdle: |
|
428 { |
|
429 break; |
|
430 } |
|
431 default:; |
|
432 } |
|
433 } |
|
434 |
|
435 // --------------------------------------------------------------------------- |
|
436 // DoCancel |
|
437 // --------------------------------------------------------------------------- |
|
438 // |
|
439 void CAlfRsSendBuffer::DoCancel() |
|
440 { |
|
441 // TODO |
|
442 } |
|
443 |
|
444 // --------------------------------------------------------------------------- |
|
445 // WriteFlagsL |
|
446 // --------------------------------------------------------------------------- |
|
447 // |
|
448 void CAlfRsSendBuffer::WriteFlagsL( ) |
|
449 { |
|
450 if (iDisabled) // return if this send buffer is not in use |
|
451 { |
|
452 return; |
|
453 } |
|
454 |
|
455 // space has been reserved for us |
|
456 WriteInt8L( EAlfFrameFlags ); |
|
457 WriteInt32L( iFlags); |
|
458 WriteInt8L( EAlfCommandEndMarker ); |
|
459 } |
|
460 |
|
461 // --------------------------------------------------------------------------- |
|
462 // WriteCommandL |
|
463 // writes 1 TInt value to the stream |
|
464 // --------------------------------------------------------------------------- |
|
465 // |
|
466 void CAlfRsSendBuffer::WriteCommandL( const TUint8& aCommand, TInt aSize ) |
|
467 { |
|
468 if (iDisabled) // return if this send buffer is not in use |
|
469 { |
|
470 return; |
|
471 } |
|
472 |
|
473 if ( |
|
474 #ifdef _OLD_STREAM |
|
475 iBufStream->Sink() && |
|
476 #endif |
|
477 aCommand == EAlfPacketReady ) |
|
478 { |
|
479 iReceivingDrawingCommands = EFalse; |
|
480 // if offscreen content has not been flushed, we'll keep the frame in not completed state. |
|
481 // it will be delivered to CHuiCanvasVisual, but not processed until finished packet arrives. |
|
482 // make sure, that frame flags (iFlags) follow this command. |
|
483 } |
|
484 |
|
485 if (! InitCommandL( aCommand, aSize)){ return;} |
|
486 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
487 if ( !iReceivingDrawingCommands ) |
|
488 { |
|
489 aSize += sizeof(TUint8); |
|
490 } |
|
491 iCommandDebugger->SetDescriptionAndSize( aCommand, aSize, R_ALF_COMMAND_DESCRIPTION_ARRAY ); |
|
492 iCommandDebugger->Print(); |
|
493 #endif |
|
494 if ( !iReceivingDrawingCommands ) |
|
495 { |
|
496 WriteInt8L( EAlfCommandEndMarker ); |
|
497 } |
|
498 if ( aCommand == EAlfPacketReady ) |
|
499 { |
|
500 iReceivingDrawingCommands = EFalse; |
|
501 iWrappingFrame = EFalse; |
|
502 |
|
503 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
504 iCommandDebugger->PrintStatistic(); |
|
505 iCommandDebugger->EndFrame(); |
|
506 #endif |
|
507 |
|
508 } |
|
509 } |
|
510 |
|
511 // --------------------------------------------------------------------------- |
|
512 // WriteIntsL |
|
513 // writes aCount amount of variables to the stream and updates stream index. |
|
514 // --------------------------------------------------------------------------- |
|
515 // |
|
516 // @todo Reference to Tint parameter was removed, because it did not pass armv5 compiler |
|
517 |
|
518 void CAlfRsSendBuffer::WriteIntsL( const TUint8& aCommand, TInt aCount, TRefByValue<const TInt> aFirst,... ) |
|
519 { |
|
520 if (iDisabled) // return if this send buffer is not in use |
|
521 { |
|
522 return; |
|
523 } |
|
524 |
|
525 const TInt size = sizeof(TInt32) * aCount; |
|
526 if (! InitCommandL( aCommand, size )){ return;} |
|
527 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
528 iCommandDebugger->SetDescriptionAndSize( aCommand, size, R_ALF_COMMAND_DESCRIPTION_ARRAY ); |
|
529 iCommandDebugger->Print(); |
|
530 #endif |
|
531 |
|
532 if ( aCount > 0 ) |
|
533 { |
|
534 aCount--; // first item is serialized separately. It seems to exist at different location as rest of the parameters. |
|
535 WriteInt32L( aFirst ); |
|
536 WriteL( (TUint8*)&aFirst + sizeof(TInt32), aCount * sizeof(TInt32) ); |
|
537 //TInt size = sizeof(TInt32) * aCount; |
|
538 //iBufStream->WriteL( (TUint8*)&aFirst + sizeof(TInt32), size ); iOffset += size ; |
|
539 } |
|
540 if ( !iReceivingDrawingCommands ) |
|
541 { |
|
542 WriteInt8L( EAlfCommandEndMarker ); |
|
543 } |
|
544 } |
|
545 |
|
546 void CAlfRsSendBuffer::WriteIntsL(TUint8 aCommand, TInt aCount, TInt* aArray) |
|
547 { |
|
548 if (iDisabled) // return if this send buffer is not in use |
|
549 { |
|
550 return; |
|
551 } |
|
552 |
|
553 const TInt size = sizeof(TInt32) * aCount; |
|
554 if (!InitCommandL( aCommand, size )) |
|
555 { |
|
556 return; |
|
557 } |
|
558 |
|
559 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
560 iCommandDebugger->SetDescriptionAndSize( aCommand, size, R_ALF_COMMAND_DESCRIPTION_ARRAY ); |
|
561 iCommandDebugger->Print(); |
|
562 #endif |
|
563 |
|
564 for(TInt i = 0; i < aCount; i++) |
|
565 { |
|
566 WriteInt32L( aArray[i] ); |
|
567 } |
|
568 |
|
569 if ( !iReceivingDrawingCommands ) |
|
570 { |
|
571 WriteInt8L( EAlfCommandEndMarker ); |
|
572 } |
|
573 } |
|
574 |
|
575 // --------------------------------------------------------------------------- |
|
576 // WriteIntL |
|
577 // All possibly non-supported commands that have a parameter are using this version |
|
578 // of WriteIntL |
|
579 // --------------------------------------------------------------------------- |
|
580 // |
|
581 void CAlfRsSendBuffer::WriteIntL( const TUint8& aCommand, TInt aValue ) |
|
582 { |
|
583 if (iDisabled) // return if this send buffer is not in use |
|
584 { |
|
585 return; |
|
586 } |
|
587 |
|
588 TBool supported = EFalse; |
|
589 if (iNonSupportedCommands[aCommand]) |
|
590 { |
|
591 for( TInt i = iSupportedCommandParameters[aCommand][0]; i < iSupportedCommandParameters[aCommand][1]; i++ ) |
|
592 { |
|
593 if ( !supported && aValue == iSupportedParameters[i][0]) |
|
594 { |
|
595 supported = ETrue; |
|
596 iNonSupportedCommands[aCommand] = iSupportedParameters[i][1]; |
|
597 } |
|
598 } |
|
599 } |
|
600 else |
|
601 { |
|
602 supported = ETrue; |
|
603 } |
|
604 |
|
605 if ( !supported ) |
|
606 { |
|
607 iNonSupportedCommands[aCommand] = KAllRenderersMask; |
|
608 } |
|
609 if (! InitCommandL( aCommand, sizeof(TInt32) )){ return;} |
|
610 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
611 iCommandDebugger->SetDescriptionAndSize( aCommand, sizeof(TInt32), R_ALF_COMMAND_DESCRIPTION_ARRAY ); |
|
612 iCommandDebugger->Print(); |
|
613 #endif |
|
614 // only commands, that may not be supported use this function |
|
615 if ( aCommand == EAlfSetPenStyle ) |
|
616 { |
|
617 iPenStyle = aValue; // for patter search |
|
618 } |
|
619 WriteInt32L( aValue); |
|
620 if ( !iReceivingDrawingCommands ) |
|
621 { |
|
622 WriteInt8L( EAlfCommandEndMarker ); |
|
623 } |
|
624 } |
|
625 |
|
626 // --------------------------------------------------------------------------- |
|
627 // WriteRegionL |
|
628 // writes aCount amount of variables to the stream and updates stream index. |
|
629 // --------------------------------------------------------------------------- |
|
630 // |
|
631 // @todo Reference to Tint parameter was removed, because it did not pass armv5 compiler |
|
632 |
|
633 void CAlfRsSendBuffer::WriteRegionL( const TUint8& aCommand, const TRegion& aRegion ) |
|
634 { |
|
635 if (iDisabled) // return if this send buffer is not in use |
|
636 { |
|
637 return; |
|
638 } |
|
639 |
|
640 TInt count = aRegion.Count(); |
|
641 const TInt size = sizeof(TInt32) * ( 4 * count + 1); |
|
642 |
|
643 if (! InitCommandL( aCommand, size )){ return;} |
|
644 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
645 iCommandDebugger->SetDescriptionAndSize( aCommand, size, R_ALF_COMMAND_DESCRIPTION_ARRAY ); |
|
646 iCommandDebugger->SetRegion( aRegion ); |
|
647 iCommandDebugger->Print(); |
|
648 #endif |
|
649 WriteInt32L( count ); |
|
650 TInt i = 0; |
|
651 while( i < count ) |
|
652 { |
|
653 WriteL( (TUint8*)&aRegion[i].iTl.iX, 4 * sizeof(TInt32 )); |
|
654 if ( aCommand == EAlfSetClippingRegion ) |
|
655 { |
|
656 iSearchPatternClipRegion.AddRect(aRegion[i]); |
|
657 } |
|
658 i++; |
|
659 } |
|
660 |
|
661 if ( !iReceivingDrawingCommands ) |
|
662 { |
|
663 WriteInt8L( EAlfCommandEndMarker ); |
|
664 } |
|
665 |
|
666 } |
|
667 |
|
668 // --------------------------------------------------------------------------- |
|
669 // WriteDescriptorAndIntsL |
|
670 // writes aCount amount of variables to the stream and updates stream index. |
|
671 // --------------------------------------------------------------------------- |
|
672 // |
|
673 void CAlfRsSendBuffer::WriteDescriptorAndIntsL( |
|
674 const TUint8& aCommand, |
|
675 const TDesC& aText, |
|
676 const CGraphicsContext::TTextParameters* aTextParameter, |
|
677 TInt aCount, |
|
678 TRefByValue<const TInt> aFirst,... ) |
|
679 { |
|
680 if (iDisabled) // return if this send buffer is not in use |
|
681 { |
|
682 return; |
|
683 } |
|
684 |
|
685 if ( aText.Length() == 0 ) |
|
686 { |
|
687 return; |
|
688 } |
|
689 |
|
690 TBool useCachedText( EFalse ); |
|
691 if ( iCachedText |
|
692 && iCachedText->Length() == aText.Length() |
|
693 && iCachedText->Compare( aText ) == 0 ) |
|
694 { |
|
695 useCachedText = ETrue; |
|
696 } |
|
697 else |
|
698 { |
|
699 delete iCachedText; |
|
700 iCachedText = aText.AllocL(); |
|
701 } |
|
702 // calculate size for the command |
|
703 TInt size = sizeof(TInt32) * ( 2 + aCount ) + // ints |
|
704 + 2 * sizeof(TInt8); // existances of: text and TextParameters |
|
705 |
|
706 if ( !useCachedText ) |
|
707 { |
|
708 size += aText.Size() + sizeof(TInt32); // text + its length |
|
709 } |
|
710 |
|
711 if ( aTextParameter ) |
|
712 { |
|
713 size += ( 2 * sizeof(TInt32) )+ sizeof(TUint16); |
|
714 } |
|
715 |
|
716 if (! InitCommandL( aCommand, size )){ return;} |
|
717 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
718 iCommandDebugger->SetDescriptionAndSize( aCommand, size, R_ALF_COMMAND_DESCRIPTION_ARRAY ); |
|
719 iCommandDebugger->Print(); |
|
720 #endif |
|
721 WriteInt8L( useCachedText ); |
|
722 if ( !useCachedText ) |
|
723 { |
|
724 WriteInt32L( aText.Size() ); |
|
725 |
|
726 TInt offset = iOffset + 2 * sizeof(TUint8); |
|
727 TInt startPadding = offset % KDivisibleByX; |
|
728 startPadding = startPadding == 0 ? 0 : KDivisibleByX - startPadding; |
|
729 WriteInt8L( startPadding ); |
|
730 |
|
731 TInt endPadding = (offset + startPadding + aText.Size() ) % KDivisibleByX; |
|
732 endPadding = endPadding == 0 ? 0 : KDivisibleByX - endPadding; |
|
733 WriteInt8L( endPadding ); |
|
734 TUint8 padding[KDivisibleByX]; |
|
735 WriteL( (TUint8*)padding, startPadding ); |
|
736 WriteL( (TUint8*)aText.Ptr(), aText.Size() ); |
|
737 WriteL( (TUint8*)padding, endPadding ); |
|
738 // aTextParameter can be null. |
|
739 } |
|
740 if ( aTextParameter ) |
|
741 { |
|
742 // TODO: Remove commented code, when this is tested. |
|
743 if ( aTextParameter->iStart == 0 |
|
744 && aTextParameter->iEnd == aText.Length() |
|
745 && aTextParameter->iFlags == 0 ) |
|
746 { |
|
747 // actually, this never comes so far... |
|
748 WriteInt8L( 2 ); // Use the default values |
|
749 } |
|
750 else |
|
751 { |
|
752 WriteInt8L( 1 ); |
|
753 TInt size = 2 * sizeof (TInt) + sizeof (TUint16) ; |
|
754 WriteL( (TUint8*)&aTextParameter->iStart, size); |
|
755 } |
|
756 } |
|
757 else |
|
758 { |
|
759 WriteInt8L( 0 ); |
|
760 } |
|
761 if ( aCount > 0 ) |
|
762 { |
|
763 aCount--; |
|
764 WriteInt32L( aFirst ); |
|
765 TInt size = aCount * sizeof(TInt32); |
|
766 WriteL( (TUint8*)&aFirst + sizeof(TInt32), size ); |
|
767 } |
|
768 if ( !iReceivingDrawingCommands ) |
|
769 { |
|
770 WriteInt8L( EAlfCommandEndMarker ); |
|
771 } |
|
772 } |
|
773 |
|
774 // --------------------------------------------------------------------------- |
|
775 // WritePointArrayL |
|
776 // --------------------------------------------------------------------------- |
|
777 // |
|
778 void CAlfRsSendBuffer::WritePointArrayL( const TUint8& aCommand, const CArrayFix<TPoint>* aPoWriteIntList ) |
|
779 { |
|
780 if (iDisabled) // return if this send buffer is not in use |
|
781 { |
|
782 return; |
|
783 } |
|
784 |
|
785 TInt count = aPoWriteIntList->Count(); |
|
786 const TInt size = sizeof(TInt32) * (2 * count + 1); |
|
787 |
|
788 if (! InitCommandL( aCommand, size )){ return;} |
|
789 |
|
790 TInt index(0); |
|
791 WriteInt32L( count ); |
|
792 while( index < count ) |
|
793 { |
|
794 WriteInt32L( aPoWriteIntList->At(index).iX ); |
|
795 WriteInt32L( aPoWriteIntList->At(index).iY ); |
|
796 index++; |
|
797 } |
|
798 if ( !iReceivingDrawingCommands ) |
|
799 { |
|
800 WriteInt8L( EAlfCommandEndMarker ); |
|
801 } |
|
802 } |
|
803 |
|
804 // --------------------------------------------------------------------------- |
|
805 // WritePointArrayL |
|
806 // --------------------------------------------------------------------------- |
|
807 // |
|
808 void CAlfRsSendBuffer::WritePointArrayL( const TUint8& aCommand, const TPoint* aPoWriteIntList, TInt aNumPoints ) |
|
809 { |
|
810 if (iDisabled) // return if this send buffer is not in use |
|
811 { |
|
812 return; |
|
813 } |
|
814 |
|
815 const TInt size = sizeof(TInt32) * (2 * aNumPoints + 1); |
|
816 if (! InitCommandL( aCommand, size )){ return;} |
|
817 |
|
818 TInt index(0); |
|
819 WriteInt32L( aNumPoints ); |
|
820 while( index < aNumPoints ) |
|
821 { |
|
822 WriteInt32L( aPoWriteIntList[index].iX ); |
|
823 WriteInt32L( aPoWriteIntList[index].iY ); |
|
824 index++; |
|
825 } |
|
826 if ( !iReceivingDrawingCommands ) |
|
827 { |
|
828 WriteInt8L( EAlfCommandEndMarker ); |
|
829 } |
|
830 } |
|
831 |
|
832 // --------------------------------------------------------------------------- |
|
833 // WritePointArrayL |
|
834 // --------------------------------------------------------------------------- |
|
835 // |
|
836 void CAlfRsSendBuffer::WritePointArrayL( const TUint8& aCommand, const TArray<TPoint>* aPoWriteIntList ) |
|
837 { |
|
838 if (iDisabled) // return if this send buffer is not in use |
|
839 { |
|
840 return; |
|
841 } |
|
842 |
|
843 const TInt size = sizeof(TInt32) * (2 * aPoWriteIntList->Count() + 1); |
|
844 if (! InitCommandL( aCommand, size )){ return;} |
|
845 |
|
846 TInt index(0); |
|
847 TInt count = aPoWriteIntList->Count(); |
|
848 WriteInt32L( count ); |
|
849 TArray<TPoint> list = *aPoWriteIntList; |
|
850 |
|
851 while( index < count ) |
|
852 { |
|
853 const TPoint& point = list[index]; |
|
854 WriteInt32L( point.iX ); |
|
855 WriteInt32L( point.iY ); |
|
856 index++; |
|
857 } |
|
858 if ( !iReceivingDrawingCommands ) |
|
859 { |
|
860 WriteInt8L( EAlfCommandEndMarker ); |
|
861 } |
|
862 } |
|
863 |
|
864 // --------------------------------------------------------------------------- |
|
865 // ConnectL |
|
866 // --------------------------------------------------------------------------- |
|
867 // |
|
868 TBool CAlfRsSendBuffer::ConnectL() |
|
869 { |
|
870 /* if (iDisabled) // return if this send buffer is not in use |
|
871 { |
|
872 return ETrue; |
|
873 } |
|
874 */ |
|
875 if ( iAlfBridgerClient ) |
|
876 { |
|
877 return ETrue; // already connected |
|
878 } |
|
879 iAlfBridgerClient = new(ELeave)RAlfBridgerClient(); |
|
880 TInt result = iAlfBridgerClient->Connect(); |
|
881 if ( result != KErrNone ) |
|
882 { |
|
883 // server is not available |
|
884 delete iAlfBridgerClient; |
|
885 iAlfBridgerClient = NULL; |
|
886 return EFalse; |
|
887 } |
|
888 TIpcArgs args(iScreenNumber); |
|
889 User::LeaveIfError(iAlfBridgerClient->SendSynch(KAlfCompositionWServScreenNumber, args)); |
|
890 |
|
891 MAlfCompositionController* compcntrl = (MAlfCompositionController*)iParent.ResolveObjectInterface(KAlfCompositionControllerIfUid); |
|
892 if (compcntrl) |
|
893 { |
|
894 #ifndef USE_UI_LAYER_FOR_ALF |
|
895 TAlfNativeWindowData data; |
|
896 TPckg<TAlfNativeWindowData> pkg(data); |
|
897 |
|
898 if( iScreenNumber == 0) // only for primary screen |
|
899 { |
|
900 User::LeaveIfError(iAlfBridgerClient->SendSynch(EAlfGetNativeWindowHandles, TIpcArgs(&pkg))); |
|
901 compcntrl->AlfBridgeCallback(MAlfBridge::EAlfNativeWindowCreated, &data); |
|
902 } |
|
903 } |
|
904 #endif //#ifdef USE_UI_LAYER_FOR_ALF |
|
905 iAlfCompositionCntrlClient = CAlfCompositionCntrlClient::NewL(iAlfBridgerClient, compcntrl); |
|
906 return ETrue; |
|
907 } |
|
908 |
|
909 // --------------------------------------------------------------------------- |
|
910 // WriteWindowIdentifierL |
|
911 // Convenience function |
|
912 // --------------------------------------------------------------------------- |
|
913 // |
|
914 void CAlfRsSendBuffer::WriteWindowIdentifierL( ) |
|
915 { |
|
916 if (iDisabled) // return if this send buffer is not in use |
|
917 { |
|
918 return; |
|
919 } |
|
920 #ifdef _OLD_STREAM |
|
921 if ( !iBufStream->Sink() ) |
|
922 { |
|
923 return; |
|
924 } |
|
925 #endif |
|
926 // <HEADER1> |
|
927 // if you change <HEADER1>, you must update its size in the beginning of this file |
|
928 WriteInt8L( EAlfSetWindowId ); |
|
929 ResetPatternSearch(); |
|
930 |
|
931 WriteInt8L( iScreenNumber ); |
|
932 WriteInt32L( iWindowId ); |
|
933 // </HEADER1> |
|
934 WriteFollowingFrameOffsetTemplateL(); |
|
935 } |
|
936 |
|
937 // --------------------------------------------------------------------------- |
|
938 // WriteWindowDataL |
|
939 // --------------------------------------------------------------------------- |
|
940 // |
|
941 void CAlfRsSendBuffer::WriteWindowDataL( |
|
942 TUint32 aWindowUid, |
|
943 TInt aRegionSize, |
|
944 TInt aShapeRegionSize ) |
|
945 { |
|
946 if (iDisabled) // return if this send buffer is not in use |
|
947 { |
|
948 return; |
|
949 } |
|
950 |
|
951 // TODO: TERO: END |
|
952 iNonSupportedCommandsInWindow = 0; |
|
953 iPerformanceIssueCommandCount = 0; |
|
954 iFlags = 0; |
|
955 delete iCachedText; |
|
956 iCachedText = NULL; |
|
957 |
|
958 iPreviousCommand = EAlfCommandNotInitialized; |
|
959 // Note, the size tells the maximum space needed for the command |
|
960 TInt size = sizeof(TUint32) + // windowId |
|
961 sizeof(TUint32) + // next frame offset |
|
962 3 * sizeof(TUint8) + // command + contains unsupported commands + end marker |
|
963 sizeof(TUint8) + // screen number ( in WriteFollowingFrameOffsetTemplate) |
|
964 sizeof(TUint32) * ( 4 * aRegionSize + 1 ) + // updateregion |
|
965 sizeof(TUint8) * KDivisibleByX + // possible padding |
|
966 sizeof(TUint32) * ( 4 * aShapeRegionSize + 1) + // possible shape region |
|
967 sizeof(EAlfCommandEndMarker); // endmarker for update region and this command |
|
968 if (! InitCommandL( EAlfSetWindowId, size )){ return;} |
|
969 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
970 iCommandDebugger->StartFrame(); |
|
971 #endif |
|
972 ResetPatternSearch(); |
|
973 iWindowId = aWindowUid; |
|
974 WriteInt32L( aWindowUid ); |
|
975 WriteFollowingFrameOffsetTemplateL(); |
|
976 iReceivingDrawingCommands = ETrue; // WriteCommand will set to false, when ERedrawComplete is received |
|
977 } |
|
978 |
|
979 // --------------------------------------------------------------------------- |
|
980 // WriteFollowingFrameOffsetTemplateL |
|
981 // Convenience function |
|
982 // --------------------------------------------------------------------------- |
|
983 // |
|
984 void CAlfRsSendBuffer::WriteFollowingFrameOffsetTemplateL() |
|
985 { |
|
986 if (iDisabled) // return if this send buffer is not in use |
|
987 { |
|
988 return; |
|
989 } |
|
990 |
|
991 #ifdef _OLD_STREAM |
|
992 if ( iBufStream->Sink() ) |
|
993 #endif |
|
994 { |
|
995 iTemplateOpen++; |
|
996 if ( iTemplateOpen != 1 ) |
|
997 { |
|
998 USER_INVARIANT(); |
|
999 } |
|
1000 iNextFrameOffsetPos = iOffset; |
|
1001 |
|
1002 // If you add anything to <HEADER2>, you must update its size in the beginning of the file. |
|
1003 // <HEADER2> |
|
1004 TInt chunkId = 0; |
|
1005 if ( iChunkInUse) |
|
1006 { |
|
1007 chunkId = iCacheChunks[iChunkInUse-1].Handle(); |
|
1008 } |
|
1009 WriteInt32L( chunkId ); |
|
1010 WriteInt32L( KFrameOffsetTemplate ); // we'll come back later on, and write the correct frame size to this location |
|
1011 // determine need for padding |
|
1012 TInt pos = iOffset; |
|
1013 TInt offset = pos + 2 * sizeof(TUint8) + sizeof(TUint8) + sizeof(TInt32); // padding and endmarker. |
|
1014 TInt startPadding = offset % KDivisibleByX; |
|
1015 startPadding = startPadding == 0 ? 0 : KDivisibleByX - startPadding; |
|
1016 WriteInt8L( EAlfFrameFlags ); |
|
1017 WriteInt32L( 0 ); |
|
1018 |
|
1019 WriteInt8L( startPadding ); |
|
1020 iFramePadding = startPadding; |
|
1021 WriteInt8L( EAlfCommandEndMarker ); |
|
1022 // actual padding |
|
1023 while ( startPadding-- ) |
|
1024 { |
|
1025 WriteInt8L( 0 ); |
|
1026 } |
|
1027 iArrayImplOffset = iOffset; |
|
1028 InitMarker(iMarker); |
|
1029 WriteInt8L( EAlfFrameContainsUnsupportedCommands ); |
|
1030 WriteInt8L( 0 ); |
|
1031 WriteArrayHeaderTemplateL(); |
|
1032 InitTOffsetElemArray(iOffsetArray); |
|
1033 // </HEADER2> |
|
1034 } |
|
1035 } |
|
1036 |
|
1037 // --------------------------------------------------------------------------- |
|
1038 // WriteFollowingFrameOffsetL |
|
1039 // --------------------------------------------------------------------------- |
|
1040 // |
|
1041 TBool CAlfRsSendBuffer::WriteFollowingFrameOffsetL(TBool aSendArray) |
|
1042 { |
|
1043 if (iDisabled) // return if this send buffer is not in use |
|
1044 { |
|
1045 return ETrue; |
|
1046 } |
|
1047 TOffsetElem e; |
|
1048 if (aSendArray) |
|
1049 { |
|
1050 e = WriteIndexArrayL(iOffsetArray); |
|
1051 } |
|
1052 |
|
1053 #ifdef _OLD_STREAM |
|
1054 if ( iBufStream->Sink() ) |
|
1055 #endif |
|
1056 { |
|
1057 if ( iPerformanceIssueCommandCount > KPossiblePerformanceProblemInWindowThreshold ) |
|
1058 { |
|
1059 if ( iPerformanceIssueCommandCount > iMaxPerformanceIssueCommandCount ) |
|
1060 { |
|
1061 iMaxPerformanceIssueCommandCount = iPerformanceIssueCommandCount; |
|
1062 } |
|
1063 iNonSupportedCommandsInWindow |= KPossiblePerformanceProblemInWindow; |
|
1064 } |
|
1065 |
|
1066 iTemplateOpen--; |
|
1067 // Empty frames should not be serialized as they cause unnecessary work on Alfserver side. |
|
1068 // WServ sends empty frames from time to time |
|
1069 TInt previousPos = iOffset; |
|
1070 // Remember to update KWindowFrameHeaderX, if you add stuff to frame header |
|
1071 TInt frameSize = previousPos - iNextFrameOffsetPos - KWindowFrameHeader2 - iFramePadding; |
|
1072 if ( !frameSize ) |
|
1073 { |
|
1074 SeekL( iNextFrameOffsetPos - KWindowFrameHeader1 ); |
|
1075 iReceivingDrawingCommands = EFalse; |
|
1076 return EFalse; |
|
1077 } |
|
1078 SeekL( iNextFrameOffsetPos ); |
|
1079 // <HEADER2> |
|
1080 TInt chunkId = 0; |
|
1081 if ( iChunkInUse) |
|
1082 { |
|
1083 chunkId = iCacheChunks[iChunkInUse-1].Handle(); |
|
1084 } |
|
1085 WriteInt32L( chunkId ); |
|
1086 WriteInt32L( previousPos ); |
|
1087 WriteInt8L( EAlfFrameFlags ); |
|
1088 WriteInt32L( iFlags ); |
|
1089 |
|
1090 WriteInt8L( iFramePadding ); |
|
1091 WriteInt8L( EAlfCommandEndMarker ); |
|
1092 // Padding |
|
1093 while ( iFramePadding-- ) |
|
1094 { |
|
1095 WriteInt8L( 0xff ); |
|
1096 } |
|
1097 WriteInt8L( EAlfFrameContainsUnsupportedCommands ); |
|
1098 WriteInt8L( iNonSupportedCommandsInWindow ); |
|
1099 if (aSendArray) |
|
1100 { |
|
1101 WriteArrayHeaderL(e); |
|
1102 } |
|
1103 /*iWindowHeaderStruct.iWindowEndOffset = previousPos.Offset(); |
|
1104 iWindowHeaderStruct.iUnsupportedCommandsInWindow = iNonSupportedCommandsInWindow; |
|
1105 iBufStream->WriteL( (TUint8*)&iWindowHeaderStruct, sizeof(TWindowHeaderStruct) );*/ |
|
1106 // <HEADER2> |
|
1107 // return to end of frame |
|
1108 SeekL( previousPos ); |
|
1109 |
|
1110 if ( iTemplateOpen ) |
|
1111 { |
|
1112 USER_INVARIANT(); |
|
1113 } |
|
1114 } |
|
1115 return ETrue; |
|
1116 } |
|
1117 // |
|
1118 // ARRAY IMPLEMENTATION |
|
1119 // |
|
1120 |
|
1121 const TInt KArrayOffsetTemplate = 23456789; |
|
1122 const TInt KArraySizeTemplate = 23456789; |
|
1123 |
|
1124 void CAlfRsSendBuffer::WriteArrayHeaderTemplateL() |
|
1125 { |
|
1126 WriteInt8L( EAlfCommandIndexArrayHeader ); |
|
1127 WriteInt8L( 0 ); // align |
|
1128 WriteInt32L( KArrayOffsetTemplate ); // these will be rewritten in WriteArrayHeader2 |
|
1129 WriteInt32L( KArraySizeTemplate ); // these will be rewritten in WriteArrayHeader2 |
|
1130 } |
|
1131 |
|
1132 |
|
1133 void CAlfRsSendBuffer::InitTOffsetElemArray(RArray<TOffsetElem> &aOffsets) |
|
1134 { |
|
1135 TInt count = aOffsets.Count(); |
|
1136 for(TInt i=0;i<count;i++) |
|
1137 aOffsets.Remove(0); |
|
1138 } |
|
1139 |
|
1140 CAlfRsSendBuffer::TOffsetElem CAlfRsSendBuffer::WriteIndexArrayL(const RArray<TOffsetElem> &aOffsets) |
|
1141 { |
|
1142 TInt marker = iBufStream->Sink()->TellL( MStreamBuf::EWrite ).Offset(); |
|
1143 if (iPreviousBlockOffset != marker && iLayersEnabled) |
|
1144 { |
|
1145 TInt size = marker - iPreviousBlockOffset; |
|
1146 TOffsetElem e; |
|
1147 e.iOffset = iPreviousBlockOffset - iArrayImplOffset; //iFrameBeginOffset + KWindowFrameHeader1 + KWindowFrameHeader2; |
|
1148 e.iSize = size; |
|
1149 e.iBoundingRectangle = TRect(0,0,0,0); |
|
1150 e.iLayerId = iExtraLayerId++; |
|
1151 iOffsetArray.AppendL( e ); |
|
1152 } |
|
1153 InsertPaddingL(); |
|
1154 |
|
1155 // first command to allow wspainter to skip the index array section |
|
1156 WriteInt8L(EAlfCommandIndexArray); |
|
1157 WriteInt8L(aOffsets.Count()); |
|
1158 WriteInt8L(0); |
|
1159 WriteInt8L(0); |
|
1160 TInt offset = iOffset; |
|
1161 TInt count = aOffsets.Count(); |
|
1162 |
|
1163 // then the actual index array |
|
1164 for(TInt i = 0; i<count; i++) |
|
1165 { |
|
1166 WriteInt32L( aOffsets[i].iOffset ); |
|
1167 WriteInt32L( aOffsets[i].iSize ); |
|
1168 WriteInt32L( aOffsets[i].iLayerId); |
|
1169 WriteL( (TUint8*)&aOffsets[i].iBoundingRectangle, sizeof(TRect) ); |
|
1170 } |
|
1171 TOffsetElem e; |
|
1172 e.iOffset = offset - iArrayImplOffset; //iFrameBeginOffset + KWindowFrameHeader1 + KWindowFrameHeader2; |
|
1173 e.iSize = aOffsets.Count()*sizeof(TOffsetElem); |
|
1174 return e; |
|
1175 } |
|
1176 |
|
1177 void CAlfRsSendBuffer::WriteArrayHeaderL(const TOffsetElem &aIndexArrayOffset) |
|
1178 { |
|
1179 WriteInt8L( EAlfCommandIndexArrayHeader ); |
|
1180 WriteInt8L( 0 ); // align |
|
1181 WriteInt32L( aIndexArrayOffset.iOffset ); |
|
1182 WriteInt32L( aIndexArrayOffset.iSize ); |
|
1183 } |
|
1184 |
|
1185 void CAlfRsSendBuffer::InitMarker(TInt &aMarker) |
|
1186 { |
|
1187 aMarker = -1; |
|
1188 iPreviousBlockOffset = iBufStream->Sink()->TellL( MStreamBuf::EWrite ).Offset(); |
|
1189 iExtraLayerId = 667; |
|
1190 iLayersEnabled = EFalse; |
|
1191 } |
|
1192 void CAlfRsSendBuffer::StartMarkerL(TInt &aMarker, TRect &aRectangle, TInt &aLayer, TRect aBoundingRectangle, TInt aLayerId) |
|
1193 { |
|
1194 ASSERT(aMarker == -1); |
|
1195 aMarker = iBufStream->Sink()->TellL( MStreamBuf::EWrite ).Offset(); |
|
1196 if (iPreviousBlockOffset != aMarker) |
|
1197 { |
|
1198 TInt size = aMarker - iPreviousBlockOffset; |
|
1199 TOffsetElem e; |
|
1200 e.iOffset = iPreviousBlockOffset - iArrayImplOffset; //iFrameBeginOffset + KWindowFrameHeader1 + KWindowFrameHeader2; |
|
1201 e.iSize = size; |
|
1202 e.iBoundingRectangle = TRect(0,0,0,0); |
|
1203 e.iLayerId = iExtraLayerId++; |
|
1204 iOffsetArray.AppendL( e ); |
|
1205 } |
|
1206 |
|
1207 //aMarker = iOffset; |
|
1208 aRectangle = aBoundingRectangle; |
|
1209 aLayer = aLayerId; |
|
1210 iLayersEnabled = ETrue; |
|
1211 } |
|
1212 void CAlfRsSendBuffer::EndMarkerL(RArray<TOffsetElem> &aOffset, TInt &aMarker, const TRect &aRectangle, TInt aLayerId) |
|
1213 { |
|
1214 //TODO ASSERT(aMarker != -1); |
|
1215 if (aMarker==-1) return; |
|
1216 TInt offset = iBufStream->Sink()->TellL( MStreamBuf::EWrite ).Offset(); |
|
1217 |
|
1218 TInt size = offset - aMarker; |
|
1219 TOffsetElem e; |
|
1220 e.iOffset = aMarker - iArrayImplOffset; //iFrameBeginOffset + KWindowFrameHeader1 + KWindowFrameHeader2; |
|
1221 e.iSize = size; |
|
1222 e.iBoundingRectangle = aRectangle; |
|
1223 e.iLayerId = aLayerId; |
|
1224 aOffset.AppendL( e ); |
|
1225 aMarker = -1; |
|
1226 iPreviousBlockOffset = offset; |
|
1227 } |
|
1228 void CAlfRsSendBuffer::StartMarkerL(TRect aBoundingRectangle, TInt aLayerId) |
|
1229 { |
|
1230 StartMarkerL(iMarker, iBoundingRectangle, iLayerId, aBoundingRectangle, aLayerId); |
|
1231 } |
|
1232 void CAlfRsSendBuffer::EndMarkerL() |
|
1233 { |
|
1234 EndMarkerL(iOffsetArray, iMarker, iBoundingRectangle, iLayerId); |
|
1235 } |
|
1236 // --------------------------------------------------------------------------- |
|
1237 // SendL |
|
1238 // sends data syncronously in one or more packets to the streamer server |
|
1239 // --------------------------------------------------------------------------- |
|
1240 // |
|
1241 void CAlfRsSendBuffer::SendL( TRequestStatus* aStatus ) |
|
1242 { |
|
1243 // dont send to alf, if chunk is not available or nothing was written |
|
1244 if (iDisabled || !iChunk.Handle() ) |
|
1245 { |
|
1246 if ( aStatus ) |
|
1247 { |
|
1248 // AlfRenderStage may complete the request, because we wont do anything with the data |
|
1249 iParent.EndCallBack( aStatus ); |
|
1250 } |
|
1251 return; |
|
1252 } |
|
1253 |
|
1254 WriteInt8L( EAlfCommitBatch ); |
|
1255 WriteInt8L( iScreenNumber ); |
|
1256 WriteInt8L( EAlfCommandEndMarker ); |
|
1257 |
|
1258 iState = EWaitingAck; |
|
1259 TInt lastWrittenOffset( iOffset ); |
|
1260 Commit(); |
|
1261 |
|
1262 TIpcArgs args( lastWrittenOffset ); |
|
1263 // __ALFLOGSTRING1("CAlfRsSendBuffer::SendL, offset %d ( TRequestStatus)"), lastWrittenOffset ); |
|
1264 if ( iFlushBufferTimer ) |
|
1265 { |
|
1266 iFlushBufferTimer->Cancel(); |
|
1267 } |
|
1268 iAlfBridgerClient->SendAsynchronous( EAlfBridgerAsyncronousData, args, iStatus ); |
|
1269 |
|
1270 if ( aStatus ) // aStatus is null, if this was event notification and not drawing |
|
1271 { |
|
1272 iQuedStatus = aStatus; |
|
1273 *aStatus = KRequestPending; |
|
1274 } |
|
1275 |
|
1276 if ( !IsActive() ) |
|
1277 { |
|
1278 SetActive(); |
|
1279 } |
|
1280 } |
|
1281 |
|
1282 // --------------------------------------------------------------------------- |
|
1283 // FlushBuffer |
|
1284 // --------------------------------------------------------------------------- |
|
1285 // |
|
1286 void CAlfRsSendBuffer::FlushBuffer() |
|
1287 { |
|
1288 if (iDisabled) // return if this send buffer is not in use |
|
1289 { |
|
1290 return; |
|
1291 } |
|
1292 |
|
1293 TBool connected = (iAlfBridgerClient != NULL); |
|
1294 if (!connected) |
|
1295 { |
|
1296 TRAP_IGNORE(connected = ConnectL()); |
|
1297 } |
|
1298 if (!connected) |
|
1299 { |
|
1300 // Cannot connect |
|
1301 return; |
|
1302 } |
|
1303 TIpcArgs args( 0 ); |
|
1304 TInt result = iAlfBridgerClient->SendBlind( EAlfBridgerBlindSend, args ); |
|
1305 if ( result != KErrNone && result != KErrServerBusy) |
|
1306 { |
|
1307 __ALFLOGSTRING1("CAlfRsSendBuffer::FlushBuffer, err %d", result ); |
|
1308 // This means that AlfDecoderServer has died and is not coming back. |
|
1309 // There is no point of continuing with non updating UI. |
|
1310 USER_INVARIANT(); |
|
1311 } |
|
1312 if ( iFlushBufferTimer ) |
|
1313 { |
|
1314 iFlushBufferTimer->Cancel(); |
|
1315 } |
|
1316 |
|
1317 // during boot time, server is known to answer with this. Just try again little later. |
|
1318 if ( result == KErrServerBusy) |
|
1319 { |
|
1320 CommitL(); |
|
1321 } |
|
1322 } |
|
1323 |
|
1324 // --------------------------------------------------------------------------- |
|
1325 // CommitL |
|
1326 // --------------------------------------------------------------------------- |
|
1327 // |
|
1328 void CAlfRsSendBuffer::CommitL( ) |
|
1329 { |
|
1330 if (iDisabled) // return if this send buffer is not in use |
|
1331 { |
|
1332 return; |
|
1333 } |
|
1334 |
|
1335 if ( iBooting ) |
|
1336 { |
|
1337 return; |
|
1338 } |
|
1339 Commit(); |
|
1340 // RDebug::Print(_L("CAlfRsSendBuffer::CommitL - %d %d %d "), iChunkHeader, iChunkHeader->iCommittedWriteOffset, iOffset ); |
|
1341 if ( !iFlushBufferTimer ) |
|
1342 { |
|
1343 iFlushBufferTimer = CPeriodic::NewL( EPriorityNormal ); |
|
1344 iFlushBufferTimer->Start( 5000, 10 * 1000000 , TCallBack( doFlushBuffer, this )); |
|
1345 } |
|
1346 if ( !iFlushBufferTimer->IsActive() ) |
|
1347 { |
|
1348 //__ALFLOGSTRING("CAlfRsSendBuffer::CommitL, activating timer"); |
|
1349 iFlushBufferTimer->After( 5000 ); |
|
1350 } |
|
1351 else |
|
1352 { |
|
1353 //__ALFLOGSTRING("CAlfRsSendBuffer::CommitL, timer already active "); |
|
1354 } |
|
1355 } |
|
1356 |
|
1357 // --------------------------------------------------------------------------- |
|
1358 // SendAsyncCmd |
|
1359 // Send asynchronous command |
|
1360 // --------------------------------------------------------------------------- |
|
1361 // |
|
1362 void CAlfRsSendBuffer::SendAsyncCmd(TInt aCmd, TDes8& aBuf, TRequestStatus& aStatus) |
|
1363 { |
|
1364 if (iDisabled) // return if this send buffer is not in use |
|
1365 { |
|
1366 return; |
|
1367 } |
|
1368 |
|
1369 iAlfBridgerClient->SendAsynchronous(aCmd, TIpcArgs(&aBuf), aStatus); |
|
1370 } |
|
1371 |
|
1372 // --------------------------------------------------------------------------- |
|
1373 // OpenPrimaryChunkForWritingL |
|
1374 // --------------------------------------------------------------------------- |
|
1375 // |
|
1376 void CAlfRsSendBuffer::OpenPrimaryChunkForWritingL() |
|
1377 { |
|
1378 if (iDisabled) // return if this send buffer is not in use |
|
1379 { |
|
1380 return; |
|
1381 } |
|
1382 |
|
1383 iChunkHeader = reinterpret_cast<TChunkHeader*>(iChunk.Base()); |
|
1384 if ( iChunkHeader->iMemWriteStream ) |
|
1385 { |
|
1386 #ifdef _OLD_STREAM |
|
1387 iBufStream->Close(); |
|
1388 delete iBufStream; |
|
1389 iBufStream=NULL; |
|
1390 iBufStream = new(ELeave)RMemWriteStream; |
|
1391 // iBufStream = iChunkHeader->iMemWriteStream; |
|
1392 iBufStream->Open( iChunk.Base() + sizeof( TChunkHeader), iPrimaryChunkMaxSize ); |
|
1393 #else |
|
1394 delete iStreamPtr; |
|
1395 iStreamPtr = new(ELeave)TPtr8( (TUint8*)(iChunk.Base() + sizeof( TChunkHeader)), iPrimaryChunkMaxSize - sizeof( TChunkHeader)); |
|
1396 iChunkHeader->iMemWriteStream = (RMemWriteStream*)1; |
|
1397 #endif |
|
1398 SeekL( iOffset ); |
|
1399 iChunkInUse = 0; |
|
1400 } |
|
1401 else |
|
1402 { |
|
1403 #ifdef _OLD_STREAM |
|
1404 iBufStream->Open( iChunk.Base() + sizeof( TChunkHeader), iPrimaryChunkMaxSize ); |
|
1405 iChunkHeader->iMemWriteStream = iBufStream; |
|
1406 #else |
|
1407 iStreamPtr = new(ELeave)TPtr8( (TUint8*)(iChunk.Base() + sizeof( TChunkHeader)), iPrimaryChunkMaxSize - sizeof( TChunkHeader) ); |
|
1408 iChunkHeader->iMemWriteStream = (RMemWriteStream*)1; |
|
1409 #endif |
|
1410 SeekL(0); |
|
1411 iChunkHeader->iMemWriteStreamUsers++; |
|
1412 } |
|
1413 WriteInt8L( EAlfCommandEndMarker ); |
|
1414 Commit(); |
|
1415 |
|
1416 } |
|
1417 |
|
1418 // --------------------------------------------------------------------------- |
|
1419 // Commit |
|
1420 // --------------------------------------------------------------------------- |
|
1421 // |
|
1422 void CAlfRsSendBuffer::Commit() |
|
1423 { |
|
1424 iChunkHeader->iCommittedWriteOffset = iOffset; |
|
1425 // RDebug::Print(_L("CAlfRsSendBuffer::Commit - %d"), iChunkHeader->iCommittedWriteOffset ); |
|
1426 } |
|
1427 |
|
1428 // --------------------------------------------------------------------------- |
|
1429 // PrepareBufferL |
|
1430 // Sets up the stream |
|
1431 // --------------------------------------------------------------------------- |
|
1432 // |
|
1433 void CAlfRsSendBuffer::PrepareBufferL() |
|
1434 { |
|
1435 if (iDisabled) // return if this send buffer is not in use |
|
1436 { |
|
1437 return; |
|
1438 } |
|
1439 |
|
1440 // is alfstreamerserver running? |
|
1441 if ( !ConnectL() ) |
|
1442 { |
|
1443 return; |
|
1444 } |
|
1445 iBeginTime.HomeTime(); |
|
1446 |
|
1447 // alfstreamerserver is now running, but do we already have chunk for serialization |
|
1448 if ( iChunk.Handle() == 0 ) |
|
1449 {// Note, ConnectL() == ETrue and iChunk.Handle() == 0 is true ONLY ONCE in runtime. |
|
1450 |
|
1451 // write jump to the primary chunk. This chunk jump gets special treatment in RunL. Look for iBooting variable. |
|
1452 JumpToAnotherChunkL( 0, iPrimaryChunkMaxSize ); // 2nd parameter is ignored on alfside, because it knows the primary chunksize |
|
1453 Commit(); |
|
1454 #ifdef _OLD_STREAM |
|
1455 iBufStream->Close(); |
|
1456 #endif |
|
1457 // Request chunk from server: handle and lenght of chunk come as response |
|
1458 TPckg<TInt> pkgLength( iUsedChunkMaxSize ); |
|
1459 TIpcArgs args( &pkgLength, iScreenNumber ); |
|
1460 TInt handle; |
|
1461 handle = iAlfBridgerClient->SendSynch( EAlfBridgerRequestDataBlock, args); |
|
1462 iPrimaryChunkMaxSize = iUsedChunkMaxSize; |
|
1463 iChunk.SetReturnedHandle( handle ); |
|
1464 |
|
1465 if ( iChunk.Handle() > 0 ) |
|
1466 { |
|
1467 OpenPrimaryChunkForWritingL(); |
|
1468 } |
|
1469 else |
|
1470 { |
|
1471 // Chunk was not received from server. We cannot continue |
|
1472 USER_INVARIANT(); |
|
1473 } |
|
1474 } |
|
1475 // The first boot cache chunk is sent here. |
|
1476 if ( iBooting && iCacheChunks.Count() && iChunkInUse ) |
|
1477 { |
|
1478 if ( iChunkHeader->iMemWriteStreamUsers > 1 ) |
|
1479 { |
|
1480 // make "sure", that there will be space for all the cached data |
|
1481 CommitL(); |
|
1482 } |
|
1483 |
|
1484 while ( iChunkInUse ) |
|
1485 { |
|
1486 iChunkInUse--; |
|
1487 TInt size( KCacheChunkMinSize ); |
|
1488 TIpcArgs args( size, iCacheChunks[iChunkInUse], iChunkInUse == 0 /* open chunk for reading */); |
|
1489 iAlfBridgerClient->SendSynch( EAlfBridgerSendChunk, args); |
|
1490 } |
|
1491 } |
|
1492 iFrameBeginOffset = iOffset; // iBufStream->Sink()->TellL( MStreamBuf::EWrite); |
|
1493 } |
|
1494 |
|
1495 // --------------------------------------------------------------------------- |
|
1496 // FrameContainsDataL |
|
1497 // --------------------------------------------------------------------------- |
|
1498 // |
|
1499 TBool CAlfRsSendBuffer::FrameContainsDataL() |
|
1500 { |
|
1501 if (iDisabled) // return if this send buffer is not in use |
|
1502 { |
|
1503 return EFalse; // Must return false as no draw commands are allowed |
|
1504 } |
|
1505 |
|
1506 #ifdef _OLD_STREAM |
|
1507 if ( iBufStream->Sink() ) |
|
1508 #endif |
|
1509 { |
|
1510 #ifdef _OLD_STREAM |
|
1511 iBufStream->CommitL(); |
|
1512 #endif |
|
1513 return ( iFrameBeginOffset != iOffset ); |
|
1514 } |
|
1515 #ifdef _OLD_STREAM |
|
1516 else |
|
1517 { |
|
1518 return EFalse; |
|
1519 } |
|
1520 #endif |
|
1521 } |
|
1522 |
|
1523 // --------------------------------------------------------------------------- |
|
1524 // JumpToAnotherChunkL |
|
1525 // --------------------------------------------------------------------------- |
|
1526 // |
|
1527 void CAlfRsSendBuffer::JumpToAnotherChunkL( TInt32 aChunkId, TInt aChunkSize ) |
|
1528 { |
|
1529 WriteInt8L( EAlfJumpToAnotherChunk ); |
|
1530 WriteInt8L( 0 ); // screen number, not used. |
|
1531 WriteInt32L( aChunkId ); |
|
1532 WriteInt32L( aChunkSize ); |
|
1533 WriteInt8L( EAlfCommandEndMarker ); |
|
1534 Commit(); |
|
1535 } |
|
1536 |
|
1537 // --------------------------------------------------------------------------- |
|
1538 // DoCreateTemporaryChunkL |
|
1539 // |
|
1540 // If wserv pushes more data in frame that we can handle, separate one time use |
|
1541 // "temporary" chunks are taken into use. |
|
1542 // 1. Big enough chunk to contain atleast the command + minimum chunk size is created |
|
1543 // 2. Jump of from the current chunk to the temporary chunk is created |
|
1544 // 3. new chunk is taken as the active chunk |
|
1545 // 4. chunk is rewinded |
|
1546 // 5. commands can be serialized as before |
|
1547 // |
|
1548 // Same starts from the step 1, if temporary chunk turns out to be not big enough. |
|
1549 // |
|
1550 // Chunks are destroyed in RunL, when asyncronous (frame processed) complete is |
|
1551 // received. In RunL, (see RunL for the code) |
|
1552 // |
|
1553 // The following things are serialized to the active (the last temporary chunk created) |
|
1554 // 1. destroy command for each existing temporary chunk is created |
|
1555 // 2. if not in first boot, jump to the primary chunk is created. |
|
1556 // 3. handles to the temporary chunks on this side are closed |
|
1557 // and chunks removed. |
|
1558 // |
|
1559 // After AlfHierarchy has read the jump command, serialization will be in the normal mode. |
|
1560 // --------------------------------------------------------------------------- |
|
1561 // |
|
1562 void CAlfRsSendBuffer::DoCreateTemporaryChunkL( TInt aMinimumRequiredSize ) |
|
1563 { |
|
1564 __ALFLOGSTRING2("CAlfRsSendBuffer::DoWaitWrapperL iReceivingDrawing commands %d chunk in use: %d", iReceivingDrawingCommands, iChunkInUse ); |
|
1565 // Optimize bitblits backtracks in a _single chunk_, so changing or wrapping a chunk is |
|
1566 // a very bad idea. Lets skip the optimization, if this rare occation happens. |
|
1567 ResetPatternSearch(); |
|
1568 |
|
1569 if ( iReceivingDrawingCommands ) |
|
1570 { |
|
1571 // if window drawing is active, the window commands are split. |
|
1572 InsertPaddingL(); // padding is required, that the combined parts on the other side have correct alignment for descriptors |
|
1573 WriteFollowingFrameOffsetL(EFalse); |
|
1574 WriteInt8L( EAlfPacketNotReady ); |
|
1575 WriteInt8L( EAlfCommandEndMarker ); |
|
1576 } |
|
1577 else |
|
1578 { |
|
1579 __ALFLOGSTRING("CAlfRsSendBuffer::DoCreateTemporaryChunkL, creating during hierarchy commands"); |
|
1580 } |
|
1581 |
|
1582 // rest of this frame will be serilized to cache chunk |
|
1583 CommitL(); |
|
1584 if ( ConnectL() ) |
|
1585 { |
|
1586 FlushBuffer(); |
|
1587 } |
|
1588 TInt chunkSize = aMinimumRequiredSize; |
|
1589 if ( CreateTemporaryChunkL( chunkSize ) == KErrNone ) |
|
1590 { |
|
1591 if ( ConnectL() ) |
|
1592 { |
|
1593 TInt size( chunkSize ); |
|
1594 TIpcArgs args( size, iCacheChunks[iChunkInUse], EFalse /* open chunk for reading */ ); |
|
1595 iAlfBridgerClient->SendSynch( EAlfBridgerSendChunk, args); // alf server must open the chunk before it can be read. reading is asyncronous |
|
1596 } |
|
1597 JumpToAnotherChunkL( iCacheChunks[iChunkInUse].Handle(), chunkSize ); |
|
1598 OpenRewindChunkL( chunkSize ); |
|
1599 WriteInt8L( EAlfCommandEndMarker ); // This is must command after jumping to another chunk. |
|
1600 CommitL(); |
|
1601 |
|
1602 if ( iReceivingDrawingCommands ) |
|
1603 { |
|
1604 WriteWindowIdentifierL(); |
|
1605 } |
|
1606 } |
|
1607 else |
|
1608 { |
|
1609 // TODO: We could not reserve memory. The only option will be to ignore this frame. |
|
1610 // 1. rollback to the beginning of the frame |
|
1611 // 2. skip all sequential drawing commands to this frame. |
|
1612 // problem: what if OOM during hierarchy tree commmands |
|
1613 } |
|
1614 } |
|
1615 |
|
1616 // --------------------------------------------------------------------------- |
|
1617 // ReserveSpaceL |
|
1618 // |
|
1619 // Check, if buffer has enough space for this command. |
|
1620 // If we encounter the end of buffer, then do a wrap around if possible. |
|
1621 // If wrap is not possible, create a temporary space for command |
|
1622 // --------------------------------------------------------------------------- |
|
1623 // |
|
1624 TBool CAlfRsSendBuffer::ReserveSpaceL( TInt aCommandSize ) |
|
1625 { |
|
1626 // TInt minumumHeaderSize = iCacheChunks.Count() > 0 ? KFrameHeaderSizeWhenCacheChunks : KFrameHeaderSize; |
|
1627 TInt minumumHeaderSize = KFrameHeaderSize; |
|
1628 if ( iCacheChunks.Count() > 0 ) |
|
1629 { |
|
1630 // if cache chunks still exists, then wserv is trying to push commands out of redrawstart/end loop and we hope that |
|
1631 minumumHeaderSize = KFrameHeaderSizeWhenCacheChunks; |
|
1632 } |
|
1633 TInt writeOffset = iOffset; |
|
1634 TInt commandTailOffset = writeOffset + aCommandSize + KFrameHeaderSize; |
|
1635 TInt readOffset = iChunkHeader->iReadOffset; |
|
1636 TInt bytesFree(0); |
|
1637 if ( readOffset > writeOffset) |
|
1638 {// V |
|
1639 // |RRRRRRRRR|W---------RRRRRRRRRRRR | |
|
1640 // ASSERT( iWrappingFrame ); |
|
1641 bytesFree = readOffset - writeOffset; |
|
1642 } |
|
1643 if ( readOffset < writeOffset ) |
|
1644 { |
|
1645 // V W |
|
1646 // | ----RRRRRRRRRRRRRRRW------ | |
|
1647 iWrappingFrame = EFalse; |
|
1648 bytesFree = iUsedChunkMaxSize - writeOffset; // there might be more free and the beginning of the chunk, but this is not relevant. The entire command needs to fit as one piece |
|
1649 } |
|
1650 if ( readOffset == writeOffset ) |
|
1651 { |
|
1652 if ( iWrappingFrame ) |
|
1653 { |
|
1654 // V |
|
1655 // | RRRRRRRRRRRRRWRRRRRRRRRRRRR | |
|
1656 bytesFree = 0; |
|
1657 } |
|
1658 else |
|
1659 { |
|
1660 // V |
|
1661 // | --------------------------- | |
|
1662 // the entire chunk is free |
|
1663 bytesFree = iUsedChunkMaxSize; |
|
1664 } |
|
1665 } |
|
1666 // are we trying to overwrite unprocessed data |
|
1667 if ( bytesFree < aCommandSize + minumumHeaderSize && commandTailOffset <= iUsedChunkMaxSize |
|
1668 || ( bytesFree < aCommandSize + minumumHeaderSize && iWrappingFrame )) |
|
1669 { |
|
1670 // __ALFLOGSTRING("CAlfRsSendBuffer::CanWriteToBufferL -> DoCreateTemporaryChunkL"); |
|
1671 DoCreateTemporaryChunkL( aCommandSize ); |
|
1672 } |
|
1673 else if ( commandTailOffset > iUsedChunkMaxSize ) |
|
1674 { |
|
1675 if ( !iChunkInUse ) |
|
1676 { |
|
1677 DoWrapL( aCommandSize, aCommandSize > readOffset ); |
|
1678 } |
|
1679 else |
|
1680 { |
|
1681 // we are already using temporary chunks and those cannot be wrapped. The only option is to create |
|
1682 // yet another temporary chunk. |
|
1683 DoCreateTemporaryChunkL( aCommandSize ); |
|
1684 } |
|
1685 } |
|
1686 return ETrue; |
|
1687 } |
|
1688 |
|
1689 // --------------------------------------------------------------------------- |
|
1690 // DoWrapL |
|
1691 // --------------------------------------------------------------------------- |
|
1692 // |
|
1693 void CAlfRsSendBuffer::DoWrapL( TInt aCommandSize, TBool aCreateTempororaryChunk ) |
|
1694 { |
|
1695 if ( iCacheChunks.Count() ) |
|
1696 { |
|
1697 DoCreateTemporaryChunkL( aCommandSize ); |
|
1698 } |
|
1699 __ALFLOGSTRING2("CanWriteToBufferL Read/Write %d/%d", iChunkHeader->iReadOffset, iChunkHeader->iWriteOffset); |
|
1700 |
|
1701 if ( aCreateTempororaryChunk ) |
|
1702 { |
|
1703 __ALFLOGSTRING("CAlfRsSendBuffer::DoWrapL -> DoCreateTemporaryChunkL"); |
|
1704 DoCreateTemporaryChunkL( aCommandSize ); |
|
1705 return; |
|
1706 } |
|
1707 else |
|
1708 { |
|
1709 if ( iReceivingDrawingCommands ) |
|
1710 { |
|
1711 InsertPaddingL(); |
|
1712 WriteFollowingFrameOffsetL(EFalse); |
|
1713 WriteInt8L( EAlfPacketNotReady ); |
|
1714 WriteInt8L( EAlfCommandEndMarker ); |
|
1715 } |
|
1716 else |
|
1717 { |
|
1718 __ALFLOGSTRING("CAlfRsSendBuffer::CanWriteToBufferL, non drawing command"); |
|
1719 } |
|
1720 } |
|
1721 WriteInt8L( EAlfWrap ); |
|
1722 WriteInt8L( iScreenNumber ); |
|
1723 WriteInt8L( EAlfCommandEndMarker ); |
|
1724 // Optimize bitblits backtracks in a _single chunk_, so changing or wrapping a chunk is |
|
1725 // a very bad idea. Lets skip the optimization, if this rare occation happens. |
|
1726 ResetPatternSearch(); |
|
1727 |
|
1728 iWrappingFrame = ETrue; |
|
1729 __ALFLOGSTRING1("CAlfRsSendBuffer::CanWriteToBufferL, Wrap at offset %d", iChunkHeader->iWriteOffset); |
|
1730 SeekL(0); |
|
1731 WriteInt8L( EAlfCommandEndMarker ); |
|
1732 |
|
1733 if ( iReceivingDrawingCommands ) |
|
1734 { |
|
1735 WriteWindowIdentifierL(); |
|
1736 } |
|
1737 else |
|
1738 { |
|
1739 __ALFLOGSTRING("CAlfRsSendBuffer::CanWriteToBufferL Wrapping while not receiving drawing commands"); |
|
1740 } |
|
1741 } |
|
1742 |
|
1743 // --------------------------------------------------------------------------- |
|
1744 // SetSupportedCommand |
|
1745 // --------------------------------------------------------------------------- |
|
1746 // |
|
1747 void CAlfRsSendBuffer::SetSupportedCommand( TInt aIndex, TInt8 aSupport ) |
|
1748 { |
|
1749 if (iDisabled) // return if this send buffer is not in use |
|
1750 { |
|
1751 return; |
|
1752 } |
|
1753 |
|
1754 iNonSupportedCommands[aIndex] = aSupport; |
|
1755 } |
|
1756 |
|
1757 // --------------------------------------------------------------------------- |
|
1758 // InitCommandL |
|
1759 // Takes care that data fits to the stream |
|
1760 // --------------------------------------------------------------------------- |
|
1761 // |
|
1762 TBool CAlfRsSendBuffer::InitCommandL( const TUint8& aCommand, TInt aCommandSize ) |
|
1763 { |
|
1764 // THIS IS DIRTY HACK UNTIL WSERV STOPS DOING DRAWING OUTSIDE WINDOW |
|
1765 // RE-EVALUATE FOR WK14 RELEASE |
|
1766 if ( ( aCommand >= EAlfDrawCommandsStart && aCommand <= EAlfDrawCommandsEnd && !iReceivingDrawingCommands ) && |
|
1767 ( aCommand != EAlfPacketReady && aCommand != EAlfPacketNotReady )) |
|
1768 { |
|
1769 #ifdef _DEBUG |
|
1770 RDebug::Print(_L("CAlfRsSendBuffer::InitCommandL - Drawing outside window, Cmd: %d"), aCommand ); |
|
1771 #endif |
|
1772 return EFalse; |
|
1773 } |
|
1774 // END OF DIRTY HACK |
|
1775 if ( iReceivingDrawingCommands ) |
|
1776 { |
|
1777 aCommandSize += sizeof(EAlfCommandEndMarker); |
|
1778 } |
|
1779 iNonSupportedCommandsInWindow |= iNonSupportedCommands[aCommand] & KAllRenderersMask; |
|
1780 if ( iNonSupportedCommands[aCommand] & KPossiblePerformanceProblemInWindow ) // indicates possible performance problem if frame has many of this of commands |
|
1781 { |
|
1782 iPerformanceIssueCommandCount++; |
|
1783 } |
|
1784 |
|
1785 // Check if chunk has been opened. Must for streaming. |
|
1786 if ( |
|
1787 #ifdef _OLD_STREAM |
|
1788 !iBufStream && |
|
1789 #else |
|
1790 !iChunkHeader && |
|
1791 #endif |
|
1792 iCacheChunks.Count() == 0 ) |
|
1793 { |
|
1794 TInt chunkSize = aCommandSize; |
|
1795 CreateTemporaryChunkL( chunkSize ); |
|
1796 OpenRewindChunkL( chunkSize ); |
|
1797 } |
|
1798 |
|
1799 |
|
1800 // EAlfPacketReady is the last command in the window, and it is guaranteened to fit without checking. Checking would possible slice the command stream unnecessary. |
|
1801 if ( aCommand != EAlfPacketReady ) |
|
1802 { |
|
1803 // check for running out of space in the chunk |
|
1804 if ( !ReserveSpaceL( aCommandSize + 2*sizeof(TUint8)) ) |
|
1805 { |
|
1806 return EFalse; |
|
1807 } |
|
1808 } |
|
1809 // write command to a chunk. There will be space. |
|
1810 // __ALFLOGSTRING3("Command %d, Offset: %d Screen: %d Command: %d", aCommand, iScreenNumber, aCommand ); |
|
1811 WriteInt8L( aCommand ); |
|
1812 iPreviousCommand = aCommand; |
|
1813 if ( aCommand < EAlfDrawCommandsStart || aCommand > EAlfDrawCommandsEnd ) |
|
1814 { |
|
1815 WriteInt8L( iScreenNumber ); |
|
1816 } |
|
1817 else |
|
1818 { |
|
1819 // Uncomment following line to do chaff bitblit optimization |
|
1820 #ifndef __NVG // TODO: Implement the 9-piece drawing for NVG |
|
1821 // DoPatternSearch( aCommand, aCommandSize ); |
|
1822 #endif |
|
1823 } |
|
1824 return ETrue; |
|
1825 } |
|
1826 |
|
1827 // --------------------------------------------------------------------------- |
|
1828 // CreateTemporaryChunkL |
|
1829 // --------------------------------------------------------------------------- |
|
1830 // |
|
1831 TBool CAlfRsSendBuffer::CreateTemporaryChunkL( TInt& aSize ) |
|
1832 { |
|
1833 aSize+= KCacheChunkMinSize; |
|
1834 iCacheChunks.Append( RChunk() ); |
|
1835 TInt result = iCacheChunks[iChunkInUse].CreateDisconnectedGlobal( KNullDesC, 0, aSize, aSize ); |
|
1836 return result; |
|
1837 } |
|
1838 |
|
1839 // --------------------------------------------------------------------------- |
|
1840 // OpenRewindChunkL |
|
1841 // --------------------------------------------------------------------------- |
|
1842 // |
|
1843 void CAlfRsSendBuffer::OpenRewindChunkL( TInt aSize ) |
|
1844 { |
|
1845 #ifdef _OLD_STREAM |
|
1846 if ( iBufStream && iChunkInUse) |
|
1847 { |
|
1848 iBufStream->Close(); |
|
1849 } |
|
1850 iBufStream = new(ELeave)RMemWriteStream; |
|
1851 iBufStream->Open( iCacheChunks[iChunkInUse].Base() + sizeof( TChunkHeader), aSize ); |
|
1852 #else |
|
1853 iStreamPtr = new(ELeave)TPtr8( (TUint8*)(iCacheChunks[iChunkInUse].Base() + sizeof( TChunkHeader)), aSize - sizeof( TChunkHeader)); |
|
1854 |
|
1855 #endif |
|
1856 iChunkHeader = reinterpret_cast<TChunkHeader*>(iCacheChunks[iChunkInUse].Base()); |
|
1857 SeekL(0); |
|
1858 memset( iChunkHeader, 0, sizeof( TChunkHeader ) ); |
|
1859 iUsedChunkMaxSize = aSize - sizeof( TChunkHeader); |
|
1860 iChunkInUse++; |
|
1861 } |
|
1862 |
|
1863 // --------------------------------------------------------------------------- |
|
1864 // DoPatternSearch |
|
1865 // |
|
1866 // Pattern search seeks for predefined sequence of commands. In TSearchPatternBitBlit case the seqence is |
|
1867 // EAlfSetBrushStyle -> EAlfSetBrushStyle -> EAlfSetClippingRegion -> EAlfBitBltMasked -> EAlfResetClippingRegion . |
|
1868 // |
|
1869 // When possible pattern is found, the start offset of the pattern is saved. If pattern is |
|
1870 // noticed 8 or more times in sequence, the pattern is complete. Functions seeks back to the |
|
1871 // start offset and serializes cached data of the pattern. Some data can be dropped as it has |
|
1872 // no significance. |
|
1873 // --------------------------------------------------------------------------- |
|
1874 // |
|
1875 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
1876 void CAlfRsSendBuffer::DoPatternSearch( const TUint8& aCommand, TInt aSize ) |
|
1877 #else |
|
1878 void CAlfRsSendBuffer::DoPatternSearch( const TUint8& aCommand, TInt ) |
|
1879 #endif |
|
1880 { |
|
1881 TInt sizeOfPattern = sizeof(TSearchPatternBitBlit) / (3 * sizeof(TInt32)); // rows = size / width |
|
1882 if ( ( TSearchPatternBitBlit[iPatternSearchState][0] == aCommand |
|
1883 || ( TSearchPatternBitBlit[iPatternSearchState][2] != KErrNotFound && TSearchPatternBitBlit[iPatternSearchState][2] == aCommand )) |
|
1884 && TSearchPatternBitBlit[iPatternSearchState][1] == iPatternSearchState ) |
|
1885 { |
|
1886 TInt tmp = iPatternSearchState; |
|
1887 iPatternSearchState = TSearchPatternBitBlit[iPatternSearchState+1][1]; |
|
1888 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
1889 TPatternCommand command( aCommand, aSize ); |
|
1890 iPatternCommands.Append( command ); |
|
1891 #endif |
|
1892 if ( tmp == 0 && iPatterSearchSequentialBlits == 0 ) |
|
1893 { |
|
1894 // This is the beginning of the sequence. Save position (offset minus size of the current command) |
|
1895 // the for later use. |
|
1896 iPatternCacheBeginPosition = iOffset; |
|
1897 #ifdef _OLD_STREAM |
|
1898 iPatternCacheBeginPosition = TStreamPos( iPatternCacheBeginPosition - sizeof(TUint8) ); // the command |
|
1899 #else |
|
1900 iPatternCacheBeginPosition = iPatternCacheBeginPosition - sizeof(TUint8) ; // the command |
|
1901 #endif |
|
1902 iSearchPatternClipRegion.Clear(); |
|
1903 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
1904 iPatternCommands.Reset(); |
|
1905 #endif |
|
1906 } |
|
1907 else if ( tmp == sizeOfPattern - 1) |
|
1908 { |
|
1909 // Start from the beginning the next sequential pattern |
|
1910 iPatternSearchState = TSearchPatternBitBlit[0][1]; |
|
1911 iPatterSearchSequentialBlits++; |
|
1912 } |
|
1913 } |
|
1914 else |
|
1915 { |
|
1916 TRAP_IGNORE(FinalizePatternL( aCommand )); |
|
1917 } |
|
1918 } |
|
1919 |
|
1920 // --------------------------------------------------------------------------- |
|
1921 // FinalizePatternL |
|
1922 // --------------------------------------------------------------------------- |
|
1923 // |
|
1924 void CAlfRsSendBuffer::FinalizePatternL( const TUint8& aCommand ) |
|
1925 { |
|
1926 // We are looking 8 or more connected chaff pieces |
|
1927 if ( iPatterSearchSequentialBlits >= 9 ) |
|
1928 { |
|
1929 iSearchPatternClipRegion.Tidy(); // will return only one region, if pieces are connected |
|
1930 iSearchPatternBlitRect.Tidy(); |
|
1931 |
|
1932 |
|
1933 if ( iSearchPatternClipRegion.Count() == 1 && iSearchPatternBlitRect.Count() == 1) |
|
1934 { |
|
1935 #ifdef _OLD_STREAM |
|
1936 SeekL( iPatternCacheBeginPosition.Offset() ); |
|
1937 #else |
|
1938 SeekL( iPatternCacheBeginPosition ); |
|
1939 #endif |
|
1940 WriteInt8L( EAlfCombinedBitBlitMasked ); |
|
1941 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
1942 TInt size = iPatterSearchSequentialBlits * sizeof(TBlitStruct) + 2 * sizeof(TRect); |
|
1943 iCommandDebugger->SetDescriptionAndSize( EAlfCombinedBitBlitMasked, size, R_ALF_COMMAND_DESCRIPTION_ARRAY ); |
|
1944 iCommandDebugger->Print(); |
|
1945 while ( iPatternCommands.Count()) |
|
1946 { |
|
1947 iCommandDebugger->AdjustCommand( iPatternCommands[0].iCommand, (-1) * iPatternCommands[0].iSize ); |
|
1948 iPatternCommands.Remove(0); |
|
1949 } |
|
1950 #endif |
|
1951 // item count |
|
1952 WriteInt8L( iPatterSearchSequentialBlits ); |
|
1953 // Clipping region for all the pieces. |
|
1954 // This contains the clippingregion (set by EAlfSetClippingRegion) and rect for all the pieces |
|
1955 // (from EAlfBitBlit, EAlfBitBltRect, EAlfBitBlitMasked ) |
|
1956 TRect clipRect = iSearchPatternClipRegion.BoundingRect(); |
|
1957 TRect clipBlitRect = iSearchPatternBlitRect.BoundingRect(); |
|
1958 |
|
1959 WriteL( (TUint8*)&clipRect, sizeof(TRect)); |
|
1960 WriteL( (TUint8*)&clipBlitRect, sizeof(TRect)); |
|
1961 |
|
1962 // Items |
|
1963 while( iPatterSearchSequentialBlits-- ) |
|
1964 { |
|
1965 TPoint point = iPatternHandleCache[iPatterSearchSequentialBlits].iTl; |
|
1966 WriteL( (TUint8*)&iPatternHandleCache[iPatterSearchSequentialBlits], sizeof(TBlitStruct) ); |
|
1967 } |
|
1968 #ifndef _OPTIMIZE_WS_COMMANDS_ADVANCED_ |
|
1969 WriteInt8L( EAlfSetPenStyle ); |
|
1970 WriteInt32L( iPenStyle ); |
|
1971 #endif |
|
1972 // Write again the current command (after the pattern sequence), because we just overwrote it |
|
1973 WriteInt8L( aCommand ); |
|
1974 } |
|
1975 } |
|
1976 ResetPatternSearch(); |
|
1977 } |
|
1978 |
|
1979 // --------------------------------------------------------------------------- |
|
1980 // ResetPatternSearch |
|
1981 // --------------------------------------------------------------------------- |
|
1982 // |
|
1983 void CAlfRsSendBuffer::ResetPatternSearch() |
|
1984 { |
|
1985 iPatternSearchState = ESeekSetClippingRegion; |
|
1986 iPatterSearchSequentialBlits = 0; |
|
1987 iSearchPatternClipRegion.Clear(); |
|
1988 iSearchPatternBlitRect.Clear(); |
|
1989 iPatternHandleCache.Reset(); |
|
1990 #ifdef _ALF_PRINT_WS_COMMANDS_ |
|
1991 iPatternCommands.Reset(); |
|
1992 #endif |
|
1993 } |
|
1994 |
|
1995 // --------------------------------------------------------------------------- |
|
1996 // AppendPatternSearchCache |
|
1997 // saves masked bitblits to the cache |
|
1998 // --------------------------------------------------------------------------- |
|
1999 // |
|
2000 void CAlfRsSendBuffer::AppendPatternSearchCache( const CFbsBitmap& aSourceBitmap, const CFbsBitmap* aMaskBitmap, const TRect& aSourceRect, const TPoint& aDestPos, TBool aInvertMask ) |
|
2001 { |
|
2002 if (iDisabled) // return if this send buffer is not in use |
|
2003 { |
|
2004 return; |
|
2005 } |
|
2006 |
|
2007 TSize size1 = aSourceRect.Size(); |
|
2008 TSize size2 = aSourceBitmap.SizeInPixels(); |
|
2009 if ( aInvertMask == 1 ) |
|
2010 { |
|
2011 TInt handle = aMaskBitmap ? aMaskBitmap->Handle() : 0; |
|
2012 iPatternHandleCache.Append( TBlitStruct( aSourceBitmap.Handle(),handle, aDestPos ) ); |
|
2013 TRect rect( TPoint(0,0), aSourceRect.Size() ); |
|
2014 rect.Move( aDestPos ); |
|
2015 iSearchPatternBlitRect.AddRect( rect ); |
|
2016 } |
|
2017 else |
|
2018 { |
|
2019 ResetPatternSearch(); |
|
2020 } |
|
2021 } |
|
2022 |
|
2023 |
|
2024 // --------------------------------------------------------------------------- |
|
2025 // InsertPaddingL |
|
2026 // --------------------------------------------------------------------------- |
|
2027 // |
|
2028 void CAlfRsSendBuffer::InsertPaddingL() |
|
2029 { |
|
2030 // padding is required for the 1st part of the package, because the 2nd package |
|
2031 // is attached straight to it and it MUST start at offset divisible by 4. Otherwise |
|
2032 // possible strings in the second package will not be correctly alligned. |
|
2033 TInt offset = iOffset; |
|
2034 TInt padding = offset % KDivisibleByX; |
|
2035 if ( padding > 0) |
|
2036 { |
|
2037 padding = KDivisibleByX - ( offset + sizeof(TUint8) * 2 ) % KDivisibleByX; // 2 = sizeof( EAlfPacketPadding + padding ) |
|
2038 WriteInt8L( EAlfPacketPadding ); |
|
2039 WriteInt8L( padding ); |
|
2040 while( padding--) |
|
2041 { |
|
2042 WriteInt8L( 0 ); |
|
2043 } |
|
2044 if ( !iReceivingDrawingCommands ) |
|
2045 { |
|
2046 WriteInt8L( EAlfCommandEndMarker ); |
|
2047 } |
|
2048 } |
|
2049 #ifdef _DEBUG |
|
2050 ASSERT( ( offset = iOffset ) % KDivisibleByX == 0); |
|
2051 #endif |
|
2052 } |
|
2053 |
|
2054 // --------------------------------------------------------------------------- |
|
2055 // SetFlag |
|
2056 // --------------------------------------------------------------------------- |
|
2057 // |
|
2058 void CAlfRsSendBuffer::SetFlag( TAlfSendBufferFrameFlags aFlag ) |
|
2059 { |
|
2060 if (iDisabled) // return if this send buffer is not in use |
|
2061 { |
|
2062 return; |
|
2063 } |
|
2064 |
|
2065 iFlags |= aFlag; |
|
2066 } |
|
2067 |
|
2068 // --------------------------------------------------------------------------- |
|
2069 // EndFrameL |
|
2070 // --------------------------------------------------------------------------- |
|
2071 // |
|
2072 void CAlfRsSendBuffer::EndFrameL() |
|
2073 { |
|
2074 if (iDisabled) // return if this send buffer is not in use |
|
2075 { |
|
2076 return; |
|
2077 } |
|
2078 |
|
2079 TUint8 command(EAlfPacketReady); |
|
2080 if ( iFlags & EAlfTransparentContent && !(iFlags & EAlfTransparentContentFlush ) ) |
|
2081 { |
|
2082 InsertPaddingL(); |
|
2083 } |
|
2084 |
|
2085 if ( WriteFollowingFrameOffsetL() ) |
|
2086 { |
|
2087 WriteCommandL( command ); |
|
2088 } |
|
2089 #ifdef ALF_DEBUG_TRACK_DRAWING |
|
2090 TInt trackThisNode = 0; |
|
2091 if ( trackThisNode ) |
|
2092 { |
|
2093 WriteIntsL( EAlfDebugTrackNode, 2, (TInt32)&iWindowId, 1 ); |
|
2094 } |
|
2095 #endif |
|
2096 } |
|
2097 |
|
2098 // --------------------------------------------------------------------------- |
|
2099 // SeekL |
|
2100 // --------------------------------------------------------------------------- |
|
2101 // |
|
2102 void CAlfRsSendBuffer::SeekL( const TInt aOffset ) |
|
2103 { |
|
2104 #ifdef _OLD_STREAM |
|
2105 iBufStream->Sink()->SeekL( MStreamBuf::EWrite, TStreamPos(aOffset)); |
|
2106 #endif |
|
2107 iOffset = aOffset; |
|
2108 } |