os/graphics/egl/egltest/endpointtestsuite/automated/tsrc/egltest_endpoint_images.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/egl/egltest/endpointtestsuite/automated/tsrc/egltest_endpoint_images.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,417 @@
     1.4 +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +/**
    1.20 + @file
    1.21 + @test
    1.22 + @internalComponent - Internal Symbian test code
    1.23 +*/
    1.24 +
    1.25 +#include "egltest_endpoint_images.h"
    1.26 +
    1.27 +_LIT(KImage1, "z:\\resource\\apps\\egltest_endpoint\\image1.mbm");
    1.28 +_LIT(KImage2, "z:\\resource\\apps\\egltest_endpoint\\image2.mbm");
    1.29 +_LIT(KImage3, "z:\\resource\\apps\\egltest_endpoint\\image3.mbm");
    1.30 +_LIT(KImage4, "z:\\resource\\apps\\egltest_endpoint\\image4.mbm");
    1.31 +
    1.32 +
    1.33 +const static TDesC *KImageList[]=
    1.34 +{
    1.35 +        &KImage1,
    1.36 +        &KImage2,
    1.37 +        &KImage3,
    1.38 +        &KImage4,
    1.39 +};
    1.40 +
    1.41 +typedef VGImage (*PFNCreateFromEglImage)(EGLImageKHR);
    1.42 +
    1.43 +const TInt CTestImage::KImageCount = sizeof(KImageList)/sizeof(KImageList[0]);
    1.44 +
    1.45 +CTestImage::~CTestImage()
    1.46 +    {
    1.47 +    }
    1.48 +
    1.49 +CTestImage::CTestImage()
    1.50 +    {
    1.51 +    }
    1.52 +
    1.53 +TBool CTestImage::ComparePixel(TRgb aPixel1, TRgb aPixel2, TBool aExpectError)
    1.54 +    {
    1.55 +    // In a 16-bit per pixel scenario, we allow (8 bits - 5 bits) = 3 bits,
    1.56 +    // which gives a value of 8  worth of difference.
    1.57 +    const TInt KMargin = 8;
    1.58 +    TBool match = ETrue;
    1.59 +    if (Abs(aPixel1.Red()-aPixel2.Red()) > KMargin ||
    1.60 +        Abs(aPixel1.Green()-aPixel2.Green()) > KMargin ||
    1.61 +        Abs(aPixel1.Blue()-aPixel2.Blue()) > KMargin)
    1.62 +        {
    1.63 +        if (!aExpectError)
    1.64 +            {
    1.65 +            RDebug::Printf("%s:%d: pixel %08x doesn't match %08x", __FILE__, __LINE__, aPixel1.Color16MA(), aPixel2.Color16MA());
    1.66 +            }
    1.67 +        match = EFalse;
    1.68 +        }
    1.69 +    else if (aExpectError)
    1.70 +        {
    1.71 +        RDebug::Printf("%s:%d: pixel %08x matches %08x", __FILE__, __LINE__, aPixel1.Color16MA(), aPixel2.Color16MA());
    1.72 +        }
    1.73 +    return match;
    1.74 +    }
    1.75 +
    1.76 +
    1.77 +// Compare the this image with the aImage.
    1.78 +// Images must be same size.
    1.79 +TBool CTestImage::CompareImageL(const CTestImage *aImage, TBool aExpectError) const
    1.80 +    {
    1.81 +    TSize size = Size();
    1.82 +    TSize otherSize = aImage->Size();
    1.83 +    if (otherSize != size)
    1.84 +        {
    1.85 +        size.iHeight = Min(size.iHeight, otherSize.iHeight);
    1.86 +        size.iWidth  = Min(size.iWidth, otherSize.iWidth);
    1.87 +        }
    1.88 +
    1.89 +    RArray<TPoint> points;
    1.90 +    CleanupClosePushL(points);
    1.91 +    points.AppendL(TPoint(0, 0));     // Top left.
    1.92 +    points.AppendL(TPoint(size.iWidth-1, 0));  // Top right.
    1.93 +    points.AppendL(TPoint(0, size.iHeight-1)); // Bottom left.
    1.94 +    points.AppendL(TPoint(size.iWidth-1, size.iHeight-1)); // Bottom right
    1.95 +    points.AppendL(TPoint(size.iWidth >> 1, size.iHeight >> 1));   // Middle
    1.96 +
    1.97 +    TBool retVal = ETrue;
    1.98 +    for(TInt i = 0; i < points.Count(); i++)
    1.99 +        {
   1.100 +        TInt x = points[i].iX;
   1.101 +        TInt y = points[i].iY;
   1.102 +        if (!ComparePixel(Pixel(x, y), aImage->Pixel(x, y), aExpectError))
   1.103 +            {
   1.104 +            retVal = EFalse;
   1.105 +            break;
   1.106 +            }
   1.107 +        }
   1.108 +    TInt err = vgGetError();
   1.109 +    if (err != VG_NO_ERROR)
   1.110 +        {
   1.111 +        RDebug::Printf("%s:%d: Could not fetch pixels??? err=%x", __FILE__, __LINE__, err);
   1.112 +        retVal = EFalse;
   1.113 +        }
   1.114 +    CleanupStack::PopAndDestroy(&points);
   1.115 +    return retVal;
   1.116 +    }
   1.117 +
   1.118 +
   1.119 +//Checks if the image is a solid colour.
   1.120 +//Only checks corners and middle pixel.
   1.121 +TBool CTestImage::IsSolidColourL() const
   1.122 +    {
   1.123 +    //Points in image to compare (corners and middle).
   1.124 +    TSize size = Size();
   1.125 +    RArray<TPoint> points;
   1.126 +    CleanupClosePushL(points);
   1.127 +    points.AppendL(TPoint(0, 0));                                // Top left.
   1.128 +    points.AppendL(TPoint(size.iWidth-1, 0));                    // Top right.
   1.129 +    points.AppendL(TPoint(0, size.iHeight-1));                   // Bottom left.
   1.130 +    points.AppendL(TPoint(size.iWidth-1, size.iHeight-1));       // Bottom right.
   1.131 +    points.AppendL(TPoint(size.iWidth >> 1, size.iHeight >> 1)); // Middle.
   1.132 +
   1.133 +    //Check that all points contain the same colour.
   1.134 +    TBool retVal = ETrue;
   1.135 +    for(TInt i = 1; i < points.Count(); ++i)
   1.136 +        {
   1.137 +        if(Pixel(points[i-1].iX, points[i-1].iY) != Pixel(points[i].iX, points[i].iY))
   1.138 +            {
   1.139 +            retVal = EFalse;
   1.140 +            break;
   1.141 +            }
   1.142 +        }
   1.143 +    TInt err = vgGetError();
   1.144 +    if (err != VG_NO_ERROR)
   1.145 +        {
   1.146 +        RDebug::Printf("Could not fetch pixels??? err=%x", err);
   1.147 +        retVal = EFalse;
   1.148 +        }
   1.149 +    
   1.150 +    CleanupStack::PopAndDestroy(&points);
   1.151 +    return retVal;
   1.152 +    }
   1.153 +
   1.154 +
   1.155 +CTestCFbsImage *CTestCFbsImage::NewL(TInt aIndex)
   1.156 +    {
   1.157 +    CTestCFbsImage* self = new (ELeave) CTestCFbsImage;
   1.158 +    CleanupStack::PushL(self);
   1.159 +    self->ConstructL(aIndex);
   1.160 +    CleanupStack::Pop(self);
   1.161 +    return self;
   1.162 +    }
   1.163 +
   1.164 +
   1.165 +void CTestCFbsImage::ConstructL(TInt aIndex)
   1.166 +    {
   1.167 +    // Do this before we leave - else we may disconnect more than we connect!
   1.168 +    RFbsSession::Connect();
   1.169 +    if (aIndex >= KImageCount)
   1.170 +        {
   1.171 +        User::Leave(KErrOverflow);
   1.172 +        }
   1.173 +    iBitmap = new (ELeave) CFbsBitmap;
   1.174 +    TInt err = iBitmap->Load(*KImageList[aIndex], 0);
   1.175 +    if (err != KErrNone)
   1.176 +        {
   1.177 +        RDebug::Printf("Image load error %d for image %d (name=%S)", err, aIndex, KImageList[aIndex]);
   1.178 +        User::Leave(err);
   1.179 +        }
   1.180 +
   1.181 +    // Check if it's a 24bpp image. If so, we must convert it to 32bpp.
   1.182 +    // as vgImages can't be 24bpp [in the Hybrid EGL/VG implementation],
   1.183 +    // and we (may) want to make this into a vg-image at some point in future.
   1.184 +    if(iBitmap->DisplayMode() == EColor16M)
   1.185 +        {
   1.186 +        CFbsBitmap *newBitmap = new (ELeave) CFbsBitmap;
   1.187 +        CleanupStack::PushL(newBitmap);
   1.188 +        TSize size = iBitmap->SizeInPixels();
   1.189 +        newBitmap->Create(size, EColor16MU);
   1.190 +        TInt32 *b = new TInt32[size.iWidth];
   1.191 +        TPtr8 buf((TUint8*)b, size.iWidth * sizeof(*b));
   1.192 +        for (TInt y=0; y<size.iHeight; ++y)
   1.193 +            {
   1.194 +            iBitmap->GetScanLine(buf, TPoint(0, y), size.iWidth, EColor16MU);
   1.195 +            newBitmap->SetScanLine(buf, y);
   1.196 +            }
   1.197 +        delete b;
   1.198 +        delete iBitmap;
   1.199 +        CleanupStack::Pop(newBitmap);
   1.200 +        iBitmap = newBitmap;
   1.201 +        }
   1.202 +    }
   1.203 +
   1.204 +
   1.205 +CFbsBitmap *CTestCFbsImage::Bitmap()
   1.206 +    {
   1.207 +    return iBitmap;
   1.208 +    }
   1.209 +
   1.210 +
   1.211 +CTestCFbsImage::CTestCFbsImage()
   1.212 +    {
   1.213 +    iBitmap = NULL;
   1.214 +    }
   1.215 +
   1.216 +
   1.217 +CTestCFbsImage::~CTestCFbsImage()
   1.218 +    {
   1.219 +    delete iBitmap;
   1.220 +    RFbsSession::Disconnect();
   1.221 +    }
   1.222 +
   1.223 +TSize CTestCFbsImage::Size() const
   1.224 +    {
   1.225 +    ASSERT(iBitmap);
   1.226 +    return iBitmap->SizeInPixels();
   1.227 +    }
   1.228 +
   1.229 +TRgb CTestCFbsImage::Pixel(TInt x, TInt y) const
   1.230 +    {
   1.231 +    TRgb rgb;
   1.232 +    iBitmap->GetPixel(rgb, TPoint(x, y));
   1.233 +    return rgb;
   1.234 +    }
   1.235 +
   1.236 +// CTestVgImage...
   1.237 +CTestVgImage::CTestVgImage()
   1.238 +    {
   1.239 +    iVgImage = VG_INVALID_HANDLE;
   1.240 +    iDataFormat = VG_IMAGE_FORMAT_INVALID;
   1.241 +    }
   1.242 +
   1.243 +
   1.244 +CTestVgImage::~CTestVgImage()
   1.245 +    {
   1.246 +    vgDestroyImage(iVgImage);
   1.247 +    }
   1.248 +
   1.249 +
   1.250 +CTestVgImage *CTestVgImage::NewL(TInt aIndex)
   1.251 +    {
   1.252 +    CTestVgImage *self = new (ELeave) CTestVgImage;
   1.253 +    CleanupStack::PushL(self);
   1.254 +    self->ConstructL(aIndex);
   1.255 +    CleanupStack::Pop(self);
   1.256 +    return self;
   1.257 +    }
   1.258 +
   1.259 +
   1.260 +void CTestVgImage::ConstructL(TInt aIndex)
   1.261 +    {
   1.262 +    CTestCFbsImage* bmp = CTestCFbsImage::NewL(aIndex);
   1.263 +    CleanupStack::PushL(bmp);
   1.264 +    CFbsBitmap *bitmap = bmp->Bitmap();
   1.265 +    ASSERT(bitmap);
   1.266 +    TUint8* address = (TUint8*)bitmap->DataAddress();
   1.267 +    TSize size = bitmap->SizeInPixels();
   1.268 +    iDataFormat = VG_IMAGE_FORMAT_INVALID;
   1.269 +    TDisplayMode mode = bitmap->DisplayMode();
   1.270 +    switch(mode)
   1.271 +        {
   1.272 +        case EColor64K:
   1.273 +            iDataFormat = VG_sRGB_565;
   1.274 +            break;
   1.275 +        case EColor16MAP:
   1.276 +            iDataFormat = VG_sARGB_8888_PRE;
   1.277 +            break;
   1.278 +        case EColor16MU:
   1.279 +            iDataFormat = VG_sXRGB_8888;
   1.280 +            break;
   1.281 +        case EColor16MA:
   1.282 +            iDataFormat = VG_sARGB_8888;
   1.283 +            break;
   1.284 +        }
   1.285 +    if (iDataFormat == VG_IMAGE_FORMAT_INVALID)
   1.286 +        {
   1.287 +        User::Leave(KErrBadHandle);
   1.288 +        }
   1.289 +    VGint width = size.iWidth;
   1.290 +    VGint height = size.iHeight;
   1.291 +    VGint dataStride = bitmap->DataStride();
   1.292 +
   1.293 +    //this allows us to copy the image correctly into vg coordinates
   1.294 +    address += ((height) - 1) * (dataStride);
   1.295 +    dataStride = 0 - (dataStride);
   1.296 +
   1.297 +    //Create VGImage and load Symbian bitmap into it
   1.298 +    iVgImage = vgCreateImage(iDataFormat, width, height, VG_IMAGE_QUALITY_NONANTIALIASED);
   1.299 +    if (iVgImage == VG_INVALID_HANDLE)
   1.300 +        {
   1.301 +        VGint err = vgGetError();
   1.302 +        RDebug::Printf("%s:%d: Could not create vgimage: error = 0x%x", __FILE__, __LINE__, err);
   1.303 +        User::Leave(KErrNotSupported);
   1.304 +        }
   1.305 +    vgImageSubData(iVgImage, address, dataStride, iDataFormat, 0, 0, width, height);
   1.306 +    CleanupStack::PopAndDestroy(bmp);
   1.307 +    }
   1.308 +
   1.309 +VGImage CTestVgImage::VGImage()
   1.310 +    {
   1.311 +    return iVgImage;
   1.312 +    }
   1.313 +
   1.314 +
   1.315 +TSize CTestVgImage::Size() const
   1.316 +    {
   1.317 +    VGint x, y;
   1.318 +    // If this is called a lot, maybe we should cache the value.
   1.319 +    x = vgGetParameteri(iVgImage, VG_IMAGE_WIDTH);
   1.320 +    y = vgGetParameteri(iVgImage, VG_IMAGE_HEIGHT);
   1.321 +    return TSize(x, y);
   1.322 +    }
   1.323 +
   1.324 +
   1.325 +TRgb CTestVgImage::Pixel(TInt x, TInt y) const
   1.326 +    {
   1.327 +    TRgb rgb(0, 0, 0);
   1.328 +    TSize size = Size();
   1.329 +    if (size.iHeight <= y || size.iWidth <= x)
   1.330 +        {
   1.331 +        ASSERT(0 && "Asked for pixel outside image size");
   1.332 +        return TRgb(0, 0, 0);
   1.333 +        }
   1.334 +    // VG images are "y = 0, x = 0 => bottom left", so we translate it from "y = 0, x = 0 => top left".
   1.335 +    y = (size.iHeight - 1) - y;
   1.336 +    switch(iDataFormat)
   1.337 +        {
   1.338 +        case VG_sRGB_565:
   1.339 +            {
   1.340 +            TUint16 intPixelSample;
   1.341 +            vgGetImageSubData(iVgImage, &intPixelSample, sizeof(intPixelSample), iDataFormat, x, y, 1, 1);
   1.342 +            rgb = TRgb::Color64K(intPixelSample);
   1.343 +            }
   1.344 +            break;
   1.345 +        case VG_sARGB_8888:
   1.346 +        case VG_sXRGB_8888:
   1.347 +        case VG_sARGB_8888_PRE:
   1.348 +            {
   1.349 +            TUint32 intPixelSample;
   1.350 +            vgGetImageSubData(iVgImage, &intPixelSample, sizeof(intPixelSample), iDataFormat, x, y, 1, 1);
   1.351 +            rgb = TRgb::Color16MA(intPixelSample);
   1.352 +            }
   1.353 +            break;
   1.354 +            
   1.355 +        case VG_sABGR_8888:
   1.356 +        case VG_sXBGR_8888:
   1.357 +        case VG_sABGR_8888_PRE:
   1.358 +            {
   1.359 +            TUint32 intPixelSample;
   1.360 +            vgGetImageSubData(iVgImage, &intPixelSample, sizeof(intPixelSample), iDataFormat, x, y, 1, 1);
   1.361 +            rgb = TRgb::Color16MA(intPixelSample);
   1.362 +            // Now swap R & B, as we have BGR in the source, not RGB!
   1.363 +            TInt temp = rgb.Red();
   1.364 +            rgb.SetRed(rgb.Blue());
   1.365 +            rgb.SetBlue(temp);
   1.366 +            }
   1.367 +            break;
   1.368 +            
   1.369 +        default:
   1.370 +            ASSERT(0 && "Invalid dataformat");
   1.371 +            break;
   1.372 +        }
   1.373 +    return rgb;
   1.374 +    }
   1.375 +
   1.376 +CTestVgEglImage::CTestVgEglImage()
   1.377 +    {
   1.378 +    }
   1.379 +
   1.380 +CTestVgEglImage* CTestVgEglImage::New(EGLImageKHR aEglImage)
   1.381 +    {
   1.382 +    CTestVgEglImage *self = new (ELeave) CTestVgEglImage;
   1.383 +    if (self)
   1.384 +        {
   1.385 +        CleanupStack::PushL(self);
   1.386 +        TRAPD(err, self->ConstructL(aEglImage));
   1.387 +        if (err != KErrNone)
   1.388 +            {
   1.389 +            CleanupStack::PopAndDestroy(self);
   1.390 +            return NULL;
   1.391 +            }
   1.392 +        else
   1.393 +            {
   1.394 +            CleanupStack::Pop(self);
   1.395 +            }
   1.396 +        }
   1.397 +    return self;
   1.398 +    }
   1.399 +
   1.400 +
   1.401 +CTestVgEglImage* CTestVgEglImage::NewL(EGLImageKHR aEglImage)
   1.402 +    {
   1.403 +    CTestVgEglImage *self = New(aEglImage);
   1.404 +    User::LeaveIfNull(self);
   1.405 +    return self;
   1.406 +    }
   1.407 +
   1.408 +
   1.409 +void CTestVgEglImage::ConstructL(EGLImageKHR aEglImage)
   1.410 +    {
   1.411 +    PFNCreateFromEglImage createFromEglTarget =
   1.412 +        reinterpret_cast<PFNCreateFromEglImage>(eglGetProcAddress("vgCreateEGLImageTargetKHR"));
   1.413 +    iVgImage = createFromEglTarget(aEglImage);
   1.414 +    if (iVgImage == VG_INVALID_HANDLE)
   1.415 +        {
   1.416 +        RDebug::Printf("%s:%d: Unable to create VGImage from EGLImage: Error code=0x%x", __FILE__, __LINE__, vgGetError());
   1.417 +        User::Leave(KErrBadHandle);
   1.418 +        }
   1.419 +    iDataFormat = static_cast<VGImageFormat>(vgGetParameteri(iVgImage, VG_IMAGE_FORMAT));
   1.420 +    }