graphicsdeviceinterface/directgdi/src/directgdidriver.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 2007-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 //
       
    15 
       
    16 #include "directgdipaniccodes.h" // Included first to resolve dependency
       
    17 
       
    18 #include <graphics/sgimage.h>
       
    19 #include <graphics/directgdiimagetarget.h>
       
    20 #include <graphics/directgdidrawablesource.h>
       
    21 #include <graphics/directgdipanics.h>
       
    22 #include <graphics/directgdidriverinternal.h>
       
    23 #include <e32svr.h>
       
    24 #include <u32hal.h>
       
    25 
       
    26 #include "directgdidriver.h"
       
    27 #include "directgditypes.h"
       
    28 #include "directgdidriverinternallibrary.inl"
       
    29 
       
    30 typedef TInt (*TDriverCreateFunction)(CDirectGdiDriverInternal*&, RLibrary);
       
    31 
       
    32 /**
       
    33 Returns the singleton instance of CDirectGdiDriver for the calling thread. 
       
    34 
       
    35 @return Pointer to an opened CDirectGdiDriver object else NULL if a CDirectGdiDriver had not been opened yet.
       
    36 */
       
    37 EXPORT_C CDirectGdiDriver* CDirectGdiDriver::Static()
       
    38 	{
       
    39 	return static_cast<CDirectGdiDriver*>(Dll::Tls());						
       
    40 	}
       
    41 
       
    42 /**
       
    43 Creates a new CDirectGdiDriver object if one has not already been created in this thread.
       
    44 Performs any adaptation initialisation that is needed to allow the calling thread to use 
       
    45 functionality provided by the new DirectGDI interfaces. Calling this method multiple times 
       
    46 from the same client thread has no effect after the first call, other than to increase the 
       
    47 open count. 
       
    48 
       
    49 @see CDirectGdiDriver::Close()
       
    50 
       
    51 @pre None.
       
    52 @post The object reference counter is incremented. Adaptation resources for the 
       
    53 calling thread are created and initialised. The new DirectGDI interfaces are ready 
       
    54 to be used from the calling thread.  
       
    55 
       
    56 @return KErrNone if successful, otherwise one of the system-wide error codes.
       
    57 */
       
    58 EXPORT_C TInt CDirectGdiDriver::Open()
       
    59 	{
       
    60 	TInt err = KErrNone;
       
    61 	CDirectGdiDriver* self = Static(); 
       
    62 		
       
    63 	// Check we're not already opened
       
    64 	if (!self)
       
    65 		{				
       
    66 		self = new CDirectGdiDriver();
       
    67 		if (!self)
       
    68 			{
       
    69 			err = KErrNoMemory;
       
    70 			return err;
       
    71 			}
       
    72 
       
    73 #ifdef __WINS__
       
    74 		// Dynamically load DirectGDI adapter library.
       
    75 		// Under WINS two dlls will be available - directgdiadapter_sw.dll and directgdiadapter_vg.dll
       
    76 		// Need to select which dll to load.  The value of the keyword SYMBIAN_GRAPHICS_DIRECTGDI_USE
       
    77 		// in the epoc.ini file will determine the dll to load.
       
    78 		// If this keyword does not appear in the epoc.ini file, the software version of
       
    79 		// directgdiadapter will be loaded by default.
       
    80 		_LIT(KVgAdapterDllName, "directgdiadapter_vg.dll");
       
    81 		_LIT(KSwAdapterDllName, "directgdiadapter_sw.dll");
       
    82 		TBool useOpenVg = EFalse;
       
    83 		UserSvr::HalFunction(EHalGroupEmulator, EEmulatorHalBoolProperty,  (TAny*)"symbian_graphics_directgdi_use_openvg",  &useOpenVg);
       
    84 		TPtrC libraryName;
       
    85 		if(useOpenVg)
       
    86 			{
       
    87 			libraryName.Set(KVgAdapterDllName);
       
    88 			}
       
    89 		else
       
    90 			{
       
    91 			libraryName.Set(KSwAdapterDllName);
       
    92 			}
       
    93 		RLibrary lib;
       
    94 		err = lib.Load(libraryName);
       
    95 		if (err != KErrNone)
       
    96 			{
       
    97 			delete self;
       
    98 			return (err==KErrNotFound ? KErrNotSupported : err);
       
    99 			}
       
   100 		
       
   101 		// Create internal driver
       
   102 		err = self->CreateInternalDriver(lib);
       
   103 		if (err != KErrNone)
       
   104 			{
       
   105 			delete self;
       
   106 			lib.Close();
       
   107 			return err;
       
   108 			}
       
   109 #else
       
   110 		// Under armv5, the appropriate dll (software or vg) is determined at rom build time.
       
   111 		err = self->CreateInternalDriver();
       
   112 		if (err != KErrNone)
       
   113 			{
       
   114 			delete self;
       
   115 			return err;
       
   116 			}
       
   117 #endif
       
   118 
       
   119 		// Store a pointer to the new driver instance in thread local storage:
       
   120 		err = Dll::SetTls(self);
       
   121 		if (err != KErrNone)	
       
   122 			{
       
   123 			delete self;
       
   124 			}				
       
   125 		}
       
   126 	
       
   127 	if (err == KErrNone)
       
   128 		{
       
   129 		++(self->iOpenCount);
       
   130 		}
       
   131 	
       
   132 	return err;
       
   133 	}
       
   134 
       
   135 /**
       
   136 Create the adaptation/internal object for this driver.
       
   137 
       
   138 @pre The adaptation/internal driver object has not been created yet.
       
   139 @post The adaptation/internal object has been created.
       
   140 
       
   141 @return KErrNone if successful, otherwise one of the system-wide error codes.
       
   142  */
       
   143 #ifdef __WINS__
       
   144 TInt CDirectGdiDriver::CreateInternalDriver(const RLibrary& aLibrary)
       
   145 	{
       
   146 	// Function at ordinal 1 creates new CDirectGdiDriverInternal
       
   147 	TDriverCreateFunction create = reinterpret_cast<TDriverCreateFunction>(aLibrary.Lookup(1));
       
   148 	return create(iDriverInternal, aLibrary);
       
   149 	}
       
   150 #else
       
   151 TInt CDirectGdiDriver::CreateInternalDriver()
       
   152 	{
       
   153 	return CDirectGdiDriverInternal::New(iDriverInternal, RLibrary());
       
   154 	}
       
   155 #endif
       
   156 
       
   157 /**
       
   158 Performs adaptation termination which is needed to release any internal resources 
       
   159 allocated by the calling thread. It will also perform an implicit Finish() by submitting
       
   160 all outstanding requests from the calling thread. A DirectGDI client's thread that 
       
   161 uses the new DirectGDI interfaces must call this method at the end of its lifetime.
       
   162 
       
   163 @see CDirectGdiDriver::Open()
       
   164 
       
   165 @pre The driver is open from a call to Open().
       
   166 @post The object open count is decremented. If the open count reaches zero, any 
       
   167 adaptation resources allocated to the calling thread must be released, and the CDirectGdiDriver 
       
   168 object for the calling thread is destroyed.
       
   169 
       
   170 @panic DGDI 14, if Close() is called on a CDirectGdiDriver object that is not open.
       
   171 */
       
   172 EXPORT_C void CDirectGdiDriver::Close()
       
   173 	{	
       
   174 	GRAPHICS_ASSERT_ALWAYS(iOpenCount > 0, EDirectGdiPanicDriverOpenCountError);
       
   175 		
       
   176 	if (--iOpenCount == 0)
       
   177 		{
       
   178 		// We call Finish() instead of Flush() because it will decrease the reference count
       
   179 		// of images used in DrawResource() (if any) and is guaranteed that it will complete.
       
   180 		// Flush() cannot guarantee completion so we can't decrement image reference counts.
       
   181 		Finish();
       
   182 
       
   183 		// Get the handle to the DLL used by iDriverInternal so that we can close
       
   184 		// it once iDriverInternal has been deleted.
       
   185 		RLibrary lib = iDriverInternal->Library();
       
   186 		delete this;
       
   187 		lib.Close();
       
   188 			
       
   189 		// Free the space we saved for the driver singleton pointer in thead local storage
       
   190 		Dll::FreeTls();		
       
   191 		}		
       
   192 	}
       
   193 
       
   194 /**
       
   195 Ensures all outstanding requests on the calling thread are submitted for processing.
       
   196 The method immediately returns and does not wait until all outstanding requests are
       
   197 completely processed. Clients can continue issuing rendering requests after calling
       
   198 this method.
       
   199 
       
   200 @see    CDirectGdiDriver::Finish()
       
   201 
       
   202 @pre 	CDirectGdiDriver object has been initialised for the calling thread.
       
   203 @post 	All outstanding requests have been submitted for processing.
       
   204 */
       
   205 EXPORT_C void CDirectGdiDriver::Flush()
       
   206 	{
       
   207 	iDriverInternal->Flush();
       
   208 	}
       
   209 
       
   210 /**
       
   211 Ensures all outstanding rendering requests from the calling thread are submitted
       
   212 and processed. This method will wait until all the outstanding rendering requests
       
   213 have been completely processed.
       
   214 
       
   215 @see    CDirectGdiDriver::Flush()
       
   216 
       
   217 @pre 	CDirectGdiDriver object has been initialised for the calling thread.
       
   218 @post 	All outstanding requests have been completely processed.
       
   219 */
       
   220 EXPORT_C void CDirectGdiDriver::Finish()
       
   221 	{
       
   222 	iDriverInternal->Finish();
       
   223 	}
       
   224 
       
   225 /**
       
   226 Returns the first error code (as the result of calling any DirectGDI API), if any,
       
   227 since the last call to this function or, if it has not previously been called, since
       
   228 the CDirectGdiDriver was initialised. Calling this function clears the error code.
       
   229 
       
   230 @see    CDirectGdiDriver::SetError(TInt)
       
   231 
       
   232 @pre 	CDirectGdiDriver object has been initialised for the calling thread.
       
   233 @post 	The error code has been reset after being read.
       
   234 
       
   235 @return The first error code, if any, since the last call to this function or, 
       
   236 		if it has not previously been called, since the CDirectGdiDriver was initialised. 
       
   237 		KErrNone will indicate that no such error has occurred.
       
   238 */
       
   239 EXPORT_C TInt CDirectGdiDriver::GetError()
       
   240 	{
       
   241 	return iDriverInternal->GetError();
       
   242 	}
       
   243 
       
   244 
       
   245 /**
       
   246 Sets the error code on the driver. If the error code is already set to a value other
       
   247 than KErrNone, the error code will not be modified.
       
   248 
       
   249 @see    CDirectGdiDriver::GetError()
       
   250 
       
   251 @param  aErr The error code to set.
       
   252 
       
   253 @pre 	CDirectGdiDriver object has been initialised for the calling thread.
       
   254 @post 	The error code has been set.
       
   255 */
       
   256 EXPORT_C void CDirectGdiDriver::SetError(TInt aErr)
       
   257 	{
       
   258 	iDriverInternal->SetError(aErr);
       
   259 	}
       
   260 
       
   261 /**
       
   262 Retrieves a pointer to an instance of the requested extension interface implementation, if provided.
       
   263 
       
   264 @param	aInterfaceId The globally unique identifier of the requested interface.	
       
   265 @param	aInterface On return, holds the specified interface, or NULL if the interface cannot be found.
       
   266 
       
   267 @pre	CDirectGdiDriver object has been initialised for the calling thread.
       
   268 
       
   269 @return KErrNone If the interface is supported, KErrExtensionNotSupported otherwise.
       
   270  */
       
   271 EXPORT_C TInt CDirectGdiDriver::GetInterface(TUid aInterfaceId, TAny*& aInterface)
       
   272 	{
       
   273 	return iDriverInternal->GetInterface(aInterfaceId, aInterface);
       
   274 	}
       
   275 
       
   276 /**
       
   277 CDirectGdiDriver private constructor as this class is singleton.
       
   278 
       
   279 @pre 	None.
       
   280 @post 	Initialises the member reference counter to zero.
       
   281 */
       
   282 CDirectGdiDriver::CDirectGdiDriver()
       
   283 	{	
       
   284 	}
       
   285 
       
   286 /**
       
   287 CDirectGdiDriver default destructor.
       
   288 
       
   289 @pre None.
       
   290 @post None.
       
   291 
       
   292 @panic DGDI 15, if the resource count is not zero.
       
   293 */
       
   294 CDirectGdiDriver::~CDirectGdiDriver()
       
   295 	{
       
   296 	GRAPHICS_ASSERT_ALWAYS(iOpenCount == 0, EDirectGdiPanicDriverDestructorOpenCountError);
       
   297 	delete iDriverInternal;		
       
   298 	}
       
   299 
       
   300 /**
       
   301 Delegates the call to the CDirectGdiDriverInternal object, which creates a DirectGDI 
       
   302 adaptation-specific resource from the given drawable resource so it can be drawn 
       
   303 using the DirectGDI rendering API.
       
   304 
       
   305 @see CloseDrawableSource()
       
   306 
       
   307 @param 	aRDirectGdiDrawableSource The RDirectGdiDrawableSource object to be created
       
   308 @param 	aRSgDrawable The RSgDrawable object to use when creating aRDirectGdiDrawableSource
       
   309 
       
   310 @pre 	CDirectGdiDriver object has been initialised from the calling thread.
       
   311 @post 	The DirectGDI adaptation-specific resource that is bound to the given 
       
   312 drawable resource is created and this handle is now associated with it. The reference 
       
   313 counter on the drawable resource is incremented. The CDirectGdiDriver for this thread 
       
   314 is now aware of and owns the adaptation specific resource.
       
   315 
       
   316 @return KErrNone if successful, KErrNotSupported if the drawable resource is not 
       
   317 created with the correct usage (ESgUsageDirectGdiSource must be set), otherwise one of the system-wide error codes.
       
   318 
       
   319 @panic DGDI 19, if this handle is already associated with a DirectGDI adaptation-specific drawable resource.
       
   320 @panic DGDI 20, if the drawable resource is not valid.
       
   321 */
       
   322 TInt CDirectGdiDriver::CreateDrawableSource(RDirectGdiDrawableSource& aRDirectGdiDrawableSource, const RSgDrawable& aRSgDrawable)
       
   323 	{				
       
   324 	GRAPHICS_ASSERT_ALWAYS(aRDirectGdiDrawableSource.Handle() == KNullHandle, EDirectGdiPanicDrawableSourceAlreadyExists);
       
   325     
       
   326 	if(aRSgDrawable.DrawableType() == KSgImageTypeUid)
       
   327 		{// make sure that drawable was created with the flag ESgUsageDirectGdiSource
       
   328 		RSgImage *image = (RSgImage*) &aRSgDrawable;
       
   329 		TSgImageInfo info;
       
   330 		TInt err = image ->GetInfo (info);
       
   331 		GRAPHICS_ASSERT_ALWAYS(err == KErrNone, EDirectGdiPanicImageSourceInfoError);
       
   332 	
       
   333 		if (!(info.iUsage & ESgUsageDirectGdiSource))
       
   334 			{
       
   335 			return KErrNotSupported;
       
   336 			}
       
   337 		}
       
   338 	return iDriverInternal->CreateDrawableSource(aRDirectGdiDrawableSource.iHandle, aRSgDrawable);
       
   339 	}
       
   340 
       
   341 /**
       
   342 Delegates call to the CDirectGdiDriverInternal object, which destroys the DirectGDI
       
   343 adaptation-specific resource associated with this handle. Calling this method on a
       
   344 handle that is not associated with any DirectGDI adaptation specific resource will 
       
   345 do nothing. Once Close() is called, this handle can be reused.
       
   346 
       
   347 @see CreateDrawableSource()
       
   348 
       
   349 @param 	aSource The RDirectGdiDrawableSource object.
       
   350 
       
   351 @pre 	CDirectGdiDriver object has been initialised from the calling thread.
       
   352 @post 	The DirectGDI specific resource associated with this handle will be 
       
   353 destroyed (at any time preferred by the adaptation). This handle is no longer 
       
   354 associated with a DirectGDI specific resource. The reference counter of the 
       
   355 underlying non-image resource is decremented. 
       
   356 */
       
   357 void CDirectGdiDriver::CloseDrawableSource(RDirectGdiDrawableSource& aSource)
       
   358 	{
       
   359 	iDriverInternal->CloseDrawableSource(aSource.iHandle);
       
   360 	}
       
   361 	
       
   362 /**
       
   363 Delegates call to the CDirectGdiDriverInternal object, which creates a DirectGDI 
       
   364 adaptation-specific resource from the given image resource so it can be used as a 
       
   365 target of DirectGDI rendering.
       
   366 
       
   367 @see CloseImageTarget()
       
   368 
       
   369 @param 	aTarget The RDirectGdiImageTarget object.
       
   370 @param 	aImage The RSgImage object.
       
   371 
       
   372 @pre 	CDirectGdiDriver object has been initialised from the calling thread.
       
   373 The image resource has been fully constructed and created with the correct usage 
       
   374 that allows it to be used as a DirectGDI target.
       
   375 
       
   376 @post 	The DirectGDI adaptation-specific resource that is bound to the given image 
       
   377 resource is created and this handle is now associated with it. The reference counter
       
   378 on the image resource is incremented. 
       
   379 
       
   380 @return KErrNone if successful, KErrNotSupported if the image resource is not 
       
   381 created with the correct usage, otherwise one of the system-wide error codes.
       
   382 
       
   383 @panic DGDI 17, if this handle is already associated with a DirectGDI adaptation-specific resource.
       
   384 @panic DGDI 21, if the image resource is not valid.
       
   385 */
       
   386 TInt CDirectGdiDriver::CreateImageTarget(RDirectGdiImageTarget& aTarget, const RSgImage& aImage)
       
   387 	{		
       
   388 	GRAPHICS_ASSERT_ALWAYS(aTarget.Handle() == KNullHandle, EDirectGdiPanicImageTargetAlreadyExists);
       
   389     TSgImageInfo info;
       
   390 	TInt err = aImage.GetInfo(info);
       
   391 	GRAPHICS_ASSERT_ALWAYS(err == KErrNone, EDirectGdiPanicImageTargetInfoError);
       
   392 		
       
   393 	if (!(info.iUsage & ESgUsageDirectGdiTarget))
       
   394 		{
       
   395 		return KErrNotSupported;
       
   396 		}
       
   397 	return iDriverInternal->CreateImageTarget(aTarget.iHandle, aImage);
       
   398 	}
       
   399 	
       
   400 /**
       
   401 Delegates call to the CDirectGdiDriverInternal object, which destroys the DirectGDI 
       
   402 adaptation specific resource associated with this handle. Calling this method on a 
       
   403 handle that is not associated with any DirectGDI adaptation specific resource will 
       
   404 do nothing. Once Close() is called, this handle can be reused.
       
   405 
       
   406 @see CreateImageTarget()
       
   407 
       
   408 @param 	aTarget The RDirectGdiImageTarget object.
       
   409 
       
   410 @pre 	CDirectGdiDriver object has been initialised from the calling thread.
       
   411 
       
   412 @post 	The DirectGDI specific resource associated with this handle will be destroyed
       
   413 (at any time preferred by the adaptation). This handle is no longer associated with 
       
   414 a DirectGDI specific resource. The reference counter of the underlying image 
       
   415 resource is decremented. 
       
   416 */
       
   417 void CDirectGdiDriver::CloseImageTarget(RDirectGdiImageTarget& aTarget)
       
   418 	{
       
   419 	iDriverInternal->CloseImageTarget(aTarget.iHandle);
       
   420 	}
       
   421 		
       
   422 /**
       
   423 Delegates call to the CDirectGdiDriverInternal object, which creates a
       
   424 MDirectGdiEngine object.
       
   425 
       
   426 @param 	aEngine The MDirectGdiEngine object.
       
   427 
       
   428 @pre 	CDirectGdiDriver object has been initialised from the calling thread.
       
   429 @post   None.
       
   430 
       
   431 @return KErrNone if successful, otherwise one of the system-wide error codes.
       
   432 */
       
   433 TInt CDirectGdiDriver::CreateEngine(MDirectGdiEngine*& aEngine)
       
   434 	{
       
   435 	return iDriverInternal->CreateEngine(aEngine);
       
   436 	}
       
   437 	
       
   438 /**
       
   439 Delegates call to the CDirectGdiDriverInternal object, which destroys a
       
   440 MDirectGdiEngine object.
       
   441 
       
   442 @param 	aEngine The MDirectGdiEngine object.
       
   443 
       
   444 @pre 	CDirectGdiDriver object has been initialised from the calling thread.
       
   445 @post   None.
       
   446 */
       
   447 void CDirectGdiDriver::DestroyEngine(MDirectGdiEngine* aEngine)
       
   448 	{
       
   449 	iDriverInternal->DestroyEngine(aEngine);
       
   450 	}
       
   451