VirtualBox

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

Last change on this file since 20554 was 19817, checked in by vboxsync, 16 years ago

IFramebuffer cleanup next part:

  • removed obsolete internal framebuffer
  • removed IFramebuffer::setupInternalFramebuffer(), IFramebuffer::lockFramebuffer(), IFramebuffer::unlockFramebuffer(), IFramebuffer::registerExternalFramebuffer()
  • removed unused finished parameter of IFramebuffer::NotifyUpdate()
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.0 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)
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 }
212 else
213 {
214 DFBCHECK(surface->Blit(surface, fbInternalSurface, &blitRectangle,
215 x + ((screenWidth - fbWidth) / 2),
216 y + (screenHeight - fbHeight) / 2));
217 }
218 }
219 return NS_OK;
220}
221
222NS_IMETHODIMP VBoxDirectFB::RequestResize(ULONG aScreenId, ULONG pixelFormat, uint32_t vram,
223 uint32_t bitsPerPixel, uint32_t bytesPerLine,
224 uint32_t w, uint32_t h,
225 PRBool *finished)
226{
227 uint32_t needsLocking = fbSurfaceLocked;
228 uint32_t bitsPerPixel;
229
230 GetBitsPerPixel(&bitsPerPixel);
231 printf("RequestResize: w = %d, h = %d, fbSurfaceLocked = %d\n", w, h, fbSurfaceLocked);
232
233 // we can't work with a locked surface
234 if (needsLocking)
235 {
236 Unlock();
237 }
238
239 // in any case we gotta free a possible internal framebuffer
240 if (fbInternalSurface)
241 {
242 printf("freeing internal surface\n");
243 fbInternalSurface->Release(fbInternalSurface);
244 fbInternalSurface = NULL;
245 }
246
247 // check if we have a fixed host video mode
248 if (useFixedVideoMode)
249 {
250 // does the current video mode differ from what the guest wants?
251 if ((screenWidth == w) && (screenHeight == h))
252 {
253 printf("requested guest mode matches current host mode!\n");
254 } else
255 {
256 createSurface(w, h);
257 }
258 } else
259 {
260 // we adopt to the guest resolution or the next higher that is available
261 int32_t bestMode = getBestVideoMode(w, h, bitsPerPixel);
262 if (bestMode == -1)
263 {
264 // oh oh oh oh
265 printf("RequestResize: no suitable mode found!\n");
266 return NS_OK;
267 }
268
269 // does the mode differ from what we wanted?
270 if ((videoModes[bestMode].width != w) || (videoModes[bestMode].height != h) ||
271 (videoModes[bestMode].bpp != bitsPerPixel))
272 {
273 printf("The mode does not fit exactly!\n");
274 createSurface(w, h);
275 } else
276 {
277 printf("The mode fits exactly!\n");
278 }
279 // switch to this mode
280 DFBCHECK(dfb->SetVideoMode(dfb, videoModes[bestMode].width, videoModes[bestMode].height,
281 videoModes[bestMode].bpp));
282 }
283
284 // update dimensions to the new size
285 fbWidth = w;
286 fbHeight = h;
287
288 // clear the screen
289 DFBCHECK(surface->Clear(surface, 0, 0, 0, 0));
290
291 // if it was locked before the resize, obtain the lock again
292 if (needsLocking)
293 {
294 Lock();
295 }
296
297 if (finished)
298 *finished = true;
299 return NS_OK;
300}
301
302int VBoxDirectFB::createSurface(uint32_t w, uint32_t h)
303{
304 printf("creating a new internal surface, w = %u, h = %u...\n", w, h);
305 // create a surface
306 DFBSurfaceDescription dsc;
307 DFBSurfacePixelFormat pixelFormat;
308 dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT);
309 dsc.width = w;
310 dsc.height = h;
311 DFBCHECK(surface->GetPixelFormat(surface, &pixelFormat));
312 dsc.pixelformat = pixelFormat;
313 DFBCHECK(dfb->CreateSurface(dfb, &dsc, &fbInternalSurface));
314 return 0;
315}
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