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 653:3202ff01d48e
next661:99d9494955a9
author nkeynes
date Fri Mar 28 12:32:25 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Merge lxdream-render branch (643:670) to trunk
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/osmesa.h>
    25 #include "lxdream.h"
    26 #include "display.h"
    28 #define MAX_PIXBUF 16
    30 extern GtkWidget *gtk_video_win;
    31 extern int video_width, video_height;
    33 static render_buffer_t gdk_pixbuf_create_render_buffer( uint32_t width, uint32_t height );
    34 static void gdk_pixbuf_destroy_render_buffer( render_buffer_t buffer );
    35 static gboolean gdk_pixbuf_set_render_target( render_buffer_t buffer );
    36 static gboolean gdk_pixbuf_display_render_buffer( render_buffer_t buffer );
    37 static void gdk_pixbuf_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer );
    38 static gboolean gdk_pixbuf_display_blank( uint32_t colour );
    39 static gboolean gdk_pixbuf_read_render_buffer( unsigned char *target, render_buffer_t buffer, int rowstride, int format );
    41 static void *pixbuf_array[MAX_PIXBUF];
    42 unsigned int pixbuf_max = 0;
    43 OSMesaContext osmesa_context = NULL;
    45 void video_gdk_init_driver( display_driver_t driver )
    46 {
    47     pixbuf_max = 0;
    48     driver->create_render_buffer = gdk_pixbuf_create_render_buffer;
    49     driver->destroy_render_buffer = gdk_pixbuf_destroy_render_buffer;
    50     driver->set_render_target = gdk_pixbuf_set_render_target;
    51     driver->display_render_buffer = gdk_pixbuf_display_render_buffer;
    52     driver->load_frame_buffer = gdk_pixbuf_load_frame_buffer;
    53     driver->display_blank = gdk_pixbuf_display_blank;
    54     driver->read_render_buffer = gdk_pixbuf_read_render_buffer;
    56     osmesa_context = OSMesaCreateContextExt( OSMESA_RGBA, 32, 0, 0, 0 );
    57     OSMesaMakeCurrent( osmesa_context, NULL, GL_UNSIGNED_BYTE, 640, 480 );
    58     pvr2_setup_gl_context();
    59 }
    61 int video_gdk_find_free()
    62 {
    63     unsigned int i;
    64     for( i=0; i<pixbuf_max; i++ ) {
    65 	if( pixbuf_array[i] == NULL ) {
    66 	    return i;
    67 	}
    68     }
    69     if( i < MAX_PIXBUF ) {
    70 	return pixbuf_max++;
    71     }
    72     return -1;
    73 }
    75 void video_gdk_shutdown()
    76 {
    77     unsigned int i;
    78     for( i=0; i<pixbuf_max; i++ ) {
    79 	if( pixbuf_array[i] != NULL ) {
    80 	    g_free(pixbuf_array[i]);
    81 	    pixbuf_array[i] = NULL;
    82 	}
    83     }
    84     pixbuf_max = 0;
    85     OSMesaDestroyContext( osmesa_context );
    86 }
    89 static render_buffer_t gdk_pixbuf_create_render_buffer( uint32_t width, uint32_t height )
    90 {
    91     render_buffer_t buf = g_malloc0(sizeof(struct render_buffer));
    92     gboolean alpha = FALSE;
    93     buf->width = width;
    94     buf->height = height;
    95     buf->buf_id = video_gdk_find_free();
    96     pixbuf_array[buf->buf_id] = g_malloc0( width * height * 4 );
    97     return buf;
    98 }
   100 static void gdk_pixbuf_destroy_render_buffer( render_buffer_t buffer )
   101 {
   102     g_free(pixbuf_array[buffer->buf_id] );
   103     pixbuf_array[buffer->buf_id] = NULL;
   104     if( buffer->buf_id == (pixbuf_max-1) ) {
   105 	pixbuf_max--;
   106     }
   107 }
   109 static gboolean gdk_pixbuf_display_render_buffer( render_buffer_t buffer )
   110 {
   111     glFinish();
   113     void *pb = pixbuf_array[buffer->buf_id];
   114     GdkGC *gc = gtk_video_win->style->fg_gc[GTK_STATE_NORMAL];
   115     GdkColor black = {0,0,0,0};
   117     assert(gc);
   119     int x1=0,y1=0,x2=video_width,y2=video_height;
   121     int ah = video_width * 0.75;
   124     if( ah > video_height ) {
   125 	int w = (video_height/0.75);
   126 	x1 = (video_width - w)/2;
   127 	x2 -= x1;
   128 	gdk_gc_set_foreground( gc, &black );
   129 	gdk_gc_set_background( gc, &black );
   130 	gdk_draw_rectangle( gtk_video_win->window, gc, TRUE, 0, 0, x1, video_height );
   131 	gdk_draw_rectangle( gtk_video_win->window, gc, TRUE, x2, 0, video_width, video_height );
   132     } else if( ah < video_height ) {
   133 	y1 = (video_height - ah)/2;
   134 	y2 -= y1;
   135 	gdk_gc_set_foreground( gc, &black );
   136 	gdk_gc_set_background( gc, &black );
   137 	gdk_draw_rectangle( gtk_video_win->window, gc, TRUE, 0, 0, video_width, y1 );
   138 	gdk_draw_rectangle( gtk_video_win->window, gc, TRUE, 0, y2, video_width, video_height );
   139     }
   140     int w = x2-x1;
   141     int h = y2-y1;
   143     if( w != buffer->width || h != buffer->height ) {
   144 	gdk_draw_rgb_32_image( gtk_video_win->window, gc, x1, y1, buffer->width, buffer->height, GDK_RGB_DITHER_NONE,
   145 			       pb, buffer->width*4 );
   146     } else {
   147 	gdk_draw_rgb_32_image( gtk_video_win->window, gc, x1, y1, buffer->width, buffer->height, GDK_RGB_DITHER_NONE,
   148 			       pb, buffer->width*4 );
   149     }
   150 }
   152 static gboolean gdk_pixbuf_display_blank( uint32_t colour )
   153 {
   154     GdkGC *gc = gtk_video_win->style->fg_gc[GTK_STATE_NORMAL];
   155     GdkColor col = { };
   157     gdk_gc_set_foreground( gc, &col );
   158     gdk_gc_set_background( gc, &col );
   159     gdk_draw_rectangle( gtk_video_win->window, gc, TRUE, 0, 0, video_width, video_height );
   160     return TRUE;
   161 }
   163 static gboolean gdk_pixbuf_set_render_target( render_buffer_t buffer )
   164 {
   165     glFinish();
   166     void *pb = pixbuf_array[buffer->buf_id];
   167     OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE,
   168 		       buffer->width, buffer->height );
   169     //OSMesaPixelStore( OSMESA_Y_UP, 0 );
   170     glViewport( 0, 0, buffer->width, buffer->height );
   171     glDrawBuffer(GL_FRONT);
   172     return TRUE;
   173 }
   175 static void gdk_pixbuf_load_frame_buffer( frame_buffer_t frame, render_buffer_t buffer )
   176 {
   177     glFinish();
   178     void *pb = pixbuf_array[buffer->buf_id];
   179     OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE,
   180 		       buffer->width, buffer->height );
   181     GLenum type = colour_formats[frame->colour_format].type;
   182     GLenum format = colour_formats[frame->colour_format].format;
   183     int bpp = colour_formats[frame->colour_format].bpp;
   184     int rowstride = (frame->rowstride / bpp) - frame->width;
   186     gl_reset_state();
   187     glPixelStorei( GL_UNPACK_ROW_LENGTH, rowstride );
   188     glRasterPos2f(0.375, frame->height-0.375);
   189     glPixelZoom( 1.0, 1.0 );
   190     glDrawPixels( frame->width, frame->height, format, type, frame->data );
   191     glFlush();
   192 }
   194 static gboolean gdk_pixbuf_read_render_buffer( unsigned char *target, render_buffer_t buffer, int rowstride, int format )
   195 {
   196     glFinish();
   197     void *pb = pixbuf_array[buffer->buf_id];
   198     OSMesaMakeCurrent( osmesa_context, pb, GL_UNSIGNED_BYTE,
   199 		       buffer->width, buffer->height );
   200     glReadBuffer( GL_FRONT );
   201     return gl_read_render_buffer( target, buffer, rowstride, format );
   203 }
.