diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiFxVg10Engine.cpp --- /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(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(&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(&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); + } + }