os/graphics/egl/eglrefimpl/src/display.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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     }