diff -r 000000000000 -r 15bf7259bb7c uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiVg10RenderPlugin.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiVg10RenderPlugin.cpp Tue Feb 02 07:56:43 2010 +0200 @@ -0,0 +1,558 @@ +/* +* Copyright (c) 2006-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: Implementation of CHuiVg10RenderPlugin. Rendering plugin for OpenVG 1.0. +* +*/ + + + +#include "HuiVg10RenderPlugin.h" +#include "HuiVg10RenderSurface.h" +#include "HuiVg10PBufferSurface.h" +#include "HuiVg10Gc.h" +#include "HuiVg10Texture.h" +#include "HuiVg10TextureManager.h" +#include "HuiVg10CurvePath.h" +#include "huivg10canvasgc.h" +#include "HuiRasterizedTextMesh.h" +#include "uiacceltk/HuiStatic.h" +#include "uiacceltk/HuiPanic.h" +#include "uiacceltk/HuiUtil.h" +#include "uiacceltk/HuiEnv.h" +#include "uiacceltk/HuiDisplay.h" +#include "HuiFxVg10Engine.h" + +#ifdef __NVG + #include + #include "HuiVg10VgImageBinder.h" +#endif + +#include +#include + +#if !defined(EGL_VERSION_1_2) +# error At least EGL version 1.2 is required by the OpenVG render plugin. +#endif + + + +const TImplementationProxy ImplementationTable[] = + { + IMPLEMENTATION_PROXY_ENTRY( 0x200184B8, CHuiVg10RenderPlugin::NewL ) + }; + +EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount ) + { + aTableCount = sizeof( ImplementationTable ) / sizeof( TImplementationProxy ); + return ImplementationTable; + } + + +CHuiVg10RenderPlugin* CHuiVg10RenderPlugin::NewL() + { + CHuiVg10RenderPlugin* self = CHuiVg10RenderPlugin::NewLC(); + CleanupStack::Pop(self); + return self; + } + + +CHuiVg10RenderPlugin* CHuiVg10RenderPlugin::NewLC() + { + CHuiVg10RenderPlugin* self = new (ELeave) CHuiVg10RenderPlugin(); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + + +CHuiVg10RenderPlugin::CHuiVg10RenderPlugin(THuiRenderPluginId aId) + : CHuiRenderPlugin(aId) + { + } + + +void CHuiVg10RenderPlugin::ConstructL() + { + HUI_DEBUG(_L("CHuiVg10RenderPlugin::ConstructL() - Initializing Rendering plugin.") ); + + iIsHardwareAccelerated = EFalse; + iEGLStateForTextureUpload.iContext = KErrNotFound; // this will be defined later by the first upload in CHuiVg10Texture::PushEGLContext + iEglDisplay = NULL; + iDefaultRenderSurface = NULL; + + + // Restore (Create the EGL surfaces) + RestoreL(); + +// The disable flag is defined in coretkoptions.mmh +#ifndef VG10_DISABLE_DEFAULT_RENDER_SURFACE + HUI_DEBUG(_L("CHuiVg10RenderPlugin::ConstructL() - Create default PBuffer rendering surface for texture preloads.") ); + // Create default PBuffer rendering surface. This will allow us to for instance preload + // and create textures before actual rendering surface exists. + iDefaultRenderSurface = CHuiVg10PBufferSurface::NewLC(*this, TSize(64, 64)); + CleanupStack::Pop(iDefaultRenderSurface); + iDefaultRenderSurface->MakeCurrent(); + iIsHardwareAccelerated = IsHardwareAccelerated(); +#endif + HUI_DEBUG(_L("CHuiVg10RenderPlugin::ConstructL() - Rendering plugin for OpenVG 1.0 ready.") ); + + // Initialize some "allow flags" which depend on used HW + ReadAllowsSwapBufferPreserved(); + ReadAllowsVisualPBufferSurfaces(); + } + +CHuiVg10RenderPlugin::~CHuiVg10RenderPlugin() + { + Release(); + +#ifndef VG10_DISABLE_DEFAULT_RENDER_SURFACE + if (iDefaultRenderSurface) + { + HUI_DEBUG(_L("CHuiVg10RenderPlugin::~CHuiVg10RenderPlugin() - Destroying default rendering surface.")); + // Destroy default rendering surface + delete iDefaultRenderSurface; iDefaultRenderSurface = NULL; + } +#endif + + } + +void CHuiVg10RenderPlugin::RestoreL() + { + HUI_DEBUG(_L("CHuiVg10RenderPlugin::RestoreL() - Restoring renderer..") ); + + // Get the display for drawing graphics. + if (CHuiStatic::Env().GlesRefCounter() == 0) + { + HUI_DEBUG(_L("CHuiVg10RenderPlugin::RestoreL() - Getting default EGL Display.") ); + iEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if(iEglDisplay == EGL_NO_DISPLAY) + { + HUI_DEBUG(_L("CHuiVg10RenderPlugin::RestoreL() - ERROR! No connection to EGL display was available.")); + TInt eglerr = eglGetError(); + switch (eglerr) + { + case EGL_BAD_ALLOC: + HUI_DEBUG(_L("CHuiVg10RenderPlugin::RestoreL() - Cause: Out of memory. Leaving.")); + User::Leave(KErrNoMemory); + default: + HUI_DEBUG2(_L("CHuiVg10RenderPlugin::RestoreL() - EGL information for the error: %S (EGL error code: %i). Leaving."), &CHuiVg10RenderSurface::EglErrorMessage(eglerr), eglerr); + case EGL_SUCCESS: + User::Leave(KErrNotSupported); + } + } + EGLint majorVersion=0; + EGLint minorVersion=0; + + // Initialize display. + if(eglInitialize(iEglDisplay, &majorVersion, &minorVersion) == EGL_FALSE) + { + TInt eglerr = eglGetError(); + switch (eglerr) + { + case EGL_BAD_ALLOC: + HUI_DEBUG(_L("CHuiVg10RenderPlugin::RestoreL() - Cause: Out of memory. Leaving.")); + User::Leave(KErrNoMemory); + default: + HUI_DEBUG2(_L("CHuiVg10RenderPlugin::RestoreL() - ERROR! Failed to initialize EGL display. Cause: %S (EGL error code: %i). Leaving."), &CHuiVg10RenderSurface::EglErrorMessage(eglerr), eglerr); + case EGL_SUCCESS: // indicates that no error was recorded, but still the eglInitialize call failed (=> unable to continue!) + case EGL_NOT_INITIALIZED: + User::Leave(KErrNotSupported); + } + } + HUI_DEBUG2(_L("CHuiVg10RenderPlugin::RestoreL() - EGL Initialized. EGL Version %i.%i"), majorVersion, minorVersion); + CHuiStatic::Env().GlesRefCounter()++; + + // Indicate that we are going to use OpenVG for our drawing + eglBindAPI(EGL_OPENVG_API); + } + +#ifndef VG10_DISABLE_DEFAULT_RENDER_SURFACE + if (iDefaultRenderSurface != NULL) + { + HUI_DEBUG(_L("CHuiVg10RenderPlugin::RestoreL() - Restoring default rendering surface..") ); + iDefaultRenderSurface->RestoreL(); + iDefaultRenderSurface->MakeCurrent(); + } +#endif + + iStateFlags = 0; +#ifdef __NVG + iNvgEngine = CNvgEngine::NewL(); + // Set the image binder for NVG-TLV special case "Group opacity" + iMVGImageBinder = CHuiVg10VgImageBinder::NewL(this); + iNvgEngine->SetVGImageBinder(iMVGImageBinder); +#endif + HUI_DEBUG(_L("CHuiVg10RenderPlugin::RestoreL() - Renderer restored!") ); + + } + +void CHuiVg10RenderPlugin::Release() + { +#ifndef VG10_DISABLE_DEFAULT_RENDER_SURFACE + if (iDefaultRenderSurface != NULL) + { + HUI_DEBUG(_L("CHuiVg10RenderPlugin::Release() - Releasing default rendering surface..") ); + iDefaultRenderSurface->Release(); + } +#endif + // Uninitialize EGL. + if (--CHuiStatic::Env().GlesRefCounter() == 0) + { + HUI_DEBUG(_L("CHuiVg10RenderPlugin::Release() - Uninitializing EGL.")); + eglMakeCurrent(iEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglTerminate(iEglDisplay); + eglReleaseThread(); + iEglDisplay = 0; + } +#ifdef __NVG + delete iNvgEngine; + iNvgEngine = NULL; + delete iMVGImageBinder; + iMVGImageBinder = NULL; +#endif + HUI_DEBUG(_L("CHuiVg10RenderPlugin::Release() - Renderer released.")); + } + + +TBool CHuiVg10RenderPlugin::Allows(THuiRenderPluginAllow aAllow) const + { + switch(aAllow) + { + case EHuiRenderPluginAllowTextureModeInterpolate: + // OpenVG does not support texture interpolation. + return EFalse; +#ifdef VG10_DISABLE_DEFAULT_RENDER_SURFACE + case EHuiRenderPluginAllowPBufferSurfaces: + return EFalse; +#endif + case EHuiRenderPluginAllowSwapBufferPreserve: + return iAllowsSwapBufferPreserved; + case EHuiRenderPluginAllowVisualPBufferSurfaces: + return iAllowsVisualPBufferSurfaces; + default: + return ETrue; + } + } + + +MHuiRenderSurface* CHuiVg10RenderPlugin::CreateRenderSurfaceL(CHuiDisplay& aDisplay) + { + return CHuiVg10RenderSurface::NewL(aDisplay); + } + + +CHuiVg10PBufferSurface* CHuiVg10RenderPlugin::CreatePBufferSurfaceL(TSize aSize, TInt aEglBufferType, TInt aBufferColorMode) + { + CHuiVg10PBufferSurface* surface = CHuiVg10PBufferSurface::NewLC(*this, aSize, 0, aEglBufferType, aBufferColorMode); + CleanupStack::Pop(surface); + return surface; + } + + +CHuiGc* CHuiVg10RenderPlugin::CreateGcL() + { + return CHuiVg10Gc::NewL(); + } + + +CHuiTexture* CHuiVg10RenderPlugin::CreateTextureL(const THuiTextureHandle* aExistingTexture) + { + return CHuiVg10Texture::NewL(*this, aExistingTexture); + } + +CHuiTextureManager* CHuiVg10RenderPlugin::CreateTextureManagerL(CHuiEnv& aEnv) + { + return CHuiVg10TextureManager::NewL(aEnv); + } + + +CHuiMesh* CHuiVg10RenderPlugin::CreateMeshL(THuiMeshType aMeshType) + { + CHuiMesh* ret = NULL; + + switch(aMeshType) + { + default: + User::Leave(KErrNotSupported); + break; + } + + return ret; + } + + +CHuiTextMesh* CHuiVg10RenderPlugin::CreateTextMeshL() + { + return CHuiRasterizedTextMesh::NewL(); + } + + +CHuiCurvePath* CHuiVg10RenderPlugin::CreateCurvePathL() + { + CHuiVg10CurvePath* curve = new (ELeave) CHuiVg10CurvePath(); + CleanupStack::PushL(curve); + curve->ConstructL(); + CleanupStack::Pop(curve); + return curve; + } + + +void CHuiVg10RenderPlugin::DeleteNamedTexture(TUint aName) + { + (void)aName; + } + + +#ifndef VG10_DISABLE_DEFAULT_RENDER_SURFACE +void CHuiVg10RenderPlugin::NotifyDisplayCountL(TUint aCount) + { + if( aCount == 0 ) + { + // No current display available in the environment. + // Make default surface current to be able to continue resource loading. + iDefaultRenderSurface->MakeCurrent(); + } + } +#else +void CHuiVg10RenderPlugin::NotifyDisplayCountL(TUint /*aCount*/) + { + } +#endif + +EGLConfig CHuiVg10RenderPlugin::EglDisplay() + { + return iEglDisplay; + } + + +EGLContext CHuiVg10RenderPlugin::EglSharedContext() const + { + return iSharedContext; + } + + +void CHuiVg10RenderPlugin::EglSetSharedContext(EGLContext aContext) + { + iSharedContext = aContext; + } + + +TInt CHuiVg10RenderPlugin::EglChooseConfig(const TInt* aAttribList) + { + EGLint numOfConfigs = 0; + if(eglChooseConfig(iEglDisplay, aAttribList, iConfigs, KVg10ConfigsCount, + &numOfConfigs) == EGL_FALSE) + { + return 0; + } + return numOfConfigs; + } + + +TInt CHuiVg10RenderPlugin::EglConfig(TInt aIndex) + { + if(aIndex < 0 || aIndex >= KVg10ConfigsCount) + { + THuiPanic::Panic(THuiPanic::EEnvConfigNotFound); + } + return iConfigs[aIndex]; + } + + +void CHuiVg10RenderPlugin::EglPrintConfig(TInt aIndex) + { + if(aIndex < 0 || aIndex >= KVg10ConfigsCount) + { + THuiPanic::Panic(THuiPanic::EEnvConfigNotFound); + } + + EGLint value; + EGLConfig cfg = iConfigs[aIndex]; + + CHuiStatic::Printf(_L("EGL Configuration %i:"), aIndex); + +#ifdef WIN32 +#define HUI_PRINT_EGL_ATTRIB(aAttr) \ + eglGetConfigAttrib(iEglDisplay, cfg, aAttr, &value); \ + CHuiStatic::Printf(_L(#aAttr " = %i (%04x)"), value, value); +#else +#define HUI_PRINT_EGL_ATTRIB(aAttr) \ + eglGetConfigAttrib(iEglDisplay, cfg, aAttr, &value); \ + CHuiStatic::Printf(_L("Parameter (id %04x):"), aAttr); \ + CHuiStatic::Printf(_L8(#aAttr)); \ + CHuiStatic::Printf(_L("Value: %i (%04x)"), value, value); +#endif + HUI_PRINT_EGL_ATTRIB(EGL_CONFIG_ID); + HUI_PRINT_EGL_ATTRIB(EGL_CONFIG_CAVEAT); + HUI_PRINT_EGL_ATTRIB(EGL_SURFACE_TYPE); + HUI_PRINT_EGL_ATTRIB(EGL_BUFFER_SIZE); + HUI_PRINT_EGL_ATTRIB(EGL_RED_SIZE); + HUI_PRINT_EGL_ATTRIB(EGL_GREEN_SIZE); + HUI_PRINT_EGL_ATTRIB(EGL_BLUE_SIZE); + HUI_PRINT_EGL_ATTRIB(EGL_ALPHA_SIZE); + HUI_PRINT_EGL_ATTRIB(EGL_DEPTH_SIZE); + HUI_PRINT_EGL_ATTRIB(EGL_LEVEL); + HUI_PRINT_EGL_ATTRIB(EGL_MAX_PBUFFER_WIDTH); + HUI_PRINT_EGL_ATTRIB(EGL_MAX_PBUFFER_HEIGHT); + HUI_PRINT_EGL_ATTRIB(EGL_MAX_PBUFFER_PIXELS); + HUI_PRINT_EGL_ATTRIB(EGL_NATIVE_RENDERABLE); + HUI_PRINT_EGL_ATTRIB(EGL_NATIVE_VISUAL_ID); + HUI_PRINT_EGL_ATTRIB(EGL_NATIVE_VISUAL_TYPE); + HUI_PRINT_EGL_ATTRIB(EGL_SAMPLE_BUFFERS); + HUI_PRINT_EGL_ATTRIB(EGL_SAMPLES); + HUI_PRINT_EGL_ATTRIB(EGL_STENCIL_SIZE); + HUI_PRINT_EGL_ATTRIB(EGL_TRANSPARENT_TYPE); +#ifdef EGL_VERSION_1_1 + HUI_PRINT_EGL_ATTRIB(EGL_BIND_TO_TEXTURE_RGB); + HUI_PRINT_EGL_ATTRIB(EGL_BIND_TO_TEXTURE_RGBA); + HUI_PRINT_EGL_ATTRIB(EGL_MAX_SWAP_INTERVAL); + HUI_PRINT_EGL_ATTRIB(EGL_MIN_SWAP_INTERVAL); +#endif +#ifdef EGL_VERSION_1_2 + HUI_PRINT_EGL_ATTRIB(EGL_PRESERVED_RESOURCES); + HUI_PRINT_EGL_ATTRIB(EGL_LUMINANCE_SIZE); + HUI_PRINT_EGL_ATTRIB(EGL_ALPHA_MASK_SIZE); + HUI_PRINT_EGL_ATTRIB(EGL_COLOR_BUFFER_TYPE); + HUI_PRINT_EGL_ATTRIB(EGL_RENDERABLE_TYPE); +#endif + +#undef HUI_PRINT_EGL_ATTRIB + } + + +TBool CHuiVg10RenderPlugin::IsReleased() const + { + if(CHuiStatic::Env().GlesRefCounter() == 0) + { + return ETrue; + } + return EFalse; + } + +const TDesC& CHuiVg10RenderPlugin::VgErrorMessage(VGErrorCode aErrorCode) + { + // Error messages. + _LIT(KGlesErrorUnknown, "Invalid or unknown error."); + + switch(aErrorCode) + { + default: + return KGlesErrorUnknown; + } + } + + +VGErrorCode CHuiVg10RenderPlugin::VgError() + { + VGErrorCode error = vgGetError(); +#ifdef _DEBUG + // Print the vgError always in debug mode, not just when HUI_DEBUG is in use + if (error != VG_NO_ERROR) + { + RDebug::Print(_L("CHuiVg10RenderPlugin::VgError -- %04x"), error); + } +#endif + return error; + } + + +TBool CHuiVg10RenderPlugin::IsHardwareAccelerated() + { + // consider vg10 plugin as HW accelerated until a better check + +// TBool HWFound = EFalse; + iIsHardwareAccelerated = ETrue; + return ETrue; + } + +CHuiCanvasGc* CHuiVg10RenderPlugin::CreateCanvasGcL() + { + return new (ELeave) CHuiVg10CanvasGc(); + } + +CHuiFxEngine* CHuiVg10RenderPlugin::CreateEffectsEngineL() + { + return CHuiFxVg10Engine::NewL(*this); + } + +void CHuiVg10RenderPlugin::AddRestoreStateFlags(TInt aFlags) + { + iStateFlags |= aFlags; + } + +TInt CHuiVg10RenderPlugin::GetRestoreStateFlags() + { + return iStateFlags; + } + +void CHuiVg10RenderPlugin::ClearRestoreStateFlags() + { + iStateFlags &= 0x00000000; + } + +#ifdef __NVG +CNvgEngine& CHuiVg10RenderPlugin::NvgEngine() const + { + return *iNvgEngine; + } +#endif + +// TODO: This is only a temporary check until all HW platforms support feature +void CHuiVg10RenderPlugin::ReadAllowsSwapBufferPreserved() + { +#ifdef __WINS__ + iAllowsSwapBufferPreserved = ETrue; +#else + const char* vendor = eglQueryString(iEglDisplay, EGL_VENDOR); + //const VGubyte* vendor = vgGetString(VG_VENDOR); + //RDebug::Print(_L("vendor = %s"), vendor); + + TBool found = EFalse; + if( vendor[0] != 0 && vendor[0] == 'B' && vendor[1] == 'r') + { + RDebug::Print(_L("CHuiVg10RenderPlugin::ReadAllowsSwapBufferPreserved() -- ETrue")); + found = ETrue; + } + else + { + RDebug::Print(_L("CHuiVg10RenderPlugin::ReadAllowsSwapBufferPreserved() -- EFalse")); + } + iAllowsSwapBufferPreserved = found; +#endif + } + +// TODO: This is only a temporary check until all HW platforms support feature +void CHuiVg10RenderPlugin::ReadAllowsVisualPBufferSurfaces() + { +#ifdef __WINS__ + iAllowsVisualPBufferSurfaces = ETrue; +#else + const char* vendor = eglQueryString(iEglDisplay, EGL_VENDOR); + //const VGubyte* vendor = vgGetString(VG_VENDOR); + //RDebug::Print(_L("vendor = %s"), vendor); + + TBool found = EFalse; + if( vendor[0] != 0 && vendor[0] == 'B' && vendor[1] == 'r') + { + RDebug::Print(_L("CHuiVg10RenderPlugin::ReadAllowsVisualPBufferSurfaces() -- ETrue")); + found = ETrue; + } + else + { + RDebug::Print(_L("CHuiVg10RenderPlugin::ReadAllowsVisualPBufferSurfaces() -- EFalse")); + } + iAllowsVisualPBufferSurfaces = found; +#endif + } +