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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
/**
 * 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;
}