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 25extern const char * color_space_name(color_space space); 26 27 28extern "C" _EXPORT BGLRenderer* 29instantiate_gl_renderer(BGLView* view, ulong options, 30 BGLDispatcher* dispatcher) 31{ 32 return new FakeRenderer(view, options, dispatcher); 33} 34 35 36FakeRenderer::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 53FakeRenderer::~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 65void 66FakeRenderer::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 89void 90FakeRenderer::Draw(BRect updateRect) 91{ 92/* 93 if (fBitmap && (!fDirectModeEnabled || (fInfo == NULL))) 94 GLView()->DrawBitmap(fBitmap, updateRect, updateRect); 95*/ 96} 97 98 99void 100FakeRenderer::EnableDirectMode(bool enabled) 101{ 102 fDisabled = ! enabled; 103} 104 105 106void 107FakeRenderer::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 149int32 150FakeRenderer::_DirectDrawThread(void *data) 151{ 152 FakeRenderer *me = (FakeRenderer *) data; 153 return me->_DirectDrawThread(); 154} 155 156 157int32 158FakeRenderer::_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