egl/eglrefimpl/src/display.cpp
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     1 // Copyright (c) 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 // Reference EGL implementation to support EGL sync objects and OpenWF extensions
       
    15 
       
    16 #include "eglprivate.h"
       
    17 
       
    18 CEglDisplay::CEglDisplay(RHeap& aHeap):
       
    19     iHandle(KEglDefaultDisplayHandle),
       
    20 	iHeap(aHeap)
       
    21 	{
       
    22 	}
       
    23 
       
    24 CEglDisplay::~CEglDisplay()
       
    25 	{
       
    26 	Terminate();
       
    27 	
       
    28 	if (iSyncObjList)
       
    29 	    {
       
    30         __ASSERT_DEBUG(iSyncObjList->Count() == 0, User::Panic(KEglPanicCategory, EEglPanicOutstandingSyncObj));
       
    31 
       
    32         // we're about to free hash map and its underlying memory, make sure EGL shared heap is used
       
    33         RHeap* callerHeap = User::SwitchHeap(&iHeap);
       
    34         iSyncObjList->Close();
       
    35         delete iSyncObjList;
       
    36         User::SwitchHeap(callerHeap);
       
    37 	    }
       
    38 	}
       
    39 
       
    40 TInt CEglDisplay::Initialize()
       
    41 	{
       
    42 	TInt err = KErrNone;
       
    43 	if (iIsInitialized)
       
    44 		{
       
    45 		return err;
       
    46 		}
       
    47 
       
    48 	// hash map is only created once, check that when re-initialising display
       
    49 	if (iSyncObjList)
       
    50 	    {
       
    51 	    iIsInitialized = ETrue;
       
    52 	    }
       
    53 	else
       
    54 	    {
       
    55 	    // make sure underlying hash implementation memory is allocated in share heap
       
    56 	    //
       
    57         RHeap* callerHeap = User::SwitchHeap(&iHeap);
       
    58         iSyncObjList = new REglSyncHashMap;
       
    59         if (iSyncObjList)
       
    60             {
       
    61             iIsInitialized = ETrue;
       
    62             }
       
    63         else
       
    64             {
       
    65             err = KErrNoMemory;
       
    66             }
       
    67         User::SwitchHeap(callerHeap);        
       
    68 	    }
       
    69 	
       
    70 	return err;
       
    71 	}
       
    72 
       
    73 void CEglDisplay::Terminate()
       
    74 	{
       
    75 	if (!iIsInitialized)
       
    76 		{
       
    77 		return;
       
    78 		}
       
    79 
       
    80     REglSyncHashMap::TIter iter(*iSyncObjList);
       
    81     // iter begin at index -1, must move it once to get to first item
       
    82     while (iter.NextKey())
       
    83         {
       
    84         CEglSync** ppSyncObj = iter.CurrentValue();
       
    85         __ASSERT_DEBUG(ppSyncObj, User::Panic(KEglPanicCategory, EEglPanicInvalidSyncObj));
       
    86         
       
    87         // In a regular iteration, we should not modify the hash map itself while it is being iterated.
       
    88         // However, this is not a regular iteration, we need to remove destroyed object from
       
    89         // this hash map without using additional memory e.g. copying destroyed object key temporarily.
       
    90         // The reason we do not want to do that is because allocating memory can fail and Terminate
       
    91         // must not fail.
       
    92         CEglSync* syncObj = *ppSyncObj;
       
    93         
       
    94         // Destroy() will switch current heap to the EGL shared heap and restore it back.
       
    95         // It will also remove the sync object from hash map, but not necessarily delete it (because
       
    96         // some other threads may still use it)
       
    97         syncObj->Destroy();
       
    98         iter.Reset();
       
    99         }
       
   100     
       
   101 	iIsInitialized = EFalse;
       
   102 	}
       
   103 
       
   104 CEglSync* CEglDisplay::FindSyncObj(EGLSyncKHR aObj) const
       
   105 	{
       
   106 	__ASSERT_DEBUG(iSyncObjList, User::Panic(KEglPanicCategory, EEglPanicDisplayStateInvalid));
       
   107 
       
   108 	const TInt key = reinterpret_cast<TInt>(aObj);
       
   109 	CEglSync** ppso = iSyncObjList->Find(key);
       
   110 	CEglSync* syncObj = ppso ? *ppso : NULL;
       
   111 	
       
   112 	return syncObj;
       
   113 	}
       
   114 
       
   115 CEglSync* CEglDisplay::CreateSyncObj()
       
   116 	{
       
   117     __ASSERT_DEBUG(iSyncObjList, User::Panic(KEglPanicCategory, EEglPanicDisplayStateInvalid));
       
   118     
       
   119     CEglSync* syncObj = CEglSync::Create(*this);
       
   120 
       
   121     return syncObj;
       
   122 	}
       
   123 
       
   124 TInt CEglDisplay::DestroySyncObj(EGLSyncKHR aSyncObj)
       
   125 	{
       
   126     __ASSERT_DEBUG(iSyncObjList, User::Panic(KEglPanicCategory, EEglPanicDisplayStateInvalid));
       
   127 
       
   128     CEglSync* syncObj = reinterpret_cast<CEglSync*>(aSyncObj);
       
   129     const TInt key = reinterpret_cast<TInt>(syncObj);
       
   130     CEglSync** ppso = iSyncObjList->Find(key);
       
   131     if (!ppso)
       
   132         {
       
   133         return KErrNotFound;
       
   134         }
       
   135 
       
   136     // Destroy() will not delete sync obj or remove it from the list if it is still being used in other threads
       
   137     // if there is no more reference to this sync obj when Destroy() is called, it will delete the object and remove it from the list
       
   138     __ASSERT_DEBUG(syncObj == *ppso, User::Panic(KEglPanicCategory, EEglPanicInvalidSyncObj));
       
   139     syncObj->Destroy();
       
   140 
       
   141     return KErrNone;
       
   142 	}
       
   143 
       
   144 TInt CEglDisplay::RegisterSyncObj(CEglSync& aSyncObj)
       
   145     {
       
   146     __ASSERT_DEBUG(&iHeap == &User::Heap(), User::Panic(KEglPanicCategory, EEglPanicInvalidHeap));
       
   147     __ASSERT_DEBUG(iSyncObjList, User::Panic(KEglPanicCategory, EEglPanicDisplayStateInvalid));
       
   148     
       
   149     const TInt key = reinterpret_cast<TInt>(&aSyncObj);
       
   150     const TInt err = iSyncObjList->Insert(key, &aSyncObj);
       
   151 
       
   152     return err;
       
   153     }
       
   154 
       
   155 void CEglDisplay::UnregisterSyncObj(CEglSync& aSyncObj)
       
   156     {
       
   157     __ASSERT_DEBUG(&iHeap == &User::Heap(), User::Panic(KEglPanicCategory, EEglPanicInvalidHeap));
       
   158     __ASSERT_DEBUG(iSyncObjList, User::Panic(KEglPanicCategory, EEglPanicDisplayStateInvalid));
       
   159     
       
   160     const TInt key = reinterpret_cast<TInt>(&aSyncObj);
       
   161     const TInt err = iSyncObjList->Remove(key);
       
   162     // the only possible error is KErrNotFound which should never happen in our case
       
   163     __ASSERT_DEBUG(err == KErrNone, User::Panic(KEglPanicCategory, EEglPanicInvalidSyncObj));
       
   164     }