Changeset 56566 in vbox for trunk/src/VBox/HostServices/SharedOpenGL
- Timestamp:
- Jun 20, 2015 8:10:59 AM (10 years ago)
- svn:sync-xref-src-repo-rev:
- 101192
- Location:
- trunk/src/VBox/HostServices/SharedOpenGL
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedOpenGL/Makefile.kmk
r56301 r56566 31 31 32 32 ifeq ($(KBUILD_TARGET),darwin) 33 #VBOX_WITH_CR_DISPLAY_LISTS=133 VBOX_WITH_CR_DISPLAY_LISTS=1 34 34 endif 35 35 -
trunk/src/VBox/HostServices/SharedOpenGL/crserverlib/server_lists.c
r55014 r56566 40 40 static GLuint TranslateListID( GLuint id ) 41 41 { 42 #ifndef VBOX_WITH_CR_DISPLAY_LISTS 42 43 if (!cr_server.sharedDisplayLists) { 43 44 int client = cr_server.curClient->number; 44 45 return id + client * 100000; 45 46 } 47 #endif 46 48 return id; 47 49 } -
trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.c
r56473 r56566 49 49 CRDLMContextState *listState = (CRDLMContextState *)tsd; 50 50 51 if (listState) {52 if (listState->currentListInfo){53 crdlm_free_list(listState->currentListInfo); 54 } 55 56 51 if (listState) 52 { 53 //if (listState->currentListInfo) 54 // crdlm_free_list(listState->currentListInfo); 55 56 crFree(listState); 57 57 } 58 58 } … … 144 144 * itself when no one is still using the DLM. 145 145 */ 146 void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm )146 void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm, SPUDispatchTable *dispatchTable) 147 147 { 148 148 /* We're about to change the displayLists hash; lock it first */ … … 157 157 if (dlm->userCount == 0) { 158 158 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); 165 160 dlm->displayLists = NULL; 166 161 … … 269 264 */ 270 265 271 void DLM_APIENTRY crDLMFreeContext(CRDLMContextState *state )272 { 273 274 275 276 if (listState == state) { 277 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 294 295 296 266 void 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); 297 292 } 298 293 -
trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm.h
r54905 r56566 26 26 */ 27 27 extern void crdlmWarning( int line, char *file, GLenum error, char *format, ... ); 28 extern void crdlm _free_list(/* DLMListInfo * */ void *listInfo);28 extern void crdlmFreeDisplayListResourcesCb(void *pParm1, void *pParam2); 29 29 extern void crdlm_error(int line, const char *file, GLenum error, const char *info); 30 30 -
trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_calllist.c
r54905 r56566 1 1 /* $Id$ */ 2 #if 0 3 2 4 #include <stdio.h> 3 5 #include "cr_spu.h" … … 62 64 crdlm_add_to_list((DLMInstanceList *)instance, executeCallLists); 63 65 } 66 67 #endif -
trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_header.py
r56473 r56566 16 16 ('CRDLM DLM_APIENTRY *', 'crDLMNewDLM', 'unsigned int configSize, const CRDLMConfig *config'), 17 17 ('CRDLMContextState DLM_APIENTRY *', 'crDLMNewContext', 'CRDLM *dlm'), 18 ('void DLM_APIENTRY', 'crDLMFreeContext', 'CRDLMContextState *state '),18 ('void DLM_APIENTRY', 'crDLMFreeContext', 'CRDLMContextState *state, SPUDispatchTable *dispatchTable'), 19 19 ('void DLM_APIENTRY', 'crDLMUseDLM', 'CRDLM *dlm'), 20 ('void DLM_APIENTRY','crDLMFreeDLM', 'CRDLM *dlm '),20 ('void DLM_APIENTRY','crDLMFreeDLM', 'CRDLM *dlm, SPUDispatchTable *dispatchTable'), 21 21 ('void DLM_APIENTRY', 'crDLMSetCurrentState', 'CRDLMContextState *state'), 22 22 ('CRDLMContextState DLM_APIENTRY *', 'crDLMGetCurrentState', 'void'), … … 42 42 ('GLenum DLM_APIENTRY', 'crDLMGetCurrentMode', 'void'), 43 43 ('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'), 50 52 ('int32_t DLM_APIENTRY', 'crDLMSaveState', 'void'), 51 53 #('void DLM_APIENTRY', 'crDLMListSent', 'CRDLM *dlm, unsigned long listIdentifier'), … … 115 117 CRDLMBounds bbox; 116 118 GLboolean listSent; 119 GLuint hwid; 117 120 } DLMListInfo; 118 121 -
trunk/src/VBox/HostServices/SharedOpenGL/dlm/dlm_lists.c
r56473 r56566 1 1 /* $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 2 24 #include <float.h> 3 25 #include "cr_dlm.h" … … 6 28 7 29 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 */ 33 static 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 */ 50 void 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 */ 78 GLuint 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 */ 144 void 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. 27 172 */ 28 173 void 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 } 174 crDLMNewList(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 */ 235 void 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 */ 264 void 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 */ 294 inline 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 */ 331 void 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 */ 374 void 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 */ 400 GLboolean 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 11 11 # inside display lists, we can manage state updates for 12 12 # these sorts of elements. 13 CallList14 CallLists13 #CallList 14 #CallLists 15 15 16 16 # Calls to be ignored. -
trunk/src/VBox/HostServices/SharedOpenGL/expando/expando_special
r54905 r56566 6 6 DeleteLists 7 7 GenLists 8 ListBase 8 9 IsList 9 10 CallList -
trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.c
r54905 r56566 1 1 /* $Id$ */ 2 /** @file 3 * Implementation of routines which Expando SPU explicitly overrides. 4 */ 5 2 6 /* Copyright (c) 2001, Stanford University 3 7 * All rights reserved 4 8 * 5 9 * 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. 6 23 */ 7 24 … … 15 32 expandoCreateContext(const char *displayName, GLint visBits, GLint shareCtx) 16 33 { 17 ExpandoContextState *contextState; 18 GLint contextId; 34 ExpandoContextState *contextState; 19 35 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; 26 41 27 28 42 /* Get an official context ID from our super */ 43 contextId = expando_spu.super.CreateContext(displayName, visBits, shareCtx); 29 44 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); 39 60 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); 44 63 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); 49 67 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."); 52 72 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; 54 84 } 55 85 56 86 void expando_free_context_state(void *data) 57 87 { 58 ExpandoContextState * expandoContextState = (ExpandoContextState *)data;88 ExpandoContextState *contextState = (ExpandoContextState *)data; 59 89 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); 64 98 } 65 99 66 externvoid EXPANDOSPU_APIENTRY100 void EXPANDOSPU_APIENTRY 67 101 expandoDestroyContext(GLint contextId) 68 102 { 69 /* Destroy our context information */ 70 crHashtableDelete(expando_spu.contextTable, contextId, 71 expando_free_context_state); 103 crDebug("Expando SPU: destroy context %d.", contextId); 72 104 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); 75 110 } 76 111 77 externvoid EXPANDOSPU_APIENTRY112 void EXPANDOSPU_APIENTRY 78 113 expandoMakeCurrent(GLint crWindow, GLint nativeWindow, GLint contextId) 79 114 { 80 115 ExpandoContextState *expandoContextState; 81 116 82 117 expando_spu.super.MakeCurrent(crWindow, nativeWindow, contextId); 83 118 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 } 93 134 } 94 135 … … 96 137 expandoNewList(GLuint list, GLenum mode) 97 138 { 98 crDebug("Expando SPU: expandoNewList()"); 99 crDLMNewList(list, mode); 139 crDLMNewList(list, mode, &expando_spu.super); 100 140 } 101 141 … … 103 143 expandoEndList(void) 104 144 { 105 crDebug("Expando SPU: expandoEndList()"); 106 crDLMEndList(); 145 crDLMEndList(&expando_spu.super); 107 146 } 108 147 … … 110 149 expandoDeleteLists(GLuint first, GLsizei range) 111 150 { 112 crDLMDeleteLists(first, range);151 crDLMDeleteLists(first, range, &expando_spu.super); 113 152 } 114 153 … … 116 155 expandoGenLists(GLsizei range) 117 156 { 118 return crDLMGenLists(range); 157 return crDLMGenLists(range, &expando_spu.super); 158 } 159 160 void EXPANDOSPU_APIENTRY 161 expandoListBase(GLuint base) 162 { 163 crDLMListBase(base, &expando_spu.super); 119 164 } 120 165 … … 122 167 expandoIsList(GLuint list) 123 168 { 124 return crDLMIsList(list);169 return crDLMIsList(list, &expando_spu.super); 125 170 } 126 171 … … 128 173 expandoCallList(GLuint list) 129 174 { 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); 142 176 } 143 177 … … 145 179 expandoCallLists(GLsizei n, GLenum type, const GLvoid *lists) 146 180 { 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); 158 182 } -
trunk/src/VBox/HostServices/SharedOpenGL/expando/expandospu.h
r54905 r56566 62 62 extern void EXPANDOSPU_APIENTRY expandoDeleteLists(GLuint first, GLsizei range); 63 63 extern GLuint EXPANDOSPU_APIENTRY expandoGenLists(GLsizei range); 64 extern void EXPANDOSPU_APIENTRY expandoListBase(GLuint base); 64 65 extern GLboolean EXPANDOSPU_APIENTRY expandoIsList(GLuint list); 65 66 extern void EXPANDOSPU_APIENTRY expandoCallList(GLuint list);
Note:
See TracChangeset
for help on using the changeset viewer.