vghwinterface/vghwapiwrapper/src/driverapiwrapper.cpp
branchbug235_bringup_0
changeset 53 c2ef9095503a
parent 30 f204b762818d
child 71 243bbc1d70db
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vghwinterface/vghwapiwrapper/src/driverapiwrapper.cpp	Wed Oct 06 17:59:01 2010 +0100
@@ -0,0 +1,400 @@
+// Copyright (c) 2010 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 <stdio.h>
+#include <stdlib.h>
+#include <EGL/egl.h>//EGL operations will be called a lot from here
+#include <vg/openvg.h>
+
+#include "driverapiwrapper.h"
+#include "KhronosAPIWrapper.h"
+
+
+bool DriverAPIWrapper::IsSgBackingVGImage( VGImage aImage )
+	{
+		for( std::list<VGImage>::iterator cur = m_SgImageVGImages.begin();
+			 cur != m_SgImageVGImages.end();
+			 ++cur )
+		{
+			if( (*cur) == aImage )
+			{
+				return true;
+			}
+		}
+		return false;
+	}
+
+bool DriverAPIWrapper::IsSgBackingPBuffer( EGLSurface aSurface )
+	{
+		for( std::list<EGLSurface>::iterator cur = m_SgImagePbuffers.begin();
+			 cur != m_SgImagePbuffers.end();
+			 ++cur )
+		{
+			if( (*cur) == aSurface )
+			{
+				return true;
+			}
+		}
+		return false;
+	}
+
+int DriverAPIWrapper::CreatePoolContext()
+	{
+	//Initialize EGL on the first run, as per 5.1 in the "Implementing SgImage" design doc
+	if( m_initialized ){ return 0; }
+	TRACE("DriverAPIWrapper::CreatePoolContext() ->\n");
+    EGLDisplay display(0);
+
+    EGLConfig config(0);
+	EGLint num_config;
+
+	EGLContext PoolContext(0);//for sharing
+    EGLContext ContextWithFormatARGB_8888_PRE(0);//for sharing
+    EGLContext ContextWithFormatARGB_8888(0);
+    EGLContext ContextWithFormatXRGB_8888(0);
+    EGLContext ContextWithFormatRGB_565(0);
+    EGLContext ContextWithFormatA_8(0);
+    EGLSurface DudSurface(0);
+
+	int red(0);
+	int green(0);
+	int blue(0);
+	int alpha(0);
+    
+	display = ::eglGetDisplay( EGL_DEFAULT_DISPLAY );//Notice: there is no support for multiple displays here
+
+	if( !::eglInitialize(display, NULL, NULL) )
+	{
+		TRACE("DriverAPIWrapper::CreatePoolContext() <- (eglInitialize failed)\n");
+		return 0;
+	}
+
+	m_Dpy = display;
+	//Pool Context
+    //get a Configuration, then get the context
+	if( ::eglChooseConfig(	display,
+							getColorAttributes( EUidPixelFormatARGB_8888, red, green, blue, alpha ),
+							&config,
+							1,
+							&num_config ) == EGL_TRUE )
+	{
+		/* create an EGL rendering context */
+		PoolContext = ContextWithFormatARGB_8888 = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
+		m_PoolConfig = config;
+	}
+
+
+    /* get an appropriate EGL surface buffer configuration */
+	if( ::eglChooseConfig(	display,
+							getColorAttributes( EUidPixelFormatXRGB_8888, red, green, blue, alpha ),
+							&config,
+							1,
+							&num_config ) == EGL_TRUE )
+	{
+		/* create an EGL rendering context */
+		PoolContext = ContextWithFormatXRGB_8888 = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
+	}
+
+
+    //get a Configuration, then get the context
+	if( ::eglChooseConfig(	display,
+							getColorAttributes( EUidPixelFormatARGB_8888_PRE, red, green, blue, alpha ),
+							&config,
+							1,
+							&num_config ) == EGL_TRUE )
+	{
+		/* create an EGL rendering context */
+		ContextWithFormatARGB_8888_PRE = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
+	}
+	
+
+    //get a Configuration, then get the context
+	if( ::eglChooseConfig(	display,
+							getColorAttributes( EUidPixelFormatRGB_565, red, green, blue, alpha ),
+							&config,
+							1,
+							&num_config ) == EGL_TRUE )
+	{
+		/* create an EGL rendering context */
+		ContextWithFormatRGB_565 = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
+	}
+	
+
+    //get a Configuration, then get the context
+	if( ::eglChooseConfig(	display,
+							getColorAttributes( EUidPixelFormatA_8, red, green, blue, alpha ),
+							&config,
+							1,
+							&num_config ) == EGL_TRUE )
+	{
+		/* create an EGL rendering context */
+		ContextWithFormatA_8 = eglCreateContext(display, config, EGL_NO_CONTEXT, NULL);
+	}
+
+
+	EGLint attribs[] = { EGL_NONE };
+	DudSurface = ::eglCreatePbufferSurface( display, PoolContext, attribs );
+
+
+	TRACE( "PoolContext = %u\n", PoolContext );
+	TRACE( "ContextWithFormatARGB_8888_PRE = %u\n", ContextWithFormatARGB_8888_PRE );
+	TRACE( "ContextWithFormatARGB_8888 = %u\n", ContextWithFormatARGB_8888 );
+	TRACE( "ContextWithFormatXRGB_8888 = %u\n", ContextWithFormatXRGB_8888 );
+	TRACE( "ContextWithFormatRGB_565 = %u\n", ContextWithFormatRGB_565 );
+	TRACE( "ContextWithFormatA_8 = %u\n", ContextWithFormatA_8 );
+	TRACE( "DummySurface = %u\n", DudSurface );
+
+	m_Dpy								= display;
+	m_PoolContext						= PoolContext;
+    m_ContextWithFormatARGB_8888_PRE	= ContextWithFormatARGB_8888_PRE;
+    m_ContextWithFormatARGB_8888		= ContextWithFormatARGB_8888;
+    m_ContextWithFormatXRGB_8888		= ContextWithFormatXRGB_8888;
+    m_ContextWithFormatRGB_565			= ContextWithFormatRGB_565;
+    m_ContextWithFormatA_8				= ContextWithFormatA_8;
+    m_DudSurface						= DudSurface;
+
+	//m_currentFunctionCall.AppendEGLContext( PoolContext );//for sharing
+    //m_currentFunctionCall.AppendEGLContext( ContextWithFormatARGB_8888_PRE );//for sharing
+    //m_currentFunctionCall.AppendEGLContext( ContextWithFormatARGB_8888 );
+    //m_currentFunctionCall.AppendEGLContext( ContextWithFormatXRGB_8888 );
+    //m_currentFunctionCall.AppendEGLContext( ContextWithFormatRGB_565 );
+    //m_currentFunctionCall.AppendEGLContext( ContextWithFormatA_8 );
+	//m_currentFunctionCall.AppendEGLSurface( DudSurface );
+
+	TRACE("DriverAPIWrapper::CreatePoolContext() <-\n");
+	m_initialized = true;
+	return 1;
+	}
+
+
+
+
+/**
+* This code is supposed to create a pbuffer to back an sgImage
+* TODO: not tested at all
+*/
+int DriverAPIWrapper::CreatePbufferSg(  )
+	{
+	TRACE("DriverAPIWrapper::CreatePbufferSg ->\n");
+	EGLint w;
+	EGLint h;
+
+	if( !m_initialized )
+		{
+		CreatePoolContext();
+		}
+	
+	m_currentFunctionCall.GetEGLint( w, 0 );
+	m_currentFunctionCall.GetEGLint( h, 1 );
+
+	//eglCreatePbufferSurface
+	EGLint pbuffer_surface_attribs[] =
+	{
+      EGL_WIDTH,    w,
+	  EGL_HEIGHT,   h,
+      EGL_NONE
+	};
+	
+    EGLSurface surface = ::eglCreatePbufferSurface( m_Dpy, m_PoolConfig, pbuffer_surface_attribs );
+	if( surface != EGL_NO_SURFACE )
+	{
+		m_SgImagePbuffers.push_back( surface );
+	}
+	TRACE("DriverAPIWrapper::CreatePbufferSg surface=%u \n", surface );
+    m_currentFunctionCall.SetReturnValue( (TUint32)surface );
+    TRACE("DriverAPIWrapper::CreatePbufferSg <-\n");
+    return WriteReply();
+	}
+
+
+/**
+* This code is supposed to create a pbuffer to back an sgImage
+* TODO: not tested at all
+*/
+int DriverAPIWrapper::CreateVGImageSg(  )
+	{
+	TRACE("DriverAPIWrapper::CreateVGImageSg ->\n");
+	EGLint w;
+	EGLint h;
+	EGLint pixelformat;
+	VGImage img;
+
+	if( !m_initialized )
+	{
+		CreatePoolContext();
+	}
+	
+	EGLenum previousApi = ::eglQueryAPI();
+	::eglBindAPI( EGL_OPENVG_API );
+
+	m_currentFunctionCall.GetEGLint( w, 0 );
+	m_currentFunctionCall.GetEGLint( h, 1 );
+	m_currentFunctionCall.GetEGLint( pixelformat, 2 );
+
+	::eglMakeCurrent( m_Dpy, m_DudSurface, m_DudSurface, m_PoolContext );
+
+	//eglCreatePbufferSurface
+	EGLint pbuffer_surface_attribs[] =
+	{
+      EGL_WIDTH,    w,
+	  EGL_HEIGHT,   h,
+      EGL_NONE
+	};
+	VGImageFormat format = getVGColorFormat( pixelformat );
+	img = ::vgCreateImage(format, w, h, VG_IMAGE_QUALITY_NONANTIALIASED);//todo: quality; how to decide (TSgImageInfo only provides w,h, pixelformat)?
+		if( img != VG_INVALID_HANDLE )
+	{
+		m_SgImageVGImages.push_back( img );
+	}
+
+    m_currentFunctionCall.SetReturnValue( (TUint32)img );
+	::eglBindAPI( previousApi );
+    TRACE("DriverAPIWrapper::CreateVGImageSg <-\n");
+    return WriteReply();
+	}
+
+int DriverAPIWrapper::DeleteSgImage()
+{
+	EGLSurface surface;
+	VGImage image;
+	m_currentFunctionCall.GetEGLSurface( surface, 0 );
+	m_currentFunctionCall.GetVGParamValue( image, 1 );
+
+	eglDestroySurface( m_Dpy, surface );
+	vgDestroyImage( image );
+
+	return WriteReply();
+}
+
+void DriverAPIWrapper::SyncVGImageFromPBuffer( EGLSurface aPbuffer, VGImage aVGImage )
+{
+	TRACE("DriverAPIWrapper::SyncVGImageFromPBuffer ->\n");
+	//Store the previous current
+	EGLDisplay disp = ::eglGetCurrentDisplay();
+	EGLSurface draw = ::eglGetCurrentSurface( EGL_DRAW );
+	EGLSurface read = ::eglGetCurrentSurface( EGL_READ );
+	EGLContext ctx  = ::eglGetCurrentContext();
+
+	EGLint width(0);
+	EGLint height(0);
+	eglSurfaceAttrib( disp, aPbuffer, EGL_WIDTH, width );
+	eglSurfaceAttrib( disp, aPbuffer, EGL_HEIGHT, height );
+
+	::eglMakeCurrent( m_Dpy, aPbuffer, aPbuffer, m_PoolContext );
+	::vgGetPixels( aVGImage, 0, 0, 0, 0, width, height );
+	//Set the previous current
+	::eglMakeCurrent( disp, draw, read, ctx );
+	TRACE("DriverAPIWrapper::SyncVGImageFromPBuffer <-\n");
+}
+
+
+int DriverAPIWrapper::SyncPBufferFromVGImage( VGImage aSrc, VGint aWidth, VGint aHeight )
+{
+	TRACE("DriverAPIWrapper::SyncPBufferFromVGImage ->\n");
+	if( ((VGboolean)vgGeti( VG_SCISSORING )) == VG_TRUE )
+	{
+		::vgSeti( VG_SCISSORING, VG_FALSE );
+		//The surface is the same size, as the vgimage
+		::vgSetPixels( 0, 0, aSrc, 0, 0, aWidth, aHeight );
+		::vgSeti( VG_SCISSORING, VG_TRUE );
+	}
+	else
+	{
+		::vgSetPixels( 0, 0, aSrc, 0, 0, aWidth, aHeight );
+	}
+	TRACE("DriverAPIWrapper::SyncPBufferFromVGImage <-\n");
+	return 0;
+}
+
+
+VGImageFormat DriverAPIWrapper::getVGColorFormat( int aPixelFormat )
+{
+	switch( aPixelFormat )
+		{
+		case  EUidPixelFormatXRGB_8888:
+			{
+			return VG_sXRGB_8888;
+			}
+		case EUidPixelFormatARGB_8888:
+			{
+			return VG_sARGB_8888;
+			}
+		case EUidPixelFormatARGB_8888_PRE:
+			{
+			return VG_sARGB_8888_PRE;
+			}
+		case EUidPixelFormatRGB_565:
+			{
+			return VG_sRGB_565;
+			}
+		case EUidPixelFormatA_8:
+			{
+			return VG_A_8;
+			}
+		default:
+			{
+			return VG_sARGB_8888;
+			}
+		}
+}
+
+EGLint* DriverAPIWrapper::getColorAttributes( int aPixelFormat, int& aRed, int& aGreen, int& aBlue, int& aAlpha )
+	{
+	switch( aPixelFormat )
+		{
+		case  EUidPixelFormatXRGB_8888:
+			{
+			aRed = aGreen = aBlue = aAlpha = 8;
+			break;
+			}
+		case EUidPixelFormatARGB_8888:
+			{
+			aRed = aGreen = aBlue = aAlpha = 8;
+			break;
+			}
+		case EUidPixelFormatARGB_8888_PRE:
+			{
+			aRed = aGreen = aBlue = aAlpha = 8;
+			break;
+			}
+		case EUidPixelFormatRGB_565:
+			{
+			aRed = 5; aGreen = 6; aBlue = 5; aAlpha = 0;
+			break;
+			}
+		case EUidPixelFormatA_8:
+			{
+			aRed = aGreen = aBlue = 0; aAlpha = 8;
+			break;
+			}
+		default:
+			{
+			aRed = aGreen = aBlue = aAlpha = 0;
+			break;
+			}
+		}
+		static EGLint attribs[] =
+		{
+		  EGL_RED_SIZE,   aRed,
+		  EGL_GREEN_SIZE, aGreen,
+		  EGL_BLUE_SIZE,  aBlue,
+		  EGL_ALPHA_SIZE, aAlpha,
+	      EGL_RENDERABLE_TYPE, EGL_OPENVG_BIT,
+		  EGL_SURFACE_TYPE,   EGL_PBUFFER_BIT,
+		  EGL_NONE
+		};
+	return attribs;
+	}
+