os/graphics/graphicscomposition/openwfc_ri_displaychannel/src/openwfc_ri_displaychannel.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/graphicscomposition/openwfc_ri_displaychannel/src/openwfc_ri_displaychannel.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,466 @@
     1.4 +// Copyright (c) 2009-2010 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +//
     1.6 +// Permission is hereby granted, free of charge, to any person obtaining a
     1.7 +// copy of this software and/or associated documentation files (the
     1.8 +// "Materials"), to deal in the Materials without restriction, including
     1.9 +// without limitation the rights to use, copy, modify, merge, publish,
    1.10 +// distribute, sublicense, and/or sell copies of the Materials, and to
    1.11 +// permit persons to whom the Materials are furnished to do so, subject to
    1.12 +// the following conditions:
    1.13 +//
    1.14 +// The above copyright notice and this permission notice shall be included
    1.15 +// in all copies or substantial portions of the Materials.
    1.16 +//
    1.17 +// THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    1.18 +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    1.19 +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    1.20 +// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
    1.21 +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
    1.22 +// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
    1.23 +// MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
    1.24 +// 
    1.25 +// Description:
    1.26 +// Display Adaptation Interface Implementation for Display channel
    1.27 +// 
    1.28 +//
    1.29 +
    1.30 +#include "openwfc_ri_displaychannel.h"
    1.31 +#include <e32debug.h>
    1.32 +#include <hal.h>
    1.33 +
    1.34 +_LIT(KDisplayChannelLdd, "display0.ldd");
    1.35 +const TUint32 KDefaultScreenNumber = 0;
    1.36 +
    1.37 +#ifdef _DEBUG
    1.38 +void Panic(TInt aPanic)
    1.39 +    {
    1.40 +    _LIT(KPanic, "DA-DC");
    1.41 +    User::Panic(KPanic, aPanic);
    1.42 +    }
    1.43 +#endif
    1.44 +
    1.45 +EXPORT_C COpenWFC_RI_Display* COpenWFC_RI_Display::NewL(TUint aScreen)
    1.46 +    {
    1.47 +    return COpenWFC_RI_DisplayChannel::NewL(aScreen);
    1.48 +    }
    1.49 +
    1.50 +EXPORT_C TUint32 COpenWFC_RI_Display::DefaultScreenNumber()
    1.51 +    {
    1.52 +    return KDefaultScreenNumber;
    1.53 +    }
    1.54 +    
    1.55 +COpenWFC_RI_DisplayChannel::COpenWFC_RI_DisplayChannel(TUint aScreen):
    1.56 +iScreenNumber(aScreen),
    1.57 +iCurrentSceneStream(SYMBIAN_INVALID_HANDLE)
    1.58 +    {
    1.59 +    }
    1.60 +
    1.61 +COpenWFC_RI_DisplayChannel* COpenWFC_RI_DisplayChannel::NewL(TUint aScreen)
    1.62 +    {
    1.63 +    COpenWFC_RI_DisplayChannel* screenContext = new(ELeave) COpenWFC_RI_DisplayChannel(aScreen);
    1.64 +    CleanupStack::PushL(screenContext);
    1.65 +    screenContext->ConstructL();
    1.66 +    CleanupStack::Pop(screenContext);
    1.67 +    return screenContext;
    1.68 +    }
    1.69 +
    1.70 +COpenWFC_RI_DisplayChannel::~COpenWFC_RI_DisplayChannel()
    1.71 +    {
    1.72 +    TInt count = iCompositionBuffer.Count();
    1.73 +    for(TInt ii = 0; ii < count; ++ii)
    1.74 +        {
    1.75 +        TBufferAddress* addr = iCompositionBuffer[ii];
    1.76 +        if (addr)
    1.77 +            {
    1.78 +            addr->iChunk.Close();
    1.79 +            delete addr;
    1.80 +            }
    1.81 +        }
    1.82 +    iCompositionBuffer.Close();
    1.83 +    // We do not need to use this boolean
    1.84 +    TBool unused;
    1.85 +    // Reset the initial rotation for next time.
    1.86 +    iDispChan.SetRotation(iDefaultRotation, unused);
    1.87 +    iDispChan.Close();
    1.88 +    }
    1.89 +
    1.90 +void COpenWFC_RI_DisplayChannel::ConstructL()
    1.91 +    {
    1.92 +    TInt err = User::LoadLogicalDevice(KDisplayChannelLdd);
    1.93 +    if (err != KErrNone && err != KErrAlreadyExists)
    1.94 +        {
    1.95 +        User::Leave(err);
    1.96 +        }
    1.97 +    
    1.98 +    User::LeaveIfError(iDispChan.Open(iScreenNumber));
    1.99 +//#ifdef __WINS__
   1.100 +    iScreenInfo.iDefaultRotation = EScreenRotate0;
   1.101 +    iDefaultRotation = RDisplayChannel::ERotationNormal;
   1.102 +    iRotationOffset = 0;
   1.103 +//#else
   1.104 +//    iScreenInfo.iDefaultRotation = EScreenRotate270;
   1.105 +//    iDefaultRotation = RDisplayChannel::ERotation270CW;
   1.106 +//    iRotationOffset = 3;
   1.107 +//#endif
   1.108 +    RDisplayChannel::TDisplayRotation rotation = iDispChan.CurrentRotation();
   1.109 +    switch (rotation)
   1.110 +        {
   1.111 +        case RDisplayChannel::ERotationNormal:
   1.112 +            iScreenInfo.iCurrentRotation = EScreenRotate0;
   1.113 +            break;
   1.114 +        case RDisplayChannel::ERotation90CW:
   1.115 +            iScreenInfo.iCurrentRotation = EScreenRotate90;
   1.116 +            break;
   1.117 +        case RDisplayChannel::ERotation180:
   1.118 +            iScreenInfo.iCurrentRotation = EScreenRotate180;
   1.119 +            break;
   1.120 +        case RDisplayChannel::ERotation270CW:
   1.121 +            iScreenInfo.iCurrentRotation = EScreenRotate270;
   1.122 +            break;
   1.123 +        default:
   1.124 +            RDebug::Printf("COpenWFC_RI_DisplayChannel::ConstructL() unsupported rotation %d", rotation);
   1.125 +            User::Leave(KErrNotSupported);
   1.126 +        }
   1.127 +    
   1.128 +    iNewRotation = iScreenInfo.iCurrentRotation;
   1.129 +    TPckgBuf<RDisplayChannel::TDisplayInfo> pkgInfo;
   1.130 +    iDispChan.GetDisplayInfo(pkgInfo);
   1.131 +    RDisplayChannel::TDisplayInfo info = pkgInfo();
   1.132 +    /* Note that in theory other formats could be supported for composition 
   1.133 +     * (eg  EUidPixelFormatARGB_8888 | EUidPixelFormatARGB_8888_PRE )
   1.134 +     * So long as the background colour is opaque then the final composed image should end up opaque,
   1.135 +     * so compatible with alpha modes.
   1.136 +     * However, it would give problems for fastpathing, where alpha byte should be ignored,
   1.137 +     * probably fastpath would need to be disabled.
   1.138 +     * At present we only care about PlatSim, 
   1.139 +     * and it is unlikely that any platform will NOT support xrgb32,
   1.140 +     * so it is better to assert the capabilities match than think about this hypothetical case too hard.  
   1.141 +     */
   1.142 +    if (info.iPixelFormat != EUidPixelFormatXRGB_8888)
   1.143 +        {
   1.144 +        RDebug::Printf("COpenWFC_RI_DisplayChannel::ConstructL() unsupported pixel format 0x%08.8x", info.iPixelFormat);
   1.145 +        User::Leave(KErrNotSupported);
   1.146 +        }
   1.147 +
   1.148 +    iScreenInfo.iPixelFormat = EUidPixelFormatXRGB_8888;
   1.149 +    iScreenInfo.iSupportedRotations = info.iAvailableRotations;
   1.150 +    
   1.151 +    TInt bytesPerPixel = 4;
   1.152 +    if((info.iBitsPerPixel != 24) && (info.iBitsPerPixel != 32))
   1.153 +        {
   1.154 +        RDebug::Printf("COpenWFC_RI_DisplayChannel::ConstructL()unexpected bpp value %d", info.iBitsPerPixel);
   1.155 +        }
   1.156 +    
   1.157 +    iScreenInfo.iBytesPerPixel = bytesPerPixel;
   1.158 +    
   1.159 +    if (iRotationOffset & 1)
   1.160 +        {
   1.161 +        // Either 90 or 270 degree rotation, so reverse the normal and flipped
   1.162 +        // sizes (which relate to zero degrees rotation).
   1.163 +        iScreenInfo.iNormalWidth = info.iFlipped.iWidth;
   1.164 +        iScreenInfo.iNormalHeight = info.iFlipped.iHeight;
   1.165 +        iScreenInfo.iNormalStride = info.iFlipped.iOffsetBetweenLines;
   1.166 +        iScreenInfo.iFlippedWidth = info.iNormal.iWidth;
   1.167 +        iScreenInfo.iFlippedHeight = info.iNormal.iHeight;
   1.168 +        iScreenInfo.iFlippedStride = info.iNormal.iOffsetBetweenLines;
   1.169 +        }
   1.170 +    else
   1.171 +        {
   1.172 +        iScreenInfo.iNormalWidth = info.iNormal.iWidth;
   1.173 +        iScreenInfo.iNormalHeight = info.iNormal.iHeight;
   1.174 +        iScreenInfo.iNormalStride = info.iNormal.iOffsetBetweenLines;
   1.175 +        iScreenInfo.iFlippedWidth = info.iFlipped.iWidth;
   1.176 +        iScreenInfo.iFlippedHeight = info.iFlipped.iHeight;
   1.177 +        iScreenInfo.iFlippedStride = info.iFlipped.iOffsetBetweenLines;
   1.178 +        }
   1.179 +        
   1.180 +    if (iScreenInfo.iNormalStride < 0)
   1.181 +        {
   1.182 +        iScreenInfo.iNormalStride = bytesPerPixel * iScreenInfo.iNormalWidth;
   1.183 +        }
   1.184 +    if (iScreenInfo.iFlippedStride < 0)
   1.185 +        {
   1.186 +        iScreenInfo.iFlippedStride = bytesPerPixel * iScreenInfo.iFlippedWidth;
   1.187 +        }
   1.188 +    
   1.189 +    for(TInt i = 0; i < info.iNumCompositionBuffers; ++i)
   1.190 +        {
   1.191 +        iCompositionBuffer.AppendL(NULL);
   1.192 +        TBufferAddress* address = new(ELeave) TBufferAddress;
   1.193 +        iCompositionBuffer[i] = address;
   1.194 +        User::LeaveIfError(iDispChan.GetCompositionBufferInfo(i, address->iChunk, address->iOffset));
   1.195 +        address->iAddress = address->iChunk.Base() + address->iOffset;
   1.196 +        }
   1.197 +    }
   1.198 +
   1.199 +TInt COpenWFC_RI_Display::GetAttributeSize(TUint aAttributeId)
   1.200 +    {
   1.201 +    switch (aAttributeId)
   1.202 +        {
   1.203 +        case EScreenAttributeImplementationVersion:
   1.204 +        case EScreenAttributePixelFormat:
   1.205 +        case EScreenAttributeBytesPerPixel:
   1.206 +        case EScreenAttributeSupportedRotation:
   1.207 +        case EScreenAttributeNormalWidth:
   1.208 +        case EScreenAttributeNormalHeight:
   1.209 +        case EScreenAttributeNormalStride:
   1.210 +        case EScreenAttributeFlippedWidth:
   1.211 +        case EScreenAttributeFlippedHeight:
   1.212 +        case EScreenAttributeFlippedStride:
   1.213 +        case EScreenAttributeDefaultRotation:
   1.214 +        case EScreenAttributeCurrentRotation:
   1.215 +            return sizeof(TUint32);
   1.216 +         
   1.217 +        case EScreenAttributeScreenGeometry:
   1.218 +            return sizeof(TScreenGeometryAttribute);
   1.219 +            
   1.220 +        default:
   1.221 +            return 0;
   1.222 +        }
   1.223 +    }
   1.224 +
   1.225 +TInt COpenWFC_RI_DisplayChannel::GetAttribute(TInt aAttributeId, TAny* aAttribute, TInt aAttributeSize)
   1.226 +    {
   1.227 +    TInt parameterSize = GetAttributeSize(aAttributeId);
   1.228 +
   1.229 +    if (aAttribute == NULL)
   1.230 +        {
   1.231 +        return KErrArgument;
   1.232 +        }
   1.233 +    
   1.234 +    if (parameterSize == 0) 
   1.235 +        {
   1.236 +        return KErrNotSupported;
   1.237 +        }
   1.238 +    
   1.239 +    if (aAttributeSize != parameterSize)
   1.240 +        {
   1.241 +        return KErrArgument;
   1.242 +        }
   1.243 +    
   1.244 +    switch (aAttributeId)
   1.245 +        {
   1.246 +        case EScreenAttributeImplementationVersion:
   1.247 +            *((TUint32*)aAttribute) = KImplementationVersion;
   1.248 +            break;
   1.249 +        case EScreenAttributePixelFormat:
   1.250 +            *((TUint32*)aAttribute) = iScreenInfo.iPixelFormat;
   1.251 +            break;            
   1.252 +        case EScreenAttributeBytesPerPixel:
   1.253 +            *((TUint32*)aAttribute) = iScreenInfo.iBytesPerPixel;
   1.254 +            break;
   1.255 +        case EScreenAttributeSupportedRotation:
   1.256 +            *((TUint32*)aAttribute) = iScreenInfo.iSupportedRotations;
   1.257 +            break;
   1.258 +        case EScreenAttributeNormalWidth:
   1.259 +            *((TUint32*)aAttribute) = iScreenInfo.iNormalWidth;
   1.260 +            break;
   1.261 +        case EScreenAttributeNormalHeight:
   1.262 +            *((TUint32*)aAttribute) = iScreenInfo.iNormalHeight;
   1.263 +            break;
   1.264 +        case EScreenAttributeNormalStride:
   1.265 +            *((TUint32*)aAttribute) = iScreenInfo.iNormalStride;
   1.266 +            break;
   1.267 +        case EScreenAttributeFlippedWidth:
   1.268 +            *((TUint32*)aAttribute) = iScreenInfo.iFlippedWidth;
   1.269 +            break;
   1.270 +        case EScreenAttributeFlippedHeight:
   1.271 +            *((TUint32*)aAttribute) = iScreenInfo.iFlippedHeight;
   1.272 +            break;
   1.273 +        case EScreenAttributeFlippedStride:
   1.274 +            *((TUint32*)aAttribute) = iScreenInfo.iFlippedStride;
   1.275 +            break;
   1.276 +        case EScreenAttributeDefaultRotation:
   1.277 +            *((TUint32*)aAttribute) = iScreenInfo.iDefaultRotation;
   1.278 +            break;
   1.279 +        case EScreenAttributeCurrentRotation:
   1.280 +            *((TUint32*)aAttribute) = iScreenInfo.iCurrentRotation;
   1.281 +            break;
   1.282 +        case EScreenAttributeScreenGeometry:
   1.283 +            *((TScreenGeometryAttribute*)aAttribute) = iScreenInfo;
   1.284 +            break;
   1.285 +        default:
   1.286 +            return KErrNotSupported;
   1.287 +        }
   1.288 +    
   1.289 +    return KErrNone;
   1.290 +    }
   1.291 +
   1.292 +
   1.293 +TInt COpenWFC_RI_DisplayChannel::SetAttribute(TInt aAttributeId, TAny* aAttribute, TInt aAttributeSize)
   1.294 +    {
   1.295 +    // the only parameter we can modify is the current rotation
   1.296 +    TInt parameterSize = GetAttributeSize(aAttributeId);
   1.297 +
   1.298 +    if (aAttributeSize != parameterSize || aAttribute == NULL)
   1.299 +        {
   1.300 +        return KErrArgument;
   1.301 +        }
   1.302 +    
   1.303 +    switch (aAttributeId)
   1.304 +        {
   1.305 +        case EScreenAttributeCurrentRotation:
   1.306 +            iNewRotation = static_cast<TScreenRotation>(*((TUint32*)aAttribute));
   1.307 +            break;
   1.308 +        default:
   1.309 +            return KErrNotSupported;
   1.310 +        }
   1.311 +    return KErrNone;
   1.312 +    }
   1.313 +
   1.314 +
   1.315 +TInt COpenWFC_RI_DisplayChannel::CommitAttribute()
   1.316 +    {
   1.317 +    // For DisplayChannel the new screen attributes must be applied
   1.318 +    // at the same time with the composition.
   1.319 +    if (iScreenInfo.iCurrentRotation != iNewRotation)
   1.320 +        {
   1.321 +        TInt totalRotation;
   1.322 +        RDisplayChannel::TDisplayRotation dcRotation;
   1.323 +
   1.324 +        // Change the rotation to a numeric index from zero
   1.325 +        switch (iNewRotation)
   1.326 +            {
   1.327 +            case EScreenRotate90:
   1.328 +                totalRotation = 1;
   1.329 +                break;
   1.330 +            case EScreenRotate180:
   1.331 +                totalRotation = 2;
   1.332 +                break;
   1.333 +            case EScreenRotate270:
   1.334 +                totalRotation = 3;
   1.335 +                break;
   1.336 +            case EScreenRotate0:
   1.337 +            default:
   1.338 +                __ASSERT_DEBUG(iNewRotation == EScreenRotate0, Panic(__LINE__));
   1.339 +                totalRotation = 0;
   1.340 +                break;
   1.341 +            }
   1.342 +
   1.343 +        // Add the initial rotation of the device and wrap to get final one.
   1.344 +        totalRotation = (totalRotation + iRotationOffset) % 4;
   1.345 +
   1.346 +        // Now change the final rotation to the display channel rotation
   1.347 +        switch (totalRotation)
   1.348 +            {
   1.349 +            case 1:
   1.350 +                dcRotation = RDisplayChannel::ERotation90CW;
   1.351 +                break;
   1.352 +            case 2:
   1.353 +                dcRotation = RDisplayChannel::ERotation180;
   1.354 +                break;
   1.355 +            case 3:
   1.356 +                dcRotation = RDisplayChannel::ERotation270CW;
   1.357 +                break;
   1.358 +            case 0:
   1.359 +            default:
   1.360 +                __ASSERT_DEBUG(totalRotation == 0, Panic(__LINE__));
   1.361 +                dcRotation = RDisplayChannel::ERotationNormal;
   1.362 +                break;
   1.363 +            }
   1.364 +
   1.365 +        if (!(iScreenInfo.iSupportedRotations & dcRotation))
   1.366 +            {
   1.367 +            return KErrNotSupported;
   1.368 +            }
   1.369 +        
   1.370 +        // We do not need to use this boolean
   1.371 +        TBool displayConfigChanged;
   1.372 +        TInt err = iDispChan.SetRotation(dcRotation, displayConfigChanged);
   1.373 +        __ASSERT_DEBUG(err == KErrNone, Panic(__LINE__));
   1.374 +        if (err == KErrNone)
   1.375 +            {
   1.376 +            iScreenInfo.iCurrentRotation = iNewRotation;
   1.377 +            }
   1.378 +        else
   1.379 +            {
   1.380 +            return err;
   1.381 +            }
   1.382 +        }
   1.383 +    return KErrNone;
   1.384 +    }
   1.385 +
   1.386 +TInt COpenWFC_RI_DisplayChannel::SetLayerSurface(TInt aLayer, SymbianStreamType aStream,TInt* aNonTrivialAttribs)
   1.387 +    {
   1.388 +    // display channel interface can be seen as mono-layered
   1.389 +    if (aLayer != 0)
   1.390 +        {
   1.391 +        return KErrArgument;
   1.392 +        }
   1.393 +    if (aNonTrivialAttribs && *aNonTrivialAttribs)
   1.394 +        {
   1.395 +        return KErrNotSupported;
   1.396 +        }
   1.397 +    TBool acceptable=ETrue;
   1.398 +    khronos_int32_t format,pixSize;
   1.399 +    SymbianStreamGetHeader(aStream,NULL,NULL,NULL,&format,&pixSize);
   1.400 +    if (format!=EUidPixelFormatARGB_8888 && format!=EUidPixelFormatARGB_8888_PRE && format!=EUidPixelFormatXRGB_8888)
   1.401 +        {
   1.402 +        acceptable=EFalse;
   1.403 +        }
   1.404 +            
   1.405 +    if (!acceptable)
   1.406 +        {
   1.407 +        return KErrNotSupported;
   1.408 +        }
   1.409 +    
   1.410 +    iCurrentSceneStream = aStream;
   1.411 +    return KErrNone;
   1.412 +    }
   1.413 +
   1.414 +TInt COpenWFC_RI_DisplayChannel::SetTopLayerSurface(SymbianStreamType aStream,TInt* aNonTrivialAttribs)
   1.415 +    {
   1.416 +    return SetLayerSurface(KTopMostLayer, aStream,aNonTrivialAttribs);
   1.417 +    }
   1.418 +
   1.419 +TInt COpenWFC_RI_DisplayChannel::UpdateDisplay()
   1.420 +    {
   1.421 +    // The solution is suboptimal because a blit is used insteat of posting a user buffer
   1.422 +    // The solution is more simpler and because the emulator is to be phased-out soon,
   1.423 +    // there is no much incentive in complicating the code
   1.424 +    TInt err;
   1.425 +    
   1.426 +    TUint bufferIndex;
   1.427 +    TRequestStatus status;
   1.428 +    iDispChan.GetCompositionBuffer(bufferIndex, status);
   1.429 +    User::WaitForRequest(status);
   1.430 +    
   1.431 +    err = status.Int();
   1.432 +    if (err != KErrNone || bufferIndex >= iCompositionBuffer.Count()) 
   1.433 +        {
   1.434 +        return KErrGeneral;
   1.435 +        }
   1.436 +    
   1.437 +    TUint8* firstPixelAddr = iCompositionBuffer[bufferIndex]->iAddress;
   1.438 +    
   1.439 +    // Only 32 or 16bpp supported and assume stride == width * pixel size
   1.440 +    TInt size = 0;
   1.441 +    if (iNewRotation == EScreenRotate0 || iNewRotation == EScreenRotate180)
   1.442 +        {
   1.443 +        size = iScreenInfo.iNormalHeight * iScreenInfo.iNormalStride; 
   1.444 +        }
   1.445 +    else
   1.446 +        {
   1.447 +        size = iScreenInfo.iFlippedHeight * iScreenInfo.iFlippedStride; 
   1.448 +        }
   1.449 +    SymbianStreamBuffer frontBuffer;
   1.450 +    SymbianStreamAcquireReadBuffer(iCurrentSceneStream, &frontBuffer);
   1.451 +    void* pixelDataPtr = NULL;
   1.452 +    SymbianStreamGetBufferPointer(iCurrentSceneStream, frontBuffer,&pixelDataPtr);
   1.453 +    Mem::Move(firstPixelAddr, pixelDataPtr, size);
   1.454 +    RDisplayChannel::TPostCount postCount;
   1.455 +    err = iDispChan.PostCompositionBuffer(NULL, postCount);
   1.456 +    if (err == KErrNone)
   1.457 +        {
   1.458 +        // This will throttle composition more than necessary,
   1.459 +        // since it will wait until buffer is being displayed
   1.460 +        iDispChan.WaitForPost(postCount, status);
   1.461 +        User::WaitForRequest(status);
   1.462 +        err = status.Int();
   1.463 +        }
   1.464 +    
   1.465 +    SymbianStreamReleaseReadBuffer(iCurrentSceneStream, frontBuffer);
   1.466 +
   1.467 +    return err;
   1.468 +    }
   1.469 +