sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include "sgdriver.h" sl@0: #include "sgresourceadapter.h" sl@0: sl@0: /** sl@0: Function pointer type used to instantiate the Graphics Resource Adapter singleton. sl@0: */ sl@0: typedef TInt (*TSgDriverCreateFunction)(MSgDriverAdapter*&); sl@0: sl@0: XSgDriverPls::XSgDriverPls() sl@0: { sl@0: iError = iMutex.CreateLocal(); sl@0: iOpenCount = 0; sl@0: iDriver = NULL; sl@0: } sl@0: sl@0: sl@0: #ifndef __WINS__ sl@0: XSgDriverPls gPls; sl@0: #endif sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @prototype sl@0: @deprecated sl@0: sl@0: Opens the Graphics Resource driver in the context of the calling process. sl@0: sl@0: This function must be called by any process using the Graphics Resource API before sl@0: any other function in the API. When finished the process should call Close(). If sl@0: Open() has already been called from the same process then calling it again just sl@0: increments a process-local open count. Each successful call to Open() must be sl@0: balanced by a corresponding call to Close() later on. sl@0: sl@0: Note that, in a multi-threaded process, it is not necessary for each thread to call sl@0: this function. A possible strategy is therefore for the main thread to call sl@0: SgDriver::Open() at the beginning and SgDriver::Close() at the end, while the rest sl@0: of the threads do not call either of these but simply use the Graphics Resource API. sl@0: sl@0: @pre None. sl@0: @post The Graphics Resource driver is initialised for use in the context of the sl@0: calling process and the process-local open count is incremented by one. sl@0: @return KErrNone if successful. sl@0: @return KErrNotSupported if no implementation of the Graphics Resource API is present. sl@0: @return KErrNoMemory if there is not enough system memory. sl@0: @see SgDriver::Close() sl@0: */ sl@0: EXPORT_C TInt SgDriver::Open() sl@0: { sl@0: if (gPls.iError != KErrNone) sl@0: { sl@0: return gPls.iError; sl@0: } sl@0: gPls.iMutex.Wait(); sl@0: if (gPls.iDriver) sl@0: { sl@0: ++gPls.iOpenCount; sl@0: gPls.iMutex.Signal(); sl@0: return KErrNone; sl@0: } sl@0: #ifdef __WINS__ sl@0: const TUidType KSgResourceAdapterLibraryUidType(KDynamicLibraryUid, KSharedLibraryUid, KSgResourceAdapterLibraryUid); sl@0: RLibrary lib; sl@0: TInt err = lib.Load(KSgResourceAdapterLibraryName, KSgResourceAdapterLibraryUidType); sl@0: if (err != KErrNone) sl@0: { sl@0: if (err == KErrNotFound) sl@0: { sl@0: err = KErrNotSupported; sl@0: } sl@0: gPls.iMutex.Signal(); sl@0: return err; sl@0: } sl@0: gPls.iLibrary = lib; sl@0: err = gPls.iLibrary.Duplicate(RThread()); // Get a process-wide handle sl@0: lib.Close(); sl@0: if (err != KErrNone) sl@0: { sl@0: gPls.iMutex.Signal(); sl@0: return err; sl@0: } sl@0: TSgDriverCreateFunction create = reinterpret_cast(gPls.iLibrary.Lookup(1)); sl@0: err = create(gPls.iDriver); sl@0: if (err != KErrNone) sl@0: { sl@0: gPls.iLibrary.Close(); sl@0: gPls.iMutex.Signal(); sl@0: return err; sl@0: } sl@0: #else sl@0: TInt err = MSgDriverAdapter::New(gPls.iDriver); sl@0: if (err != KErrNone) sl@0: { sl@0: gPls.iMutex.Signal(); sl@0: return err; sl@0: } sl@0: #endif sl@0: gPls.iOpenCount = 1; sl@0: gPls.iMutex.Signal(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @publishedPartner sl@0: @prototype sl@0: @deprecated sl@0: sl@0: Closes the Graphics Resource driver in the context of the calling process. sl@0: sl@0: This function must be called by a process when finished using the Graphics Resource sl@0: API. It decrements the process-local open count and, when the count becomes zero, sl@0: it carries out termination tasks needed to release the internal resources allocated sl@0: for the calling process. sl@0: sl@0: Each call to Close() must correspond to a prior successful call to Open(). Note that, sl@0: in a multi-threaded process, it is not generally safe to call Close() regardless of sl@0: whether the corresponding call to Open() succeeded or failed, since too many calls to sl@0: Close() from a thread could have an unexpected effect on all the other threads in the sl@0: process. The following example demonstrates how to open and close the Graphics sl@0: Resource driver safely from a worker thread. sl@0: sl@0: @code sl@0: // Open Graphics Resource driver sl@0: TBool isDriverOpen = EFalse; sl@0: if (SgDriver::Open() == KErrNone) sl@0: { sl@0: isDriverOpen = ETrue; sl@0: } sl@0: // Do some work in this thread sl@0: DoThreadWork(); sl@0: // Close Graphics Resource driver sl@0: if (isDriverOpen) sl@0: { sl@0: SgDriver::Close(); sl@0: } sl@0: @endcode sl@0: sl@0: @pre If the process-local open count is one then there are no open handles to graphics sl@0: resources in the calling process. sl@0: @post The process-local open count is decremented by one if greater than zero. If the sl@0: count becomes zero, then the calling process is not able to use the Graphics sl@0: Resource API any longer. sl@0: @panic SGRES 1 in debug builds if there still are any open handles to graphics resources sl@0: in the calling process when the process termination tasks are carried out. sl@0: @see SgDriver::Open() sl@0: */ sl@0: EXPORT_C void SgDriver::Close() sl@0: { sl@0: if (gPls.iError != KErrNone) sl@0: { sl@0: return; sl@0: } sl@0: gPls.iMutex.Wait(); sl@0: if (gPls.iOpenCount > 0 && --gPls.iOpenCount == 0) sl@0: { sl@0: gPls.iDriver->Delete(); sl@0: gPls.iDriver = NULL; sl@0: #ifdef __WINS__ sl@0: gPls.iLibrary.Close(); sl@0: #endif sl@0: } sl@0: gPls.iMutex.Signal(); sl@0: } sl@0: sl@0: sl@0: /** sl@0: @internalComponent sl@0: @test sl@0: */ sl@0: EXPORT_C TInt SgDriver::ResourceCount() sl@0: { sl@0: #ifdef _DEBUG sl@0: gPls.iMutex.Wait(); sl@0: __ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver)); sl@0: #endif sl@0: TInt count = gPls.iDriver->ResourceCount(); sl@0: #ifdef _DEBUG sl@0: gPls.iMutex.Signal(); sl@0: #endif sl@0: return count; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @internalComponent sl@0: @test sl@0: */ sl@0: EXPORT_C void SgDriver::AllocMarkStart() sl@0: { sl@0: #ifdef _DEBUG sl@0: gPls.iMutex.Wait(); sl@0: __ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver)); sl@0: #endif sl@0: gPls.iDriver->AllocMarkStart(); sl@0: #ifdef _DEBUG sl@0: gPls.iMutex.Signal(); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: /** sl@0: @internalComponent sl@0: @test sl@0: */ sl@0: EXPORT_C void SgDriver::AllocMarkEnd(TInt aCount) sl@0: { sl@0: #ifdef _DEBUG sl@0: gPls.iMutex.Wait(); sl@0: __ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver)); sl@0: #endif sl@0: gPls.iDriver->AllocMarkEnd(aCount); sl@0: #ifdef _DEBUG sl@0: gPls.iMutex.Signal(); sl@0: #endif sl@0: } sl@0: sl@0: sl@0: /** sl@0: @internalComponent sl@0: @test sl@0: */ sl@0: EXPORT_C void SgDriver::SetAllocFail(RAllocator::TAllocFail aType, TInt aRate) sl@0: { sl@0: #ifdef _DEBUG sl@0: gPls.iMutex.Wait(); sl@0: __ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver)); sl@0: #endif sl@0: gPls.iDriver->SetAllocFail(aType, aRate); sl@0: #ifdef _DEBUG sl@0: gPls.iMutex.Signal(); sl@0: #endif sl@0: }