1/* 2 * Copyright 1999, Be Incorporated. 3 * Copyright 2007, Haiku. 4 * Distributed under the terms of the MIT License. 5 * 6 * Authors: 7 * Be Incorporated 8 * Eric Petit <eric.petit@lapsus.org> 9 */ 10 11 12#include "GlobalData.h" 13 14 15/*--------------------------------------------------------------------*/ 16/* UpdateThread: we explicitely need to tell VMware what and when 17 * something should be refreshed from the frame buffer. Since the 18 * app_server doesn't tell us what it's doing, we simply force a full 19 * screen update every 1/50 second */ 20 21static int32 22UpdateThread(void *data) 23{ 24 bigtime_t begin, end, wait; 25 26 while (!gUpdateThreadDie) { 27 begin = system_time(); 28 FifoUpdateFullscreen(); 29 end = system_time(); 30 31 /* 50 Hz refresh */ 32 wait = 20000 - (end - begin); 33 if (wait > 0) 34 snooze(wait); 35 } 36 37 return B_OK; 38} 39 40 41static void 42FifoPrintCapabilities(int c) 43{ 44 TRACE("fifo capabilities:\n"); 45 if (c & SVGA_FIFO_CAP_FENCE) TRACE("FENCE\n"); 46 if (c & SVGA_FIFO_CAP_ACCELFRONT) TRACE("ACCELFRONT\n"); 47 if (c & SVGA_FIFO_CAP_PITCHLOCK) TRACE("PITCHLOCK\n"); 48} 49 50 51void 52FifoInit(void) 53{ 54 uint32 *fifo = gSi->fifo; 55 56 /* Stop update thread, if any */ 57 if (gUpdateThread > B_OK) { 58 status_t exitValue; 59 gUpdateThreadDie = 1; 60 wait_for_thread(gUpdateThread, &exitValue); 61 } 62 63 gSi->fifoCapabilities = 0; 64 gSi->fifoFlags = 0; 65 if (gSi->capabilities & SVGA_CAP_EXTENDED_FIFO) { 66 gSi->fifoCapabilities = fifo[SVGA_FIFO_CAPABILITIES]; 67 gSi->fifoFlags = fifo[SVGA_FIFO_FLAGS]; 68 FifoPrintCapabilities(gSi->fifoCapabilities); 69 } 70 71 fifo[SVGA_FIFO_MIN] = gSi->fifoMin * 4; 72 fifo[SVGA_FIFO_MAX] = gSi->fifoSize; 73 fifo[SVGA_FIFO_NEXT_CMD] = fifo[SVGA_FIFO_MIN]; 74 fifo[SVGA_FIFO_STOP] = fifo[SVGA_FIFO_MIN]; 75 76 gSi->fifoNext = fifo[SVGA_FIFO_NEXT_CMD]; 77 78 /* Launch a new update thread */ 79 gUpdateThreadDie = 0; 80 gUpdateThread = spawn_thread(UpdateThread, "VMware", 81 B_REAL_TIME_DISPLAY_PRIORITY, NULL); 82 resume_thread(gUpdateThread); 83 84 TRACE("init fifo: %ld -> %ld\n", 85 fifo[SVGA_FIFO_MIN], fifo[SVGA_FIFO_MAX]); 86} 87 88 89void 90FifoSync(void) 91{ 92 ioctl(gFd, VMWARE_FIFO_SYNC, NULL, 0); 93} 94 95 96void 97FifoBeginWrite(void) 98{ 99 ACQUIRE_BEN(gSi->fifoLock); 100} 101 102 103void 104FifoWrite(uint32 value) 105{ 106 uint32 *fifo = gSi->fifo; 107 uint32 fifoCapacity = fifo[SVGA_FIFO_MAX] - fifo[SVGA_FIFO_MIN]; 108 109 /* If the fifo is full, sync it */ 110 if (fifo[SVGA_FIFO_STOP] == fifo[SVGA_FIFO_NEXT_CMD] + 4 || 111 fifo[SVGA_FIFO_STOP] + fifoCapacity == fifo[SVGA_FIFO_NEXT_CMD] + 4) 112 FifoSync(); 113 114 fifo[gSi->fifoNext / 4] = value; 115 gSi->fifoNext = fifo[SVGA_FIFO_MIN] + 116 (gSi->fifoNext + 4 - fifo[SVGA_FIFO_MIN]) % fifoCapacity; 117} 118 119 120void 121FifoEndWrite(void) 122{ 123 uint32 *fifo = gSi->fifo; 124 125 fifo[SVGA_FIFO_NEXT_CMD] = gSi->fifoNext; 126 RELEASE_BEN(gSi->fifoLock); 127} 128 129 130void 131FifoUpdateFullscreen(void) 132{ 133 FifoBeginWrite(); 134 FifoWrite(SVGA_CMD_UPDATE); 135 FifoWrite(0); 136 FifoWrite(0); 137 FifoWrite(gSi->dm.virtual_width); 138 FifoWrite(gSi->dm.virtual_height); 139 FifoEndWrite(); 140} 141 142