--- /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);
+ }
+ }