2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "gnashconfig.h"
30 #include "GnashException.h"
32 #include "RawFBDevice.h"
33 #include "GnashDevice.h"
41 // The debug log used by all the gnash libraries.
42 static LogFile
& dbglogfile
= LogFile::getDefaultInstance();
45 RawFBDevice::RawFBDevice()
49 // GNASH_REPORT_FUNCTION;
51 // dbglogfile.setVerbosity();
54 RawFBDevice::RawFBDevice(int /* vid */)
58 // GNASH_REPORT_FUNCTION;
60 memset(&_cmap
, 0, sizeof(struct fb_cmap
));
62 if (!initDevice(0, 0)) {
63 log_error(_("Couldn't initialize RAWFB device!"));
67 RawFBDevice::RawFBDevice(int /* argc */ , char ** /* argv */)
71 // GNASH_REPORT_FUNCTION;
73 memset(&_cmap
, 0, sizeof(struct fb_cmap
));
79 GNASH_REPORT_FUNCTION
;
81 memset(_fbmem
, 0, _fixinfo
.smem_len
);
83 if (_offscreen_buffer
) {
84 memset(_offscreen_buffer
.get(), 0, _fixinfo
.smem_len
);
88 RawFBDevice::~RawFBDevice()
90 // GNASH_REPORT_FUNCTION;
94 log_debug(_("Freeing framebuffer memory"));
98 if (_offscreen_buffer
) {
99 log_debug(_("Freeing offscreen buffer"));
100 _offscreen_buffer
.reset();
110 RawFBDevice::initDevice(int /* argc */, char **/
* argv
[] */
)
112 GNASH_REPORT_FUNCTION
;
114 const char *devname
= 0;
115 // Open the framebuffer device
116 #ifdef ENABLE_FAKE_FRAMEBUFFER
117 _fd
= open(FAKEFB
, O_RDWR
);
118 log_debug(_("WARNING: Using %s as a fake framebuffer!"), FAKEFB
);
120 devname
= getenv("FRAMEBUFFER");
122 // We can't use the fake framebuffer with the FRAMEBUFFER
123 // environment variable, as it coinfuses X11. So this
124 // lets us redefine this at runtime.
125 devname
= getenv("FAKE_FRAMEBUFFER");
127 devname
= "/dev/fb0";
130 _fd
= open(devname
, O_RDWR
);
133 log_error(_("Could not open framebuffer device: %s"), strerror(errno
));
136 log_debug(_("Opened framebuffer device: %s"), devname
);
139 // Load framebuffer properties
140 #ifdef ENABLE_FAKE_FRAMEBUFFER
141 fakefb_ioctl(_fd
, FBIOGET_VSCREENINFO
, &_varinfo
);
142 fakefb_ioctl(_fd
, FBIOGET_FSCREENINFO
, &_fixinfo
);
144 ioctl(_fd
, FBIOGET_VSCREENINFO
, &_varinfo
);
145 ioctl(_fd
, FBIOGET_FSCREENINFO
, &_fixinfo
);
147 log_debug(_("Framebuffer device uses %d bytes of memory."),
149 log_debug(_("Video mode: %dx%d with %d bits per pixel."),
150 _varinfo
.xres
, _varinfo
.yres
,
151 _varinfo
.bits_per_pixel
);
153 log_debug(_("Framebuffer stride is: %d."), _fixinfo
.line_length
);
159 RawFBDevice::setGrayscaleLUT8()
161 #define TO_16BIT(x) (x | (x<<8))
163 GNASH_REPORT_FUNCTION
;
167 log_debug(_("LUT8: Setting up colormap"));
171 _cmap
.red
= (__u16
*)malloc(CMAP_SIZE
);
172 _cmap
.green
= (__u16
*)malloc(CMAP_SIZE
);
173 _cmap
.blue
= (__u16
*)malloc(CMAP_SIZE
);
176 for (i
=0; i
<256; i
++) {
181 _cmap
.red
[i
] = TO_16BIT(r
);
182 _cmap
.green
[i
] = TO_16BIT(g
);
183 _cmap
.blue
[i
] = TO_16BIT(b
);
186 #ifdef ENABLE_FAKE_FRAMEBUFFER
187 if (fakefb_ioctl(_fd
, FBIOPUTCMAP
, &_cmap
))
189 if (ioctl(_fd
, FBIOPUTCMAP
, &_cmap
))
192 log_error(_("LUT8: Error setting colormap: %s"), strerror(errno
));
201 // Initialize RAWFB Window layer
203 RawFBDevice::attachWindow(GnashDevice::native_window_t window
)
205 GNASH_REPORT_FUNCTION
;
207 // map framebuffer into memory. There isn't really a native
208 // window when using a frambuffer, it's actualy the file descriptor
209 // of the opened device. EGL wants the descriptor here too, so
210 // this way we work in a similar manner.
212 _fbmem
= reinterpret_cast<boost::uint8_t *>(mmap(0, _fixinfo
.smem_len
,
213 PROT_READ
|PROT_WRITE
, MAP_SHARED
,
218 log_error(("Couldn't mmap() %d bytes of memory!"),
223 if (!isSingleBuffered()) {
224 // Create an offscreen buffer the same size as the Framebuffer
225 _offscreen_buffer
.reset(new boost::uint8_t[_fixinfo
.smem_len
]);
226 memset(_offscreen_buffer
.get(), 0, _fixinfo
.smem_len
);
233 RawFBDevice::swapBuffers()
235 // When using AGG, the pointer to the offscreen buffer has been
236 // passed to AGG, so it renders in the offscreen buffer by default,
237 // leaving it up to us to manually copy the data from the offscreeen
238 // buffer into the real framebuffer memory.
239 if (_fbmem
&& _offscreen_buffer
) {
240 std::copy(_offscreen_buffer
.get(),
241 _offscreen_buffer
.get() + _fixinfo
.smem_len
,
245 // When single buffered, there is no data to copy, so always true
251 // Return a string with the error code as text, instead of a numeric value
253 RawFBDevice::getErrorString(int /* error */)
258 // Create an RAWFB window to render in. This is only used by testing
260 RawFBDevice::createWindow(const char * /* name */, int /* x */,
261 int /* y */, int /* width */, int /* height */)
263 GNASH_REPORT_FUNCTION
;
267 RawFBDevice::eventLoop(size_t /* passes */)
269 GNASH_REPORT_FUNCTION
;
272 #ifdef ENABLE_FAKE_FRAMEBUFFER
273 // Simulate the ioctls used to get information from the framebuffer
274 // driver. Since this is an emulator, we have to set these fields
275 // to a reasonable default.
277 fakefb_ioctl(int /* fd */, int request
, void *data
)
279 // GNASH_REPORT_FUNCTION;
282 case FBIOGET_VSCREENINFO
:
284 struct fb_var_screeninfo
*ptr
=
285 reinterpret_cast<struct fb_var_screeninfo
*>(data
);
286 // Note that the fake framebuffer is only used for
287 // debugging and development.
288 // Framebuffer device uses 1536000 bytes of memory at this size
290 ptr
->xres
= 1024; // visible resolution
291 ptr
->xres_virtual
= 1024; // virtual resolution
292 ptr
->yres
= 768; // visible resolution
293 ptr
->yres_virtual
= 768; // virtual resolution
295 // standard PC framebuffer use a 32 bit 8/8/8 framebuffer
296 ptr
->bits_per_pixel
= 24;
299 ptr
->green
.offset
= 16;
300 ptr
->green
.length
= 8;
301 ptr
->blue
.offset
= 0;
302 ptr
->blue
.length
= 6;
303 ptr
->transp
.offset
= 0;
304 ptr
->transp
.length
= 0;
306 ptr
->xres
= 800; // visible resolution
307 ptr
->xres_virtual
= 1600; // virtual resolution
308 ptr
->yres
= 480; // visible resolution
309 ptr
->yres_virtual
= 480; // virtual resolution
311 // Most modile devices use a 16bit 5/6/5 framebuffer
312 ptr
->bits_per_pixel
= 16;
314 ptr
->red
.offset
= 11;
315 ptr
->green
.length
= 6;
316 ptr
->green
.offset
= 5;
317 ptr
->blue
.length
= 5;
318 ptr
->blue
.offset
= 0;
319 ptr
->transp
.offset
= 0;
320 ptr
->transp
.length
= 0;
323 // ptr->bits_per_pixel = 8;
324 // ptr->red.length = 8;
325 // ptr->red.offset = 0;
326 // ptr->green.length = 8;
327 // ptr->green.offset = 0;
328 // ptr->blue.length = 8;
329 // ptr->blue.offset = 0;
330 // ptr->transp.offset = 0;
331 // ptr->transp.length = 0;
332 ptr
->grayscale
= 1; // != 0 Graylevels instead of color
336 case FBIOGET_FSCREENINFO
:
338 struct fb_fix_screeninfo
*ptr
=
339 reinterpret_cast<struct fb_fix_screeninfo
*>(data
);
341 // Most mobile devices use a 16bit 5/6/5 framebuffer
342 ptr
->smem_len
= 33554432; // size of frame buffer memory
343 ptr
->type
= 0; // see FB_TYPE_*
344 ptr
->visual
= 2; // see FB_VISUAL_*
345 ptr
->xpanstep
= 1; // zero if no hardware panning
346 ptr
->ypanstep
= 1; // zero if no hardware panning
347 ptr
->ywrapstep
= 0; // zero if no hardware panning
348 ptr
->line_length
= 1600; // line length
349 ptr
->accel
= FB_ACCEL_NONE
; // Indicate to driver which specific
352 // Android and fbe use a 16bit 5/6/5 framebuffer
353 ptr
->smem_len
= 307200; // Length of frame buffer mem
354 ptr
->type
= FB_TYPE_PACKED_PIXELS
; // see FB_TYPE_*
355 ptr
->visual
= FB_VISUAL_PSEUDOCOLOR
; // see FB_VISUAL_*
356 ptr
->xpanstep
= 0; // zero if no hardware panning
357 ptr
->ypanstep
= 0; // zero if no hardware panning
358 ptr
->ywrapstep
= 0; // zero if no hardware panning
359 ptr
->accel
= FB_ACCEL_NONE
; // Indicate to driver which specific
366 // Fbe uses this name for the fake framebuffer, so in this
367 // case assume we're using fbe, so write to the known fbe
369 std::string str
= FAKEFB
;
370 if (str
== "/tmp/fbe_buffer") {
371 int fd
= open("/tmp/fbe_cmap", O_WRONLY
);
373 write(fd
, data
, sizeof(struct fb_cmap
));
376 log_error(_("Couldn't write to the fake cmap!"));
380 log_error(_("Couldn't write to the fake cmap, unknown type!"));
383 // If we send a SIGUSR1 signal to fbe, it'll reload the
385 int fd
= open("/tmp/fbe.pid", O_RDONLY
);
388 if (read(fd
, buf
, 10) == 0) {
392 pid_t pid
= strtol(buf
, 0, NULL
);
394 log_debug(_("Signaled fbe to reload it's colormap."));
401 log_unimpl(_("fakefb_ioctl(%d)"), request
);
407 #endif // ENABLE_FAKE_FRAMEBUFFER
410 } // namespace renderer
415 // indent-tabs-mode: nil