uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiFxVg10Engine.cpp
changeset 0 15bf7259bb7c
child 18 1801340c26a2
equal deleted inserted replaced
-1:000000000000 0:15bf7259bb7c
       
     1 /*
       
     2 * Copyright (c) 2008 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 
       
    20 #include "HuiFxVg10Engine.h"
       
    21 #include "HuiFxVg10OnscreenRenderbuffer.h"
       
    22 #include "HuiFxVg10OffscreenRenderbuffer.h"
       
    23 #include "HuiFxVg10BlurFilter.h"
       
    24 #include "HuiFxVg10BrightnessContrastFilter.h"
       
    25 #include "HuiFxVg10HSLFilter.h"
       
    26 #include "HuiFxVg10ColorizeFilter.h"
       
    27 #include "HuiFxVg10OutlineFilter.h"
       
    28 #include "HuiFxVg10BevelFilter.h"
       
    29 #include "HuiVg10Gc.h"
       
    30 #include "uiacceltk/HuiEnv.h"
       
    31 #include "uiacceltk/HuiDisplay.h"
       
    32 #include "uiacceltk/HuiStatic.h"
       
    33 
       
    34 CHuiFxVg10Engine* CHuiFxVg10Engine::NewL(CHuiVg10RenderPlugin& aPlugin)
       
    35     {
       
    36     CHuiFxVg10Engine* e = new (ELeave) CHuiFxVg10Engine();
       
    37     CleanupStack::PushL(e);
       
    38     e->ConstructL(aPlugin);
       
    39     CleanupStack::Pop(e);
       
    40     return e;
       
    41     }
       
    42 
       
    43 void CHuiFxVg10Engine::ConstructL(CHuiVg10RenderPlugin& aPlugin)
       
    44     {
       
    45     CHuiFxEngine::ConstructL(EHuiFxEngineVg10);
       
    46     iPlugin = &aPlugin;
       
    47     iDefaultBuffer = 0;
       
    48     iCompPaint = vgCreatePaint();
       
    49     }
       
    50 
       
    51 CHuiFxVg10Engine::~CHuiFxVg10Engine()
       
    52     {
       
    53     delete iDefaultBuffer;
       
    54     vgDestroyPaint(iCompPaint);
       
    55     }
       
    56 
       
    57 CHuiFxRenderbuffer* CHuiFxVg10Engine::AcquireNativeRenderbuffer(const TSize& aDesiredSize)
       
    58     {
       
    59     CHuiFxRenderbuffer* ret = NULL;
       
    60     TRAP_IGNORE(ret = CHuiFxVg10OffscreenRenderbuffer::NewL(*iPlugin, aDesiredSize));
       
    61     return ret;
       
    62     }
       
    63 
       
    64 void CHuiFxVg10Engine::ReleaseNativeRenderbuffer(CHuiFxRenderbuffer* aBuffer)
       
    65     {
       
    66     ASSERT(aBuffer);
       
    67     ASSERT(aBuffer != iDefaultBuffer);
       
    68     
       
    69     delete aBuffer;
       
    70     aBuffer = 0;
       
    71     }
       
    72 
       
    73 CHuiFxRenderbuffer* CHuiFxVg10Engine::DefaultRenderbuffer()
       
    74     {
       
    75     if (!iDefaultBuffer)
       
    76         {
       
    77         TRAPD(err, RestoreL());
       
    78         if(err != KErrNone)
       
    79             {
       
    80             return NULL;
       
    81             }
       
    82         }
       
    83     return iDefaultBuffer;
       
    84     }
       
    85 
       
    86 void CHuiFxVg10Engine::Release()
       
    87     {
       
    88     delete iDefaultBuffer;
       
    89     iDefaultBuffer = 0;
       
    90     }
       
    91 
       
    92 void CHuiFxVg10Engine::RestoreL()
       
    93     {
       
    94     if (!iDefaultBuffer)
       
    95         {
       
    96         CHuiVg10RenderSurface* surface = static_cast<CHuiVg10RenderSurface*>(CHuiStatic::CurrentRenderSurface());
       
    97         if (surface)
       
    98             {
       
    99             iDefaultBuffer = CHuiFxVg10OnscreenRenderbuffer::NewL(*iPlugin, *surface);
       
   100             }
       
   101         }
       
   102     }
       
   103 
       
   104 CHuiFxFilter* CHuiFxVg10Engine::CreateFilterL(THuiFxFilterType aType)
       
   105     {
       
   106     switch (aType)
       
   107         {
       
   108         case EFilterTypeBrightnessContrast:
       
   109             return CHuiFxVg10BrightnessContrastFilter::NewL();
       
   110             // no break because we returned already
       
   111             
       
   112         case EFilterTypeBlur:
       
   113             return CHuiFxVg10BlurFilter::NewL();
       
   114             // no break because we returned already
       
   115 
       
   116         case EFilterTypeHSL:
       
   117         case EFilterTypeDesaturate: // desaturate is generated by hsl filter
       
   118             return CHuiFxVg10HSLFilter::NewL();
       
   119             // no break because we returned already
       
   120             
       
   121         case EFilterTypeColorize:
       
   122             return CHuiFxVg10ColorizeFilter::NewL();
       
   123             // no break because we returned already
       
   124 
       
   125         case EFilterTypeOutline:
       
   126             return CHuiFxVg10OutlineFilter::NewL();
       
   127             // no break because we returned already
       
   128 
       
   129         case EFilterTypeBevel:
       
   130             return CHuiFxVg10BevelFilter::NewL();
       
   131             // no break because we returned already
       
   132 
       
   133         default: // unsupported
       
   134             break;
       
   135         }
       
   136     return NULL;    
       
   137     }
       
   138 
       
   139 void CHuiFxVg10Engine::Composite(CHuiFxRenderbuffer& aTarget, CHuiFxRenderbuffer& aSource, 
       
   140                                       const TRect& aTargetRect, const TRect& aSourceRect,
       
   141                                       THuiFxBlendingMode aMode, TInt aAlpha)
       
   142     {
       
   143     const TInt VG_MATRIX_SIZE = 9;
       
   144     CHuiGc& gc = aTarget.BindAsRenderTarget();
       
   145     aSource.BindAsTexture(ERenderbufferUsageReadOnly);
       
   146         
       
   147 #if 0 // render debug rectangle
       
   148     VGint x = aTargetRect.iTl.iX;
       
   149     VGint y = aTarget.Size().iHeight - aTargetRect.iBr.iY;
       
   150     VGint w = aTargetRect.Size().iWidth;
       
   151     VGint h = aTargetRect.Size().iHeight;
       
   152     VGfloat color[] = 
       
   153         {
       
   154         .2f, .4f, .6f, 1.0f
       
   155         };
       
   156     vgSetfv(VG_CLEAR_COLOR, 4, color);
       
   157     vgClear(x, y, w, h);
       
   158     HUIFX_VG_INVARIANT();
       
   159 #else
       
   160     VGImage image = (reinterpret_cast<CHuiFxVg10RenderbufferBase*>(&aSource))->AcquireSubImage(aSourceRect);
       
   161 
       
   162     ASSERT(vgGeti(VG_MATRIX_MODE) == VG_MATRIX_IMAGE_USER_TO_SURFACE);
       
   163     VGfloat oldMatrix[VG_MATRIX_SIZE];
       
   164     vgGetMatrix(oldMatrix);
       
   165     vgLoadIdentity();
       
   166     vgSeti(VG_SCISSORING, VG_FALSE); 
       
   167     VGint blendMode = vgGeti(VG_BLEND_MODE);
       
   168 
       
   169     // Choose a blending mode
       
   170     switch (aMode)
       
   171         {
       
   172     case EBlendingModeReplace:
       
   173         vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
       
   174         break;
       
   175     case EBlendingModeOver:
       
   176         vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
       
   177         break;
       
   178     case EBlendingModeMultiply:
       
   179         vgSeti(VG_BLEND_MODE, VG_BLEND_MULTIPLY);
       
   180         break;
       
   181     case EBlendingModeAdditive:
       
   182         vgSeti(VG_BLEND_MODE, VG_BLEND_ADDITIVE);
       
   183         break;
       
   184     case EBlendingModeLighten:
       
   185         vgSeti(VG_BLEND_MODE, VG_BLEND_LIGHTEN);
       
   186         break;
       
   187     case EBlendingModeDarken:
       
   188         vgSeti(VG_BLEND_MODE, VG_BLEND_DARKEN);
       
   189         break;
       
   190     default:
       
   191         ASSERT(0);
       
   192         }
       
   193     HUIFX_VG_INVARIANT();
       
   194     
       
   195     // Update alpha
       
   196     TBool mustRestorePaint = EFalse;
       
   197     VGPaint userPaint = VG_INVALID_HANDLE;
       
   198 
       
   199     if (aAlpha < 0xff)
       
   200         {
       
   201         if ( iCompPaint == VG_INVALID_HANDLE )
       
   202             {
       
   203             iCompPaint = vgCreatePaint();
       
   204             }
       
   205         if ( iCompPaint != VG_INVALID_HANDLE )
       
   206             {
       
   207             mustRestorePaint = ETrue;
       
   208             userPaint = vgGetPaint( VG_FILL_PATH );
       
   209             // if the original paint is not set, we'll get an error that must be cleared
       
   210             vgSetPaint(iCompPaint, VG_FILL_PATH);
       
   211             }
       
   212         vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
       
   213         vgSetColor(iCompPaint, 0xffffff00 | aAlpha);
       
   214         }
       
   215     else
       
   216         {
       
   217         vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
       
   218         }
       
   219     
       
   220     // we've taken childimage from source so no clipping or adjusting is needed 
       
   221     // by source rectangle.
       
   222     if (aTarget.BufferType() == EBufferTypeOnscreen)
       
   223         {
       
   224 		// we need to adjust our coordinates to screen coordinates. Hitchcock 
       
   225         // thinks origo is on top-left of screen. VG thinks origo is on 
       
   226         // bottom-left.
       
   227         // We must take orientation if we access vg matrixes directly..
       
   228         CHuiDisplay* display = &CHuiStatic::Env().PrimaryDisplay(); // TODO: should use CHuiEnv::CurrentDisplay() ? 
       
   229         
       
   230         if (display->Orientation() == CHuiGc::EOrientationCCW90)
       
   231             {
       
   232             // Rotate around origo and move back to displayarea
       
   233             vgRotate(-90);
       
   234             vgTranslate(aTargetRect.iTl.iX - aTarget.Size().iHeight , aTarget.Size().iWidth - aTargetRect.iBr.iY);
       
   235             }
       
   236         else if (display->Orientation() == CHuiGc::EOrientationCW90)
       
   237             {
       
   238             // Rotate around origo and move back to displayarea
       
   239             vgRotate(90);
       
   240             vgTranslate(aTargetRect.iTl.iX , - aTargetRect.iBr.iY);
       
   241             }
       
   242         else if (display->Orientation() == CHuiGc::EOrientation180)
       
   243             {
       
   244             // Rotate around origo and move back to displayarea
       
   245             vgRotate(180);
       
   246             vgTranslate(aTarget.Size().iWidth- aTargetRect.iTl.iX , - aTargetRect.iBr.iY);
       
   247             }
       
   248         else
       
   249             {
       
   250             vgTranslate(aTargetRect.iTl.iX, aTarget.Size().iHeight - aTargetRect.iBr.iY);
       
   251             }        
       
   252         
       
   253         }
       
   254     else 
       
   255         {
       
   256         // offscreen renderbuffer --- we use VG coordinates
       
   257         vgTranslate(aTargetRect.iTl.iX, aTargetRect.iTl.iY);
       
   258         }
       
   259     
       
   260     // slowpath
       
   261     if(aTargetRect.Size() != aSourceRect.Size())
       
   262         {
       
   263         VGfloat scaleX = (VGfloat)aTargetRect.Width() / aSourceRect.Width();
       
   264         VGfloat scaleY = (VGfloat)aTargetRect.Height() / aSourceRect.Height();
       
   265         vgScale(scaleX, scaleY);
       
   266         }
       
   267     
       
   268     vgDrawImage(image);
       
   269     
       
   270     // Restore default VG state
       
   271     vgSeti(VG_SCISSORING, VG_TRUE);     
       
   272 //    vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
       
   273     vgSeti(VG_BLEND_MODE, blendMode);
       
   274     vgLoadMatrix(oldMatrix);
       
   275     HUIFX_VG_INVARIANT();
       
   276     if ( mustRestorePaint )
       
   277         {
       
   278         vgSetPaint(userPaint, VG_FILL_PATH);
       
   279         // if the original handle was invalid, this may produce an error
       
   280         }
       
   281     reinterpret_cast<CHuiFxVg10RenderbufferBase*>(&aSource)->ReleaseSubImage(image);
       
   282 #endif // debug rectangle
       
   283     aSource.UnbindAsTexture();
       
   284     aTarget.UnbindAsRenderTarget();
       
   285     }
       
   286 
       
   287 void CHuiFxVg10Engine::Composite(CHuiGc& aGc, CHuiFxRenderbuffer& aSource, const TPoint& aTargetPoint,TBool aOpaque, TInt aAlpha)
       
   288     {
       
   289     // Directly to screen, overrides onscreen buffer. Always "over" blending mode, constant alpha.
       
   290     const CHuiFxVg10OffscreenRenderbuffer* vg10RenderBuffer = (const CHuiFxVg10OffscreenRenderbuffer*) &aSource;        
       
   291     CHuiVg10Gc* vg10Gc = (CHuiVg10Gc*)&aGc;
       
   292     if (vg10RenderBuffer->Image())
       
   293         {
       
   294         // For some reason color is weird at this point, so set our own.
       
   295         TRgb oldPencolor = aGc.PenColor();
       
   296         TInt oldPenAlpha = aGc.PenAlpha();
       
   297         
       
   298         aGc.SetPenColor(KRgbWhite);
       
   299         aGc.SetPenAlpha(aAlpha);
       
   300         vg10Gc->UpdateColor();
       
   301 
       
   302         // Push matrix
       
   303         aGc.Push(EHuiGcMatrixModel);
       
   304         
       
   305         // Take into account the screen relative position of the buffer
       
   306         aGc.Translate(EHuiGcMatrixModel, aTargetPoint.iX, aTargetPoint.iY, 0);
       
   307 
       
   308         // Flip the content (because of hitchcock/openvg coordinate differencies       
       
   309         aGc.Translate(EHuiGcMatrixModel, 0.0f, aSource.Size().iHeight, 0.0f);
       
   310         aGc.Scale(EHuiGcMatrixModel, 1.0f, -1.0f, 1.0f);
       
   311 
       
   312         // Do the drawing, handle opaque windows with writealpha, otherwise blend
       
   313 		if (aOpaque)
       
   314 			{
       
   315 			aGc.Disable(CHuiGc::EFeatureBlending);
       
   316 			}
       
   317 		else
       
   318 			{
       
   319             aGc.Enable(CHuiGc::EFeatureBlending);
       
   320 			}
       
   321         vgDrawImage(vg10RenderBuffer->Image());
       
   322 
       
   323         // Restore pen color, matrix
       
   324         aGc.Enable(CHuiGc::EFeatureBlending);        
       
   325         aGc.SetPenColor(oldPencolor);                
       
   326         aGc.SetPenAlpha(oldPenAlpha);
       
   327         aGc.Pop(EHuiGcMatrixModel);
       
   328         }
       
   329     }