os/graphics/egl/eglswitch/src/eglswitch.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // For the Winscw Emulator only, selects between REF, GCE and non-GCE version of EGL.
    15 // Notes:
    16 //   The default is the non-GCE based version.
    17 //   To use the REF version GCE needs to be enabled. 
    18 //
    19 // To select the GCE version do one of:
    20 // 1. Add a line to the epoc.ini file in \epoc32\data like this:
    21 // symbian_graphics_use_gce ON
    22 // or
    23 // 2. Start epoc.exe with these parameters, (the "--" IS necessary):
    24 // -Dsymbian_graphics_use_gce=ON --
    25 // or
    26 // 3. epoc.exe can be told to switch to a different initialisation file than epoc.ini, with the -M parameter.
    27 // Progress chaining to the real libEGL is logged in epocwind.out.
    28 // 
    29 // To select the REF version do one of the steps above, adding 
    30 // symbian_graphics_use_egl_ref in addition to symbian_graphics_use_gce. 
    31 //
    32 //
    33 
    34 
    35 #include <emulator.h>
    36 #include <e32svr.h>
    37 #include <u32hal.h>
    38 
    39 
    40 extern "C" {
    41 
    42 #include "egl_stubs.h"
    43 
    44 FARPROC vector[MAX_ORDINAL+1];		// 1 additional entry: vector[0] to set the initialised state
    45 
    46 
    47 #ifdef _DEBUG
    48 void Stop(char* aErrorMessage)
    49 #else
    50 void Stop(char* /*aErrorMessage*/)
    51 #endif
    52 	{
    53 	int err = GetLastError();
    54 #ifdef _DEBUG
    55 	RDebug::Printf("%S, (last error = %i)", aErrorMessage, err);
    56 #endif
    57 	_asm int 3;
    58 	}
    59 
    60 void fill_vector(HINSTANCE aDll)
    61 	{
    62 	FARPROC address = NULL;
    63 	for (int i=1;i<=MAX_ORDINAL;i++)
    64 		{
    65 		address = GetProcAddress(aDll, (LPCSTR)i);
    66 		if (address == NULL)
    67 			{
    68 			Stop("... has too few exported functions");
    69 			}
    70 		vector[i] = address;
    71 		}
    72 
    73 	// There's an additional _E32Dll entry point after last ordinal position.
    74 	// Read it, but no need to store it
    75 	address = GetProcAddress(aDll, (LPCSTR)(MAX_ORDINAL+1));
    76 	if (address == NULL)
    77 		{
    78 		Stop("... has too few exported functions");
    79 		}
    80 	
    81   // next position should be empty
    82 	address = GetProcAddress(aDll, (LPCSTR)(MAX_ORDINAL+2));
    83 	if (address != NULL)
    84 		{
    85 		Stop("... has too many exported functions");
    86 		}
    87 	// Set initialised
    88 	vector[0] = (FARPROC)1;	
    89 	}
    90 
    91 // redirects DLL calls to GCE or non-GCE implementation
    92 void init_vector()
    93 	{
    94 	// ask HAL which configuration to use
    95 	TBool gce = EFalse;
    96 	UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalBoolProperty,  (TAny*)"symbian_graphics_use_gce",  &gce);
    97     const char* library = "";
    98     if (gce)
    99         {
   100 		// reference EGL is for NGA only
   101 		TBool ref = EFalse;
   102         UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalBoolProperty,  (TAny*)"symbian_graphics_use_egl_ref",  &ref);
   103         library = ref ? "libegl_ref.dll" : "libegl_gce.dll";
   104         }
   105 	else
   106 		{
   107 		library = "libegl_nongce.dll";
   108 		}
   109 
   110 #ifdef _DEBUG
   111 	RDebug::Printf("Redirecting libEGL.dll to \"%s\" ...\n", library);
   112 #endif
   113   	
   114 	Emulator::Escape();		// prevent deadlock between EKA2 scheduler and MS kernel
   115 	// try to load selected DLL
   116 	HINSTANCE instance = LoadLibraryA(library);
   117 	Emulator::Reenter();
   118 
   119 	if (instance == NULL)
   120 		{
   121 		Stop("... unable to load");
   122 		}
   123 	else
   124 		{
   125 		fill_vector(instance);
   126 #ifdef _DEBUG
   127 		RDebug::Printf("... DLL loaded successfully");
   128 #endif
   129 		}
   130 	}
   131 
   132 __declspec(naked) void common_dispatch()
   133 	{
   134 	_asm cmp	dword ptr vector,0		// initialised?
   135 	_asm je  	do_init_vector
   136 call_though_vector:
   137 	_asm jmp	[vector+eax*4]
   138 
   139 do_init_vector:
   140 	_asm push	eax
   141 	_asm push	ecx
   142 	_asm push	edx
   143 	_asm call	init_vector
   144 	_asm pop	edx
   145 	_asm pop 	ecx
   146 	_asm pop 	eax
   147 	_asm jmp	call_though_vector
   148 	}
   149 
   150 }