VirtualBox

Ignore:
Timestamp:
Jun 20, 2015 8:10:59 AM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
101192
Message:

Host 3D: Expando SPU, DLM module.

  • DLM module reworked. Now it uses hardware way in order to execute Display List (software approach dropped);
  • Chromium/utils slightly extended with more helper functions needed for Expando/DLM;
  • More testing needed especially for glCallLists() and glListBase();
  • Expando/DLM code now enabed for Mac hosts.
Location:
trunk/src/VBox/HostServices/SharedOpenGL
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk

    r56301 r56566  
    3131
    3232ifeq ($(KBUILD_TARGET),darwin)
    33  #VBOX_WITH_CR_DISPLAY_LISTS=1
     33 VBOX_WITH_CR_DISPLAY_LISTS=1
    3434endif
    3535
  • trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_lists.c

    r55014 r56566  
    4040static GLuint TranslateListID( GLuint id )
    4141{
     42#ifndef VBOX_WITH_CR_DISPLAY_LISTS
    4243    if (!cr_server.sharedDisplayLists) {
    4344        int client = cr_server.curClient->number;
    4445        return id + client * 100000;
    4546    }
     47#endif
    4648    return id;
    4749}
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c

    r56473 r56566  
    4949    CRDLMContextState *listState = (CRDLMContextState *)tsd;
    5050
    51     if (listState) {
    52         if (listState->currentListInfo) {
    53             crdlm_free_list(listState->currentListInfo);
    54         }
    55 
    56         crFree(listState);
     51    if (listState)
     52    {
     53        //if (listState->currentListInfo)
     54        //    crdlm_free_list(listState->currentListInfo);
     55
     56        crFree(listState);
    5757    }
    5858}
     
    144144 * itself when no one is still using the DLM.
    145145 */
    146 void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm)
     146void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm, SPUDispatchTable *dispatchTable)
    147147{
    148148    /* We're about to change the displayLists hash; lock it first */
     
    157157    if (dlm->userCount == 0) {
    158158
    159         /* Free the set of display lists.  As each one is freed, the
    160          * crdlm_free_list function will be called to free up its
    161          * internal resources.  The crdlm_free_list() routine is
    162          * cast to a (void *) to avoid warnings about being an
    163          */
    164         crFreeHashtable(dlm->displayLists, crdlm_free_list);
     159        crFreeHashtableEx(dlm->displayLists, crdlmFreeDisplayListResourcesCb, dispatchTable);
    165160        dlm->displayLists = NULL;
    166161
     
    269264 */
    270265
    271 void DLM_APIENTRY crDLMFreeContext(CRDLMContextState *state)
    272 {
    273         CRDLMContextState *listState = CURRENT_STATE();
    274 
    275         /* If we're currently using this context, release it first */
    276         if (listState == state) {
    277                 crDLMSetCurrentState(NULL);
    278         }
    279 
    280         /* Try to free the DLM.  This will either decrement the use count,
    281          * or will actually free the DLM, if we were the last user.
    282          */
    283         crDLMFreeDLM(state->dlm);
    284         state->dlm = NULL;
    285 
    286         /* If any buffers still remain (e.g. because there was an open
    287          * display list), remove those as well.
    288          */
    289         if (state->currentListInfo) {
    290                 crdlm_free_list((void *)state->currentListInfo);
    291         }
    292         state->currentListInfo = NULL;
    293         state->currentListIdentifier = 0;
    294 
    295         /* Free the state record itself */
    296         crFree(state);
     266void DLM_APIENTRY crDLMFreeContext(CRDLMContextState *state, SPUDispatchTable *dispatchTable)
     267{
     268    CRDLMContextState *listState = CURRENT_STATE();
     269
     270    /* If we're currently using this context, release it first */
     271    if (listState == state)
     272        crDLMSetCurrentState(NULL);
     273
     274    /* Try to free the DLM.  This will either decrement the use count,
     275     * or will actually free the DLM, if we were the last user.
     276     */
     277    crDLMFreeDLM(state->dlm, dispatchTable);
     278    state->dlm = NULL;
     279
     280    /* If any buffers still remain (e.g. because there was an open
     281     * display list), remove those as well.
     282     */
     283    if (state->currentListInfo)
     284    {
     285        crdlmFreeDisplayListResourcesCb((void *)state->currentListInfo, (void *)dispatchTable);
     286        state->currentListInfo = NULL;
     287    }
     288    state->currentListIdentifier = 0;
     289
     290    /* Free the state record itself */
     291    crFree(state);
    297292}
    298293
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h

    r54905 r56566  
    2626 */
    2727extern void crdlmWarning( int line, char *file, GLenum error, char *format, ... );
    28 extern void crdlm_free_list(/* DLMListInfo * */ void *listInfo);
     28extern void crdlmFreeDisplayListResourcesCb(void *pParm1, void *pParam2);
    2929extern void crdlm_error(int line, const char *file, GLenum error, const char *info);
    3030
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c

    r54905 r56566  
    11/* $Id$ */
     2#if 0
     3
    24#include <stdio.h>
    35#include "cr_spu.h"
     
    6264        crdlm_add_to_list((DLMInstanceList *)instance, executeCallLists);
    6365}
     66
     67#endif
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py

    r56473 r56566  
    1616        ('CRDLM DLM_APIENTRY *', 'crDLMNewDLM', 'unsigned int configSize, const CRDLMConfig *config'),
    1717        ('CRDLMContextState DLM_APIENTRY *', 'crDLMNewContext', 'CRDLM *dlm'),
    18         ('void DLM_APIENTRY', 'crDLMFreeContext', 'CRDLMContextState *state'),
     18        ('void DLM_APIENTRY', 'crDLMFreeContext', 'CRDLMContextState *state, SPUDispatchTable *dispatchTable'),
    1919        ('void DLM_APIENTRY', 'crDLMUseDLM', 'CRDLM *dlm'),
    20         ('void DLM_APIENTRY','crDLMFreeDLM', 'CRDLM *dlm'),
     20        ('void DLM_APIENTRY','crDLMFreeDLM', 'CRDLM *dlm, SPUDispatchTable *dispatchTable'),
    2121        ('void DLM_APIENTRY', 'crDLMSetCurrentState', 'CRDLMContextState *state'),
    2222        ('CRDLMContextState DLM_APIENTRY *', 'crDLMGetCurrentState', 'void'),
     
    4242        ('GLenum DLM_APIENTRY', 'crDLMGetCurrentMode', 'void'),
    4343        ('void DLM_APIENTRY', 'crDLMErrorFunction', 'CRDLMErrorCallback callback'),
    44         ('void DLM_APIENTRY', 'crDLMNewList', 'GLuint listIdentifier, GLenum mode'),
    45         ('void DLM_APIENTRY', 'crDLMEndList', 'void'),
    46         ('void DLM_APIENTRY', 'crDLMDeleteLists', 'GLuint firstListIdentifier, GLsizei range'),
    47         ('GLboolean DLM_APIENTRY', 'crDLMIsList', 'GLuint list'),
    48         ('GLuint DLM_APIENTRY', 'crDLMGenLists', 'GLsizei range'),
    49         ('void DLM_APIENTRY', 'crDLMListBase', 'GLuint base'),
     44        ('void DLM_APIENTRY', 'crDLMNewList', 'GLuint list, GLenum mode, SPUDispatchTable *dispatchTable'),
     45        ('void DLM_APIENTRY', 'crDLMEndList', 'SPUDispatchTable *dispatchTable'),
     46        ('void DLM_APIENTRY', 'crDLMCallList', 'GLuint list, SPUDispatchTable *dispatchTable'),
     47        ('void DLM_APIENTRY', 'crDLMCallLists', 'GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable'),
     48        ('void DLM_APIENTRY', 'crDLMDeleteLists', 'GLuint list, GLsizei range, SPUDispatchTable *dispatchTable'),
     49        ('void DLM_APIENTRY', 'crDLMListBase', 'GLuint base, SPUDispatchTable *dispatchTable'),
     50        ('GLboolean DLM_APIENTRY', 'crDLMIsList', 'GLuint list, SPUDispatchTable *dispatchTable'),
     51        ('GLuint DLM_APIENTRY', 'crDLMGenLists', 'GLsizei range, SPUDispatchTable *dispatchTable'),
    5052        ('int32_t DLM_APIENTRY', 'crDLMSaveState', 'void'),
    5153        #('void DLM_APIENTRY', 'crDLMListSent', 'CRDLM *dlm, unsigned long listIdentifier'),
     
    115117        CRDLMBounds bbox;
    116118        GLboolean listSent;
     119        GLuint hwid;
    117120} DLMListInfo;
    118121
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c

    r56473 r56566  
    11/* $Id$ */
     2
     3/** @file
     4 * Implementation of all the Display Lists related routines:
     5 *
     6 *   glGenLists, glDeleteLists, glNewList, glEndList, glCallList, glCallLists,
     7 *   glListBase and glIsList.
     8 *
     9 * Privide OpenGL IDs mapping between host and guest.
     10 */
     11
     12/*
     13 * Copyright (C) 2015 Oracle Corporation
     14 *
     15 * This file is part of VirtualBox Open Source Edition (OSE), as
     16 * available from http://www.virtualbox.org. This file is free software;
     17 * you can redistribute it and/or modify it under the terms of the GNU
     18 * General Public License (GPL) as published by the Free Software
     19 * Foundation, in version 2 as it comes in the "COPYING" file of the
     20 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     21 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
     22 */
     23
    224#include <float.h>
    325#include "cr_dlm.h"
     
    628
    729
    8 
    9 /* This file defines the display list functions such as NewList, EndList,
    10  * IsList, DeleteLists, etc.
    11  * Generally, SPUs will call these as needed to implement display lists.
    12  * See the expando, replicate, and tilesort SPUs for examples.
    13  *
    14  * The functions which compile GL functions into our display lists are named:
    15  *     void DLM_APIENTRY crdlm_<function name>
    16  * where <function_name> is the Chromium function name (which in
    17  * turn is the GL function name with the "gl" prefix removed).
    18  *
    19  * All these entry points require that a CRDLMContextState structure
    20  * be created (with crDLMNewContext()) and assigned to the current
    21  * thread (with crDLMSetCurrentState()).
    22  */
    23 
    24 
    25 /*
    26  * Begin compiling a list.
     30/**
     31 * Destroy each list entry.
     32 */
     33static void crdlmFreeDisplayListElements(DLMInstanceList *instance)
     34{
     35    while (instance)
     36    {
     37        DLMInstanceList *nextInstance = instance->next;
     38        crFree(instance);
     39        instance = nextInstance;
     40    }
     41}
     42
     43
     44/**
     45 * A callback routine used when iterating over all
     46 * available lists in order to remove them.
     47 *
     48 * NOTE: @param pParam2 might be NULL.
     49 */
     50void crdlmFreeDisplayListResourcesCb(void *pParm1, void *pParam2)
     51{
     52    DLMListInfo      *pListInfo     = (DLMListInfo *)pParm1;
     53    SPUDispatchTable *dispatchTable = (SPUDispatchTable *)pParam2;
     54
     55    if (pListInfo)
     56    {
     57        crdlmFreeDisplayListElements(pListInfo->first);
     58        pListInfo->first = pListInfo->last = NULL;
     59
     60        /* The references list has no allocated information; it's
     61         * just a set of entries.  So we don't need to free any
     62         * information as each entry is deleted.
     63         */
     64        crFreeHashtable(pListInfo->references, NULL);
     65
     66        /* Free host OpenGL resources. */
     67        if (dispatchTable)
     68            dispatchTable->DeleteLists(pListInfo->hwid, 1);
     69
     70        crFree(pListInfo);
     71    }
     72}
     73
     74
     75/**
     76 * Generate host and guest IDs, setup IDs mapping between host and guest.
     77 */
     78GLuint DLM_APIENTRY crDLMGenLists(GLsizei range, SPUDispatchTable *dispatchTable)
     79{
     80    CRDLMContextState *listState = CURRENT_STATE();
     81    GLuint             idHostRangeStart = 0;
     82    GLuint             idGuestRangeStart = 0;
     83
     84    crDebug("DLM: GenLists(%d) (DLM=%p).", range, listState ? listState->dlm : 0);
     85
     86    if (listState)
     87    {
     88        idHostRangeStart = dispatchTable->GenLists(range);
     89        if (idHostRangeStart > 0)
     90        {
     91            idGuestRangeStart = crHashtableAllocKeys(listState->dlm->displayLists, range);
     92            if (idGuestRangeStart > 0)
     93            {
     94                GLuint i;
     95                bool fSuccess = true;
     96
     97                /* Now have successfully generated IDs range for host and guest. Let's make IDs association. */
     98                for (i = 0; i < (GLuint)range; i++)
     99                {
     100                    DLMListInfo *pListInfo;
     101
     102                    pListInfo = (DLMListInfo *)crCalloc(sizeof(DLMListInfo));
     103                    if (pListInfo)
     104                    {
     105                        crMemset(pListInfo, 0, sizeof(DLMListInfo));
     106                        pListInfo->hwid = idHostRangeStart + i;
     107
     108                        /* Insert pre-initialized list data which contains IDs mapping into the hash. */
     109                        crHashtableReplace(listState->dlm->displayLists, idGuestRangeStart + i, pListInfo, NULL);
     110                    }
     111                    else
     112                    {
     113                        fSuccess = false;
     114                        break;
     115                    }
     116                }
     117
     118                /* All structures allocated and initialized successfully. */
     119                if (fSuccess)
     120                    return idGuestRangeStart;
     121
     122                /* Rollback some data was not allocated. */
     123                crDLMDeleteLists(idGuestRangeStart, range, NULL /* we do DeleteLists() later in this routine */ );
     124            }
     125            else
     126                crDebug("DLM: Can't allocate Display List IDs range for the guest.");
     127
     128            dispatchTable->DeleteLists(idHostRangeStart, range);
     129        }
     130        else
     131            crDebug("DLM: Can't allocate Display List IDs range on the host side.");
     132    }
     133    else
     134        crDebug("DLM: GenLists(%u) called with no current state.", range);
     135
     136    /* Can't reserve IDs range.  */
     137    return 0;
     138}
     139
     140
     141/**
     142 * Release host and guest IDs, free memory resources.
     143 */
     144void DLM_APIENTRY crDLMDeleteLists(GLuint list, GLsizei range, SPUDispatchTable *dispatchTable)
     145{
     146    CRDLMContextState *listState = CURRENT_STATE();
     147
     148    crDebug("DLM: DeleteLists(%u, %d) (DLM=%p).", list, range, listState ? listState->dlm : 0);
     149
     150    if (listState)
     151    {
     152        if (range >= 0)
     153        {
     154            int i;
     155
     156            /* Free resources: host memory, host IDs and guest IDs. */
     157            DLM_LOCK(listState->dlm)
     158            for (i = 0; i < range; i++)
     159                crHashtableDeleteEx(listState->dlm->displayLists, list + i, crdlmFreeDisplayListResourcesCb, dispatchTable);
     160            DLM_UNLOCK(listState->dlm)
     161        }
     162        else
     163            crDebug("DLM: DeleteLists(%u, %d) not allowed.", list, range);
     164    }
     165    else
     166        crDebug("DLM: DeleteLists(%u, %d) called with no current state.", list, range);
     167}
     168
     169
     170/**
     171 * Start recording a list.
    27172 */
    28173void DLM_APIENTRY
    29 crDLMNewList(GLuint listIdentifier, GLenum mode)
    30 {
    31     DLMListInfo *listInfo;
    32     CRDLMContextState *listState = CURRENT_STATE();
    33 
    34     /* Error checks: 0 is not a valid identifier, and
    35      * we can't call NewList if NewList has been called
    36      * more recently than EndList.
    37      *
    38      * The caller is expected to check for an improper
    39      * mode parameter (GL_INVALID_ENUM), or for a NewList
    40      * within a glBegin/glEnd (GL_INVALID_OPERATION).
    41      */
    42     if (listState == NULL)
    43     {
    44         crWarning("DLM error: NewList(%d,%d) called with no current state (%s line %d)\n",
    45             (int) listIdentifier, (int) mode, __FILE__, __LINE__);
    46         return;
    47     }
    48 
    49     if (listIdentifier == 0)
    50     {
    51         crdlm_error(__LINE__, __FILE__, GL_INVALID_VALUE,
    52              "NewList called with a list identifier of 0");
    53         return;
    54     }
    55 
    56     if (listState->currentListInfo != NULL)
    57     {
    58         char msg[1000];
    59         sprintf(msg, "NewList called with display list %d while display list %d was already open",
    60             (int) listIdentifier, (int) listState->currentListIdentifier);
    61         crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION, msg);
    62         return;
    63     }
    64 
    65     listInfo = (DLMListInfo *) crCalloc(sizeof(DLMListInfo));
    66     if (!(listInfo))
    67     {
    68         char msg[1000];
    69         sprintf(msg, "could not allocate %u bytes of memory in NewList",
    70             (unsigned) sizeof(DLMListInfo));
    71         crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY, msg);                                                                 
    72         return;
    73     }
    74 
    75     listInfo->first = listInfo->last = NULL;
    76     listInfo->stateFirst = listInfo->stateLast = NULL;
    77     listInfo->references = crAllocHashtable();
    78     if (!(listInfo->references))
    79     {
    80         crFree(listInfo);
    81         crdlm_error(__LINE__, __FILE__, GL_OUT_OF_MEMORY,
    82             "could not allocate memory in NewList");
    83         return;
    84     }
    85     listInfo->numInstances = 0;
    86     listInfo->listSent = GL_FALSE;
    87     listInfo->bbox.xmin = FLT_MAX;
    88     listInfo->bbox.xmax = -FLT_MAX;
    89     listInfo->bbox.ymin = FLT_MAX;
    90     listInfo->bbox.ymax = -FLT_MAX;
    91     listInfo->bbox.zmin = FLT_MAX;
    92     listInfo->bbox.zmax = -FLT_MAX;
    93 
    94     listState->currentListInfo = listInfo;
    95     listState->currentListIdentifier = listIdentifier;
    96     listState->currentListMode = mode;
    97 
    98     crDebug("Display Lists: create new with guest ID %u.", listIdentifier);
    99 }
    100 
    101 
    102 /* This small utility routine is used to traverse a buffer
    103  * list, freeing each buffer.  It is used to free the buffer
    104  * list in the DLMListInfo structure, both when freeing the
    105  * entire structure and when freeing just the retained content.
    106  */
    107 static void free_instance_list(DLMInstanceList * instance)
    108 {
    109         while (instance)
    110         {
    111                 DLMInstanceList *nextInstance = instance->next;
    112                 crFree(instance);
    113                 instance = nextInstance;
    114         }
    115 }
    116 
    117 /* This utility routine frees a DLMListInfo structure and all
    118  * of its components.  It is used directly, when deleting a
    119  * single list; it is also used as a callback function for
    120  * hash tree operations (Free and Replace).
    121  *
    122  * The parameter is listed as a (void *) instead of a (DLMListInfo *)
    123  * in order that the function can be used as a callback routine for
    124  * the hash table functions.  The (void *) designation causes no
    125  * other harm, save disabling type-checking on the pointer argument
    126  * of the function.
    127  */
    128 void crdlm_free_list(void *parm)
    129 {
    130         DLMListInfo *listInfo = (DLMListInfo *) parm;
    131 
    132         free_instance_list(listInfo->first);
    133         listInfo->first = listInfo->last = NULL;
    134 
    135         /* The references list has no allocated information; it's
    136          * just a set of entries.  So we don't need to free any
    137          * information as each entry is deleted.
    138          */
    139         crFreeHashtable(listInfo->references, NULL);
    140 
    141         crFree(listInfo);
    142 }
    143 
    144 
    145 void DLM_APIENTRY crDLMEndList(void)
    146 {
    147     CRDLMContextState *listState = CURRENT_STATE();
    148 
    149     /* Error check: cannot call EndList without a (successful)
    150      * preceding NewList.
    151      *
    152      * The caller is expected to check for glNewList within
    153      * a glBegin/glEnd sequence.
    154      */
    155     if (listState == NULL)
    156     {
    157         crWarning("DLM error: EndList called with no current state (%s line %d)\n",
    158             __FILE__, __LINE__);
    159         return;
    160     }
    161     if (listState->currentListInfo == NULL)
    162     {
    163         crdlm_error(__LINE__, __FILE__, GL_INVALID_OPERATION,
    164             "EndList called while no display list was open");
    165         return;
    166     }
    167 
    168     DLM_LOCK(listState->dlm)
    169 
    170     /* This function will either replace the list information that's
    171      * already present with our new list information, freeing the
    172      * former list information; or will add the new information
    173      * to the set of display lists, depending on whether the
    174      * list already exists or not.
    175      */
    176     crHashtableReplace(listState->dlm->displayLists,
    177         listState->currentListIdentifier,
    178         listState->currentListInfo, crdlm_free_list);
    179 
    180     DLM_UNLOCK(listState->dlm)
    181 
    182     /* reset the current state to show the list had been ended */
    183     listState->currentListIdentifier = 0;
    184     listState->currentListInfo = NULL;
    185     listState->currentListMode = GL_FALSE;
    186 }
    187 
    188 
    189 void DLM_APIENTRY crDLMDeleteLists(GLuint firstListIdentifier, GLsizei range)
    190 {
    191         CRDLMContextState *listState = CURRENT_STATE();
    192         register int i;
    193 
    194         if (listState == NULL)
    195         {
    196                 crWarning
    197                         ("DLM error: DeleteLists(%d,%d) called with no current state (%s line %d)\n",
    198                          (int) firstListIdentifier, (int) range, __FILE__, __LINE__);
    199                 return;
    200         }
    201         if (range < 0)
    202         {
    203                 char msg[1000];
    204                 sprintf(msg, "DeleteLists called with range (%d) less than zero", (int) range);
    205                 crdlm_error(__LINE__, __FILE__, GL_INVALID_VALUE, msg);                                                         
    206                 return;
    207         }
    208 
    209         /* Interestingly, there doesn't seem to be an error for deleting
    210          * display list 0, which cannot exist.
    211          *
    212          * We could delete the desired lists by walking the entire hash of
    213          * display lists and looking for and deleting any in our range; or we
    214          * could delete lists one by one.  The former is faster if the hashing
    215          * algorithm is inefficient or if we're deleting all or most of our
    216          * lists; the latter is faster if we're deleting a relatively small
    217          * number of lists.
    218          *
    219          * For now, we'll go with the latter; it's also easier to implement
    220          * given the current functions available.
    221          */
    222         DLM_LOCK(listState->dlm)
    223         for (i = 0; i < range; i++)
    224         {
    225                 crHashtableDelete(listState->dlm->displayLists,
    226                                   firstListIdentifier + i, crdlm_free_list);
    227         }
    228         DLM_UNLOCK(listState->dlm)
    229 }
    230 
    231 GLboolean DLM_APIENTRY crDLMIsList(GLuint list)
    232 {
    233         CRDLMContextState *listState = CURRENT_STATE();
    234 
    235         if (listState == NULL)
    236         {
    237                 crWarning
    238                         ("DLM error: IsLists(%d) called with no current state (%s line %d)\n",
    239                          (int) list, __FILE__, __LINE__);
    240                 return 0;
    241         }
    242 
    243         if (list == 0)
    244                 return GL_FALSE;
    245 
    246         return crHashtableIsKeyUsed(listState->dlm->displayLists, list);
    247 }
    248 
    249 GLuint DLM_APIENTRY crDLMGenLists(GLsizei range)
    250 {
    251         CRDLMContextState *listState = CURRENT_STATE();
    252 
    253         if (listState == NULL)
    254         {
    255                 crWarning
    256                         ("DLM error: GenLists(%d) called with no current state (%s line %d)\n",
    257                          (int) range, __FILE__, __LINE__);
    258                 return 0;
    259         }
    260 
    261         return crHashtableAllocKeys(listState->dlm->displayLists, range);
    262 }
    263 
    264 void DLM_APIENTRY crDLMListBase( GLuint base )
    265 {
    266         CRDLMContextState *listState = CURRENT_STATE();
    267 
    268         if (listState == NULL)
    269         {
    270                 crWarning
    271                         ("DLM error: ListBase(%d) called with no current state (%s line %d)\n",
    272                          (int) base, __FILE__, __LINE__);
    273                 return;
    274         }
    275 
    276         listState->listBase = base;
    277 }
     174crDLMNewList(GLuint list, GLenum mode, SPUDispatchTable *dispatchTable)
     175{
     176    DLMListInfo       *listInfo;
     177    CRDLMContextState *listState = CURRENT_STATE();
     178
     179    crDebug("DLM: NewList(%u, %u) (DLM=%p).", list, mode, listState ? listState->dlm : 0);
     180
     181    if (listState)
     182    {
     183        /* Valid list ID should be > 0. */
     184        if (list > 0)
     185        {
     186            if (listState->currentListInfo == NULL)
     187            {
     188                listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, list);
     189                if (listInfo)
     190                {
     191                    listInfo->first = listInfo->last = NULL;
     192                    listInfo->stateFirst = listInfo->stateLast = NULL;
     193                    listInfo->references = crAllocHashtable();
     194                    if (listInfo->references)
     195                    {
     196                        listInfo->numInstances = 0;
     197                        listInfo->listSent = GL_FALSE;
     198                        listInfo->bbox.xmin = FLT_MAX;
     199                        listInfo->bbox.xmax = -FLT_MAX;
     200                        listInfo->bbox.ymin = FLT_MAX;
     201                        listInfo->bbox.ymax = -FLT_MAX;
     202                        listInfo->bbox.zmin = FLT_MAX;
     203                        listInfo->bbox.zmax = -FLT_MAX;
     204
     205                        listState->currentListInfo = listInfo;
     206                        listState->currentListIdentifier = list;
     207                        listState->currentListMode = mode;
     208
     209                        dispatchTable->NewList(listInfo->hwid, mode);
     210
     211                        crDebug("DLM: create new list with [guest, host] ID pair [%u, %u].", list, listInfo->hwid);
     212
     213                        return;
     214                    }
     215                    else
     216                        crDebug("DLM: Could not allocate memory in NewList.");
     217                }
     218                else
     219                    crDebug("DLM: Requested Display List %u was not previously reserved with glGenLists().", list);
     220            }
     221            else
     222                crDebug("DLM: NewList called with display list %u while display list %u was already open.", list, listState->currentListIdentifier);
     223        }
     224        else
     225            crDebug("DLM: NewList called with a list identifier of 0.");
     226    }
     227    else
     228        crDebug("DLM: NewList(%u, %u) called with no current state.\n", list, mode);
     229}
     230
     231
     232/**
     233 * Stop recording a list.
     234 */
     235void DLM_APIENTRY crDLMEndList(SPUDispatchTable *dispatchTable)
     236{
     237    CRDLMContextState *listState = CURRENT_STATE();
     238
     239    crDebug("DLM: EndList() (DLM=%p).", listState ? listState->dlm : 0);
     240
     241    if (listState)
     242    {
     243        /* Check if list was ever started. */
     244        if (listState->currentListInfo)
     245        {
     246            /* reset the current state to show the list had been ended */
     247            listState->currentListIdentifier = 0;
     248            listState->currentListInfo = NULL;
     249            listState->currentListMode = GL_FALSE;
     250
     251            dispatchTable->EndList();
     252        }
     253        else
     254            crDebug("DLM: glEndList() is assuming glNewList() was issued previously.");
     255    }
     256    else
     257        crDebug("DLM: EndList called with no current state.");
     258}
     259
     260
     261/**
     262 * Execute list on hardware and cach ethis call if we currently recording a list.
     263 */
     264void DLM_APIENTRY crDLMCallList(GLuint list, SPUDispatchTable *dispatchTable)
     265{
     266    CRDLMContextState *listState = CURRENT_STATE();
     267
     268    //crDebug("DLM: CallList(%u).", list);
     269
     270    if (listState)
     271    {
     272        DLMListInfo *listInfo;
     273
     274        /* Add to calls cache if we recording a list. */
     275        if (listState->currentListInfo)
     276            crDLMCompileCallList(list);
     277
     278        /* Find hwid for list. */
     279        listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, list);
     280        if (listInfo)
     281            dispatchTable->CallList(listInfo->hwid);
     282        else
     283            crDebug("DLM: CallList(%u) issued for non-existent list.", list);
     284    }
     285    else
     286        crDebug("DLM: CallList(%u) called with no current state.", list);
     287}
     288
     289
     290/* Helper for crDLMCallLists().
     291 * We need to extract list ID by index from array of given type and cast it to GLuint.
     292 * Please replece it w/ something more elegant if better solution will be found!
     293 */
     294inline GLuint crDLMGetListByIndex(const GLvoid *aValues, GLsizei index, GLenum type)
     295{
     296    GLuint element = 0;
     297
     298    switch (type)
     299    {
     300#define CRDLM_LIST_BY_INDEX_HANDLE_TYPE(_type_name, _size_of_type) \
     301        case _type_name: \
     302        { \
     303            crMemcpy((void *)&element, (void *)((void *)(aValues) + (index * (_size_of_type))) \
     304            , (_size_of_type)); \
     305            break; \
     306        }
     307
     308        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_BYTE,            sizeof(GLbyte));
     309        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_UNSIGNED_BYTE,   sizeof(GLubyte));
     310        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_SHORT,           sizeof(GLshort));
     311        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_UNSIGNED_SHORT,  sizeof(GLushort));
     312        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_INT,             sizeof(GLint));
     313        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_UNSIGNED_INT,    sizeof(GLuint));
     314        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_FLOAT,           sizeof(GLfloat));
     315        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_2_BYTES,         2);
     316        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_3_BYTES,         3);
     317        CRDLM_LIST_BY_INDEX_HANDLE_TYPE(GL_4_BYTES,         4);
     318
     319        default:
     320            crError("DLM: attempt to pass to crDLMCallLists() unknown type: %u.", index);
     321
     322#undef CRDLM_LIST_BY_INDEX_HANDLE_TYPE
     323    }
     324
     325    return element;
     326}
     327
     328/**
     329 * Execute lists on hardware and cach ethis call if we currently recording a list.
     330 */
     331void DLM_APIENTRY crDLMCallLists(GLsizei n, GLenum type, const GLvoid *lists, SPUDispatchTable *dispatchTable)
     332{
     333    CRDLMContextState *listState = CURRENT_STATE();
     334
     335    crDebug("DLM: CallLists(%d, %u, %p).", n, type, lists);
     336
     337    if (listState)
     338    {
     339        GLsizei i;
     340
     341        /* Add to calls cache if we recording a list. */
     342        if (listState->currentListInfo)
     343            crDLMCompileCallLists(n, type, lists);
     344
     345        /* This is sad, but we need to translate guest IDs into host ones.
     346         * Since spec does not promise that @param lists conain contiguous set of IDs,
     347         * the only way to do that is to iterate over each guest ID and perform translation.
     348         * This might have negative performance impact. */
     349        for (i = 0; i < n; i++)
     350        {
     351            DLMListInfo *listInfo;
     352            GLuint guest_id = crDLMGetListByIndex(lists, n, type);
     353
     354            if (guest_id > 0)
     355            {
     356                listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, guest_id);
     357                if (listInfo)
     358                    dispatchTable->CallList(listInfo->hwid);
     359                else
     360                    crDebug("DLM: CallLists(%d, %u, %p) was unabbe to resolve host ID for guest ID %u.", n, type, lists, guest_id);
     361            }
     362            else
     363                crDebug("DLM: CallLists(%d, %u, %p) received bad array of IDs.", n, type, lists);
     364        }
     365    }
     366    else
     367        crDebug("DLM: CallLists(%d, %u, %p) called with no current state.", n, type, lists);
     368}
     369
     370
     371/**
     372 * Set list base, remember its value and add call to the cache.
     373 */
     374void DLM_APIENTRY crDLMListBase(GLuint base, SPUDispatchTable *dispatchTable)
     375{
     376    CRDLMContextState *listState = CURRENT_STATE();
     377
     378    crDebug("DLM: ListBase(%u).", base);
     379
     380    if (listState)
     381    {
     382        listState->listBase = base;
     383        crDLMCompileListBase(base);
     384        dispatchTable->ListBase(base);
     385    }
     386    else
     387        crDebug("DLM: ListBase(%u) called with no current state.", base);
     388}
     389
     390
     391/**
     392 * Check if specified list ID belongs to valid Display List.
     393 * Positive result is only returned in case both conditions below are satisfied:
     394 *
     395 *   - given list found in DLM hash table (i.e., it was previously allocated
     396 *     with crDLMGenLists and still not released with crDLMDeleteLists);
     397 *
     398 *   - list is valid on the host side.
     399 */
     400GLboolean DLM_APIENTRY crDLMIsList(GLuint list, SPUDispatchTable *dispatchTable)
     401{
     402    CRDLMContextState *listState = CURRENT_STATE();
     403
     404    crDebug("DLM: IsList(%u).", list);
     405
     406    if (listState)
     407    {
     408        if (list > 0)
     409        {
     410            DLMListInfo *listInfo = (DLMListInfo *)crHashtableSearch(listState->dlm->displayLists, list);
     411            if (listInfo)
     412            {
     413                if (dispatchTable->IsList(listInfo->hwid))
     414                    return true;
     415                else
     416                    crDebug("DLM: list [%u, %u] not found on the host side.", list, listInfo->hwid);
     417            }
     418            else
     419                crDebug("DLM: list %u not found in guest cache.", list);
     420        }
     421        else
     422            crDebug("DLM: IsList(%u) is not allowed.", list);
     423    }
     424    else
     425        crDebug("DLM: IsList(%u) called with no current state.", list);
     426
     427    return false;
     428}
  • trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_special

    r54905 r56566  
    1111# inside display lists, we can manage state updates for
    1212# these sorts of elements.
    13 CallList
    14 CallLists
     13#CallList
     14#CallLists
    1515
    1616# Calls to be ignored.
  • trunk/src/VBox/HostServices/SharedOpenGL/expando/expando_special

    r54905 r56566  
    66DeleteLists
    77GenLists
     8ListBase
    89IsList
    910CallList
  • trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c

    r54905 r56566  
    11/* $Id$ */
     2/** @file
     3 * Implementation of routines which Expando SPU explicitly overrides.
     4 */
     5
    26/* Copyright (c) 2001, Stanford University
    37 * All rights reserved
    48 *
    59 * See the file LICENSE.txt for information on redistributing this software.
     10 */
     11
     12
     13/*
     14 * Copyright (C) 2015 Oracle Corporation
     15 *
     16 * This file is part of VirtualBox Open Source Edition (OSE), as
     17 * available from http://www.virtualbox.org. This file is free software;
     18 * you can redistribute it and/or modify it under the terms of the GNU
     19 * General Public License (GPL) as published by the Free Software
     20 * Foundation, in version 2 as it comes in the "COPYING" file of the
     21 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
     22 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    623 */
    724
     
    1532expandoCreateContext(const char *displayName, GLint visBits, GLint shareCtx)
    1633{
    17         ExpandoContextState *contextState;
    18         GLint contextId;
     34    ExpandoContextState *contextState;
    1935
    20         /* Allocate our own per-context record */
    21         contextState = crCalloc(sizeof(ExpandoContextState));
    22         if (contextState == NULL) {
    23             crError("expando: couldn't allocate per-context state");
    24             return 0;
    25         }
     36    /* Allocate our own per-context record */
     37    contextState = crCalloc(sizeof(ExpandoContextState));
     38    if (contextState)
     39    {
     40        GLint contextId;
    2641
    27         /* Get an official context ID from our super */
    28         contextId = expando_spu.super.CreateContext(displayName, visBits, shareCtx);
     42        /* Get an official context ID from our super */
     43        contextId = expando_spu.super.CreateContext(displayName, visBits, shareCtx);
    2944
    30         /* Supplement that with our DLM.  In a more correct situation, we should
    31          * see if we've been called through glXCreateContext, which has a parameter
    32          * for sharing DLMs.  We don't currently get that information, so for now
    33          * give each context its own DLM.
    34          */
    35         contextState->dlm = crDLMNewDLM(0, NULL);
    36         if (!contextState->dlm) {
    37                 crError("expando: couldn't get DLM!");
    38         }
     45        /* Supplement that with our DLM.  In a more correct situation, we should
     46         * see if we've been called through glXCreateContext, which has a parameter
     47         * for sharing DLMs.  We don't currently get that information, so for now
     48         * give each context its own DLM.
     49         */
     50        contextState->dlm = crDLMNewDLM(0, NULL);
     51        if (contextState->dlm)
     52        {
     53            contextState->dlmContext = crDLMNewContext(contextState->dlm);
     54            if (contextState->dlmContext)
     55            {
     56                /* The DLM needs us to use the state tracker to track client
     57                 * state, so we can compile client-state-using functions correctly.
     58                 */
     59                contextState->State = crStateCreateContext(NULL, visBits, NULL);
    3960
    40         contextState->dlmContext = crDLMNewContext(contextState->dlm);
    41         if (!contextState->dlmContext) {
    42                 crError("expando: couldn't get dlmContext");
    43         }
     61                /* Associate the Expando context with the user context. */
     62                crHashtableAdd(expando_spu.contextTable, contextId, (void *)contextState);
    4463
    45         /* The DLM needs us to use the state tracker to track client
    46          * state, so we can compile client-state-using functions correctly.
    47          */
    48         contextState->State = crStateCreateContext(NULL, visBits, NULL);
     64                crDebug("Expando SPU: created context %d (contextState=%p, contextState->dlm=%p, "
     65                        "contextState->dlmContext=%p, contextState->State=%p).",
     66                        contextId, contextState, contextState->dlm, contextState->dlmContext, contextState->State);
    4967
    50         /* Associate the Expando context with the user context. */
    51         crHashtableAdd(expando_spu.contextTable, contextId, (void *)contextState);
     68                return contextId;
     69            }
     70            else
     71                crError("Expando SPU: can't allocate new DLM context.");
    5272
    53         return contextId;
     73            crDLMFreeDLM(contextState->dlm, &expando_spu.super);
     74        }
     75        else
     76            crError("Expando SPU: can't allocate new DLM.");
     77
     78        crFree(contextState);
     79    }
     80    else
     81        crError("Expando SPU: couldn't allocate per-context state");
     82
     83    return 0;
    5484}
    5585
    5686void expando_free_context_state(void *data)
    5787{
    58     ExpandoContextState *expandoContextState = (ExpandoContextState *)data;
     88    ExpandoContextState *contextState = (ExpandoContextState *)data;
    5989
    60     crDLMFreeContext(expandoContextState->dlmContext);
    61     crDLMFreeDLM(expandoContextState->dlm);
    62     crStateDestroyContext(expandoContextState->State);
    63     crFree(expandoContextState);
     90    crDebug("Expando SPU: destroying context internals: "
     91            "contextState=%p, contextState->dlm=%p, contextState->dlmContext=%p, contextState->State=%p",
     92            contextState, contextState->dlm, contextState->dlmContext, contextState->State);
     93
     94    crDLMFreeContext(contextState->dlmContext, &expando_spu.super);
     95    crDLMFreeDLM(contextState->dlm, &expando_spu.super);
     96    crStateDestroyContext(contextState->State);
     97    crFree(contextState);
    6498}
    6599
    66 extern void EXPANDOSPU_APIENTRY
     100void EXPANDOSPU_APIENTRY
    67101expandoDestroyContext(GLint contextId)
    68102{
    69         /* Destroy our context information */
    70         crHashtableDelete(expando_spu.contextTable, contextId,
    71                                 expando_free_context_state);
     103    crDebug("Expando SPU: destroy context %d.", contextId);
    72104
    73         /* Pass along the destruction to our super. */
    74         expando_spu.super.DestroyContext(contextId);
     105    /* Destroy our context information */
     106    crHashtableDelete(expando_spu.contextTable, contextId, expando_free_context_state);
     107
     108    /* Pass along the destruction to our super. */
     109    expando_spu.super.DestroyContext(contextId);
    75110}
    76111
    77 extern void EXPANDOSPU_APIENTRY
     112void EXPANDOSPU_APIENTRY
    78113expandoMakeCurrent(GLint crWindow, GLint nativeWindow, GLint contextId)
    79114{
    80         ExpandoContextState *expandoContextState;
     115    ExpandoContextState *expandoContextState;
    81116
    82         expando_spu.super.MakeCurrent(crWindow, nativeWindow, contextId);
     117    expando_spu.super.MakeCurrent(crWindow, nativeWindow, contextId);
    83118
    84         expandoContextState = crHashtableSearch(expando_spu.contextTable, contextId);
    85         if (expandoContextState) {
    86             crDLMSetCurrentState(expandoContextState->dlmContext);
    87             crStateMakeCurrent(expandoContextState->State);
    88         }
    89         else {
    90             crDLMSetCurrentState(NULL);
    91             crStateMakeCurrent(NULL);
    92         }
     119    expandoContextState = crHashtableSearch(expando_spu.contextTable, contextId);
     120    if (expandoContextState)
     121    {
     122        crDebug("Expando SPU: switch to context %d.", contextId);
     123
     124        crDLMSetCurrentState(expandoContextState->dlmContext);
     125        crStateMakeCurrent(expandoContextState->State);
     126    }
     127    else
     128    {
     129        crDebug("Expando SPU: can't switch to context %d: not found.", contextId);
     130
     131        crDLMSetCurrentState(NULL);
     132        crStateMakeCurrent(NULL);
     133    }
    93134}
    94135
     
    96137expandoNewList(GLuint list, GLenum mode)
    97138{
    98     crDebug("Expando SPU: expandoNewList()");
    99         crDLMNewList(list, mode);
     139    crDLMNewList(list, mode, &expando_spu.super);
    100140}
    101141
     
    103143expandoEndList(void)
    104144{
    105     crDebug("Expando SPU: expandoEndList()");
    106         crDLMEndList();
     145    crDLMEndList(&expando_spu.super);
    107146}
    108147
     
    110149expandoDeleteLists(GLuint first, GLsizei range)
    111150{
    112         crDLMDeleteLists(first, range);
     151    crDLMDeleteLists(first, range, &expando_spu.super);
    113152}
    114153
     
    116155expandoGenLists(GLsizei range)
    117156{
    118          return crDLMGenLists(range);
     157    return crDLMGenLists(range, &expando_spu.super);
     158}
     159
     160void EXPANDOSPU_APIENTRY
     161expandoListBase(GLuint base)
     162{
     163    crDLMListBase(base, &expando_spu.super);
    119164}
    120165
     
    122167expandoIsList(GLuint list)
    123168{
    124          return crDLMIsList(list);
     169    return crDLMIsList(list, &expando_spu.super);
    125170}
    126171
     
    128173expandoCallList(GLuint list)
    129174{
    130         GLenum mode = crDLMGetCurrentMode();
    131         if (mode != GL_FALSE) {
    132                 crDLMCompileCallList(list);
    133                 if (mode == GL_COMPILE) return;
    134         }
    135 
    136         /* Instead of passing through the CallList,
    137          * expand it into its components.  This will cause
    138          * a recursion if there are any compiled CallList
    139          * elements within the display list.
    140          */
    141         crDLMReplayList(list, &expando_spu.self);
     175    crDLMCallList(list, &expando_spu.super);
    142176}
    143177
     
    145179expandoCallLists(GLsizei n, GLenum type, const GLvoid *lists)
    146180{
    147         GLenum mode = crDLMGetCurrentMode();
    148         if (mode != GL_FALSE) {
    149                 crDLMCompileCallLists(n, type, lists);
    150                 if (mode == GL_COMPILE) return;
    151         }
    152         /* Instead of passing through the CallLists,
    153          * expand it into its components.  This will cause
    154          * a recursion if there are any compiled CallLists
    155          * elements within the display list.
    156          */
    157         crDLMReplayLists(n, type, lists, &expando_spu.self);
     181    crDLMCallLists(n, type, lists, &expando_spu.super);
    158182}
  • trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h

    r54905 r56566  
    6262extern void EXPANDOSPU_APIENTRY expandoDeleteLists(GLuint first, GLsizei range);
    6363extern GLuint EXPANDOSPU_APIENTRY expandoGenLists(GLsizei range);
     64extern void EXPANDOSPU_APIENTRY expandoListBase(GLuint base);
    6465extern GLboolean EXPANDOSPU_APIENTRY expandoIsList(GLuint list);
    6566extern  void EXPANDOSPU_APIENTRY expandoCallList(GLuint list);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette