|
1 /* |
|
2 * Copyright (c) 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: ?Description |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "alfdebugserver.h" |
|
20 #include "alfdebugextensionconstants.h" |
|
21 #include "alfdebuguid.h" |
|
22 #include "alfdebug.h" // for TAlfDebugServerMeasurements |
|
23 |
|
24 #include <uiacceltk/huienv.h> |
|
25 #include <uiacceltk/huicommand.h> |
|
26 #include <uiacceltk/huistatic.h> |
|
27 #include <uiacceltk/huicontrol.h> |
|
28 #include <uiacceltk/huicontrolgroup.h> |
|
29 #include <uiacceltk/huitextvisual.h> |
|
30 #include <uiacceltk/huieventhandler.h> |
|
31 #include <uiacceltk/huievent.h> |
|
32 #include <uiacceltk/huidisplay.h> |
|
33 #include <uiacceltk/huiroster.h> |
|
34 #include <uiacceltk/huigridlayout.h> |
|
35 |
|
36 #include <implementationproxy.h> |
|
37 |
|
38 |
|
39 _LIT8( KFrameRateTag, "FPS" ); |
|
40 _LIT8( KHeapTag, "heap" ); |
|
41 _LIT8( KContainerTag, "container" ); |
|
42 _LIT8( KIdleCheckerTag, "idle" ); |
|
43 |
|
44 |
|
45 enum TCustomEventCommands |
|
46 { |
|
47 EUpdateFrameRate, |
|
48 EUpdateServerHeap |
|
49 }; |
|
50 |
|
51 // this is a helper class to know when the refreshing goes to idle |
|
52 // assumptions: CHuiVisual::Changed() is called for every visual in the |
|
53 // shown control group. If something is drawn in the loop, the |
|
54 // CHuiVisual::ClearChanged() is called. If nothing is drawn, it is not called |
|
55 class CIdleCheckVisual : public CHuiVisual |
|
56 { |
|
57 public: |
|
58 static CIdleCheckVisual* AddNewL( |
|
59 CHuiControl& aOwnerControl, |
|
60 CHuiLayout* aParentLayout = 0); |
|
61 |
|
62 protected: |
|
63 CIdleCheckVisual(MHuiVisualOwner& aOwner); |
|
64 ~CIdleCheckVisual(); |
|
65 |
|
66 public: // from base classes |
|
67 void ClearChanged(); |
|
68 TBool Changed() const; |
|
69 |
|
70 // for async one shot |
|
71 mutable CAsyncCallBack* iAsyncCallBack; |
|
72 static TInt CallBackFunction(TAny* aAny); |
|
73 |
|
74 enum TState |
|
75 { |
|
76 EDisabled, |
|
77 EIdleNeedsReseting, |
|
78 EDrawning, |
|
79 EUpdatingText, |
|
80 EGoingToIdle1, |
|
81 EGoingToIdle2, |
|
82 EGoingToIdle3 |
|
83 }; |
|
84 |
|
85 mutable TState iState; |
|
86 |
|
87 }; |
|
88 |
|
89 |
|
90 // monitor control for showing the text visuals and receiving the events. |
|
91 class CMonitorControl : public CHuiControl |
|
92 { |
|
93 public: |
|
94 CMonitorControl(CHuiEnv& aEnv, CAlfDebugServer& aServerSession ); |
|
95 void ConstructL(); |
|
96 TBool OfferEventL(const THuiEvent& aEvent); |
|
97 |
|
98 void UpdateFrameRateTextL( TReal32 aFrameRate ); |
|
99 public: |
|
100 TInt iInitialVisualCount; |
|
101 private: |
|
102 CAlfDebugServer& iServerSession; |
|
103 }; |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 CIdleCheckVisual* CIdleCheckVisual::AddNewL( |
|
111 CHuiControl& aOwnerControl, |
|
112 CHuiLayout* aParentLayout ) |
|
113 { |
|
114 CIdleCheckVisual* visual = new (ELeave) CIdleCheckVisual(aOwnerControl); |
|
115 CleanupStack::PushL( visual ); |
|
116 visual->ConstructL(); |
|
117 aOwnerControl.AppendL(visual, aParentLayout); |
|
118 CleanupStack::Pop(visual); |
|
119 return visual; |
|
120 } |
|
121 |
|
122 CIdleCheckVisual::CIdleCheckVisual(MHuiVisualOwner& aOwner) |
|
123 : CHuiVisual( aOwner ), iState( EIdleNeedsReseting ) |
|
124 { |
|
125 } |
|
126 |
|
127 CIdleCheckVisual::~CIdleCheckVisual() |
|
128 { |
|
129 if ( iAsyncCallBack ) |
|
130 { |
|
131 iAsyncCallBack->Cancel(); |
|
132 } |
|
133 delete iAsyncCallBack; |
|
134 iAsyncCallBack = NULL; |
|
135 } |
|
136 |
|
137 TBool CIdleCheckVisual::Changed() const |
|
138 { |
|
139 if ( iState == EIdleNeedsReseting ) |
|
140 { |
|
141 CHuiStatic::FrameRate(); // just reset the framerate counter. |
|
142 iState = EDrawning; |
|
143 } |
|
144 |
|
145 if ( iAsyncCallBack ) |
|
146 { |
|
147 iAsyncCallBack->Cancel(); |
|
148 } |
|
149 else |
|
150 { |
|
151 TCallBack callback( CallBackFunction, const_cast<CIdleCheckVisual*>(this) ); |
|
152 iAsyncCallBack = new CAsyncCallBack( callback, CActive::EPriorityHigh ); |
|
153 } |
|
154 |
|
155 if ( iState != EDisabled ) |
|
156 { |
|
157 iAsyncCallBack->CallBack(); |
|
158 } |
|
159 |
|
160 return CHuiVisual::Changed(); |
|
161 } |
|
162 |
|
163 void CIdleCheckVisual::ClearChanged() |
|
164 { |
|
165 if ( iAsyncCallBack ) |
|
166 { |
|
167 iAsyncCallBack->Cancel(); |
|
168 } |
|
169 CHuiVisual::ClearChanged(); |
|
170 } |
|
171 |
|
172 TInt CIdleCheckVisual::CallBackFunction(TAny* aAny) |
|
173 { |
|
174 // if this function is called, we assume that the drawing has gone to idle |
|
175 CIdleCheckVisual* self = static_cast<CIdleCheckVisual*>( aAny ); |
|
176 |
|
177 switch (self->iState) |
|
178 { |
|
179 case EIdleNeedsReseting: |
|
180 break; |
|
181 case EDrawning: |
|
182 // real drawing loop ended. update text which will cause some more drawing. |
|
183 TRAP_IGNORE(static_cast<CMonitorControl*>( &self->Owner() )->UpdateFrameRateTextL( CHuiStatic::FrameRate() )); |
|
184 self->iState = EUpdatingText; |
|
185 break; |
|
186 case EUpdatingText: |
|
187 // text update drawing ongoing |
|
188 self->iState = EGoingToIdle1; |
|
189 break; |
|
190 case EGoingToIdle1: |
|
191 // text update drawing ongoing |
|
192 self->iState = EGoingToIdle2; |
|
193 break; |
|
194 case EGoingToIdle2: |
|
195 // text update drawing ongoing |
|
196 self->iState = EGoingToIdle3; |
|
197 break; |
|
198 case EGoingToIdle3: |
|
199 // text update drawing ongoing |
|
200 self->iState = EIdleNeedsReseting; |
|
201 break; |
|
202 default: |
|
203 break; |
|
204 } |
|
205 |
|
206 return KErrNone; |
|
207 } |
|
208 |
|
209 |
|
210 |
|
211 CMonitorControl::CMonitorControl(CHuiEnv& aEnv, CAlfDebugServer& aServerSession) : |
|
212 CHuiControl(aEnv), |
|
213 iServerSession( aServerSession ) |
|
214 { |
|
215 } |
|
216 |
|
217 void CMonitorControl::ConstructL() |
|
218 { |
|
219 CHuiControl::ConstructL(); |
|
220 |
|
221 // create idle checker |
|
222 CIdleCheckVisual* idleChecker = CIdleCheckVisual::AddNewL( *this ); |
|
223 idleChecker->SetTagL(KIdleCheckerTag); |
|
224 idleChecker->iState = CIdleCheckVisual::EDisabled; // activate when requested. |
|
225 |
|
226 // create container for the texts |
|
227 CHuiGridLayout* gridContainer = CHuiGridLayout::AddNewL( *this, 1 , 5 ); |
|
228 gridContainer->SetTagL(KContainerTag); |
|
229 |
|
230 THuiBoxMetric padding( |
|
231 THuiXYMetric( // top left |
|
232 THuiMetric( 0.5f , EHuiUnitMySize), // left |
|
233 THuiMetric( 0.2f , EHuiUnitMySize) // top |
|
234 ), |
|
235 THuiXYMetric( // bottom right |
|
236 THuiMetric( 0.f , EHuiUnitMySize), // right |
|
237 THuiMetric( 0.1f , EHuiUnitMySize)// bottom |
|
238 ) ); |
|
239 |
|
240 gridContainer->SetPadding( padding ); |
|
241 |
|
242 |
|
243 // update this at the end |
|
244 iInitialVisualCount = VisualCount(); |
|
245 } |
|
246 |
|
247 |
|
248 |
|
249 TBool CMonitorControl::OfferEventL(const THuiEvent& aEvent) |
|
250 { |
|
251 TBool handled = EFalse; |
|
252 if (aEvent.IsCustomEvent() && aEvent.iParam == EUpdateFrameRate ) |
|
253 { |
|
254 UpdateFrameRateTextL( CHuiStatic::FrameRate() ); |
|
255 |
|
256 THuiCustomEventCommand command( EUpdateFrameRate, static_cast<MHuiEventHandler*>(this) ); |
|
257 Env().Send( command, iServerSession.iFpsUpdatePeriod ); |
|
258 |
|
259 handled = ETrue; |
|
260 } |
|
261 else if ( aEvent.IsCustomEvent() && aEvent.iParam == EUpdateServerHeap ) |
|
262 { |
|
263 CHuiTextVisual* textVisual = static_cast<CHuiTextVisual*>(FindTag( KHeapTag ) ); |
|
264 |
|
265 User::Heap().Compress(); |
|
266 |
|
267 TInt totalSize = 0; |
|
268 TInt usedSize = User::AllocSize( totalSize ); |
|
269 TBuf<32> buffer; |
|
270 buffer.AppendNum( usedSize ); |
|
271 buffer.Append( _L(" cells\n") ); |
|
272 buffer.AppendNum( totalSize ); |
|
273 buffer.Append( _L("B") ); |
|
274 |
|
275 textVisual->SetTextL( buffer ); |
|
276 |
|
277 THuiCustomEventCommand command( EUpdateServerHeap, static_cast<MHuiEventHandler*>(this) ); |
|
278 Env().Send( command, iServerSession.iServerHeapUpdatePeriod ); |
|
279 |
|
280 // make sure we are on top |
|
281 if ( Env().DisplayCount() ) |
|
282 { |
|
283 CHuiDisplay& display = Env().PrimaryDisplay(); |
|
284 display.Roster().ShowL( *ControlGroup() ); |
|
285 } |
|
286 |
|
287 handled = ETrue; |
|
288 } |
|
289 |
|
290 return handled; |
|
291 } |
|
292 |
|
293 void CMonitorControl::UpdateFrameRateTextL( TReal32 aFrameRate ) |
|
294 { |
|
295 CHuiTextVisual* textVisual = static_cast<CHuiTextVisual*>(FindTag( KFrameRateTag ) ); |
|
296 |
|
297 TBuf<32> buffer; |
|
298 buffer.AppendNum(aFrameRate, TRealFormat( 4, 1 ) ); |
|
299 buffer.Append( _L(" fps") ); |
|
300 textVisual->SetTextL( buffer ); |
|
301 |
|
302 // make sure we are on top |
|
303 if ( Env().DisplayCount() ) |
|
304 { |
|
305 CHuiDisplay& display = Env().PrimaryDisplay(); |
|
306 display.Roster().ShowL( *ControlGroup() ); |
|
307 } |
|
308 } |
|
309 |
|
310 |
|
311 // ======== MEMBER FUNCTIONS ======== |
|
312 |
|
313 // --------------------------------------------------------------------------- |
|
314 // ?description_if_needed |
|
315 // --------------------------------------------------------------------------- |
|
316 // |
|
317 MAlfExtension* TAlfDebugHandler::CreateExtensionL( |
|
318 const TInt aObjectId, |
|
319 const TDesC8& /*aInitialParams*/, |
|
320 MAlfInterfaceProvider& aResolver ) |
|
321 { |
|
322 MAlfExtension* result = NULL; |
|
323 switch( aObjectId ) |
|
324 { |
|
325 case EAlfDebugExtensionCreateDebug: |
|
326 { |
|
327 result = new (ELeave) CAlfDebugServer( *aResolver.SharedHuiEnv() ); |
|
328 break; |
|
329 } |
|
330 |
|
331 default: |
|
332 User::Leave( KErrNotSupported ); |
|
333 } |
|
334 return result; |
|
335 } |
|
336 |
|
337 void TAlfDebugHandler::Release() |
|
338 { |
|
339 delete this; |
|
340 } |
|
341 |
|
342 // --------------------------------------------------------------------------- |
|
343 // ?description_if_needed |
|
344 // --------------------------------------------------------------------------- |
|
345 // |
|
346 CAlfDebugServer::CAlfDebugServer( CHuiEnv& aEnv ) : iEnv( aEnv ) |
|
347 { |
|
348 iFpsUpdatePeriod = 500; |
|
349 iServerHeapUpdatePeriod = 400; |
|
350 } |
|
351 |
|
352 CAlfDebugServer::~CAlfDebugServer() |
|
353 { |
|
354 if ( iGroup ) |
|
355 { |
|
356 iEnv.DeleteControlGroup( TInt(this) ); |
|
357 } |
|
358 iGroup = NULL; |
|
359 } |
|
360 |
|
361 void CAlfDebugServer::Release() |
|
362 { |
|
363 delete this; |
|
364 } |
|
365 |
|
366 TAny* CAlfDebugServer::GetInterface( const THuiInterfaceSupport& /*aInterface*/ ) |
|
367 { |
|
368 return NULL; |
|
369 } |
|
370 |
|
371 void CAlfDebugServer::HandleCmdL( TInt aCommandId, const TDesC8& aInputBuffer, TDes8& aResponse ) |
|
372 { |
|
373 switch (aCommandId) |
|
374 { |
|
375 case EAlfDebugCmdSetTimeFactor: |
|
376 { |
|
377 const TReal32* inParam = (TReal32*) aInputBuffer.Ptr(); |
|
378 CHuiStatic::SetTimeFactor(*inParam); |
|
379 break; |
|
380 } |
|
381 case EAlfDebugCmdGetTimeFactor: |
|
382 { |
|
383 const TReal32 result = CHuiStatic::TimeFactor(); |
|
384 TPckg<TReal32> resultPckg(result); |
|
385 aResponse = resultPckg; |
|
386 break; |
|
387 } |
|
388 case EAlfDebugCmdGetFrameCount: |
|
389 { |
|
390 const TUint result = CHuiStatic::FrameCount(); |
|
391 TPckg<TUint> resultPckg(result); |
|
392 aResponse = resultPckg; |
|
393 break; |
|
394 } |
|
395 case EAlfDebugCmdGetFrameRate: |
|
396 { |
|
397 const TReal32 result = CHuiStatic::FrameRate(); |
|
398 TPckg<TReal32> resultPckg(result); |
|
399 aResponse = resultPckg; |
|
400 |
|
401 // show on screen if needed |
|
402 if ( iControl && iFpsUpdatePeriod == -2 ) |
|
403 { |
|
404 iControl->UpdateFrameRateTextL( result ); |
|
405 } |
|
406 break; |
|
407 } |
|
408 case EAlfDebugCmdShowFrameRate: |
|
409 { |
|
410 const TInt* inParam = (TBool*) aInputBuffer.Ptr(); |
|
411 ShowFrameRateL(*inParam); |
|
412 break; |
|
413 } |
|
414 |
|
415 case EAlfDebugCmdShowServerHeap: |
|
416 { |
|
417 const TBool* inParam = (TBool*) aInputBuffer.Ptr(); |
|
418 ShowServerHeapL(*inParam); |
|
419 break; |
|
420 } |
|
421 |
|
422 case EAlfDebugCmdMeasure: |
|
423 { |
|
424 TAlfDebugServerMeasurements measurements; |
|
425 TPckg<TAlfDebugServerMeasurements> result(measurements); |
|
426 |
|
427 // Timestamp |
|
428 measurements.iTimeStamp = User::NTickCount(); |
|
429 |
|
430 // Memory measures |
|
431 measurements.iServerCells = |
|
432 User::AllocSize( measurements.iServerMemory ); |
|
433 TInt dummy; |
|
434 measurements.iServerFree = User::Available( dummy ); |
|
435 |
|
436 // Rendering measures |
|
437 measurements.iFrameCount = CHuiStatic::FrameCount(); |
|
438 |
|
439 aResponse = result; |
|
440 } |
|
441 break; |
|
442 |
|
443 default: |
|
444 User::Leave( KErrNotSupported ); |
|
445 break; |
|
446 } |
|
447 } |
|
448 |
|
449 void CAlfDebugServer::CreateControlIfNeededL() |
|
450 { |
|
451 if ( !iGroup ) |
|
452 { |
|
453 iGroup = &iEnv.NewControlGroupL( TInt(this) ); |
|
454 } |
|
455 |
|
456 if ( !iControl ) |
|
457 { |
|
458 CMonitorControl* control = new (ELeave) CMonitorControl(iEnv, *this); |
|
459 CleanupStack::PushL( control ); |
|
460 control->ConstructL(); |
|
461 iGroup->AppendL( control ); |
|
462 CleanupStack::Pop( control ); |
|
463 iControl = control; |
|
464 } |
|
465 |
|
466 // make sure we are on top |
|
467 if ( iEnv.DisplayCount() ) |
|
468 { |
|
469 CHuiDisplay& display = iEnv.PrimaryDisplay(); |
|
470 display.Roster().ShowL( *iGroup ); |
|
471 } |
|
472 } |
|
473 |
|
474 |
|
475 void CAlfDebugServer::DeteteControlIfNeeded() |
|
476 { |
|
477 if ( iControl && iControl->VisualCount() == iControl->iInitialVisualCount ) |
|
478 { |
|
479 iGroup->Remove( iControl ); |
|
480 delete iControl; |
|
481 iControl = NULL; |
|
482 } |
|
483 |
|
484 if ( iGroup && iGroup->Count() == 0 ) |
|
485 { |
|
486 iEnv.DeleteControlGroup( TInt(this) ); |
|
487 iGroup = NULL; |
|
488 } |
|
489 } |
|
490 |
|
491 void CAlfDebugServer::ShowFrameRateL( TInt aInterval ) |
|
492 { |
|
493 CHuiTextVisual* textVisual = iControl ? static_cast<CHuiTextVisual*>(iControl->FindTag( KFrameRateTag ) ) : 0; |
|
494 if ( aInterval != KAlfDebugHideFraweRate ) |
|
495 { |
|
496 CreateControlIfNeededL(); |
|
497 |
|
498 if ( !textVisual ) |
|
499 { |
|
500 textVisual = CHuiTextVisual::AddNewL(*iControl, static_cast<CHuiLayout*>(iControl->FindTag( KContainerTag )) ); |
|
501 textVisual->SetTagL( KFrameRateTag ); |
|
502 textVisual->SetColor( KRgbRed ); |
|
503 } |
|
504 |
|
505 |
|
506 CIdleCheckVisual* idleChecker = static_cast<CIdleCheckVisual*>(iControl->FindTag( KIdleCheckerTag )); |
|
507 if ( aInterval == KAlfDebugShowFraweRateAfterDrawLoop ) // idle-idle |
|
508 { |
|
509 // use idle-idle |
|
510 idleChecker->iState = CIdleCheckVisual::EIdleNeedsReseting; |
|
511 } |
|
512 else if ( aInterval == KAlfDebugShowFraweRateWhenQueried ) // manual |
|
513 { |
|
514 iFpsUpdatePeriod = aInterval; |
|
515 idleChecker->iState = CIdleCheckVisual::EDisabled; |
|
516 } |
|
517 else |
|
518 { |
|
519 iFpsUpdatePeriod = aInterval; |
|
520 idleChecker->iState = CIdleCheckVisual::EDisabled; |
|
521 |
|
522 THuiCustomEventCommand command( EUpdateFrameRate, static_cast<MHuiEventHandler*>(iControl) ); |
|
523 iEnv.Send( command, iFpsUpdatePeriod ); |
|
524 } |
|
525 } |
|
526 else |
|
527 { |
|
528 if ( iControl ) |
|
529 { |
|
530 if ( textVisual ) |
|
531 { |
|
532 textVisual->RemoveAndDestroyAllD(); |
|
533 } |
|
534 iEnv.CancelCommands( static_cast<MHuiEventHandler*>(iControl) , EHuiCommandTypeCustomEvent, EUpdateFrameRate ); |
|
535 } |
|
536 |
|
537 DeteteControlIfNeeded(); |
|
538 } |
|
539 } |
|
540 |
|
541 void CAlfDebugServer::ShowServerHeapL( TBool aShow ) |
|
542 { |
|
543 CHuiTextVisual* textVisual = iControl ? static_cast<CHuiTextVisual*>(iControl->FindTag( KHeapTag ) ) : 0; |
|
544 if ( aShow ) |
|
545 { |
|
546 CreateControlIfNeededL(); |
|
547 |
|
548 if ( !textVisual ) |
|
549 { |
|
550 textVisual = CHuiTextVisual::AddNewL(*iControl, static_cast<CHuiLayout*>(iControl->FindTag( KContainerTag ))); |
|
551 textVisual->SetTagL( KHeapTag ); |
|
552 textVisual->SetColor( KRgbRed ); |
|
553 } |
|
554 |
|
555 THuiCustomEventCommand command( EUpdateServerHeap, static_cast<MHuiEventHandler*>(iControl) ); |
|
556 iEnv.Send( command, iServerHeapUpdatePeriod ); |
|
557 } |
|
558 else |
|
559 { |
|
560 if ( iControl ) |
|
561 { |
|
562 if ( textVisual ) |
|
563 { |
|
564 textVisual->RemoveAndDestroyAllD(); |
|
565 } |
|
566 iEnv.CancelCommands( static_cast<MHuiEventHandler*>(iControl) , EHuiCommandTypeCustomEvent, EUpdateServerHeap ); |
|
567 } |
|
568 DeteteControlIfNeeded(); |
|
569 } |
|
570 } |
|
571 |
|
572 |
|
573 // Global functions: |
|
574 |
|
575 MAlfExtensionFactory* Instance() |
|
576 { |
|
577 TAlfDebugHandler* me = NULL; |
|
578 me = new TAlfDebugHandler; |
|
579 return me; |
|
580 } |
|
581 |
|
582 const TImplementationProxy ImplementationTable[] = |
|
583 { |
|
584 #ifdef __EABI__ |
|
585 {{KAlfDebugExtensionImplementationId}, (TFuncPtr)Instance} |
|
586 #else |
|
587 {{KAlfDebugExtensionImplementationId}, Instance} |
|
588 #endif |
|
589 }; |
|
590 |
|
591 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) |
|
592 { |
|
593 aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy) ; |
|
594 return ImplementationTable; |
|
595 } |
|
596 |