VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxFB/Framebuffer.cpp@ 12208

Last change on this file since 12208 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/** @file
2 *
3 * VBox frontends: Framebuffer (FB, DirectFB):
4 * Implementation of VBoxDirectFB class
5 */
6
7/*
8 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
19 * Clara, CA 95054 USA or visit http://www.sun.com if you need
20 * additional information or have any questions.
21 */
22
23#include "VBoxFB.h"
24#include "Framebuffer.h"
25
26NS_IMPL_ISUPPORTS1_CI(VBoxDirectFB, IFramebuffer)
27NS_DECL_CLASSINFO(VBoxDirectFB)
28
29VBoxDirectFB::VBoxDirectFB(IDirectFB *aDFB, IDirectFBSurface *aSurface)
30{
31 dfb = aDFB;
32 surface = aSurface;
33 fbInternalSurface = NULL;
34 fbBufferAddress = NULL;
35 // initialize screen dimensions
36 DFBCHECK(surface->GetSize(surface, (int*)&screenWidth, (int*)&screenHeight));
37 fbWidth = 640;
38 fbHeight = 480;
39 if ((screenWidth != fbWidth) || (screenHeight != fbHeight))
40 {
41 createSurface(fbWidth, fbHeight);
42 }
43 fbSurfaceLocked = 0;
44 uint32_t bitsPerPixel;
45 GetBitsPerPixel(&bitsPerPixel);
46 fbPitch = fbWidth * (bitsPerPixel / 8);
47}
48
49VBoxDirectFB::~VBoxDirectFB()
50{
51 // free our internal surface
52 if (fbInternalSurface)
53 {
54 DFBCHECK(fbInternalSurface->Release(fbInternalSurface));
55 fbInternalSurface = NULL;
56 }
57}
58
59NS_IMETHODIMP VBoxDirectFB::GetWidth(uint32 *width)
60{
61 if (!width)
62 return NS_ERROR_INVALID_POINTER;
63 *width = fbWidth;
64 return NS_OK;
65}
66
67NS_IMETHODIMP VBoxDirectFB::GetHeight(uint32_t *height)
68{
69 if (!height)
70 return NS_ERROR_INVALID_POINTER;
71 *height = fbHeight;
72 return NS_OK;
73}
74
75NS_IMETHODIMP VBoxDirectFB::Lock()
76{
77 // do we have an internal framebuffer?
78 if (fbInternalSurface)
79 {
80 if (fbSurfaceLocked)
81 {
82 printf("internal surface already locked!\n");
83 } else
84 {
85 DFBCHECK(fbInternalSurface->Lock(fbInternalSurface,
86 (DFBSurfaceLockFlags)(DSLF_WRITE | DSLF_READ),
87 &fbBufferAddress, (int*)&fbPitch));
88 fbSurfaceLocked = 1;
89 }
90 } else
91 {
92 if (fbSurfaceLocked)
93 {
94 printf("surface already locked!\n");
95 } else
96 {
97 DFBCHECK(surface->Lock(surface, (DFBSurfaceLockFlags)(DSLF_WRITE | DSLF_READ),
98 &fbBufferAddress, (int*)&fbPitch));
99 fbSurfaceLocked = 1;
100 }
101 }
102 return NS_OK;
103}
104
105NS_IMETHODIMP VBoxDirectFB::Unlock()
106{
107 // do we have an internal framebuffer?
108 if (fbInternalSurface)
109 {
110 if (!fbSurfaceLocked)
111 {
112 printf("internal surface not locked!\n");
113 } else
114 {
115 DFBCHECK(fbInternalSurface->Unlock(fbInternalSurface));
116 fbSurfaceLocked = 0;
117 }
118 } else
119 {
120 if (!fbSurfaceLocked)
121 {
122 printf("surface not locked!\n");
123 } else
124 {
125 DFBCHECK(surface->Unlock(surface));
126 fbSurfaceLocked = 0;
127 }
128 }
129 return NS_OK;
130}
131
132NS_IMETHODIMP VBoxDirectFB::GetAddress(uint32_t *address)
133{
134 if (!address)
135 return NS_ERROR_INVALID_POINTER;
136 *address = (uint32_t)fbBufferAddress;
137 return NS_OK;
138}
139
140NS_IMETHODIMP VBoxDirectFB::GetBitsPerPixel(uint32_t *bitsPerPixel)
141{
142 if (!bitsPerPixel)
143 return NS_ERROR_INVALID_POINTER;
144 DFBSurfacePixelFormat pixelFormat;
145 DFBCHECK(surface->GetPixelFormat(surface, &pixelFormat));
146 switch (pixelFormat)
147 {
148 case DSPF_RGB16:
149 *bitsPerPixel = 16;
150 break;
151 case DSPF_RGB24:
152 *bitsPerPixel = 24;
153 break;
154 case DSPF_RGB32:
155 *bitsPerPixel = 32;
156 break;
157 default:
158 // not good! @@@AH do something!
159 *bitsPerPixel = 16;
160 }
161 return NS_OK;
162}
163
164NS_IMETHODIMP VBoxDirectFB::GetBytesPerLine(uint32_t *bytesPerLine)
165{
166 if (!bytesPerLine)
167 return NS_ERROR_INVALID_POINTER;
168 *bytesPerLine = fbPitch;
169 return NS_OK;
170}
171
172NS_IMETHODIMP VBoxDirectFB::COMGETTER(PixelFormat) (ULONG *pixelFormat)
173{
174 if (!pixelFormat)
175 return NS_ERROR_INVALID_POINTER;
176 *pixelFormat = FramebufferPixelFormat_FOURCC_RGB;
177 return NS_OK;
178}
179
180NS_IMETHODIMP VBoxDirectFB::COMGETTER(UsesGuestVRAM) (BOOL *usesGuestVRAM)
181{
182 if (!usesGuestVRAM)
183 return NS_ERROR_INVALID_POINTER;
184 *usesGuestVRAM = FALSE;
185 return NS_OK;
186}
187
188NS_IMETHODIMP VBoxDirectFB::NotifyUpdate(uint32_t x, uint32_t y,
189 uint32_t w, uint32_t h, PRBool *finished)
190{
191 // we only need to take action if we have a memory framebuffer
192 if (fbInternalSurface)
193 {
194 //printf("blitting %u %u %u %u...\n", x, y, w, h);
195 DFBRectangle blitRectangle;
196 blitRectangle.x = x;
197 blitRectangle.y = y;
198 blitRectangle.w = w;
199 blitRectangle.h = h;
200 if (scaleGuest)
201 {
202 DFBRectangle hostRectangle;
203 float factorX = (float)screenWidth / (float)fbWidth;
204 float factorY = (float)screenHeight / (float)fbHeight;
205 hostRectangle.x = (int)((float)blitRectangle.x * factorX);
206 hostRectangle.y = (int)((float)blitRectangle.y * factorY);
207 hostRectangle.w = (int)((float)blitRectangle.w * factorX);
208 hostRectangle.h = (int)((float)blitRectangle.h * factorY);
209 DFBCHECK(surface->StretchBlit(surface, fbInternalSurface,
210 &blitRectangle, &hostRectangle));
211 } else
212 {
213 DFBCHECK(surface->Blit(surface, fbInternalSurface, &blitRectangle,
214 x + ((screenWidth - fbWidth) / 2),
215 y + (screenHeight - fbHeight) / 2));
216 }
217 }
218 if (finished)
219 *finished = true;
220 return NS_OK;
221}
222
223NS_IMETHODIMP VBoxDirectFB::RequestResize(ULONG aScreenId, ULONG pixelFormat, uint32_t vram,
224 uint32_t bitsPerPixel, uint32_t bytesPerLine,
225 uint32_t w, uint32_t h,
226 PRBool *finished)
227{
228 uint32_t needsLocking = fbSurfaceLocked;
229 uint32_t bitsPerPixel;
230
231 GetBitsPerPixel(&bitsPerPixel);
232 printf("RequestResize: w = %d, h = %d, fbSurfaceLocked = %d\n", w, h, fbSurfaceLocked);
233
234 // we can't work with a locked surface
235 if (needsLocking)
236 {
237 Unlock();
238 }
239
240 // in any case we gotta free a possible internal framebuffer
241 if (fbInternalSurface)
242 {
243 printf("freeing internal surface\n");
244 fbInternalSurface->Release(fbInternalSurface);
245 fbInternalSurface = NULL;
246 }
247
248 // check if we have a fixed host video mode
249 if (useFixedVideoMode)
250 {
251 // does the current video mode differ from what the guest wants?
252 if ((screenWidth == w) && (screenHeight == h))
253 {
254 printf("requested guest mode matches current host mode!\n");
255 } else
256 {
257 createSurface(w, h);
258 }
259 } else
260 {
261 // we adopt to the guest resolution or the next higher that is available
262 int32_t bestMode = getBestVideoMode(w, h, bitsPerPixel);
263 if (bestMode == -1)
264 {
265 // oh oh oh oh
266 printf("RequestResize: no suitable mode found!\n");
267 return NS_OK;
268 }
269
270 // does the mode differ from what we wanted?
271 if ((videoModes[bestMode].width != w) || (videoModes[bestMode].height != h) ||
272 (videoModes[bestMode].bpp != bitsPerPixel))
273 {
274 printf("The mode does not fit exactly!\n");
275 createSurface(w, h);
276 } else
277 {
278 printf("The mode fits exactly!\n");
279 }
280 // switch to this mode
281 DFBCHECK(dfb->SetVideoMode(dfb, videoModes[bestMode].width, videoModes[bestMode].height,
282 videoModes[bestMode].bpp));
283 }
284
285 // update dimensions to the new size
286 fbWidth = w;
287 fbHeight = h;
288
289 // clear the screen
290 DFBCHECK(surface->Clear(surface, 0, 0, 0, 0));
291
292 // if it was locked before the resize, obtain the lock again
293 if (needsLocking)
294 {
295 Lock();
296 }
297
298 if (finished)
299 *finished = true;
300 return NS_OK;
301}
302
303int VBoxDirectFB::createSurface(uint32_t w, uint32_t h)
304{
305 printf("creating a new internal surface, w = %u, h = %u...\n", w, h);
306 // create a surface
307 DFBSurfaceDescription dsc;
308 DFBSurfacePixelFormat pixelFormat;
309 dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT);
310 dsc.width = w;
311 dsc.height = h;
312 DFBCHECK(surface->GetPixelFormat(surface, &pixelFormat));
313 dsc.pixelformat = pixelFormat;
314 DFBCHECK(dfb->CreateSurface(dfb, &dsc, &fbInternalSurface));
315 return 0;
316}
Note: See TracBrowser for help on using the repository browser.

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