1 /* 2 * Copyright 2006-2008, Haiku. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Philippe Houdoin, philippe.houdoin@free.fr 7 */ 8 /* 9 * Mesa 3-D graphics library 10 * Version: 6.1 11 * 12 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. 13 */ 14 15 #include "FakeRenderer.h" 16 17 #include <stdio.h> 18 19 #include <Autolock.h> 20 #include <DirectWindowPrivate.h> 21 #include <GraphicsDefs.h> 22 #include <Screen.h> 23 24 25 extern const char * color_space_name(color_space space); 26 27 28 extern "C" _EXPORT BGLRenderer* 29 instantiate_gl_renderer(BGLView* view, ulong options, 30 BGLDispatcher* dispatcher) 31 { 32 return new FakeRenderer(view, options, dispatcher); 33 } 34 35 36 FakeRenderer::FakeRenderer(BGLView* view, ulong options, 37 BGLDispatcher* dispatcher) 38 : BGLRenderer(view, options, dispatcher), 39 fOptions(options), 40 fDrawLocker("direct draw locker"), 41 fFrameBuffer(NULL), 42 fColorSpace(B_NO_COLOR_SPACE), 43 fRects(NULL), 44 fConnected(false), 45 fDisabled(false) 46 { 47 fDrawSem = create_sem(0, "FakeRenderer draw"); 48 fDrawThread = spawn_thread(_DirectDrawThread, "FakeRenderer direct draw", B_DISPLAY_PRIORITY, this); 49 resume_thread(fDrawThread); 50 51 } 52 53 FakeRenderer::~FakeRenderer() 54 { 55 // Wakeup the draw thread by murdering its favorite semaphore 56 delete_sem(fDrawSem); 57 58 status_t exit_value; 59 wait_for_thread(fDrawThread, &exit_value); 60 61 free(fRects); 62 } 63 64 65 void 66 FakeRenderer::SwapBuffers(bool VSync) 67 { 68 if (VSync && GLView()->Window()) { 69 // TODO: find a way to check VSync support is actually working... 70 BScreen screen(GLView()->Window()); 71 screen.WaitForRetrace(); 72 } 73 74 // Simulate rendering a new buffer: randomized buffer color ;-) 75 fDrawColor = make_color(rand() % 0xFF, rand() % 0xFF, rand() % 0xFF); 76 77 if (!fConnected || fDisabled) { 78 GLView()->LockLooper(); 79 // TODO : refresh area 80 GLView()->UnlockLooper(); 81 return; 82 } 83 84 // Direct mode: wake up drawing thread 85 release_sem(fDrawSem); 86 } 87 88 89 void 90 FakeRenderer::Draw(BRect updateRect) 91 { 92 /* 93 if (fBitmap && (!fDirectModeEnabled || (fInfo == NULL))) 94 GLView()->DrawBitmap(fBitmap, updateRect, updateRect); 95 */ 96 } 97 98 99 void 100 FakeRenderer::EnableDirectMode(bool enabled) 101 { 102 fDisabled = ! enabled; 103 } 104 105 106 void 107 FakeRenderer::DirectConnected(direct_buffer_info *info) 108 { 109 if (!fConnected && fDisabled) 110 return; 111 112 BAutolock lock(fDrawLocker); 113 114 switch (info->buffer_state & B_DIRECT_MODE_MASK) { 115 case B_DIRECT_START: 116 fConnected = true; 117 /* fall through */ 118 case B_DIRECT_MODIFY: 119 fFrameBuffer = (uint8 *) info->bits; 120 fBytesPerRow = info->bytes_per_row; 121 fColorSpace = info->pixel_format; 122 123 free(fRects); 124 fRectsCount = info->clip_list_count; 125 fRects = (clipping_rect *) malloc(fRectsCount * sizeof(clipping_rect)); 126 memcpy(fRects, info->clip_list, fRectsCount * sizeof(clipping_rect)); 127 128 fprintf(stderr, "fFrameBuffer = %p\n" 129 "fBytesPerRow = %d\n" 130 "fColorSpace = %s\n", fFrameBuffer, fBytesPerRow, color_space_name(fColorSpace)); 131 for (int i = 0; i < fRectsCount; i++) { 132 fprintf(stderr, "fRects[%d] = %d, %d to %d, %d\n", 133 i, fRects[i].left, fRects[i].top, fRects[i].right, fRects[i].bottom); 134 } 135 break; 136 137 case B_DIRECT_STOP: 138 fConnected = false; 139 break; 140 } 141 142 fprintf(stderr, "fConnected = %s\n", fConnected ? "true" : "false"); 143 } 144 145 146 // ---- 147 148 149 int32 150 FakeRenderer::_DirectDrawThread(void *data) 151 { 152 FakeRenderer *me = (FakeRenderer *) data; 153 return me->_DirectDrawThread(); 154 } 155 156 157 int32 158 FakeRenderer::_DirectDrawThread(void) 159 { 160 // Let's wait forever/until semaphore death next redraw 161 while (acquire_sem(fDrawSem) == B_OK) { 162 163 BAutolock lock(fDrawLocker); 164 165 int i; 166 int32 x, y; 167 168 switch(fColorSpace) { 169 case B_RGB32: 170 case B_RGBA32: 171 for (i = 0; i < fRectsCount; i++) { 172 for (y = fRects[i].top; y <= fRects[i].bottom; y++) { 173 uint8 * p = fFrameBuffer + ( y * fBytesPerRow ) + fRects[i].left * 4; 174 for (x = fRects[i].left; x <= fRects[i].right; x++) { 175 *p++ = fDrawColor.blue; 176 *p++ = fDrawColor.green; 177 *p++ = fDrawColor.red; 178 *p++ = fDrawColor.alpha; 179 } 180 } 181 } 182 break; 183 184 case B_RGB24: 185 case B_RGB32_BIG: 186 case B_RGBA32_BIG: 187 case B_RGB24_BIG: 188 /* fill this in with the color-space conversion 189 * code of your choosing 190 */ 191 break; 192 193 case B_RGB16: 194 case B_RGB15: 195 case B_RGBA15: 196 case B_RGB16_BIG: 197 case B_RGB15_BIG: 198 case B_RGBA15_BIG: 199 /* same here */ 200 break; 201 202 case B_CMAP8: 203 /* same here */ 204 break; 205 206 default: 207 /* unsupported mode */ 208 break; 209 } 210 211 } // while draw 212 213 return 0; 214 } 215 216 217 218