Search
lxdream.org :: lxdream/src/drivers/video_gdk.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/video_gdk.c
changeset 661:99d9494955a9
prev653:3202ff01d48e
next669:ab344e42bca9
author nkeynes
date Thu Apr 17 00:01:40 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Patch up the osmesa driver
view annotate diff log raw
     1 /**
     2  * $Id$
     3  *
     4  * The PC side of the video support (responsible for actually displaying / 
     5  * rendering frames)
     6  *
     7  * Copyright (c) 2005 Nathan Keynes.
     8  *
     9  * This program is free software; you can redistribute it and/or modify
    10  * it under the terms of the GNU General Public License as published by
    11  * the Free Software Foundation; either version 2 of the License, or
    12  * (at your option) any later version.
    13  *
    14  * This program is distributed in the hope that it will be useful,
    15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17  * GNU General Public License for more details.
    18  */
    19 #include <assert.h>
    20 #include <stdlib.h>
    21 #include <gdk/gdk.h>
    22 #include <gdk-pixbuf/gdk-pixbuf.h>
    23 #include <gtk/gtkwidget.h>
    24 #include <GL/glu.h>
    25 #include <GL/osmesa.h>
    26 #include "lxdream.h"
    27 #include "display.h"
    29 #define MAX_PIXBUF 16
    31 extern GtkWidget *gtk_video_drawable;
    32 extern int video_width, video_height;
    34 static render_buffer_t gdk_pixbuf_create_render_buffer( uint32_t width, uint32_t height );
    35 static void gdk_pixbuf_destroy_render_buffer( render_buffer_t buffer );
    36 static gboolean gdk_pixbuf_set_render_target( render_buffer_t buffer );
    37 static gboolean gdk_pixbuf_display_render_buffer( render_buffer_t buffer );
    38 static void gdk_pixbuf_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer );
    39 static gboolean gdk_pixbuf_display_blank( uint32_t colour );
    40 static gboolean gdk_pixbuf_read_render_buffer( unsigned char *target, render_buffer_t buffer, int rowstride, int format );
    42 static void *pixbuf_array[MAX_PIXBUF];
    43 unsigned int pixbuf_max = 0;
    44 OSMesaContext osmesa_context = NULL;
    46 void video_gdk_init_driver( display_driver_t driver )
    47 {
    48     pixbuf_max = 0;
    49     driver->create_render_buffer = gdk_pixbuf_create_render_buffer;
    50     driver->destroy_render_buffer = gdk_pixbuf_destroy_render_buffer;
    51     driver->set_render_target = gdk_pixbuf_set_render_target;
    52     driver->display_render_buffer = gdk_pixbuf_display_render_buffer;
    53     driver->load_frame_buffer = gdk_pixbuf_load_frame_buffer;
    54     driver->display_blank = gdk_pixbuf_display_blank;
    55     driver->read_render_buffer = gdk_pixbuf_read_render_buffer;
    57     osmesa_context = OSMesaCreateContextExt( OSMESA_RGBA, 32, 0, 0, 0 );
    58     OSMesaMakeCurrent( osmesa_context, NULL, GL_UNSIGNED_BYTE, 640, 480 );
    59     pvr2_setup_gl_context();
    60 }
    62 int video_gdk_find_free()
    63 {
    64     unsigned int i;
    65     for( i=0; i<pixbuf_max; i++ ) {
    66 	if( pixbuf_array[i] == NULL ) {
    67 	    return i;
    68 	}
    69     }
    70     if( i < MAX_PIXBUF ) {
    71 	return pixbuf_max++;
    72     }
    73     return -1;
    74 }
    76 void video_gdk_shutdown()
    77 {
    78     unsigned int i;
    79     for( i=0; i<pixbuf_max; i++ ) {
    80 	if( pixbuf_array[i] != NULL ) {
    81 	    g_free(pixbuf_array[i]);
    82 	    pixbuf_array[i] = NULL;
    83 	}
    84     }
    85     pixbuf_max = 0;
    86     OSMesaDestroyContext( osmesa_context );
    87 }
    90 static render_buffer_t gdk_pixbuf_create_render_buffer( uint32_t width, uint32_t height )
    91 {
    92     render_buffer_t buf = g_malloc0(sizeof(struct render_buffer));
    93     gboolean alpha = FALSE;
    94     buf->width = width;
    95     buf->height = height;
    96     buf->buf_id = video_gdk_find_free();
    97     pixbuf_array[buf->buf_id] = g_malloc0( width * height * 4 );
    98     return buf;
    99 }
   101 static void gdk_pixbuf_destroy_render_buffer( render_buffer_t buffer )
   102 {
   103     g_free(pixbuf_array[buffer->buf_id] );
   104     pixbuf_array[buffer->buf_id] = NULL;
   105     if( buffer->buf_id == (pixbuf_max-1) ) {
   106 	pixbuf_max--;
   107     }
   108 }
   110 static gboolean gdk_pixbuf_display_render_buffer( render_buffer_t buffer )
   111 {
   112     glFinish();
   114     void *pb = pixbuf_array[buffer->buf_id];
   115     GdkGC *gc = gtk_video_drawable->style->fg_gc[GTK_STATE_NORMAL];
   116     GdkColor black = {0,0,0,0};
   118     assert(gc);
   120     int x1=0,y1=0,x2=video_width,y2=video_height;
   122     int ah = video_width * 0.75;
   125     if( ah > video_height ) {
   126 	int w = (video_height/0.75);
   127 	x1 = (video_width - w)/2;
   128 	x2 -= x1;
   129 	gdk_gc_set_foreground( gc, &black );
   130 	gdk_gc_set_background( gc, &black );
   131 	gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, x1, video_height );
   132 	gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, x2, 0, video_width, video_height );
   133     } else if( ah < video_height ) {
   134 	y1 = (video_height - ah)/2;
   135 	y2 -= y1;
   136 	gdk_gc_set_foreground( gc, &black );
   137 	gdk_gc_set_background( gc, &black );
   138 	gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, video_width, y1 );
   139 	gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, y2, video_width, video_height );
   140     }
   141     int w = x2-x1;
   142     int h = y2-y1;
   144     if( w != buffer->width || h != buffer->height ) {
   145 	gdk_draw_rgb_32_image( gtk_video_drawable->window, gc, x1, y1, buffer->width, buffer->height, GDK_RGB_DITHER_NONE,
   146 			       pb, buffer->width*4 );
   147     } else {
   148 	gdk_draw_rgb_32_image( gtk_video_drawable->window, gc, x1, y1, buffer->width, buffer->height, GDK_RGB_DITHER_NONE,
   149 			       pb, buffer->width*4 );
   150     }
   151 }
   153 static gboolean gdk_pixbuf_display_blank( uint32_t colour )
   154 {
   155     GdkGC *gc = gtk_video_drawable->style->fg_gc[GTK_STATE_NORMAL];
   156     GdkColor col = { };
   158     gdk_gc_set_foreground( gc, &col );
   159     gdk_gc_set_background( gc, &col );
   160     gdk_draw_rectangle( gtk_video_drawable->window, gc, TRUE, 0, 0, video_width, video_height );
   161     return TRUE;
   162 }
   164 static gboolean gdk_pixbuf_set_render_target( render_buffer_t buffer )
   165 {
   166     glFinish();
   167     void *pb = pixbuf_array[buffer->buf_id];
   168     OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE,
   169 		       buffer->width, buffer->height );
   170     //OSMesaPixelStore( OSMESA_Y_UP, 0 );
   171     glViewport( 0, 0, buffer->width, buffer->height );
   172     glDrawBuffer(GL_FRONT);
   173     return TRUE;
   174 }
   176 static void gdk_pixbuf_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer )
   177 {
   178     glFinish();
   179     void *pb = pixbuf_array[buffer->buf_id];
   180     OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE,
   181 		       buffer->width, buffer->height );
   182     GLenum type = colour_formats[frame->colour_format].type;
   183     GLenum format = colour_formats[frame->colour_format].format;
   184     int bpp = colour_formats[frame->colour_format].bpp;
   185     int rowstride = (frame->rowstride / bpp) - frame->width;
   187     gl_reset_state();
   188     glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
   189     glRasterPos2f(0.375, frame->height-0.375);
   190     glPixelZoom( 1.0, 1.0 );
   191     glDrawPixels( frame->width, frame->height, format, type, frame->data );
   192     glFlush();
   193 }
   195 static gboolean gdk_pixbuf_read_render_buffer( unsigned char *target, render_buffer_t buffer, int rowstride, int format )
   196 {
   197     glFinish();
   198     void *pb = pixbuf_array[buffer->buf_id];
   199     OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE,
   200 		       buffer->width, buffer->height );
   201     glReadBuffer( GL_FRONT );
   202     return gl_read_render_buffer( target, buffer, rowstride, format );
   204 }
.