uiacceltk/hitchcock/tsrc/alfdebugextension/src/alfdebugserver.cpp
changeset 0 15bf7259bb7c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/tsrc/alfdebugextension/src/alfdebugserver.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,596 @@
+/*
+* Copyright (c)  Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  ?Description
+*
+*/
+
+
+#include "alfdebugserver.h"
+#include "alfdebugextensionconstants.h"
+#include "alfdebuguid.h"
+#include "alfdebug.h" // for TAlfDebugServerMeasurements
+
+#include <uiacceltk/huienv.h>
+#include <uiacceltk/huicommand.h>
+#include <uiacceltk/huistatic.h>
+#include <uiacceltk/huicontrol.h>
+#include <uiacceltk/huicontrolgroup.h>
+#include <uiacceltk/huitextvisual.h>
+#include <uiacceltk/huieventhandler.h>
+#include <uiacceltk/huievent.h>
+#include <uiacceltk/huidisplay.h>
+#include <uiacceltk/huiroster.h>
+#include <uiacceltk/huigridlayout.h>
+
+#include <implementationproxy.h>
+
+
+_LIT8( KFrameRateTag, "FPS" );
+_LIT8( KHeapTag, "heap" );
+_LIT8( KContainerTag, "container" );
+_LIT8( KIdleCheckerTag, "idle" );
+
+
+enum TCustomEventCommands 
+    {
+    EUpdateFrameRate,
+    EUpdateServerHeap
+    };
+
+// this is a helper class to know when the refreshing goes to idle
+// assumptions: CHuiVisual::Changed() is called for every visual in the 
+// shown control group. If something is drawn in the loop, the 
+// CHuiVisual::ClearChanged() is called. If nothing is drawn, it is not called
+class CIdleCheckVisual : public CHuiVisual
+    {
+public:
+    static CIdleCheckVisual* AddNewL(
+        CHuiControl& aOwnerControl,
+        CHuiLayout* aParentLayout = 0);    
+        
+protected:
+    CIdleCheckVisual(MHuiVisualOwner& aOwner);
+    ~CIdleCheckVisual();
+        
+public: // from base classes
+    void ClearChanged();
+    TBool Changed() const;
+    
+// for async one shot
+    mutable CAsyncCallBack* iAsyncCallBack;
+    static TInt CallBackFunction(TAny* aAny);
+
+    enum TState
+        {
+        EDisabled,
+        EIdleNeedsReseting,
+        EDrawning,
+        EUpdatingText,
+        EGoingToIdle1,
+        EGoingToIdle2,
+        EGoingToIdle3
+        };
+        
+    mutable TState iState;
+        
+    };
+    
+    
+// monitor control for showing the text visuals and receiving the events.
+class CMonitorControl : public CHuiControl
+    {
+public:
+    CMonitorControl(CHuiEnv& aEnv, CAlfDebugServer& aServerSession );
+    void ConstructL();
+    TBool OfferEventL(const THuiEvent& aEvent);
+    
+    void UpdateFrameRateTextL( TReal32 aFrameRate );
+public:
+    TInt iInitialVisualCount;
+private:
+    CAlfDebugServer& iServerSession;
+    };    
+    
+    
+    
+    
+    
+    
+CIdleCheckVisual* CIdleCheckVisual::AddNewL(
+        CHuiControl& aOwnerControl,
+        CHuiLayout* aParentLayout )
+    {
+    CIdleCheckVisual* visual = new (ELeave) CIdleCheckVisual(aOwnerControl);
+    CleanupStack::PushL( visual );
+    visual->ConstructL();
+    aOwnerControl.AppendL(visual, aParentLayout);
+    CleanupStack::Pop(visual);
+    return visual;
+    }
+    
+CIdleCheckVisual::CIdleCheckVisual(MHuiVisualOwner& aOwner) 
+ : CHuiVisual( aOwner ), iState( EIdleNeedsReseting )
+    {
+    }
+    
+CIdleCheckVisual::~CIdleCheckVisual()
+    {
+    if ( iAsyncCallBack )
+        {
+        iAsyncCallBack->Cancel();
+        }
+    delete iAsyncCallBack;
+    iAsyncCallBack = NULL;
+    }
+    
+TBool CIdleCheckVisual::Changed() const
+    {
+    if ( iState == EIdleNeedsReseting )
+        {
+        CHuiStatic::FrameRate(); // just reset the framerate counter.
+        iState = EDrawning;
+        }
+    
+    if ( iAsyncCallBack )
+        {
+        iAsyncCallBack->Cancel();
+        }
+    else 
+        {
+        TCallBack callback( CallBackFunction, const_cast<CIdleCheckVisual*>(this) );
+        iAsyncCallBack = new CAsyncCallBack( callback, CActive::EPriorityHigh );
+        }  
+        
+    if ( iState != EDisabled )
+        {
+        iAsyncCallBack->CallBack();
+        }
+        
+    return CHuiVisual::Changed();
+    }
+    
+void CIdleCheckVisual::ClearChanged()
+    {
+    if ( iAsyncCallBack )
+        {
+        iAsyncCallBack->Cancel();
+        }
+    CHuiVisual::ClearChanged();
+    }
+    
+TInt CIdleCheckVisual::CallBackFunction(TAny* aAny)
+    {
+    // if this function is called, we assume that the drawing has gone to idle
+    CIdleCheckVisual* self = static_cast<CIdleCheckVisual*>( aAny );
+    
+    switch (self->iState)
+        {
+        case EIdleNeedsReseting:
+            break;
+        case EDrawning:
+            // real drawing loop ended. update text which will cause some more drawing.
+            TRAP_IGNORE(static_cast<CMonitorControl*>( &self->Owner() )->UpdateFrameRateTextL( CHuiStatic::FrameRate() ));
+            self->iState = EUpdatingText;
+            break;
+        case EUpdatingText:
+            // text update drawing ongoing
+            self->iState = EGoingToIdle1;
+            break;
+        case EGoingToIdle1:
+            // text update drawing ongoing
+            self->iState = EGoingToIdle2;
+            break;
+        case EGoingToIdle2:
+            // text update drawing ongoing
+            self->iState = EGoingToIdle3;
+            break;
+        case EGoingToIdle3:
+            // text update drawing ongoing
+            self->iState = EIdleNeedsReseting;
+            break;
+        default:
+            break;
+        }
+    
+    return KErrNone;
+    }
+
+
+    
+CMonitorControl::CMonitorControl(CHuiEnv& aEnv, CAlfDebugServer& aServerSession) : 
+    CHuiControl(aEnv), 
+    iServerSession( aServerSession )
+    {
+    }
+
+void CMonitorControl::ConstructL()
+    {
+    CHuiControl::ConstructL();
+    
+    // create idle checker
+    CIdleCheckVisual* idleChecker = CIdleCheckVisual::AddNewL( *this );
+    idleChecker->SetTagL(KIdleCheckerTag);
+    idleChecker->iState = CIdleCheckVisual::EDisabled; // activate when requested.
+    
+    // create container for the texts
+    CHuiGridLayout* gridContainer = CHuiGridLayout::AddNewL( *this, 1 , 5 );
+    gridContainer->SetTagL(KContainerTag);
+    
+    THuiBoxMetric padding( 
+        THuiXYMetric( // top left
+            THuiMetric( 0.5f , EHuiUnitMySize), // left
+            THuiMetric( 0.2f , EHuiUnitMySize)  // top
+            ),
+        THuiXYMetric( // bottom right
+            THuiMetric( 0.f , EHuiUnitMySize), // right
+            THuiMetric( 0.1f , EHuiUnitMySize)// bottom
+            ) );
+            
+    gridContainer->SetPadding( padding );
+    
+    
+    // update this at the end
+    iInitialVisualCount = VisualCount();
+    }
+    
+    
+    
+TBool CMonitorControl::OfferEventL(const THuiEvent& aEvent)
+    {
+    TBool handled = EFalse;
+    if (aEvent.IsCustomEvent() && aEvent.iParam == EUpdateFrameRate )
+        {
+        UpdateFrameRateTextL( CHuiStatic::FrameRate() );
+        
+        THuiCustomEventCommand command( EUpdateFrameRate, static_cast<MHuiEventHandler*>(this) );
+        Env().Send( command, iServerSession.iFpsUpdatePeriod );        
+        
+        handled = ETrue;
+        }
+    else if ( aEvent.IsCustomEvent() && aEvent.iParam == EUpdateServerHeap )
+        {
+        CHuiTextVisual* textVisual = static_cast<CHuiTextVisual*>(FindTag( KHeapTag ) );
+        
+        User::Heap().Compress();
+        
+        TInt totalSize = 0;
+        TInt usedSize = User::AllocSize( totalSize );
+        TBuf<32> buffer;
+        buffer.AppendNum( usedSize );
+        buffer.Append( _L(" cells\n") );
+        buffer.AppendNum( totalSize );
+        buffer.Append( _L("B") );
+
+        textVisual->SetTextL( buffer );
+        
+        THuiCustomEventCommand command( EUpdateServerHeap, static_cast<MHuiEventHandler*>(this) );
+        Env().Send( command, iServerSession.iServerHeapUpdatePeriod );
+        
+        // make sure we are on top
+        if ( Env().DisplayCount() )
+            {
+            CHuiDisplay& display = Env().PrimaryDisplay();
+            display.Roster().ShowL( *ControlGroup() );
+            }
+            
+        handled = ETrue;
+        }
+        
+    return handled;
+    }
+    
+void CMonitorControl::UpdateFrameRateTextL( TReal32 aFrameRate )
+    {
+    CHuiTextVisual* textVisual = static_cast<CHuiTextVisual*>(FindTag( KFrameRateTag ) );
+        
+    TBuf<32> buffer;
+    buffer.AppendNum(aFrameRate,  TRealFormat( 4, 1 ) );
+    buffer.Append( _L(" fps") );
+    textVisual->SetTextL( buffer );
+    
+    // make sure we are on top
+    if ( Env().DisplayCount() )
+        {
+        CHuiDisplay& display = Env().PrimaryDisplay();
+        display.Roster().ShowL( *ControlGroup() );
+        }
+    }
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// ?description_if_needed
+// ---------------------------------------------------------------------------
+//
+MAlfExtension* TAlfDebugHandler::CreateExtensionL(
+        const TInt aObjectId, 
+        const TDesC8& /*aInitialParams*/, 
+        MAlfInterfaceProvider& aResolver )
+    {
+    MAlfExtension* result = NULL;
+    switch( aObjectId )
+        {
+        case EAlfDebugExtensionCreateDebug:
+            {
+            result = new (ELeave) CAlfDebugServer( *aResolver.SharedHuiEnv() );
+            break;
+            }  
+
+        default:
+            User::Leave( KErrNotSupported );
+        }
+    return result;
+    }
+    
+void TAlfDebugHandler::Release()
+    {
+    delete this;
+    }
+
+// ---------------------------------------------------------------------------
+// ?description_if_needed
+// ---------------------------------------------------------------------------
+// 
+CAlfDebugServer::CAlfDebugServer( CHuiEnv& aEnv ) : iEnv( aEnv )
+    {
+    iFpsUpdatePeriod = 500;
+    iServerHeapUpdatePeriod = 400;
+    }
+   
+CAlfDebugServer::~CAlfDebugServer()
+    {
+    if ( iGroup )
+        {
+        iEnv.DeleteControlGroup( TInt(this) );
+        }
+    iGroup = NULL;
+    }
+    
+void CAlfDebugServer::Release()
+    {
+    delete this;
+    }
+    
+TAny* CAlfDebugServer::GetInterface( const THuiInterfaceSupport& /*aInterface*/ )
+    {
+    return NULL;
+    }
+    
+void CAlfDebugServer::HandleCmdL( TInt aCommandId, const TDesC8& aInputBuffer, TDes8& aResponse )
+    {
+    switch (aCommandId)
+        {
+        case EAlfDebugCmdSetTimeFactor:
+            {
+            const TReal32* inParam = (TReal32*) aInputBuffer.Ptr();
+            CHuiStatic::SetTimeFactor(*inParam);
+            break;
+            }
+        case EAlfDebugCmdGetTimeFactor:
+            {
+            const TReal32 result = CHuiStatic::TimeFactor();
+            TPckg<TReal32> resultPckg(result);
+            aResponse = resultPckg;
+            break;
+            }
+        case EAlfDebugCmdGetFrameCount:
+            {    
+            const TUint result = CHuiStatic::FrameCount();
+            TPckg<TUint> resultPckg(result);
+            aResponse = resultPckg;
+            break;
+            }
+        case EAlfDebugCmdGetFrameRate:
+            {    
+            const TReal32 result = CHuiStatic::FrameRate();
+            TPckg<TReal32> resultPckg(result);
+            aResponse = resultPckg;
+            
+            // show on screen if needed
+            if ( iControl && iFpsUpdatePeriod == -2 )
+                {
+                iControl->UpdateFrameRateTextL( result );
+                }
+            break;
+            }
+        case EAlfDebugCmdShowFrameRate:
+            {
+            const TInt* inParam = (TBool*) aInputBuffer.Ptr();
+            ShowFrameRateL(*inParam);
+            break;
+            }
+            
+        case EAlfDebugCmdShowServerHeap:
+            {
+            const TBool* inParam = (TBool*) aInputBuffer.Ptr();
+            ShowServerHeapL(*inParam);
+            break;
+            }
+        
+        case EAlfDebugCmdMeasure:
+            {
+            TAlfDebugServerMeasurements measurements;
+            TPckg<TAlfDebugServerMeasurements> result(measurements);
+            
+            // Timestamp
+            measurements.iTimeStamp = User::NTickCount();
+            
+            // Memory measures
+            measurements.iServerCells = 
+                User::AllocSize( measurements.iServerMemory );
+            TInt dummy;
+            measurements.iServerFree = User::Available( dummy );
+            
+            // Rendering measures
+            measurements.iFrameCount = CHuiStatic::FrameCount();
+
+            aResponse = result;
+            }
+            break;
+            
+        default:
+            User::Leave( KErrNotSupported );
+            break;
+        }
+    }
+    
+void CAlfDebugServer::CreateControlIfNeededL()
+    {
+    if ( !iGroup )
+        { 
+        iGroup = &iEnv.NewControlGroupL( TInt(this) );
+        }
+        
+    if ( !iControl )
+        {
+        CMonitorControl* control = new (ELeave) CMonitorControl(iEnv, *this);
+        CleanupStack::PushL( control );
+        control->ConstructL();
+        iGroup->AppendL( control );
+        CleanupStack::Pop( control );
+        iControl = control;
+        }
+        
+    // make sure we are on top
+    if ( iEnv.DisplayCount() )
+        {
+        CHuiDisplay& display = iEnv.PrimaryDisplay();
+        display.Roster().ShowL( *iGroup );
+        }
+    }
+    
+    
+void CAlfDebugServer::DeteteControlIfNeeded()
+    {
+    if ( iControl && iControl->VisualCount() == iControl->iInitialVisualCount )
+        {
+        iGroup->Remove( iControl );
+        delete iControl;
+        iControl = NULL;
+        }
+    
+    if ( iGroup && iGroup->Count() == 0 )
+        {
+        iEnv.DeleteControlGroup( TInt(this) );
+        iGroup = NULL;
+        }
+    }
+
+void CAlfDebugServer::ShowFrameRateL( TInt aInterval )
+    {
+    CHuiTextVisual* textVisual = iControl ? static_cast<CHuiTextVisual*>(iControl->FindTag( KFrameRateTag ) ) : 0;
+    if ( aInterval != KAlfDebugHideFraweRate )
+        {
+        CreateControlIfNeededL();
+        
+        if ( !textVisual )
+            {
+            textVisual = CHuiTextVisual::AddNewL(*iControl, static_cast<CHuiLayout*>(iControl->FindTag( KContainerTag )) );
+            textVisual->SetTagL( KFrameRateTag );
+            textVisual->SetColor( KRgbRed );
+            }
+        
+        
+        CIdleCheckVisual* idleChecker = static_cast<CIdleCheckVisual*>(iControl->FindTag( KIdleCheckerTag ));
+        if ( aInterval == KAlfDebugShowFraweRateAfterDrawLoop ) // idle-idle
+            {
+            // use idle-idle
+            idleChecker->iState = CIdleCheckVisual::EIdleNeedsReseting;
+            }
+        else if ( aInterval == KAlfDebugShowFraweRateWhenQueried ) // manual
+            {
+            iFpsUpdatePeriod = aInterval;
+            idleChecker->iState = CIdleCheckVisual::EDisabled;
+            }
+        else
+            {
+            iFpsUpdatePeriod = aInterval;
+            idleChecker->iState = CIdleCheckVisual::EDisabled;
+            
+            THuiCustomEventCommand command( EUpdateFrameRate, static_cast<MHuiEventHandler*>(iControl) );
+            iEnv.Send( command, iFpsUpdatePeriod );
+            }
+        }
+    else
+        {
+        if ( iControl )
+            {
+            if ( textVisual )
+                {
+                textVisual->RemoveAndDestroyAllD();
+                }
+            iEnv.CancelCommands( static_cast<MHuiEventHandler*>(iControl) , EHuiCommandTypeCustomEvent, EUpdateFrameRate );
+            }
+            
+        DeteteControlIfNeeded();
+        }
+    }
+    
+void CAlfDebugServer::ShowServerHeapL( TBool aShow )
+    {
+    CHuiTextVisual* textVisual = iControl ? static_cast<CHuiTextVisual*>(iControl->FindTag( KHeapTag ) ) : 0;
+    if ( aShow )
+        {
+        CreateControlIfNeededL();
+        
+        if ( !textVisual )
+            {
+            textVisual = CHuiTextVisual::AddNewL(*iControl, static_cast<CHuiLayout*>(iControl->FindTag( KContainerTag )));
+            textVisual->SetTagL( KHeapTag );    
+            textVisual->SetColor( KRgbRed );
+            }
+        
+        THuiCustomEventCommand command( EUpdateServerHeap, static_cast<MHuiEventHandler*>(iControl) );
+        iEnv.Send( command, iServerHeapUpdatePeriod );
+        }
+    else
+        {
+        if ( iControl )
+            {
+            if ( textVisual )
+                {
+                textVisual->RemoveAndDestroyAllD();
+                }
+            iEnv.CancelCommands( static_cast<MHuiEventHandler*>(iControl) , EHuiCommandTypeCustomEvent, EUpdateServerHeap );
+            }
+        DeteteControlIfNeeded();
+        }
+    }
+
+
+// Global functions:
+
+MAlfExtensionFactory* Instance()
+    {
+    TAlfDebugHandler* me = NULL;
+    me = new TAlfDebugHandler;
+    return me;
+    }
+
+const TImplementationProxy ImplementationTable[] =
+    {
+#ifdef __EABI__
+    {{KAlfDebugExtensionImplementationId}, (TFuncPtr)Instance}
+#else
+    {{KAlfDebugExtensionImplementationId}, Instance}
+#endif
+    };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+    {
+    aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy) ;
+    return ImplementationTable;
+    }
+