os/graphics/egl/egltest/endpointtestsuite/automated/tsrc/egltest_endpoint_images.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 /**
    17  @file
    18  @test
    19  @internalComponent - Internal Symbian test code
    20 */
    21 
    22 #include "egltest_endpoint_images.h"
    23 
    24 _LIT(KImage1, "z:\\resource\\apps\\egltest_endpoint\\image1.mbm");
    25 _LIT(KImage2, "z:\\resource\\apps\\egltest_endpoint\\image2.mbm");
    26 _LIT(KImage3, "z:\\resource\\apps\\egltest_endpoint\\image3.mbm");
    27 _LIT(KImage4, "z:\\resource\\apps\\egltest_endpoint\\image4.mbm");
    28 
    29 
    30 const static TDesC *KImageList[]=
    31 {
    32         &KImage1,
    33         &KImage2,
    34         &KImage3,
    35         &KImage4,
    36 };
    37 
    38 typedef VGImage (*PFNCreateFromEglImage)(EGLImageKHR);
    39 
    40 const TInt CTestImage::KImageCount = sizeof(KImageList)/sizeof(KImageList[0]);
    41 
    42 CTestImage::~CTestImage()
    43     {
    44     }
    45 
    46 CTestImage::CTestImage()
    47     {
    48     }
    49 
    50 TBool CTestImage::ComparePixel(TRgb aPixel1, TRgb aPixel2, TBool aExpectError)
    51     {
    52     // In a 16-bit per pixel scenario, we allow (8 bits - 5 bits) = 3 bits,
    53     // which gives a value of 8  worth of difference.
    54     const TInt KMargin = 8;
    55     TBool match = ETrue;
    56     if (Abs(aPixel1.Red()-aPixel2.Red()) > KMargin ||
    57         Abs(aPixel1.Green()-aPixel2.Green()) > KMargin ||
    58         Abs(aPixel1.Blue()-aPixel2.Blue()) > KMargin)
    59         {
    60         if (!aExpectError)
    61             {
    62             RDebug::Printf("%s:%d: pixel %08x doesn't match %08x", __FILE__, __LINE__, aPixel1.Color16MA(), aPixel2.Color16MA());
    63             }
    64         match = EFalse;
    65         }
    66     else if (aExpectError)
    67         {
    68         RDebug::Printf("%s:%d: pixel %08x matches %08x", __FILE__, __LINE__, aPixel1.Color16MA(), aPixel2.Color16MA());
    69         }
    70     return match;
    71     }
    72 
    73 
    74 // Compare the this image with the aImage.
    75 // Images must be same size.
    76 TBool CTestImage::CompareImageL(const CTestImage *aImage, TBool aExpectError) const
    77     {
    78     TSize size = Size();
    79     TSize otherSize = aImage->Size();
    80     if (otherSize != size)
    81         {
    82         size.iHeight = Min(size.iHeight, otherSize.iHeight);
    83         size.iWidth  = Min(size.iWidth, otherSize.iWidth);
    84         }
    85 
    86     RArray<TPoint> points;
    87     CleanupClosePushL(points);
    88     points.AppendL(TPoint(0, 0));     // Top left.
    89     points.AppendL(TPoint(size.iWidth-1, 0));  // Top right.
    90     points.AppendL(TPoint(0, size.iHeight-1)); // Bottom left.
    91     points.AppendL(TPoint(size.iWidth-1, size.iHeight-1)); // Bottom right
    92     points.AppendL(TPoint(size.iWidth >> 1, size.iHeight >> 1));   // Middle
    93 
    94     TBool retVal = ETrue;
    95     for(TInt i = 0; i < points.Count(); i++)
    96         {
    97         TInt x = points[i].iX;
    98         TInt y = points[i].iY;
    99         if (!ComparePixel(Pixel(x, y), aImage->Pixel(x, y), aExpectError))
   100             {
   101             retVal = EFalse;
   102             break;
   103             }
   104         }
   105     TInt err = vgGetError();
   106     if (err != VG_NO_ERROR)
   107         {
   108         RDebug::Printf("%s:%d: Could not fetch pixels??? err=%x", __FILE__, __LINE__, err);
   109         retVal = EFalse;
   110         }
   111     CleanupStack::PopAndDestroy(&points);
   112     return retVal;
   113     }
   114 
   115 
   116 //Checks if the image is a solid colour.
   117 //Only checks corners and middle pixel.
   118 TBool CTestImage::IsSolidColourL() const
   119     {
   120     //Points in image to compare (corners and middle).
   121     TSize size = Size();
   122     RArray<TPoint> points;
   123     CleanupClosePushL(points);
   124     points.AppendL(TPoint(0, 0));                                // Top left.
   125     points.AppendL(TPoint(size.iWidth-1, 0));                    // Top right.
   126     points.AppendL(TPoint(0, size.iHeight-1));                   // Bottom left.
   127     points.AppendL(TPoint(size.iWidth-1, size.iHeight-1));       // Bottom right.
   128     points.AppendL(TPoint(size.iWidth >> 1, size.iHeight >> 1)); // Middle.
   129 
   130     //Check that all points contain the same colour.
   131     TBool retVal = ETrue;
   132     for(TInt i = 1; i < points.Count(); ++i)
   133         {
   134         if(Pixel(points[i-1].iX, points[i-1].iY) != Pixel(points[i].iX, points[i].iY))
   135             {
   136             retVal = EFalse;
   137             break;
   138             }
   139         }
   140     TInt err = vgGetError();
   141     if (err != VG_NO_ERROR)
   142         {
   143         RDebug::Printf("Could not fetch pixels??? err=%x", err);
   144         retVal = EFalse;
   145         }
   146     
   147     CleanupStack::PopAndDestroy(&points);
   148     return retVal;
   149     }
   150 
   151 
   152 CTestCFbsImage *CTestCFbsImage::NewL(TInt aIndex)
   153     {
   154     CTestCFbsImage* self = new (ELeave) CTestCFbsImage;
   155     CleanupStack::PushL(self);
   156     self->ConstructL(aIndex);
   157     CleanupStack::Pop(self);
   158     return self;
   159     }
   160 
   161 
   162 void CTestCFbsImage::ConstructL(TInt aIndex)
   163     {
   164     // Do this before we leave - else we may disconnect more than we connect!
   165     RFbsSession::Connect();
   166     if (aIndex >= KImageCount)
   167         {
   168         User::Leave(KErrOverflow);
   169         }
   170     iBitmap = new (ELeave) CFbsBitmap;
   171     TInt err = iBitmap->Load(*KImageList[aIndex], 0);
   172     if (err != KErrNone)
   173         {
   174         RDebug::Printf("Image load error %d for image %d (name=%S)", err, aIndex, KImageList[aIndex]);
   175         User::Leave(err);
   176         }
   177 
   178     // Check if it's a 24bpp image. If so, we must convert it to 32bpp.
   179     // as vgImages can't be 24bpp [in the Hybrid EGL/VG implementation],
   180     // and we (may) want to make this into a vg-image at some point in future.
   181     if(iBitmap->DisplayMode() == EColor16M)
   182         {
   183         CFbsBitmap *newBitmap = new (ELeave) CFbsBitmap;
   184         CleanupStack::PushL(newBitmap);
   185         TSize size = iBitmap->SizeInPixels();
   186         newBitmap->Create(size, EColor16MU);
   187         TInt32 *b = new TInt32[size.iWidth];
   188         TPtr8 buf((TUint8*)b, size.iWidth * sizeof(*b));
   189         for (TInt y=0; y<size.iHeight; ++y)
   190             {
   191             iBitmap->GetScanLine(buf, TPoint(0, y), size.iWidth, EColor16MU);
   192             newBitmap->SetScanLine(buf, y);
   193             }
   194         delete b;
   195         delete iBitmap;
   196         CleanupStack::Pop(newBitmap);
   197         iBitmap = newBitmap;
   198         }
   199     }
   200 
   201 
   202 CFbsBitmap *CTestCFbsImage::Bitmap()
   203     {
   204     return iBitmap;
   205     }
   206 
   207 
   208 CTestCFbsImage::CTestCFbsImage()
   209     {
   210     iBitmap = NULL;
   211     }
   212 
   213 
   214 CTestCFbsImage::~CTestCFbsImage()
   215     {
   216     delete iBitmap;
   217     RFbsSession::Disconnect();
   218     }
   219 
   220 TSize CTestCFbsImage::Size() const
   221     {
   222     ASSERT(iBitmap);
   223     return iBitmap->SizeInPixels();
   224     }
   225 
   226 TRgb CTestCFbsImage::Pixel(TInt x, TInt y) const
   227     {
   228     TRgb rgb;
   229     iBitmap->GetPixel(rgb, TPoint(x, y));
   230     return rgb;
   231     }
   232 
   233 // CTestVgImage...
   234 CTestVgImage::CTestVgImage()
   235     {
   236     iVgImage = VG_INVALID_HANDLE;
   237     iDataFormat = VG_IMAGE_FORMAT_INVALID;
   238     }
   239 
   240 
   241 CTestVgImage::~CTestVgImage()
   242     {
   243     vgDestroyImage(iVgImage);
   244     }
   245 
   246 
   247 CTestVgImage *CTestVgImage::NewL(TInt aIndex)
   248     {
   249     CTestVgImage *self = new (ELeave) CTestVgImage;
   250     CleanupStack::PushL(self);
   251     self->ConstructL(aIndex);
   252     CleanupStack::Pop(self);
   253     return self;
   254     }
   255 
   256 
   257 void CTestVgImage::ConstructL(TInt aIndex)
   258     {
   259     CTestCFbsImage* bmp = CTestCFbsImage::NewL(aIndex);
   260     CleanupStack::PushL(bmp);
   261     CFbsBitmap *bitmap = bmp->Bitmap();
   262     ASSERT(bitmap);
   263     TUint8* address = (TUint8*)bitmap->DataAddress();
   264     TSize size = bitmap->SizeInPixels();
   265     iDataFormat = VG_IMAGE_FORMAT_INVALID;
   266     TDisplayMode mode = bitmap->DisplayMode();
   267     switch(mode)
   268         {
   269         case EColor64K:
   270             iDataFormat = VG_sRGB_565;
   271             break;
   272         case EColor16MAP:
   273             iDataFormat = VG_sARGB_8888_PRE;
   274             break;
   275         case EColor16MU:
   276             iDataFormat = VG_sXRGB_8888;
   277             break;
   278         case EColor16MA:
   279             iDataFormat = VG_sARGB_8888;
   280             break;
   281         }
   282     if (iDataFormat == VG_IMAGE_FORMAT_INVALID)
   283         {
   284         User::Leave(KErrBadHandle);
   285         }
   286     VGint width = size.iWidth;
   287     VGint height = size.iHeight;
   288     VGint dataStride = bitmap->DataStride();
   289 
   290     //this allows us to copy the image correctly into vg coordinates
   291     address += ((height) - 1) * (dataStride);
   292     dataStride = 0 - (dataStride);
   293 
   294     //Create VGImage and load Symbian bitmap into it
   295     iVgImage = vgCreateImage(iDataFormat, width, height, VG_IMAGE_QUALITY_NONANTIALIASED);
   296     if (iVgImage == VG_INVALID_HANDLE)
   297         {
   298         VGint err = vgGetError();
   299         RDebug::Printf("%s:%d: Could not create vgimage: error = 0x%x", __FILE__, __LINE__, err);
   300         User::Leave(KErrNotSupported);
   301         }
   302     vgImageSubData(iVgImage, address, dataStride, iDataFormat, 0, 0, width, height);
   303     CleanupStack::PopAndDestroy(bmp);
   304     }
   305 
   306 VGImage CTestVgImage::VGImage()
   307     {
   308     return iVgImage;
   309     }
   310 
   311 
   312 TSize CTestVgImage::Size() const
   313     {
   314     VGint x, y;
   315     // If this is called a lot, maybe we should cache the value.
   316     x = vgGetParameteri(iVgImage, VG_IMAGE_WIDTH);
   317     y = vgGetParameteri(iVgImage, VG_IMAGE_HEIGHT);
   318     return TSize(x, y);
   319     }
   320 
   321 
   322 TRgb CTestVgImage::Pixel(TInt x, TInt y) const
   323     {
   324     TRgb rgb(0, 0, 0);
   325     TSize size = Size();
   326     if (size.iHeight <= y || size.iWidth <= x)
   327         {
   328         ASSERT(0 && "Asked for pixel outside image size");
   329         return TRgb(0, 0, 0);
   330         }
   331     // VG images are "y = 0, x = 0 => bottom left", so we translate it from "y = 0, x = 0 => top left".
   332     y = (size.iHeight - 1) - y;
   333     switch(iDataFormat)
   334         {
   335         case VG_sRGB_565:
   336             {
   337             TUint16 intPixelSample;
   338             vgGetImageSubData(iVgImage, &intPixelSample, sizeof(intPixelSample), iDataFormat, x, y, 1, 1);
   339             rgb = TRgb::Color64K(intPixelSample);
   340             }
   341             break;
   342         case VG_sARGB_8888:
   343         case VG_sXRGB_8888:
   344         case VG_sARGB_8888_PRE:
   345             {
   346             TUint32 intPixelSample;
   347             vgGetImageSubData(iVgImage, &intPixelSample, sizeof(intPixelSample), iDataFormat, x, y, 1, 1);
   348             rgb = TRgb::Color16MA(intPixelSample);
   349             }
   350             break;
   351             
   352         case VG_sABGR_8888:
   353         case VG_sXBGR_8888:
   354         case VG_sABGR_8888_PRE:
   355             {
   356             TUint32 intPixelSample;
   357             vgGetImageSubData(iVgImage, &intPixelSample, sizeof(intPixelSample), iDataFormat, x, y, 1, 1);
   358             rgb = TRgb::Color16MA(intPixelSample);
   359             // Now swap R & B, as we have BGR in the source, not RGB!
   360             TInt temp = rgb.Red();
   361             rgb.SetRed(rgb.Blue());
   362             rgb.SetBlue(temp);
   363             }
   364             break;
   365             
   366         default:
   367             ASSERT(0 && "Invalid dataformat");
   368             break;
   369         }
   370     return rgb;
   371     }
   372 
   373 CTestVgEglImage::CTestVgEglImage()
   374     {
   375     }
   376 
   377 CTestVgEglImage* CTestVgEglImage::New(EGLImageKHR aEglImage)
   378     {
   379     CTestVgEglImage *self = new (ELeave) CTestVgEglImage;
   380     if (self)
   381         {
   382         CleanupStack::PushL(self);
   383         TRAPD(err, self->ConstructL(aEglImage));
   384         if (err != KErrNone)
   385             {
   386             CleanupStack::PopAndDestroy(self);
   387             return NULL;
   388             }
   389         else
   390             {
   391             CleanupStack::Pop(self);
   392             }
   393         }
   394     return self;
   395     }
   396 
   397 
   398 CTestVgEglImage* CTestVgEglImage::NewL(EGLImageKHR aEglImage)
   399     {
   400     CTestVgEglImage *self = New(aEglImage);
   401     User::LeaveIfNull(self);
   402     return self;
   403     }
   404 
   405 
   406 void CTestVgEglImage::ConstructL(EGLImageKHR aEglImage)
   407     {
   408     PFNCreateFromEglImage createFromEglTarget =
   409         reinterpret_cast<PFNCreateFromEglImage>(eglGetProcAddress("vgCreateEGLImageTargetKHR"));
   410     iVgImage = createFromEglTarget(aEglImage);
   411     if (iVgImage == VG_INVALID_HANDLE)
   412         {
   413         RDebug::Printf("%s:%d: Unable to create VGImage from EGLImage: Error code=0x%x", __FILE__, __LINE__, vgGetError());
   414         User::Leave(KErrBadHandle);
   415         }
   416     iDataFormat = static_cast<VGImageFormat>(vgGetParameteri(iVgImage, VG_IMAGE_FORMAT));
   417     }