diff -r 000000000000 -r 5d03bc08d59c graphicsresourceservices/graphicsresource/src/sgdriver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicsresourceservices/graphicsresource/src/sgdriver.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,249 @@ +// Copyright (c) 2007-2009 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 +#include "sgdriver.h" +#include "sgresourceadapter.h" + +/** +Function pointer type used to instantiate the Graphics Resource Adapter singleton. +*/ +typedef TInt (*TSgDriverCreateFunction)(MSgDriverAdapter*&); + +XSgDriverPls::XSgDriverPls() + { + iError = iMutex.CreateLocal(); + iOpenCount = 0; + iDriver = NULL; + } + + +#ifndef __WINS__ +XSgDriverPls gPls; +#endif + + +/** +@publishedPartner +@prototype +@deprecated + +Opens the Graphics Resource driver in the context of the calling process. + +This function must be called by any process using the Graphics Resource API before +any other function in the API. When finished the process should call Close(). If +Open() has already been called from the same process then calling it again just +increments a process-local open count. Each successful call to Open() must be +balanced by a corresponding call to Close() later on. + +Note that, in a multi-threaded process, it is not necessary for each thread to call +this function. A possible strategy is therefore for the main thread to call +SgDriver::Open() at the beginning and SgDriver::Close() at the end, while the rest +of the threads do not call either of these but simply use the Graphics Resource API. + +@pre None. +@post The Graphics Resource driver is initialised for use in the context of the + calling process and the process-local open count is incremented by one. +@return KErrNone if successful. +@return KErrNotSupported if no implementation of the Graphics Resource API is present. +@return KErrNoMemory if there is not enough system memory. +@see SgDriver::Close() +*/ +EXPORT_C TInt SgDriver::Open() + { + if (gPls.iError != KErrNone) + { + return gPls.iError; + } + gPls.iMutex.Wait(); + if (gPls.iDriver) + { + ++gPls.iOpenCount; + gPls.iMutex.Signal(); + return KErrNone; + } +#ifdef __WINS__ + const TUidType KSgResourceAdapterLibraryUidType(KDynamicLibraryUid, KSharedLibraryUid, KSgResourceAdapterLibraryUid); + RLibrary lib; + TInt err = lib.Load(KSgResourceAdapterLibraryName, KSgResourceAdapterLibraryUidType); + if (err != KErrNone) + { + if (err == KErrNotFound) + { + err = KErrNotSupported; + } + gPls.iMutex.Signal(); + return err; + } + gPls.iLibrary = lib; + err = gPls.iLibrary.Duplicate(RThread()); // Get a process-wide handle + lib.Close(); + if (err != KErrNone) + { + gPls.iMutex.Signal(); + return err; + } + TSgDriverCreateFunction create = reinterpret_cast(gPls.iLibrary.Lookup(1)); + err = create(gPls.iDriver); + if (err != KErrNone) + { + gPls.iLibrary.Close(); + gPls.iMutex.Signal(); + return err; + } +#else + TInt err = MSgDriverAdapter::New(gPls.iDriver); + if (err != KErrNone) + { + gPls.iMutex.Signal(); + return err; + } +#endif + gPls.iOpenCount = 1; + gPls.iMutex.Signal(); + return KErrNone; + } + + +/** +@publishedPartner +@prototype +@deprecated + +Closes the Graphics Resource driver in the context of the calling process. + +This function must be called by a process when finished using the Graphics Resource +API. It decrements the process-local open count and, when the count becomes zero, +it carries out termination tasks needed to release the internal resources allocated +for the calling process. + +Each call to Close() must correspond to a prior successful call to Open(). Note that, +in a multi-threaded process, it is not generally safe to call Close() regardless of +whether the corresponding call to Open() succeeded or failed, since too many calls to +Close() from a thread could have an unexpected effect on all the other threads in the +process. The following example demonstrates how to open and close the Graphics +Resource driver safely from a worker thread. + +@code + // Open Graphics Resource driver + TBool isDriverOpen = EFalse; + if (SgDriver::Open() == KErrNone) + { + isDriverOpen = ETrue; + } + // Do some work in this thread + DoThreadWork(); + // Close Graphics Resource driver + if (isDriverOpen) + { + SgDriver::Close(); + } +@endcode + +@pre If the process-local open count is one then there are no open handles to graphics + resources in the calling process. +@post The process-local open count is decremented by one if greater than zero. If the + count becomes zero, then the calling process is not able to use the Graphics + Resource API any longer. +@panic SGRES 1 in debug builds if there still are any open handles to graphics resources + in the calling process when the process termination tasks are carried out. +@see SgDriver::Open() +*/ +EXPORT_C void SgDriver::Close() + { + if (gPls.iError != KErrNone) + { + return; + } + gPls.iMutex.Wait(); + if (gPls.iOpenCount > 0 && --gPls.iOpenCount == 0) + { + gPls.iDriver->Delete(); + gPls.iDriver = NULL; +#ifdef __WINS__ + gPls.iLibrary.Close(); +#endif + } + gPls.iMutex.Signal(); + } + + +/** +@internalComponent +@test +*/ +EXPORT_C TInt SgDriver::ResourceCount() + { +#ifdef _DEBUG + gPls.iMutex.Wait(); + __ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver)); +#endif + TInt count = gPls.iDriver->ResourceCount(); +#ifdef _DEBUG + gPls.iMutex.Signal(); +#endif + return count; + } + + +/** +@internalComponent +@test +*/ +EXPORT_C void SgDriver::AllocMarkStart() + { +#ifdef _DEBUG + gPls.iMutex.Wait(); + __ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver)); +#endif + gPls.iDriver->AllocMarkStart(); +#ifdef _DEBUG + gPls.iMutex.Signal(); +#endif + } + + +/** +@internalComponent +@test +*/ +EXPORT_C void SgDriver::AllocMarkEnd(TInt aCount) + { +#ifdef _DEBUG + gPls.iMutex.Wait(); + __ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver)); +#endif + gPls.iDriver->AllocMarkEnd(aCount); +#ifdef _DEBUG + gPls.iMutex.Signal(); +#endif + } + + +/** +@internalComponent +@test +*/ +EXPORT_C void SgDriver::SetAllocFail(RAllocator::TAllocFail aType, TInt aRate) + { +#ifdef _DEBUG + gPls.iMutex.Wait(); + __ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver)); +#endif + gPls.iDriver->SetAllocFail(aType, aRate); +#ifdef _DEBUG + gPls.iMutex.Signal(); +#endif + }