javauis/lcdui_akn/lcdgr/src/LcdWindowSurface.cpp
branchRCL_3
changeset 26 2455ef1f5bbc
parent 14 04becd199f91
equal deleted inserted replaced
25:ae942d28ec0e 26:2455ef1f5bbc
       
     1 /*
       
     2 * Copyright (c) 2005 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:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <coemain.h>
       
    20 #include <coecntrl.h>
       
    21 #include <reflcdui.h>
       
    22 #include <hal.h>
       
    23 
       
    24 #include "LcdWindowSurface.h"
       
    25 
       
    26 /**
       
    27  * Utility function to query the frame buffer attributes for screen aScreenNo
       
    28  * when set to displayMode aMode.
       
    29  */
       
    30 LOCAL_C TInt GetScreenInfo(TAcceleratedBitmapInfo& aScreen, TInt aScreenNo, TDisplayMode aMode);
       
    31 
       
    32 CLcdWindowSurface* CLcdWindowSurface::NewL(CCoeControl& aWindow, MDirectContainer& aContainer, TBool aUpdate)
       
    33 {
       
    34     CLcdWindowSurface* surface = new(ELeave) CLcdWindowSurface(aContainer, aUpdate);
       
    35     CleanupStack::PushL(surface);
       
    36     surface->ConstructL(aWindow);
       
    37     CleanupStack::Pop(surface);
       
    38     return surface;
       
    39 }
       
    40 
       
    41 CLcdWindowSurface::CLcdWindowSurface(MDirectContainer& aContainer, TBool aUpdate)
       
    42         : iContainer(&aContainer)
       
    43         , iWsSession(CCoeEnv::Static()->WsSession())
       
    44         , iWsDevice(*CCoeEnv::Static()->ScreenDevice())
       
    45         , iUpdate(aUpdate)
       
    46 {
       
    47     ASSERT(iContainer);
       
    48     //
       
    49     // Risk of configuration problem if screen mode does not match the configured
       
    50     // primary mode. In that case it would not be possible to use any of the
       
    51     // transforming blitters and a frame buffer bitmap would have to be used.
       
    52     //
       
    53     // Solution is to provide opaque converter blitters from/to all target modes,
       
    54     // or generic blitter (as BITGDI) via XRGB8888.
       
    55     //
       
    56     iImageType.iColorMode = iWsDevice.DisplayMode();
       
    57     iImageType.iAlphaMode = ENone;
       
    58     iImageType.iTransparency = ETransparencyNone;
       
    59 }
       
    60 
       
    61 CLcdWindowSurface::~CLcdWindowSurface()
       
    62 {
       
    63     if (iContainer)
       
    64     {
       
    65         iContainer->MdcRemoveContent(this);
       
    66     }
       
    67     Deactivate();
       
    68     delete iWsContext;
       
    69     iEmptyRegion.Close();
       
    70     iUpdateRegion.Close();
       
    71 }
       
    72 
       
    73 void CLcdWindowSurface::ConstructL(CCoeControl& aWindow)
       
    74 {
       
    75     iContainer->MdcAddContent(this);
       
    76     User::LeaveIfError(iWsDevice.CreateContext(iWsContext));
       
    77     if (aWindow.IsBackedUp())
       
    78     {
       
    79         User::Leave(KErrArgument);
       
    80     }
       
    81     else
       
    82     {
       
    83         ActivateL((RWindow*)aWindow.DrawableWindow());
       
    84     }
       
    85     TRect bounds(aWindow.PositionRelativeToScreen(), aWindow.Size());
       
    86     iBounds = bounds;
       
    87     iVisible = aWindow.IsVisible();
       
    88 }
       
    89 
       
    90 CLcdSurface::TSurfaceType CLcdWindowSurface::Type() const
       
    91 {
       
    92     return CLcdSurface::EWindowSurface;
       
    93 }
       
    94 
       
    95 void CLcdWindowSurface::Update(const TRect& aRect)
       
    96 {
       
    97     if (iStarted && iUpdate && iVisible)
       
    98     {
       
    99         ASSERT(iWsAccess);
       
   100 
       
   101         iUpdateRegion.AddRect(aRect);
       
   102 
       
   103         (void) DoUpdate();
       
   104     }
       
   105 }
       
   106 
       
   107 TInt CLcdWindowSurface::DoUpdate()
       
   108 {
       
   109     CFbsScreenDevice* device = iWsAccess->ScreenDevice();
       
   110     RRegion& visibleRegion = *iWsAccess->DrawingRegion();
       
   111 
       
   112     const TInt updateCount  = iUpdateRegion.Count();
       
   113     const TInt visibleCount = visibleRegion.Count();
       
   114     if (updateCount && visibleCount)
       
   115     {
       
   116         iUpdateRegion.Intersect(visibleRegion);
       
   117         device->Update(iUpdateRegion);
       
   118     }
       
   119     iUpdateRegion.Clear();
       
   120 
       
   121     return updateCount;
       
   122 }
       
   123 
       
   124 void CLcdWindowSurface::Begin(TAcceleratedBitmapInfo& aBitmap, TBitmapLockCount& /*aCount*/)
       
   125 {
       
   126     if (!iStarted && iEnabled)
       
   127     {
       
   128         iStarted = Start();
       
   129     }
       
   130 
       
   131 #ifdef _DEBUG
       
   132     if (iStarted)
       
   133     {
       
   134         ASSERT(NULL != iScreen.iAddress);
       
   135     }
       
   136     else
       
   137     {
       
   138         ASSERT(NULL == iScreen.iAddress);
       
   139     }
       
   140 #endif
       
   141 
       
   142     aBitmap = iScreen;
       
   143 }
       
   144 
       
   145 void CLcdWindowSurface::End(TBitmapLockCount& /*aCount*/)
       
   146 {
       
   147 }
       
   148 
       
   149 TRect CLcdWindowSurface::Bounds() const
       
   150 {
       
   151     return iBounds;
       
   152 }
       
   153 
       
   154 RRegion* CLcdWindowSurface::VisibleRegion() const
       
   155 {
       
   156     if (iStarted)
       
   157     {
       
   158         ASSERT(iWsAccess);
       
   159         return iWsAccess->DrawingRegion();
       
   160     }
       
   161     return const_cast<RRegion*>(&iEmptyRegion);
       
   162 }
       
   163 
       
   164 CBitmapContext* CLcdWindowSurface::Context() const
       
   165 {
       
   166     CBitmapContext* context = iWsAccess->Gc();
       
   167     if (context)
       
   168     {
       
   169         return context;
       
   170     }
       
   171     return iWsContext;
       
   172 }
       
   173 
       
   174 TImageType CLcdWindowSurface::ImageType() const
       
   175 {
       
   176     return iImageType;
       
   177 }
       
   178 
       
   179 TBool CLcdWindowSurface::Start()
       
   180 {
       
   181     ASSERT(iWsAccess);
       
   182     TRAPD(err, iWsAccess->StartL());
       
   183     if (KErrNone == err)
       
   184     {
       
   185         const TInt screenNo = iWsDevice.GetScreenNumber();
       
   186 
       
   187         //
       
   188         // DisplayMode may change dynamically on some devices.
       
   189         //
       
   190         const TDisplayMode displayMode = iWsDevice.DisplayMode();
       
   191 
       
   192         if (displayMode != iImageType.iColorMode)
       
   193         {
       
   194             // this surface doesn't match the current screen mode.
       
   195             // Any lcdgd device created for this surface will fail.
       
   196             err = KErrNotSupported;
       
   197         }
       
   198         else
       
   199         {
       
   200             //
       
   201             // Hardware bitmaps handles that reference screen framebuffers
       
   202             // start at -1 decending with the correspondance:
       
   203             //
       
   204             // handle = -(1 + screenNo) == ~screenNo
       
   205             //
       
   206             RHardwareBitmap screenHwb(~screenNo);
       
   207 
       
   208             TAcceleratedBitmapSpec screenSpec(screenHwb);
       
   209 
       
   210             err = screenSpec.GetInfo(iScreen);
       
   211             if (err)
       
   212             {
       
   213                 // hardware bitmaps screen references may not be supported on
       
   214                 // all ports. In that case we fall back to querying the HAL
       
   215                 // in GetScreenInfo().
       
   216                 //
       
   217                 err = GetScreenInfo(iScreen, screenNo, displayMode);
       
   218             }
       
   219         }
       
   220 
       
   221         if (err)
       
   222         {
       
   223             Mem::FillZ(&iScreen, sizeof(iScreen));
       
   224             iWsAccess->Cancel();
       
   225         }
       
   226 
       
   227         //
       
   228         // Record current scale, size and rotation settings
       
   229         //
       
   230         TPixelsAndRotation sizeAndRotation;
       
   231         iWsDevice.GetDefaultScreenSizeAndRotation(sizeAndRotation);
       
   232 
       
   233         // screen size and orientation determine coordinate transform
       
   234         // we should be using during rendering.
       
   235         iScreenCoords.iSize        = sizeAndRotation.iPixelSize;
       
   236         iScreenCoords.iOrientation = sizeAndRotation.iRotation;
       
   237         iScreenCoords.iScale  = iWsDevice.GetCurrentScreenModeScale();
       
   238         iScreenCoords.iOrigin = iWsDevice.GetDefaultScreenModeOrigin();
       
   239     }
       
   240 
       
   241     return (KErrNone == err);
       
   242 }
       
   243 
       
   244 void CLcdWindowSurface::ActivateL(RWindow* aWindow)
       
   245 {
       
   246     if (iWsWindow)
       
   247     {
       
   248         Deactivate();
       
   249     }
       
   250     iWsWindow = aWindow;
       
   251     if (iWsWindow)
       
   252     {
       
   253         iWsContext->Activate(*iWsWindow);
       
   254         iWsAccess = CDirectScreenAccess::NewL(iWsSession, iWsDevice, *iWsWindow, *this);
       
   255         iEnabled  = ETrue;
       
   256     }
       
   257 }
       
   258 
       
   259 void CLcdWindowSurface::Deactivate()
       
   260 {
       
   261     if (iWsWindow && iWsContext)
       
   262     {
       
   263         iWsContext->Deactivate();
       
   264     }
       
   265     delete iWsAccess;
       
   266     iWsAccess = NULL;
       
   267     iStarted  = EFalse;
       
   268     iEnabled  = EFalse;
       
   269     iWsWindow = NULL;
       
   270 }
       
   271 
       
   272 /* CONTENT INTERFACE */
       
   273 
       
   274 /**
       
   275 Notify content that container visiblity has changed. The content must not
       
   276 be displayed when it's container is invisible.
       
   277 @param "aVisible" ETrue if the container is visible, EFalse if it is invisible.
       
   278 */
       
   279 void CLcdWindowSurface::MdcContainerVisibilityChanged(TBool aVisible)
       
   280 {
       
   281     iVisible = aVisible;
       
   282 }
       
   283 
       
   284 /**
       
   285 Notify content that the container bounds have changed.
       
   286 @param "aRect" Maximum area the content can occupy in screen co-ordinates.
       
   287 The content should be clipped to this area.
       
   288 */
       
   289 void CLcdWindowSurface::MdcContentBoundsChanged(const TRect& aRect)
       
   290 {
       
   291     iBounds = aRect;
       
   292 }
       
   293 
       
   294 /**
       
   295 Notify content that its display area has changed.
       
   296 This should only be called when the content is displayed on an Item.
       
   297 @param "aDisplayRect" Display area in Item co-ordinates.
       
   298 @param "aScreenRect" Display area in screen co-ordinates.
       
   299 */
       
   300 void CLcdWindowSurface::MdcItemContentRectChanged(const TRect& /*aContentRect*/,const TRect& /*aScreenRect*/)
       
   301 {
       
   302     ASSERT(EFalse);
       
   303 }
       
   304 
       
   305 void CLcdWindowSurface::MdcContainerDestroyed()
       
   306 {
       
   307     Deactivate();
       
   308     iContainer = NULL;
       
   309 }
       
   310 
       
   311 
       
   312 void CLcdWindowSurface::MdcAbortDSA()
       
   313 {
       
   314     // Empty implementation.
       
   315     // This DSA event is delivered via AbortNow.
       
   316 }
       
   317 
       
   318 
       
   319 void CLcdWindowSurface::MdcResumeDSA()
       
   320 {
       
   321     // Empty implementation.
       
   322     // This DSA event is delivered via Restart.
       
   323 }
       
   324 
       
   325 
       
   326 /**
       
   327  * MDirectScreenAccess
       
   328  */
       
   329 void CLcdWindowSurface::AbortNow(RDirectScreenAccess::TTerminationReasons /*aReasons*/)
       
   330 {
       
   331     iWsAccess->Cancel();
       
   332     iStarted=EFalse;
       
   333     iEnabled=EFalse;
       
   334 }
       
   335 
       
   336 void CLcdWindowSurface::Restart(RDirectScreenAccess::TTerminationReasons /*aReasons*/)
       
   337 {
       
   338     //
       
   339     // Don't bother restarting until next Begin comes through.
       
   340     //
       
   341     iEnabled=ETrue;
       
   342 }
       
   343 
       
   344 RWindow* CLcdWindowSurface::Window() const
       
   345 {
       
   346     return iWsWindow;
       
   347 }
       
   348 
       
   349 void CLcdWindowSurface::GetCoordinateSystem(TCoordinateSystem& aCoords) const
       
   350 {
       
   351     aCoords = iScreenCoords;
       
   352 }
       
   353 
       
   354 LOCAL_C TUint Log2(TInt aVal)
       
   355 {
       
   356     ASSERT(aVal > 0);
       
   357     TUint v = 1;
       
   358     TInt  x = 0;
       
   359     while (v < aVal)
       
   360     {
       
   361         v <<= 1;
       
   362         ++x;
       
   363     }
       
   364     return x;
       
   365 }
       
   366 
       
   367 LOCAL_C TInt GetScreenInfo(TAcceleratedBitmapInfo& aScreen, TInt aScreenNo, TDisplayMode aMode)
       
   368 {
       
   369     // 'current mode' attributes. These should not need the
       
   370     // displayMode but this could depend on video driver.
       
   371     //
       
   372     TInt err     = 0;
       
   373     TInt mode    = 0;
       
   374     TInt address = 0;
       
   375     TInt width   = 0;
       
   376     TInt height  = 0;
       
   377 
       
   378     // 'request mode' attributes. These need the displayMode
       
   379     // passed in the attribute value argument.
       
   380     TInt offset     = aMode;
       
   381     TInt linePitch  = aMode;
       
   382     TInt bpp        = aMode;
       
   383 
       
   384     err = HAL::Get(aScreenNo, HALData::EDisplayMode, mode);
       
   385     ASSERT(mode == (TInt)aMode);
       
   386 
       
   387     if (KErrNone == err)
       
   388     {
       
   389         err = HAL::Get(aScreenNo, HALData::EDisplayMemoryAddress, address);
       
   390     }
       
   391 
       
   392     if (KErrNone == err)
       
   393     {
       
   394         err = HAL::Get(aScreenNo, HALData::EDisplayXPixels, width);
       
   395     }
       
   396 
       
   397     if (KErrNone == err)
       
   398     {
       
   399         err = HAL::Get(aScreenNo, HALData::EDisplayYPixels, height);
       
   400     }
       
   401 
       
   402     if (KErrNone == err)
       
   403     {
       
   404         offset = mode;  // Parameter must be set to mode on input.
       
   405         err = HAL::Get(aScreenNo, HALData::EDisplayOffsetToFirstPixel, offset);
       
   406     }
       
   407 
       
   408     if (KErrNone == err)
       
   409     {
       
   410         linePitch = mode;   // Parameter must be set to mode on input.
       
   411         err = HAL::Get(aScreenNo, HALData::EDisplayOffsetBetweenLines, linePitch);
       
   412     }
       
   413 
       
   414     if (KErrNone == err)
       
   415     {
       
   416         bpp = mode; // Parameter must be set to mode on input.
       
   417         err = HAL::Get(aScreenNo, HALData::EDisplayBitsPerPixel, bpp);
       
   418     }
       
   419 
       
   420     aScreen.iPhysicalAddress = NULL;
       
   421     aScreen.iDisplayMode  = aMode;
       
   422     aScreen.iAddress      = reinterpret_cast<TUint8*>(address + offset);
       
   423     aScreen.iLinePitch    = linePitch;
       
   424     aScreen.iSize.iWidth  = width;
       
   425     aScreen.iSize.iHeight = height;
       
   426     aScreen.iPixelShift   = Log2(bpp);
       
   427 
       
   428     return err;
       
   429 }