uiacceltk/hitchcock/coretoolkit/rendervg10/src/HuiVg10RenderPlugin.cpp
changeset 0 15bf7259bb7c
child 9 3ac8bf5c5014
--- /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 <nvg.h>
+    #include "HuiVg10VgImageBinder.h"
+#endif
+
+#include <AknUtils.h>
+#include <implementationproxy.h>
+
+#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
+    }
+