void DLM_APIENTRY crDLMEndList(void) { CRDLMContextState *listState = CURRENT_STATE(); /* Error check: cannot call EndList without a (successful) * preceding NewList. * * The caller is expected to check for glNewList within * a glBegin/glEnd sequence. */ if (listState == NULL) { crWarning("DLM error: EndList called with no current state (%s line %d)\n", __FILE__, __LINE__); return; } if (listState->currentListInfo == NULL) { crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION, "EndList called while no display list was open"); return; } DLM_LOCK(listState->dlm) /* This function will either replace the list information that's * already present with our new list information, freeing the * former list information; or will add the new information * to the set of display lists, depending on whether the * list already exists or not. */ crHashtableReplace(listState->dlm->displayLists, listState->currentListIdentifier, listState->currentListInfo, crdlm_free_list); DLM_UNLOCK(listState->dlm) /* reset the current state to show the list had been ended */ listState->currentListIdentifier = 0; listState->currentListInfo = NULL; listState->currentListMode = GL_FALSE; }
static bool crDLMLoadList(CRDLM *dlm, PSSMHANDLE pSSM, SPUDispatchTable *dispatchTable) { uint32_t cElements = 0; uint32_t idList = 0; uint32_t i; int32_t rc; /* Restore Display List length. */ rc = SSMR3GetU32(pSSM, &cElements); if (RT_SUCCESS(rc)) { /* Restore Display List ID. */ rc = SSMR3GetU32(pSSM, &idList); if (RT_SUCCESS(rc)) { /* Initialize new list data and start recording it. */ DLMListInfo *pListInfo; pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo)); if (pListInfo) { GLuint hwid; crMemset(pListInfo, 0, sizeof(DLMListInfo)); hwid = dispatchTable->GenLists(1); if (hwid > 0) { bool fSuccess = true; CRDLMContextState *pDLMContextState; pListInfo->numInstances = 0; pListInfo->stateFirst = pListInfo->stateLast = NULL; pListInfo->hwid = hwid; dispatchTable->NewList(hwid, GL_COMPILE); /* Fake list state in order to prevent expando SPU from double caching. */ pDLMContextState = crDLMGetCurrentState(); pDLMContextState->currentListMode = GL_FALSE; crDebug("Restoring Display Lists:\t%u elements to restore.", cElements); /* Iterate over list instances. */ for (i = 0; i < cElements; i++) { fSuccess = crDLMLoadListInstance(pSSM, pListInfo, dispatchTable); if (!fSuccess) break; } dispatchTable->EndList(); if (fSuccess) { /* Add list to cache. */ crHashtableReplace(dlm->displayLists, idList, pListInfo, NULL); return true; } else crError("Restoring Display Lists: some elements could not be restored."); } else crError("Restoring Display Lists: can't allocate hwid for list %u.", idList); crFree(pListInfo); } else crError("Restoring Display Lists: can't allocate memory."); } else crError("Restoring Display Lists: can't get list ID."); } else crError("Restoring Display Lists: can't get number of elements in list."); return false; }
/** * Generate host and guest IDs, setup IDs mapping between host and guest. */ GLuint DLM_APIENTRY crDLMGenLists(GLsizei range, SPUDispatchTable *dispatchTable) { CRDLMContextState *listState = CURRENT_STATE(); GLuint idHostRangeStart = 0; GLuint idGuestRangeStart = 0; crDebug("DLM: GenLists(%d) (DLM=%p).", range, listState ? listState->dlm : 0); if (listState) { idHostRangeStart = dispatchTable->GenLists(range); if (idHostRangeStart > 0) { idGuestRangeStart = crHashtableAllocKeys(listState->dlm->displayLists, range); if (idGuestRangeStart > 0) { GLuint i; bool fSuccess = true; /* Now have successfully generated IDs range for host and guest. Let's make IDs association. */ for (i = 0; i < (GLuint)range; i++) { DLMListInfo *pListInfo; pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo)); if (pListInfo) { crMemset(pListInfo, 0, sizeof(DLMListInfo)); pListInfo->hwid = idHostRangeStart + i; /* Insert pre-initialized list data which contains IDs mapping into the hash. */ crHashtableReplace(listState->dlm->displayLists, idGuestRangeStart + i, pListInfo, NULL); } else { fSuccess = false; break; } } /* All structures allocated and initialized successfully. */ if (fSuccess) return idGuestRangeStart; /* Rollback some data was not allocated. */ crDLMDeleteLists(idGuestRangeStart, range, NULL /* we do DeleteLists() later in this routine */ ); } else crDebug("DLM: Can't allocate Display List IDs range for the guest."); dispatchTable->DeleteLists(idHostRangeStart, range); } else crDebug("DLM: Can't allocate Display List IDs range on the host side."); } else crDebug("DLM: GenLists(%u) called with no current state.", range); /* Can't reserve IDs range. */ return 0; }