uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiFxVg10Engine.cpp
changeset 0 15bf7259bb7c
child 18 1801340c26a2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiFxVg10Engine.cpp	Tue Feb 02 07:56:43 2010 +0200
@@ -0,0 +1,329 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:   
+*
+*/
+
+
+
+#include "HuiFxVg10Engine.h"
+#include "HuiFxVg10OnscreenRenderbuffer.h"
+#include "HuiFxVg10OffscreenRenderbuffer.h"
+#include "HuiFxVg10BlurFilter.h"
+#include "HuiFxVg10BrightnessContrastFilter.h"
+#include "HuiFxVg10HSLFilter.h"
+#include "HuiFxVg10ColorizeFilter.h"
+#include "HuiFxVg10OutlineFilter.h"
+#include "HuiFxVg10BevelFilter.h"
+#include "HuiVg10Gc.h"
+#include "uiacceltk/HuiEnv.h"
+#include "uiacceltk/HuiDisplay.h"
+#include "uiacceltk/HuiStatic.h"
+
+CHuiFxVg10Engine* CHuiFxVg10Engine::NewL(CHuiVg10RenderPlugin& aPlugin)
+    {
+    CHuiFxVg10Engine* e = new (ELeave) CHuiFxVg10Engine();
+    CleanupStack::PushL(e);
+    e->ConstructL(aPlugin);
+    CleanupStack::Pop(e);
+    return e;
+    }
+
+void CHuiFxVg10Engine::ConstructL(CHuiVg10RenderPlugin& aPlugin)
+    {
+    CHuiFxEngine::ConstructL(EHuiFxEngineVg10);
+    iPlugin = &aPlugin;
+    iDefaultBuffer = 0;
+    iCompPaint = vgCreatePaint();
+    }
+
+CHuiFxVg10Engine::~CHuiFxVg10Engine()
+    {
+    delete iDefaultBuffer;
+    vgDestroyPaint(iCompPaint);
+    }
+
+CHuiFxRenderbuffer* CHuiFxVg10Engine::AcquireNativeRenderbuffer(const TSize& aDesiredSize)
+    {
+    CHuiFxRenderbuffer* ret = NULL;
+    TRAP_IGNORE(ret = CHuiFxVg10OffscreenRenderbuffer::NewL(*iPlugin, aDesiredSize));
+    return ret;
+    }
+
+void CHuiFxVg10Engine::ReleaseNativeRenderbuffer(CHuiFxRenderbuffer* aBuffer)
+    {
+    ASSERT(aBuffer);
+    ASSERT(aBuffer != iDefaultBuffer);
+    
+    delete aBuffer;
+    aBuffer = 0;
+    }
+
+CHuiFxRenderbuffer* CHuiFxVg10Engine::DefaultRenderbuffer()
+    {
+    if (!iDefaultBuffer)
+        {
+        TRAPD(err, RestoreL());
+        if(err != KErrNone)
+            {
+            return NULL;
+            }
+        }
+    return iDefaultBuffer;
+    }
+
+void CHuiFxVg10Engine::Release()
+    {
+    delete iDefaultBuffer;
+    iDefaultBuffer = 0;
+    }
+
+void CHuiFxVg10Engine::RestoreL()
+    {
+    if (!iDefaultBuffer)
+        {
+        CHuiVg10RenderSurface* surface = static_cast<CHuiVg10RenderSurface*>(CHuiStatic::CurrentRenderSurface());
+        if (surface)
+            {
+            iDefaultBuffer = CHuiFxVg10OnscreenRenderbuffer::NewL(*iPlugin, *surface);
+            }
+        }
+    }
+
+CHuiFxFilter* CHuiFxVg10Engine::CreateFilterL(THuiFxFilterType aType)
+    {
+    switch (aType)
+        {
+        case EFilterTypeBrightnessContrast:
+            return CHuiFxVg10BrightnessContrastFilter::NewL();
+            // no break because we returned already
+            
+        case EFilterTypeBlur:
+            return CHuiFxVg10BlurFilter::NewL();
+            // no break because we returned already
+
+        case EFilterTypeHSL:
+        case EFilterTypeDesaturate: // desaturate is generated by hsl filter
+            return CHuiFxVg10HSLFilter::NewL();
+            // no break because we returned already
+            
+        case EFilterTypeColorize:
+            return CHuiFxVg10ColorizeFilter::NewL();
+            // no break because we returned already
+
+        case EFilterTypeOutline:
+            return CHuiFxVg10OutlineFilter::NewL();
+            // no break because we returned already
+
+        case EFilterTypeBevel:
+            return CHuiFxVg10BevelFilter::NewL();
+            // no break because we returned already
+
+        default: // unsupported
+            break;
+        }
+    return NULL;    
+    }
+
+void CHuiFxVg10Engine::Composite(CHuiFxRenderbuffer& aTarget, CHuiFxRenderbuffer& aSource, 
+                                      const TRect& aTargetRect, const TRect& aSourceRect,
+                                      THuiFxBlendingMode aMode, TInt aAlpha)
+    {
+    const TInt VG_MATRIX_SIZE = 9;
+    CHuiGc& gc = aTarget.BindAsRenderTarget();
+    aSource.BindAsTexture(ERenderbufferUsageReadOnly);
+        
+#if 0 // render debug rectangle
+    VGint x = aTargetRect.iTl.iX;
+    VGint y = aTarget.Size().iHeight - aTargetRect.iBr.iY;
+    VGint w = aTargetRect.Size().iWidth;
+    VGint h = aTargetRect.Size().iHeight;
+    VGfloat color[] = 
+        {
+        .2f, .4f, .6f, 1.0f
+        };
+    vgSetfv(VG_CLEAR_COLOR, 4, color);
+    vgClear(x, y, w, h);
+    HUIFX_VG_INVARIANT();
+#else
+    VGImage image = (reinterpret_cast<CHuiFxVg10RenderbufferBase*>(&aSource))->AcquireSubImage(aSourceRect);
+
+    ASSERT(vgGeti(VG_MATRIX_MODE) == VG_MATRIX_IMAGE_USER_TO_SURFACE);
+    VGfloat oldMatrix[VG_MATRIX_SIZE];
+    vgGetMatrix(oldMatrix);
+    vgLoadIdentity();
+    vgSeti(VG_SCISSORING, VG_FALSE); 
+    VGint blendMode = vgGeti(VG_BLEND_MODE);
+
+    // Choose a blending mode
+    switch (aMode)
+        {
+    case EBlendingModeReplace:
+        vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
+        break;
+    case EBlendingModeOver:
+        vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
+        break;
+    case EBlendingModeMultiply:
+        vgSeti(VG_BLEND_MODE, VG_BLEND_MULTIPLY);
+        break;
+    case EBlendingModeAdditive:
+        vgSeti(VG_BLEND_MODE, VG_BLEND_ADDITIVE);
+        break;
+    case EBlendingModeLighten:
+        vgSeti(VG_BLEND_MODE, VG_BLEND_LIGHTEN);
+        break;
+    case EBlendingModeDarken:
+        vgSeti(VG_BLEND_MODE, VG_BLEND_DARKEN);
+        break;
+    default:
+        ASSERT(0);
+        }
+    HUIFX_VG_INVARIANT();
+    
+    // Update alpha
+    TBool mustRestorePaint = EFalse;
+    VGPaint userPaint = VG_INVALID_HANDLE;
+
+    if (aAlpha < 0xff)
+        {
+        if ( iCompPaint == VG_INVALID_HANDLE )
+            {
+            iCompPaint = vgCreatePaint();
+            }
+        if ( iCompPaint != VG_INVALID_HANDLE )
+            {
+            mustRestorePaint = ETrue;
+            userPaint = vgGetPaint( VG_FILL_PATH );
+            // if the original paint is not set, we'll get an error that must be cleared
+            vgSetPaint(iCompPaint, VG_FILL_PATH);
+            }
+        vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_MULTIPLY);
+        vgSetColor(iCompPaint, 0xffffff00 | aAlpha);
+        }
+    else
+        {
+        vgSeti(VG_IMAGE_MODE, VG_DRAW_IMAGE_NORMAL);
+        }
+    
+    // we've taken childimage from source so no clipping or adjusting is needed 
+    // by source rectangle.
+    if (aTarget.BufferType() == EBufferTypeOnscreen)
+        {
+		// we need to adjust our coordinates to screen coordinates. Hitchcock 
+        // thinks origo is on top-left of screen. VG thinks origo is on 
+        // bottom-left.
+        // We must take orientation if we access vg matrixes directly..
+        CHuiDisplay* display = &CHuiStatic::Env().PrimaryDisplay(); // TODO: should use CHuiEnv::CurrentDisplay() ? 
+        
+        if (display->Orientation() == CHuiGc::EOrientationCCW90)
+            {
+            // Rotate around origo and move back to displayarea
+            vgRotate(-90);
+            vgTranslate(aTargetRect.iTl.iX - aTarget.Size().iHeight , aTarget.Size().iWidth - aTargetRect.iBr.iY);
+            }
+        else if (display->Orientation() == CHuiGc::EOrientationCW90)
+            {
+            // Rotate around origo and move back to displayarea
+            vgRotate(90);
+            vgTranslate(aTargetRect.iTl.iX , - aTargetRect.iBr.iY);
+            }
+        else if (display->Orientation() == CHuiGc::EOrientation180)
+            {
+            // Rotate around origo and move back to displayarea
+            vgRotate(180);
+            vgTranslate(aTarget.Size().iWidth- aTargetRect.iTl.iX , - aTargetRect.iBr.iY);
+            }
+        else
+            {
+            vgTranslate(aTargetRect.iTl.iX, aTarget.Size().iHeight - aTargetRect.iBr.iY);
+            }        
+        
+        }
+    else 
+        {
+        // offscreen renderbuffer --- we use VG coordinates
+        vgTranslate(aTargetRect.iTl.iX, aTargetRect.iTl.iY);
+        }
+    
+    // slowpath
+    if(aTargetRect.Size() != aSourceRect.Size())
+        {
+        VGfloat scaleX = (VGfloat)aTargetRect.Width() / aSourceRect.Width();
+        VGfloat scaleY = (VGfloat)aTargetRect.Height() / aSourceRect.Height();
+        vgScale(scaleX, scaleY);
+        }
+    
+    vgDrawImage(image);
+    
+    // Restore default VG state
+    vgSeti(VG_SCISSORING, VG_TRUE);     
+//    vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
+    vgSeti(VG_BLEND_MODE, blendMode);
+    vgLoadMatrix(oldMatrix);
+    HUIFX_VG_INVARIANT();
+    if ( mustRestorePaint )
+        {
+        vgSetPaint(userPaint, VG_FILL_PATH);
+        // if the original handle was invalid, this may produce an error
+        }
+    reinterpret_cast<CHuiFxVg10RenderbufferBase*>(&aSource)->ReleaseSubImage(image);
+#endif // debug rectangle
+    aSource.UnbindAsTexture();
+    aTarget.UnbindAsRenderTarget();
+    }
+
+void CHuiFxVg10Engine::Composite(CHuiGc& aGc, CHuiFxRenderbuffer& aSource, const TPoint& aTargetPoint,TBool aOpaque, TInt aAlpha)
+    {
+    // Directly to screen, overrides onscreen buffer. Always "over" blending mode, constant alpha.
+    const CHuiFxVg10OffscreenRenderbuffer* vg10RenderBuffer = (const CHuiFxVg10OffscreenRenderbuffer*) &aSource;        
+    CHuiVg10Gc* vg10Gc = (CHuiVg10Gc*)&aGc;
+    if (vg10RenderBuffer->Image())
+        {
+        // For some reason color is weird at this point, so set our own.
+        TRgb oldPencolor = aGc.PenColor();
+        TInt oldPenAlpha = aGc.PenAlpha();
+        
+        aGc.SetPenColor(KRgbWhite);
+        aGc.SetPenAlpha(aAlpha);
+        vg10Gc->UpdateColor();
+
+        // Push matrix
+        aGc.Push(EHuiGcMatrixModel);
+        
+        // Take into account the screen relative position of the buffer
+        aGc.Translate(EHuiGcMatrixModel, aTargetPoint.iX, aTargetPoint.iY, 0);
+
+        // Flip the content (because of hitchcock/openvg coordinate differencies       
+        aGc.Translate(EHuiGcMatrixModel, 0.0f, aSource.Size().iHeight, 0.0f);
+        aGc.Scale(EHuiGcMatrixModel, 1.0f, -1.0f, 1.0f);
+
+        // Do the drawing, handle opaque windows with writealpha, otherwise blend
+		if (aOpaque)
+			{
+			aGc.Disable(CHuiGc::EFeatureBlending);
+			}
+		else
+			{
+            aGc.Enable(CHuiGc::EFeatureBlending);
+			}
+        vgDrawImage(vg10RenderBuffer->Image());
+
+        // Restore pen color, matrix
+        aGc.Enable(CHuiGc::EFeatureBlending);        
+        aGc.SetPenColor(oldPencolor);                
+        aGc.SetPenAlpha(oldPenAlpha);
+        aGc.Pop(EHuiGcMatrixModel);
+        }
+    }