examples/SFExamples/GfxWorkbench/src/CGfxDirectAccess.cpp

00001 /*
00002 Copyright (c) 2002-2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010   this list of conditions and the following disclaimer in the documentation
00011   and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013   may be used to endorse or promote products derived from this software
00014   without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description:  
00028 */ 
00029 #include "CGfxDirectAccess.h"
00030 #include <coemain.h>
00031 #include <cdsb.h>
00032 #include <hal.h>
00033 #include <hal_data.h>
00034 
00035 const TInt KFrameIntervalInMicroSecs = 1000000/60; // 1 second divided by desired frame rate
00036 
00037 CGfxDirectAccess::CGfxDirectAccess(RWsSession& aClient, 
00038         RWindow& aWindow, const TRect& aDsaRect, TBool aGcDrawMode):
00039         CTimer(CActive::EPriorityStandard),
00040         iClient(aClient),
00041         iWindow(aWindow),
00042         iDsaRect(aDsaRect), iGcDrawMode(aGcDrawMode)
00043         {
00044         }
00045 
00046 
00047 /*
00048  * SetupScreenDataL - Populate the iScreenData with direct screen buffer access
00049  * informaton from RHardwareBitmap(if supported on handset) or from HAL otherwise
00050  * */
00051 void CGfxDirectAccess::SetupScreenDataL()
00052         {
00053         Mem::FillZ(&iScreenData, sizeof(iScreenData));  
00054         
00055         RHardwareBitmap hwBmp = iDirectScreenAccess->ScreenDevice()->HardwareBitmap();
00056         TAcceleratedBitmapInfo bmpInfo;
00057         hwBmp.GetInfo(bmpInfo);
00058         
00059         // If the platform supports s/w accessable hardware bitmap for the screen then use it
00060         // othewise get the values directly from the HAL
00061         if(hwBmp.iHandle && (bmpInfo.iSize.iWidth!=0) )
00062                 {
00063                 iScreenData.iDisplayMemoryAddress = (int)bmpInfo.iAddress;
00064                 iScreenData.iDisplayOffsetToFirstPixel = 0;
00065                 iScreenData.iDisplayXPixels = bmpInfo.iSize.iWidth;
00066                 iScreenData.iDisplayYPixels = bmpInfo.iSize.iHeight;
00067                 iScreenData.iDisplayBitsPerPixel = 1 << bmpInfo.iPixelShift;
00068                 iScreenData.iDisplayOffsetBetweenLines = bmpInfo.iLinePitch;
00069                 }
00070         else
00071                 {               
00072                 // When calling HAL::Get() The Displaymode much be set as the incoming paramater for
00073                 // all other values to return correct figures
00074                 // The display mode is used to retrieve all the other params 
00075                 
00076                 TInt err=0;
00077                 err = HAL::Get(HALData::EDisplayMode, iScreenData.iDisplayMode);
00078                 User::LeaveIfError(err);
00079                 
00080                 iScreenData.iDisplayOffsetToFirstPixel = iScreenData.iDisplayMemoryAddress = iScreenData.iDisplayXPixels = iScreenData.iDisplayYPixels = iScreenData.iDisplayOffsetBetweenLines = iScreenData.iDisplayBitsPerPixel = iScreenData.iDisplayMode;
00081                 User::LeaveIfError( HAL::Get(HALData::EDisplayMemoryAddress, iScreenData.iDisplayMemoryAddress));
00082                 User::LeaveIfError( HAL::Get(HALData::EDisplayOffsetToFirstPixel, iScreenData.iDisplayOffsetToFirstPixel));
00083                 iScreenData.iDisplayMemoryAddress+=iScreenData.iDisplayOffsetToFirstPixel;
00084                 
00085                 User::LeaveIfError( HAL::Get(HALData::EDisplayXPixels, iScreenData.iDisplayXPixels));
00086                 User::LeaveIfError( HAL::Get(HALData::EDisplayYPixels, iScreenData.iDisplayYPixels));
00087                 User::LeaveIfError( HAL::Get(HALData::EDisplayOffsetBetweenLines, iScreenData.iDisplayOffsetBetweenLines));
00088                 User::LeaveIfError( HAL::Get(HALData::EDisplayBitsPerPixel, iScreenData.iDisplayBitsPerPixel));    
00089                 User::LeaveIfError( HAL::Get(HALData::EDisplayIsPixelOrderLandscape, iScreenData.iDisplayIsPixelOrderLandscape));    
00090                 }
00091         
00092         }
00093 
00094 void CGfxDirectAccess::ConstructL()
00095     {
00096     CTimer::ConstructL();
00097     // Create the DSA object
00098     iDirectScreenAccess = CDirectScreenAccess::NewL(
00099         iClient,                // WS session
00100         *(CCoeEnv::Static()->ScreenDevice()),        // CWsScreenDevice
00101         iWindow,                // RWindowBase
00102         *this                   // MDirectScreenAccess
00103         );
00104 
00105     CActiveScheduler::Add(this);
00106     }
00107 
00108 CGfxDirectAccess::~CGfxDirectAccess()
00109         {
00110         Cancel();
00111         delete iDirectScreenAccess;
00112         }
00113 
00114         
00115    // Implement MDirectScreenAccess
00116 void CGfxDirectAccess::Restart(RDirectScreenAccess::TTerminationReasons /*aReason*/)
00117         {
00118         /* Restart only if we are drawing in a mode which supports clipping */
00119         if(iGcDrawMode)
00120                 {
00121                 TRAPD(err, StartL());
00122                 }
00123         }
00124 
00125 void CGfxDirectAccess::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReason*/)
00126         {
00127         Cancel();
00128         }
00129 
00130 /*
00131  * ProcessFrameWritePixels - Draw animated red horizontal bars using screen buffer
00132  */
00133 void CGfxDirectAccess::ProcessFrameWritePixels()
00134         {
00135         
00136         TUint32* screenAddress = (TUint32*)(iScreenData.iDisplayMemoryAddress);
00137         
00138         const TInt limitX = iDsaRect.Width();
00139         const TInt limitY = iDsaRect.Height();
00140 
00141         const TInt rowWidthInBytes = iScreenData.iDisplayOffsetBetweenLines;
00142         const TInt strideInWords = rowWidthInBytes/4;
00143         
00144         TUint32* lineAddress = screenAddress;
00145         lineAddress += (strideInWords*iDsaRect.iTl.iY);
00146 
00147         for(TInt y=0; y<limitY ; y++)
00148                 {
00149                 TUint32* p = lineAddress + iDsaRect.iTl.iX;
00150                 for(TInt x=0; x<limitX; x++)
00151                         {
00152                         TRgb rgb((y+iFrameCounter)%64 << 2,0,0); /* Vary the Red component paramater */
00153                         *(p++)=rgb._Color16MU();
00154                         }
00155                 lineAddress += strideInWords;
00156                 }       
00157         }
00158 
00159 /*
00160  * ProcessFrameGc - Draw animated green vertical bars using screen GC
00161  */
00162 void CGfxDirectAccess::ProcessFrameGc()
00163         {
00164         CBitmapContext* gc = iDirectScreenAccess->Gc();
00165         TPoint p1(0,0);
00166         TPoint p2(0,iDsaRect.Height());
00167         
00168         for(TInt x=0; x<=iDsaRect.Width(); x++)
00169                 {
00170                 TRgb penColor(0,(x+iFrameCounter)%64 << 2,0);
00171                 gc->SetPenColor(penColor);
00172                 gc->DrawLine(p1,p2);
00173                 p1+=TPoint(1,0);
00174                 p2+=TPoint(1,0);
00175                 }
00176         }
00177 
00178 void CGfxDirectAccess::RunL()
00179         {       
00180         if(iGcDrawMode)
00181                 ProcessFrameGc();
00182         else
00183                 {
00184                 ProcessFrameWritePixels();
00185                 }
00186         EndDraw();
00187         
00188         iFrameCounter++;
00189         
00190     After(TTimeIntervalMicroSeconds32(KFrameIntervalInMicroSecs));
00191         }
00192 
00193 void CGfxDirectAccess::DoCancel()
00194         {
00195     // Cancel timer
00196     CTimer::DoCancel();
00197     // Cancel DSA
00198     iDirectScreenAccess->Cancel();      
00199         }
00200 
00201 void CGfxDirectAccess::EndDraw()
00202         {
00203         TRect rect(iDsaRect);
00204         
00205         // On older Nokia phones (e.g E61) The update region needs to be flipped if this flag is set
00206         if(iScreenData.iDisplayIsPixelOrderLandscape)
00207                 rect.SetRect(TPoint(iDsaRect.iTl.iY,iDsaRect.iTl.iX), TPoint(iDsaRect.iBr.iY,iDsaRect.iBr.iX)  );
00208         
00209         TRegionFix<1> reg(rect);
00210         iDirectScreenAccess->ScreenDevice()->Update(reg);
00211     iClient.Flush();
00212         }
00213 
00214 /*
00215  * LogCapsL - Debug function to write the graphics capabilities of a handset to a file
00216  * Logs information about DSA session, HAL attributes and RHarwareBitmap
00217  */
00218 void CGfxDirectAccess::LogCapsL()
00219         {
00220         
00221         RFs session;
00222         User::LeaveIfError(session.Connect());
00223         CleanupClosePushL(session);
00224 
00225         RFile file;
00226         TBuf8<255> out;
00227         (void)session.MkDirAll(_L("c:\\data\\other\\"));
00228         User::LeaveIfError(file.Replace(session, _L("c:\\data\\other\\DSA.txt"),EFileWrite ));
00229         file.Write(_L8("DSA\n"));
00230     
00231         SScreenData sd;
00232         Mem::FillZ(&sd,sizeof(sd));
00233 
00234         TInt err = 0;  
00235         
00236         err = HAL::Get(HALData::EDisplayMode, sd.iDisplayMode);
00237         out.Format(_L8("%D\tEDisplayMode\t%D\n"), err,sd.iDisplayMode);
00238         file.Write(out);
00239         
00240         sd.iDisplayMemoryAddress = sd.iDisplayMode;
00241     err = HAL::Get(HALData::EDisplayMemoryAddress, sd.iDisplayMemoryAddress);
00242         out.Format(_L8("%D\tEDisplayMemoryAddress\t%D\n"), err,sd.iDisplayMemoryAddress);
00243         User::LeaveIfError(file.Write(out));
00244         
00245         sd.iDisplayOffsetToFirstPixel = sd.iDisplayMode;
00246     err = HAL::Get(HALData::EDisplayOffsetToFirstPixel, sd.iDisplayOffsetToFirstPixel);
00247         out.Format(_L8("%D\tEDisplayOffsetToFirstPixel\t%D\n"), err,sd.iDisplayOffsetToFirstPixel);
00248         User::LeaveIfError(file.Write(out));
00249 
00250     err = HAL::Get(HALData::EDisplayXPixels, sd.iDisplayXPixels);
00251         out.Format(_L8("%D\tEDisplayXPixels\t%D\n"), err,sd.iDisplayXPixels);
00252         User::LeaveIfError(file.Write(out));
00253 
00254     err = HAL::Get(HALData::EDisplayYPixels, sd.iDisplayYPixels);
00255         out.Format(_L8("%D\tEDisplayYPixels\t%D\n"), err,sd.iDisplayYPixels);
00256         User::LeaveIfError(file.Write(out));
00257 
00258         sd.iDisplayOffsetBetweenLines = sd.iDisplayMode;
00259     err = HAL::Get(HALData::EDisplayOffsetBetweenLines, sd.iDisplayOffsetBetweenLines);
00260         out.Format(_L8("%D\tEDisplayOffsetBetweenLines\t%D\n"), err,sd.iDisplayOffsetBetweenLines);
00261         User::LeaveIfError(file.Write(out));
00262 
00263         sd.iDisplayBitsPerPixel = sd.iDisplayMode;
00264     err = HAL::Get(HALData::EDisplayBitsPerPixel, sd.iDisplayBitsPerPixel);    
00265         out.Format(_L8("%D\tEDisplayBitsPerPixel\t%D\n"), err,sd.iDisplayBitsPerPixel);
00266         User::LeaveIfError(file.Write(out));
00267 
00268         TInt numScreens;
00269     err = HAL::Get(HALData::EDisplayNumberOfScreens, numScreens);    
00270         out.Format(_L8("%D\tEDisplayNumberOfScreens\t%D\n"), err,numScreens);
00271         User::LeaveIfError(file.Write(out));
00272         
00273         TInt rgbOrder;
00274     err = HAL::Get(HALData::EDisplayIsPixelOrderRGB, rgbOrder);    
00275         out.Format(_L8("%D\tEDisplayIsPixelOrderRGB\t%D\n"), err,rgbOrder);
00276         User::LeaveIfError(file.Write(out));
00277 
00278         TInt lanscape;
00279     err = HAL::Get(HALData::EDisplayIsPixelOrderLandscape, lanscape);    
00280         out.Format(_L8("%D\tDisplayIsPixelOrderLandscape\t%D\n"), err,lanscape);
00281         User::LeaveIfError(file.Write(out));
00282 
00283         out.Format(_L8("DSA RECT\t(%D,%D,%D,%D)\n"), 
00284                         iDsaRect.iTl.iX,
00285                         iDsaRect.iTl.iY,
00286                         iDsaRect.iBr.iX,
00287                         iDsaRect.iBr.iY);
00288         
00289         User::LeaveIfError(file.Write(out));
00290         
00291         RHardwareBitmap hwBmp = iDirectScreenAccess->ScreenDevice()->HardwareBitmap();
00292         
00293         out.Format(_L8("RHardwareBitmap handle = \t%D\n"), hwBmp.iHandle);
00294         User::LeaveIfError(file.Write(out));
00295         if(hwBmp.iHandle)
00296                 {
00297                 TAcceleratedBitmapInfo bmpInfo;
00298                 hwBmp.GetInfo(bmpInfo);
00299                 
00300                 out = _L8("RHardwareBitmap\n");
00301                 
00302                 out.Format(_L8("RHardwareBitmap\t%D\n"), bmpInfo.iAddress);
00303                 User::LeaveIfError(file.Write(out));
00304 
00305                 out.Format(_L8("RHardwareBitmap Size\t%D,%D\n"), bmpInfo.iSize.iWidth, bmpInfo.iSize.iHeight);
00306                 User::LeaveIfError(file.Write(out));
00307         
00308                 out.Format(_L8("RHardwareBitmap Line Pitch\t%D\n"),bmpInfo.iLinePitch);
00309                 User::LeaveIfError(file.Write(out));
00310 
00311                 out.Format(_L8("RHardwareBitmap Pixel Shift\t%D\n"),bmpInfo.iPixelShift);
00312                 User::LeaveIfError(file.Write(out));
00313                 }
00314         
00315         file.Flush();
00316         file.Close();
00317 
00318         CleanupStack::PopAndDestroy(&session);
00319         }
00320 
00321 void CGfxDirectAccess::StartL()
00322     {
00323     // Initialise DSA
00324     iDirectScreenAccess -> StartL();
00325     
00326     // This example is hard coded for 24bpp display
00327     if(iDirectScreenAccess->ScreenDevice()->DisplayMode16M()==ENone)
00328         {
00329         User::LeaveIfError(KErrNotSupported);
00330         }
00331     
00332     // The following is very useful for debugging different hardware
00333     LogCapsL();
00334     
00335     //
00336         SetupScreenDataL();
00337         
00338         After(TTimeIntervalMicroSeconds32(KFrameIntervalInMicroSecs));
00339     }
00340 

Generated by  doxygen 1.6.2