sl@0
|
1 |
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
//
|
sl@0
|
15 |
|
sl@0
|
16 |
#include <e32uid.h>
|
sl@0
|
17 |
#include "sgdriver.h"
|
sl@0
|
18 |
#include "sgresourceadapter.h"
|
sl@0
|
19 |
|
sl@0
|
20 |
/**
|
sl@0
|
21 |
Function pointer type used to instantiate the Graphics Resource Adapter singleton.
|
sl@0
|
22 |
*/
|
sl@0
|
23 |
typedef TInt (*TSgDriverCreateFunction)(MSgDriverAdapter*&);
|
sl@0
|
24 |
|
sl@0
|
25 |
XSgDriverPls::XSgDriverPls()
|
sl@0
|
26 |
{
|
sl@0
|
27 |
iError = iMutex.CreateLocal();
|
sl@0
|
28 |
iOpenCount = 0;
|
sl@0
|
29 |
iDriver = NULL;
|
sl@0
|
30 |
}
|
sl@0
|
31 |
|
sl@0
|
32 |
|
sl@0
|
33 |
#ifndef __WINS__
|
sl@0
|
34 |
XSgDriverPls gPls;
|
sl@0
|
35 |
#endif
|
sl@0
|
36 |
|
sl@0
|
37 |
|
sl@0
|
38 |
/**
|
sl@0
|
39 |
@publishedPartner
|
sl@0
|
40 |
@prototype
|
sl@0
|
41 |
@deprecated
|
sl@0
|
42 |
|
sl@0
|
43 |
Opens the Graphics Resource driver in the context of the calling process.
|
sl@0
|
44 |
|
sl@0
|
45 |
This function must be called by any process using the Graphics Resource API before
|
sl@0
|
46 |
any other function in the API. When finished the process should call Close(). If
|
sl@0
|
47 |
Open() has already been called from the same process then calling it again just
|
sl@0
|
48 |
increments a process-local open count. Each successful call to Open() must be
|
sl@0
|
49 |
balanced by a corresponding call to Close() later on.
|
sl@0
|
50 |
|
sl@0
|
51 |
Note that, in a multi-threaded process, it is not necessary for each thread to call
|
sl@0
|
52 |
this function. A possible strategy is therefore for the main thread to call
|
sl@0
|
53 |
SgDriver::Open() at the beginning and SgDriver::Close() at the end, while the rest
|
sl@0
|
54 |
of the threads do not call either of these but simply use the Graphics Resource API.
|
sl@0
|
55 |
|
sl@0
|
56 |
@pre None.
|
sl@0
|
57 |
@post The Graphics Resource driver is initialised for use in the context of the
|
sl@0
|
58 |
calling process and the process-local open count is incremented by one.
|
sl@0
|
59 |
@return KErrNone if successful.
|
sl@0
|
60 |
@return KErrNotSupported if no implementation of the Graphics Resource API is present.
|
sl@0
|
61 |
@return KErrNoMemory if there is not enough system memory.
|
sl@0
|
62 |
@see SgDriver::Close()
|
sl@0
|
63 |
*/
|
sl@0
|
64 |
EXPORT_C TInt SgDriver::Open()
|
sl@0
|
65 |
{
|
sl@0
|
66 |
if (gPls.iError != KErrNone)
|
sl@0
|
67 |
{
|
sl@0
|
68 |
return gPls.iError;
|
sl@0
|
69 |
}
|
sl@0
|
70 |
gPls.iMutex.Wait();
|
sl@0
|
71 |
if (gPls.iDriver)
|
sl@0
|
72 |
{
|
sl@0
|
73 |
++gPls.iOpenCount;
|
sl@0
|
74 |
gPls.iMutex.Signal();
|
sl@0
|
75 |
return KErrNone;
|
sl@0
|
76 |
}
|
sl@0
|
77 |
#ifdef __WINS__
|
sl@0
|
78 |
const TUidType KSgResourceAdapterLibraryUidType(KDynamicLibraryUid, KSharedLibraryUid, KSgResourceAdapterLibraryUid);
|
sl@0
|
79 |
RLibrary lib;
|
sl@0
|
80 |
TInt err = lib.Load(KSgResourceAdapterLibraryName, KSgResourceAdapterLibraryUidType);
|
sl@0
|
81 |
if (err != KErrNone)
|
sl@0
|
82 |
{
|
sl@0
|
83 |
if (err == KErrNotFound)
|
sl@0
|
84 |
{
|
sl@0
|
85 |
err = KErrNotSupported;
|
sl@0
|
86 |
}
|
sl@0
|
87 |
gPls.iMutex.Signal();
|
sl@0
|
88 |
return err;
|
sl@0
|
89 |
}
|
sl@0
|
90 |
gPls.iLibrary = lib;
|
sl@0
|
91 |
err = gPls.iLibrary.Duplicate(RThread()); // Get a process-wide handle
|
sl@0
|
92 |
lib.Close();
|
sl@0
|
93 |
if (err != KErrNone)
|
sl@0
|
94 |
{
|
sl@0
|
95 |
gPls.iMutex.Signal();
|
sl@0
|
96 |
return err;
|
sl@0
|
97 |
}
|
sl@0
|
98 |
TSgDriverCreateFunction create = reinterpret_cast<TSgDriverCreateFunction>(gPls.iLibrary.Lookup(1));
|
sl@0
|
99 |
err = create(gPls.iDriver);
|
sl@0
|
100 |
if (err != KErrNone)
|
sl@0
|
101 |
{
|
sl@0
|
102 |
gPls.iLibrary.Close();
|
sl@0
|
103 |
gPls.iMutex.Signal();
|
sl@0
|
104 |
return err;
|
sl@0
|
105 |
}
|
sl@0
|
106 |
#else
|
sl@0
|
107 |
TInt err = MSgDriverAdapter::New(gPls.iDriver);
|
sl@0
|
108 |
if (err != KErrNone)
|
sl@0
|
109 |
{
|
sl@0
|
110 |
gPls.iMutex.Signal();
|
sl@0
|
111 |
return err;
|
sl@0
|
112 |
}
|
sl@0
|
113 |
#endif
|
sl@0
|
114 |
gPls.iOpenCount = 1;
|
sl@0
|
115 |
gPls.iMutex.Signal();
|
sl@0
|
116 |
return KErrNone;
|
sl@0
|
117 |
}
|
sl@0
|
118 |
|
sl@0
|
119 |
|
sl@0
|
120 |
/**
|
sl@0
|
121 |
@publishedPartner
|
sl@0
|
122 |
@prototype
|
sl@0
|
123 |
@deprecated
|
sl@0
|
124 |
|
sl@0
|
125 |
Closes the Graphics Resource driver in the context of the calling process.
|
sl@0
|
126 |
|
sl@0
|
127 |
This function must be called by a process when finished using the Graphics Resource
|
sl@0
|
128 |
API. It decrements the process-local open count and, when the count becomes zero,
|
sl@0
|
129 |
it carries out termination tasks needed to release the internal resources allocated
|
sl@0
|
130 |
for the calling process.
|
sl@0
|
131 |
|
sl@0
|
132 |
Each call to Close() must correspond to a prior successful call to Open(). Note that,
|
sl@0
|
133 |
in a multi-threaded process, it is not generally safe to call Close() regardless of
|
sl@0
|
134 |
whether the corresponding call to Open() succeeded or failed, since too many calls to
|
sl@0
|
135 |
Close() from a thread could have an unexpected effect on all the other threads in the
|
sl@0
|
136 |
process. The following example demonstrates how to open and close the Graphics
|
sl@0
|
137 |
Resource driver safely from a worker thread.
|
sl@0
|
138 |
|
sl@0
|
139 |
@code
|
sl@0
|
140 |
// Open Graphics Resource driver
|
sl@0
|
141 |
TBool isDriverOpen = EFalse;
|
sl@0
|
142 |
if (SgDriver::Open() == KErrNone)
|
sl@0
|
143 |
{
|
sl@0
|
144 |
isDriverOpen = ETrue;
|
sl@0
|
145 |
}
|
sl@0
|
146 |
// Do some work in this thread
|
sl@0
|
147 |
DoThreadWork();
|
sl@0
|
148 |
// Close Graphics Resource driver
|
sl@0
|
149 |
if (isDriverOpen)
|
sl@0
|
150 |
{
|
sl@0
|
151 |
SgDriver::Close();
|
sl@0
|
152 |
}
|
sl@0
|
153 |
@endcode
|
sl@0
|
154 |
|
sl@0
|
155 |
@pre If the process-local open count is one then there are no open handles to graphics
|
sl@0
|
156 |
resources in the calling process.
|
sl@0
|
157 |
@post The process-local open count is decremented by one if greater than zero. If the
|
sl@0
|
158 |
count becomes zero, then the calling process is not able to use the Graphics
|
sl@0
|
159 |
Resource API any longer.
|
sl@0
|
160 |
@panic SGRES 1 in debug builds if there still are any open handles to graphics resources
|
sl@0
|
161 |
in the calling process when the process termination tasks are carried out.
|
sl@0
|
162 |
@see SgDriver::Open()
|
sl@0
|
163 |
*/
|
sl@0
|
164 |
EXPORT_C void SgDriver::Close()
|
sl@0
|
165 |
{
|
sl@0
|
166 |
if (gPls.iError != KErrNone)
|
sl@0
|
167 |
{
|
sl@0
|
168 |
return;
|
sl@0
|
169 |
}
|
sl@0
|
170 |
gPls.iMutex.Wait();
|
sl@0
|
171 |
if (gPls.iOpenCount > 0 && --gPls.iOpenCount == 0)
|
sl@0
|
172 |
{
|
sl@0
|
173 |
gPls.iDriver->Delete();
|
sl@0
|
174 |
gPls.iDriver = NULL;
|
sl@0
|
175 |
#ifdef __WINS__
|
sl@0
|
176 |
gPls.iLibrary.Close();
|
sl@0
|
177 |
#endif
|
sl@0
|
178 |
}
|
sl@0
|
179 |
gPls.iMutex.Signal();
|
sl@0
|
180 |
}
|
sl@0
|
181 |
|
sl@0
|
182 |
|
sl@0
|
183 |
/**
|
sl@0
|
184 |
@internalComponent
|
sl@0
|
185 |
@test
|
sl@0
|
186 |
*/
|
sl@0
|
187 |
EXPORT_C TInt SgDriver::ResourceCount()
|
sl@0
|
188 |
{
|
sl@0
|
189 |
#ifdef _DEBUG
|
sl@0
|
190 |
gPls.iMutex.Wait();
|
sl@0
|
191 |
__ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver));
|
sl@0
|
192 |
#endif
|
sl@0
|
193 |
TInt count = gPls.iDriver->ResourceCount();
|
sl@0
|
194 |
#ifdef _DEBUG
|
sl@0
|
195 |
gPls.iMutex.Signal();
|
sl@0
|
196 |
#endif
|
sl@0
|
197 |
return count;
|
sl@0
|
198 |
}
|
sl@0
|
199 |
|
sl@0
|
200 |
|
sl@0
|
201 |
/**
|
sl@0
|
202 |
@internalComponent
|
sl@0
|
203 |
@test
|
sl@0
|
204 |
*/
|
sl@0
|
205 |
EXPORT_C void SgDriver::AllocMarkStart()
|
sl@0
|
206 |
{
|
sl@0
|
207 |
#ifdef _DEBUG
|
sl@0
|
208 |
gPls.iMutex.Wait();
|
sl@0
|
209 |
__ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver));
|
sl@0
|
210 |
#endif
|
sl@0
|
211 |
gPls.iDriver->AllocMarkStart();
|
sl@0
|
212 |
#ifdef _DEBUG
|
sl@0
|
213 |
gPls.iMutex.Signal();
|
sl@0
|
214 |
#endif
|
sl@0
|
215 |
}
|
sl@0
|
216 |
|
sl@0
|
217 |
|
sl@0
|
218 |
/**
|
sl@0
|
219 |
@internalComponent
|
sl@0
|
220 |
@test
|
sl@0
|
221 |
*/
|
sl@0
|
222 |
EXPORT_C void SgDriver::AllocMarkEnd(TInt aCount)
|
sl@0
|
223 |
{
|
sl@0
|
224 |
#ifdef _DEBUG
|
sl@0
|
225 |
gPls.iMutex.Wait();
|
sl@0
|
226 |
__ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver));
|
sl@0
|
227 |
#endif
|
sl@0
|
228 |
gPls.iDriver->AllocMarkEnd(aCount);
|
sl@0
|
229 |
#ifdef _DEBUG
|
sl@0
|
230 |
gPls.iMutex.Signal();
|
sl@0
|
231 |
#endif
|
sl@0
|
232 |
}
|
sl@0
|
233 |
|
sl@0
|
234 |
|
sl@0
|
235 |
/**
|
sl@0
|
236 |
@internalComponent
|
sl@0
|
237 |
@test
|
sl@0
|
238 |
*/
|
sl@0
|
239 |
EXPORT_C void SgDriver::SetAllocFail(RAllocator::TAllocFail aType, TInt aRate)
|
sl@0
|
240 |
{
|
sl@0
|
241 |
#ifdef _DEBUG
|
sl@0
|
242 |
gPls.iMutex.Wait();
|
sl@0
|
243 |
__ASSERT_DEBUG(gPls.iDriver, Panic(ESgPanicNoDriver));
|
sl@0
|
244 |
#endif
|
sl@0
|
245 |
gPls.iDriver->SetAllocFail(aType, aRate);
|
sl@0
|
246 |
#ifdef _DEBUG
|
sl@0
|
247 |
gPls.iMutex.Signal();
|
sl@0
|
248 |
#endif
|
sl@0
|
249 |
}
|