qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* Re: [Qemu-devel] cocoa.m using openGL
@ 2005-05-23 23:58 Peter Stewart
  0 siblings, 0 replies; 18+ messages in thread
From: Peter Stewart @ 2005-05-23 23:58 UTC (permalink / raw)
  To: qemu-devel

Hi,

Just added Mike's keyboard fixes, so I could run doom.

Built and installed doom, it runs pretty well. It actually runs better 
than I expected, pretty cool.

Thanks for the .img.

peter.

^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: [Qemu-devel] cocoa.m using openGL
@ 2005-05-23 23:31 Peter Stewart
  2005-05-24  0:20 ` Mike Kronenberg
  0 siblings, 1 reply; 18+ messages in thread
From: Peter Stewart @ 2005-05-23 23:31 UTC (permalink / raw)
  To: qemu-devel

Hi,

Sorry for using up mail space, but here is the cocoa.m file.


enjoy,
peter.


/*
  * QEMU Cocoa display driver
  *
  * Copyright (c) 2005 Pierre d'Herbemont
  *                    many code/inspiration from SDL 1.2 code (LGPL)
  *
  * Permission is hereby granted, free of charge, to any person  
obtaining a copy
  * of this software and associated documentation files (the  
"Software"), to deal
  * in the Software without restriction, including without limitation  
the rights
  * to use, copy, modify, merge, publish, distribute, sublicense, and/or  
sell
  * copies of the Software, and to permit persons to whom the Software is
  * furnished to do so, subject to the following conditions:
  *
  * The above copyright notice and this permission notice shall be  
included in
  * all copies or substantial portions of the Software.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
EXPRESS OR
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT  
SHALL
  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR  
OTHER
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,  
ARISING FROM,
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER  
DEALINGS IN
  * THE SOFTWARE.
  */
/*
     Todo :    x  miniaturize window
               x  center the window
               -  save window position
               -  handle keyboard event
               -  handle mouse event
               -  non 32 bpp support
               -  full screen
               -  mouse focus
               x  simple graphical prompt to demo
               -  better graphical prompt
*/

#import <Cocoa/Cocoa.h>

#include <OpenGL/CGLCurrent.h>
#include <OpenGL/CGLContext.h>

#include "vl.h"

static NSWindow *window = NULL;
static NSOpenGLView *ogl_view = NULL;

#define SCREEN_BPP 32

int gArgc;
char **gArgv;
DisplayState current_ds;

GLint screen_tex = 0;
GLuint display_list_tex = 0;

/* main defined in qemu/vl.c */
int qemu_main(int argc, char **argv);

/* To deal with miniaturization */
@interface QemuWindow : NSWindow
{ }
@end


/*
  ------------------------------------------------------
     Qemu Video Driver
  ------------------------------------------------------
*/


/*
  ------------------------------------------------------
     cocoa_update
  ------------------------------------------------------
*/
static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
{
     //printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);

         // Make this context current
         [[ogl_view openGLContext] makeCurrentContext];

         // Bind, update and draw new image
         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);

         // glTexSubImage2D is faster when not using a texture range
         glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,  
(GLint)ds->width, (GLint)ds->height, 0, GL_BGRA,  
GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);

         // Use the compiled display list
         glCallList(display_list_tex);

         // Swap buffer to screen
         [[ogl_view openGLContext] flushBuffer];

}

/*
  ------------------------------------------------------
     cocoa_resize
  ------------------------------------------------------
*/
static void cocoa_resize(DisplayState *ds, int w, int h)
{

     NSRect contentRect;

     // printf("resizing to %d %d\n", w, h);

     contentRect = NSMakeRect (0, 0, w, h);

         [window setContentSize:contentRect.size];
         [window update];

         [[ogl_view openGLContext] makeCurrentContext];
         [[ogl_view openGLContext] update];

     glViewport(0, 0, (int) contentRect.size.width, (int)  
contentRect.size.height);

         glMatrixMode(GL_PROJECTION);
     glLoadIdentity();

         glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();

         // This is used as a init'd flag as well...
         if(screen_tex != 0) {
                 glDeleteTextures(1, &screen_tex);
                 glDeleteLists(display_list_tex, 1);
         }

         screen_tex = 1;

         if(ds->data != NULL) free(ds->data);
         ds->data = (GLubyte *) malloc(w * h * (SCREEN_BPP >> 3));
         assert(ds->data != NULL);
         ds->linesize = w * (SCREEN_BPP >> 3);
     ds->depth = SCREEN_BPP;
     ds->width = w;
     ds->height = h;

         // Setup some basic OpenGL stuff as from Apple
         glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
         glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
         glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

         glEnable(GL_TEXTURE_RECTANGLE_EXT);
         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);

         glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT,  w * h *  
(SCREEN_BPP >> 3), ds->data);

         // Use CACHED for VRAM+reused tex  Use SHARED for AGP+used once  
tex
         // Note the texture is always changing so use SHARED
         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
         glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S,  
GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T,  
GL_CLAMP_TO_EDGE);
         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);

         glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, w, h, 0,  
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);

         glFlush();

         // Setup a display list to save all the operations below

         display_list_tex = glGenLists(1);
         glNewList(display_list_tex, GL_COMPILE);

         glBegin(GL_QUADS);

         glTexCoord2f(0.0f, 0.0f);
         glVertex2f(-1.0f, 1.0f);

         glTexCoord2f(0.0f, (GLfloat)h);
         glVertex2f(-1.0f, -1.0f);

         glTexCoord2f((GLfloat)w, (GLfloat)h);
         glVertex2f(1.0f, -1.0f);

         glTexCoord2f((GLfloat)w, 0.0f);
         glVertex2f(1.0f, 1.0f);

         glEnd();

         glEndList();


         // Swap buffer to screen
         [[ogl_view openGLContext] flushBuffer];

         memcpy(&current_ds, ds, sizeof(DisplayState));
}

/*
  ------------------------------------------------------
     keymap conversion
  ------------------------------------------------------
*/

static int keymap[] =
{
     30, //'a' 0x0
     31,  //'s'
     32,  //'d'
     33,  //'f'
     35,  //'h'
     34,  //'g'
     44,  //'z'
     45,  //'x'
     46,  //'c'
     47,  //'v'
     0,   // 0  0x0a
     48,  //'b'
     16,  //'q'
     17,  //'w'
     18,  //'e'
     19,  //'r'
     21,  //'y' 0x10
     20,  //'t'
     2,  //'1'
     3,  //'2'
     4,  //'3'
     5,  //'4'
     7,  //'6'
     6,  //'5'
     0,  //'='
     10,  //'9'
     8,  //'7' 0x1A
     0,  //'-'
     9,  //'8'
     11,  //'0'
     27,  //']'
     24,  //'o'
     22,  //'u' 0x20
     26,  //'['
     23,  //'i'
     25,  //'p'
     28,  //'\n'
     38,  //'l'
     36,  //'j'
     40,  //'"'
     37,  //'k'
     39,  //';'
     15,  //'\t' 0x30
     0,  //' '
     0,  //'`'
     14,  //'<backspace>'
     0,  //'' 0x34
     0,  //'<esc>'
     0,  //'<esc>'
     /* Not completed to finish see  
http://www.libsdl.org/cgi/cvsweb.cgi/SDL12/src/video/quartz/ 
SDL_QuartzKeys.h?rev=1.6&content-type=text/x-cvsweb-markup */
};

static int cocoa_keycode_to_qemu(int keycode)
{
     if(sizeof(keymap) <= keycode)
     {
         printf("(cocoa) warning unknow keycode 0x%x\n", keycode);
         return 0;
     }
     return keymap[keycode];
}

/*
  ------------------------------------------------------
     cocoa_refresh
  ------------------------------------------------------
*/
static void cocoa_refresh(DisplayState *ds)
{
     //printf("cocoa_refresh \n");
     NSEvent *event;
     int grab = 1;
     NSDate *distantPast = [ NSDate distantPast ];;

     if (is_active_console(vga_console))
         vga_update_display();

     do {
         event = [ window nextEventMatchingMask:NSAnyEventMask  
untilDate:distantPast inMode: NSDefaultRunLoopMode dequeue:YES ];

         if (event != nil) {
             switch ([event type]) {
                 case NSKeyDown:
                     if(grab)
                     {
                         int keycode = cocoa_keycode_to_qemu([event  
keyCode]);

                         if (keycode & 0x80)
                             kbd_put_keycode(0xe0);
                         kbd_put_keycode(keycode & 0x7f);
                     }
                     break;
                 case NSKeyUp:
                     if(grab)
                     {
                         int keycode = cocoa_keycode_to_qemu([event  
keyCode]);

                         if (keycode & 0x80)
                             kbd_put_keycode(0xe0);
                         kbd_put_keycode(keycode | 0x80);
                     }
                     break;


                 case NSScrollWheel:
                                         if(grab)
                                         {
                                                 int dz = [event deltaZ];

                                                 kbd_mouse_event(0, 0,  
dz, 0);
                                         }
                                         break;


                 case NSMouseMoved:
                                         if(grab)
                                         {
                                                 int dx = [event deltaX];
                                                 int dy = [event deltaY];

                                                 kbd_mouse_event(dx, dy,  
0, 0);
                                         }
                                         break;


                 case NSOtherMouseDown:
                 case NSOtherMouseUp:
                 case NSOtherMouseDragged:
                                         if(grab)
                                         {
                                                 int dx = [event deltaX];
                                                 int dy = [event deltaY];
                                                 int dz = [event deltaZ];

                                                 kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_MBUTTON);
                                         }
                                         break;

                                 case NSRightMouseDown:
                 case NSRightMouseUp:
                 case NSRightMouseDragged:
                                         if(grab)
                                         {
                                                 int dx = [event deltaX];
                                                 int dy = [event deltaY];
                                                 int dz = [event deltaZ];

                                                 kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_RBUTTON);
                                         }
                                         break;

                 case NSLeftMouseDown:
                 case NSLeftMouseUp:
                 case NSLeftMouseDragged:
                                         if(grab)
                                         {
                                                 int dx = [event deltaX];
                                                 int dy = [event deltaY];
                                                 int dz = [event deltaZ];

                                                 kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_LBUTTON);
                                         }
                                         break;

                 default:
                                         [NSApp sendEvent:event];
             }
         }
     } while(event != nil);

}

/*
  ------------------------------------------------------
     cocoa_cleanup
  ------------------------------------------------------
*/

static void cocoa_cleanup(void)
{

}

/*
  ------------------------------------------------------
     cocoa_display_init
  ------------------------------------------------------
*/

void cocoa_display_init(DisplayState *ds, int full_screen)
{
     //printf("resizing to %d %d\n", w, h);

         const int w = 640;
         const int h = 400;

         if(window == nil)
         {
                 // Init pixel format attribs
                 NSOpenGLPixelFormatAttribute attrs[] =
                 {
                         NSOpenGLPFAAccelerated,
                         NSOpenGLPFANoRecovery,
                         NSOpenGLPFADoubleBuffer,
                         0
                 };

                 NSRect contentRect = NSMakeRect (0, 0, w, h);

                 // Get pixel format from OpenGL
                 NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat  
alloc] initWithAttributes:attrs];
                 if (!pixFmt)
                 {
                         fprintf(stderr, "No pixel format -- exiting");
                         exit(1);
                 }

                 window = [ [ QemuWindow alloc ]  
initWithContentRect:contentRect
                                                  
styleMask: 
NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
                                                  
backing:NSBackingStoreBuffered defer:NO];
                 if(!window)
                 {
                         fprintf(stderr, "(cocoa) can't create  
window\n");
                         exit(1);
                 }

                 ogl_view = [ [ NSOpenGLView alloc ]  
initWithFrame:contentRect pixelFormat:pixFmt ];

                 if(!ogl_view)
                 {
                         fprintf(stderr, "(cocoa) can't create  
ogl_view\n");
                         exit(1);
                 }

                 [ window setAcceptsMouseMovedEvents:YES ];
                 [ window setTitle:@"Qemu" ];
                 [ window setReleasedWhenClosed:NO ];

                 /* set window position */
                 [ window center ];
                 [ window makeKeyAndOrderFront:nil ];

                 [ ogl_view setAutoresizingMask: NSViewWidthSizable |  
NSViewHeightSizable ];
                 [ window setContentView:ogl_view ];
                 [ ogl_view release ];
         }

         ds->dpy_update = cocoa_update;
         ds->dpy_resize = cocoa_resize;
         ds->dpy_refresh = cocoa_refresh;

     cocoa_resize(ds, 640, 400);

         [ window display ];
         [ window makeMainWindow ];
         [ window makeKeyWindow ];

     atexit(cocoa_cleanup);
}

/*
  ------------------------------------------------------
     Interface with Cocoa
  ------------------------------------------------------
*/


/*
  ------------------------------------------------------
     QemuWindow
     Some trick from SDL to use miniwindow
  ------------------------------------------------------
*/


@implementation QemuWindow
- (void)miniaturize:(id)sender
{

     /* make the alpha channel opaque so anim won't have holes in it */
     [ super miniaturize:sender ];

}
- (void)display
{
     /*
         This method fires just before the window deminaturizes from the  
Dock.

         We'll save the current visible surface, let the window manager  
redraw any
         UI elements, and restore the SDL surface. This way, no expose  
event
         is required, and the deminiaturize works perfectly.
     */


     /* save current visible SDL surface */
     [ self cacheImageInRect:[ ogl_view frame ] ];

     /* let the window manager redraw controls, border, etc */
     [ super display ];

     /* restore visible SDL surface */
     [ self restoreCachedImage ];
}

@end


/*
  ------------------------------------------------------
     QemuCocoaGUIController
     NSApp's delegate - indeed main object
  ------------------------------------------------------
*/

@interface QemuCocoaGUIController : NSObject
{
}
- (void)applicationDidFinishLaunching: (NSNotification *) note;
- (void)applicationWillTerminate:(NSNotification *)aNotification;

- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode  
contextInfo:(void *)contextInfo;

- (void)startEmulationWithArgc:(int)argc argv:(char**)argv;
@end

@implementation QemuCocoaGUIController
/* Called when the internal event loop has just started running */
- (void)applicationDidFinishLaunching: (NSNotification *) note
{

     /* Display an open dialog box if no argument were passed or
        if qemu was launched from the finder ( the Finder passes "-psn"  
) */

     if( gArgc <= 1 || strncmp (gArgv[1], "-psn", 4) == 0)
     {
         NSOpenPanel *op = [[NSOpenPanel alloc] init];

                 cocoa_display_init(&current_ds, 0);

         [op setPrompt:@"Boot image"];

         [op setMessage:@"Select the disk image you want to boot.\n\nHit  
the \"Cancel\" button to quit"];

         [op beginSheetForDirectory:nil file:nil types:[NSArray  
arrayWithObjects: 
@"img",@"iso",@"dmg",@"qcow",@"cow",@"cloop",@"vmdk",nil]
               modalForWindow:window modalDelegate:self
                
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:)  
contextInfo:NULL];
     }
     else
     {
         /* or Launch Qemu, with the global args */
         [self startEmulationWithArgc:gArgc argv:gArgv];
     }
}

- (void)applicationWillTerminate:(NSNotification *)aNotification
{
     printf("Application will terminate\n");
     qemu_system_shutdown_request();
     /* In order to avoid a crash */
     exit(0);
}






- (void)openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode  
contextInfo:(void *)contextInfo
{
         [sheet close];

         if(returnCode == NSCancelButton)
     {
         exit(0);
     }

     if(returnCode == NSOKButton)
     {
         char *bin = "qemu";
         char *img = (char*)[ [ sheet filename ] cString];

         char **argv = (char**)malloc( sizeof(char*)*3 );

         asprintf(&argv[0], "%s", bin);
         asprintf(&argv[1], "-hda");
         asprintf(&argv[2], "%s", img);

         printf("Using argc %d argv %s -hda %s\n", 3, bin, img);

         [self startEmulationWithArgc:3 argv:(char**)argv];
     }
}

- (void)startEmulationWithArgc:(int)argc argv:(char**)argv
{
     int status;
     /* Launch Qemu */
     printf("starting qemu...\n");
     status = qemu_main (argc, argv);
     exit(status);
}
@end

/*
  ------------------------------------------------------
     Application Creation
  ------------------------------------------------------
*/

/* Dock Connection */
typedef struct CPSProcessSerNum
{
         UInt32                lo;
         UInt32                hi;
} CPSProcessSerNum;

extern OSErr    CPSGetCurrentProcess( CPSProcessSerNum *psn);
extern OSErr    CPSEnableForegroundOperation( CPSProcessSerNum *psn,  
UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
extern OSErr    CPSSetFrontProcess( CPSProcessSerNum *psn);

/* Menu Creation */
static void setApplicationMenu(void)
{
     /* warning: this code is very odd */
     NSMenu *appleMenu;
     NSMenuItem *menuItem;
     NSString *title;
     NSString *appName;

     appName = @"Qemu";
     appleMenu = [[NSMenu alloc] initWithTitle:@""];

     /* Add menu items */
     title = [@"About " stringByAppendingString:appName];
     [appleMenu addItemWithTitle:title  
action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];

     [appleMenu addItem:[NSMenuItem separatorItem]];

     title = [@"Hide " stringByAppendingString:appName];
     [appleMenu addItemWithTitle:title action:@selector(hide:)  
keyEquivalent:@"h"];

     menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others"  
action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
     [menuItem  
setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];

     [appleMenu addItemWithTitle:@"Show All"  
action:@selector(unhideAllApplications:) keyEquivalent:@""];

     [appleMenu addItem:[NSMenuItem separatorItem]];

     title = [@"Quit " stringByAppendingString:appName];
     [appleMenu addItemWithTitle:title action:@selector(terminate:)  
keyEquivalent:@"q"];


     /* Put menu into the menubar */
     menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil  
keyEquivalent:@""];
     [menuItem setSubmenu:appleMenu];
     [[NSApp mainMenu] addItem:menuItem];

     /* Tell the application object that this is now the application  
menu */
     [NSApp setAppleMenu:appleMenu];

     /* Finally give up our references to the objects */
     [appleMenu release];
     [menuItem release];
}

/* Create a window menu */
static void setupWindowMenu(void)
{
     NSMenu      *windowMenu;
     NSMenuItem  *windowMenuItem;
     NSMenuItem  *menuItem;

     windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];

     /* "Minimize" item */
     menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize"  
action:@selector(performMiniaturize:) keyEquivalent:@"m"];
     [windowMenu addItem:menuItem];
     [menuItem release];

     /* Put menu into the menubar */
     windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window"  
action:nil keyEquivalent:@""];
     [windowMenuItem setSubmenu:windowMenu];
     [[NSApp mainMenu] addItem:windowMenuItem];

     /* Tell the application object that this is now the window menu */
     [NSApp setWindowsMenu:windowMenu];

     /* Finally give up our references to the objects */
     [windowMenu release];
     [windowMenuItem release];

}

static void CustomApplicationMain (argc, argv)
{
     NSAutoreleasePool   *pool = [[NSAutoreleasePool alloc] init];
     QemuCocoaGUIController *gui_controller;
     CPSProcessSerNum PSN;

     [NSApplication sharedApplication];

     if (!CPSGetCurrentProcess(&PSN))
         if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
             if (!CPSSetFrontProcess(&PSN))
                 [NSApplication sharedApplication];

     /* Set up the menubar */
     [NSApp setMainMenu:[[NSMenu alloc] init]];
     setApplicationMenu();
     setupWindowMenu();

     /* Create SDLMain and make it the app delegate */
     gui_controller = [[QemuCocoaGUIController alloc] init];
     [NSApp setDelegate:gui_controller];

     /* Start the main event loop */
     [NSApp run];

     [gui_controller release];
     [pool release];
}

/* Real main of qemu-cocoa */
int main(int argc, char **argv)
{
     gArgc = argc;
     gArgv = argv;

     CustomApplicationMain (argc, argv);

     return 0;
}

^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: [Qemu-devel] cocoa.m using openGL
@ 2005-05-23 23:29 Peter Stewart
  0 siblings, 0 replies; 18+ messages in thread
From: Peter Stewart @ 2005-05-23 23:29 UTC (permalink / raw)
  To: qemu-devel

Hi,

Sorry, kind of new at this...

Here is the diff -u version of cocoa.m, I guess you got the  
Makefile.target fix :-)


diff -u cocoa.m.orig cocoa.m > cocoa.m.diff

enjoy,
peter.


--- cocoa.m.orig        Sat May 21 17:19:45 2005
+++ cocoa.m     Mon May 23 19:24:00 2005
@@ -37,16 +37,23 @@

  #import <Cocoa/Cocoa.h>

+#include <OpenGL/CGLCurrent.h>
+#include <OpenGL/CGLContext.h>
+
  #include "vl.h"

-NSWindow *window = NULL;
-NSQuickDrawView *qd_view = NULL;
+static NSWindow *window = NULL;
+static NSOpenGLView *ogl_view = NULL;

+#define SCREEN_BPP 32

  int gArgc;
  char **gArgv;
  DisplayState current_ds;

+GLint screen_tex = 0;
+GLuint display_list_tex = 0;
+
  /* main defined in qemu/vl.c */
  int qemu_main(int argc, char **argv);

@@ -62,6 +69,7 @@
   ------------------------------------------------------
  */

+
  /*
   ------------------------------------------------------
      cocoa_update
@@ -70,22 +78,22 @@
  static void cocoa_update(DisplayState *ds, int x, int y, int w, int h)
  {
      //printf("updating x=%d y=%d w=%d h=%d\n", x, y, w, h);
+
+       // Make this context current
+       [[ogl_view openGLContext] makeCurrentContext];
+
+       // Bind, update and draw new image
+       glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
+
+       // glTexSubImage2D is faster when not using a texture range
+       glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,  
(GLint)ds->width, (GLint)ds->height, 0, GL_BGRA,  
GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
+
+       // Use the compiled display list
+       glCallList(display_list_tex);
+
+       // Swap buffer to screen
+       [[ogl_view openGLContext] flushBuffer];

-    /* Use QDFlushPortBuffer() to flush content to display */
-    RgnHandle dirty = NewRgn ();
-    RgnHandle temp  = NewRgn ();
-
-    SetEmptyRgn (dirty);
-
-    /* Build the region of dirty rectangles */
-    MacSetRectRgn (temp, x, y,
-                        x + w, y + h);
-    MacUnionRgn (dirty, temp, dirty);
-
-    /* Flush the dirty region */
-    QDFlushPortBuffer ( [ qd_view  qdPort ], dirty );
-    DisposeRgn (dirty);
-    DisposeRgn (temp);
  }

  /*
@@ -95,74 +103,96 @@
  */
  static void cocoa_resize(DisplayState *ds, int w, int h)
  {
-    const int device_bpp = 32;
-    static void *screen_pixels;
-    static int  screen_pitch;
+
      NSRect contentRect;
+
+    // printf("resizing to %d %d\n", w, h);

-    //printf("resizing to %d %d\n", w, h);
-
-    contentRect = NSMakeRect (0, 0, w, h);
-    if(window)
-    {
-        [window close];
-        [window release];
-    }
-    window = [ [ QemuWindow alloc ] initWithContentRect:contentRect
-                                   
styleMask: 
NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
-                                  backing:NSBackingStoreBuffered  
defer:NO];
-    if(!window)
-    {
-        fprintf(stderr, "(cocoa) can't create window\n");
-        exit(1);
-    }
-
-    if(qd_view)
-        [qd_view release];
-
-    qd_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
-
-    if(!qd_view)
-    {
-         fprintf(stderr, "(cocoa) can't create qd_view\n");
-        exit(1);
-    }
-
-    [ window setAcceptsMouseMovedEvents:YES ];
-    [ window setTitle:@"Qemu" ];
-    [ window setReleasedWhenClosed:NO ];
-
-    /* Set screen to black */
-    [ window setBackgroundColor: [NSColor blackColor] ];
-
-    /* set window position */
-    [ window center ];
-
-    [ qd_view setAutoresizingMask: NSViewWidthSizable |  
NSViewHeightSizable ];
-    [ [ window contentView ] addSubview:qd_view ];
-    [ qd_view release ];
-    [ window makeKeyAndOrderFront:nil ];
-
-    /* Careful here, the window seems to have to be onscreen to do  
that */
-    LockPortBits ( [ qd_view qdPort ] );
-    screen_pixels = GetPixBaseAddr ( GetPortPixMap ( [ qd_view qdPort  
] ) );
-    screen_pitch  = GetPixRowBytes ( GetPortPixMap ( [ qd_view qdPort  
] ) );
-    UnlockPortBits ( [ qd_view qdPort ] );
-    {
-            int vOffset = [ window frame ].size.height -
-                [ qd_view frame ].size.height - [ qd_view frame  
].origin.y;
-
-            int hOffset = [ qd_view frame ].origin.x;
-
-            screen_pixels += (vOffset * screen_pitch) + hOffset *  
(device_bpp/8);
-    }
-    ds->data = screen_pixels;
-    ds->linesize = screen_pitch;
-    ds->depth = device_bpp;
+    contentRect = NSMakeRect (0, 0, w, h);
+
+       [window setContentSize:contentRect.size];
+       [window update];
+
+       [[ogl_view openGLContext] makeCurrentContext];
+       [[ogl_view openGLContext] update];
+
+    glViewport(0, 0, (int) contentRect.size.width, (int)  
contentRect.size.height);
+
+       glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+
+       glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+       // This is used as a init'd flag as well...
+       if(screen_tex != 0) {
+               glDeleteTextures(1, &screen_tex);
+               glDeleteLists(display_list_tex, 1);
+       }
+
+       screen_tex = 1;
+
+       if(ds->data != NULL) free(ds->data);
+       ds->data = (GLubyte *) malloc(w * h * (SCREEN_BPP >> 3));
+       assert(ds->data != NULL);
+       ds->linesize = w * (SCREEN_BPP >> 3);
+    ds->depth = SCREEN_BPP;
      ds->width = w;
      ds->height = h;
-
-    current_ds = *ds;
+
+       // Setup some basic OpenGL stuff as from Apple
+       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+       glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+       glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+
+       glEnable(GL_TEXTURE_RECTANGLE_EXT);
+       glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
+
+       glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT,  w * h *  
(SCREEN_BPP >> 3), ds->data);
+
+       // Use CACHED for VRAM+reused tex  Use SHARED for AGP+used once  
tex
+       // Note the texture is always changing so use SHARED
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
+       glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S,  
GL_CLAMP_TO_EDGE);
+       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T,  
GL_CLAMP_TO_EDGE);
+       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+
+       glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, w, h, 0,  
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
+
+       glFlush();
+
+       // Setup a display list to save all the operations below
+
+       display_list_tex = glGenLists(1);
+       glNewList(display_list_tex, GL_COMPILE);
+
+       glBegin(GL_QUADS);
+
+       glTexCoord2f(0.0f, 0.0f);
+       glVertex2f(-1.0f, 1.0f);
+
+       glTexCoord2f(0.0f, (GLfloat)h);
+       glVertex2f(-1.0f, -1.0f);
+
+       glTexCoord2f((GLfloat)w, (GLfloat)h);
+       glVertex2f(1.0f, -1.0f);
+
+       glTexCoord2f((GLfloat)w, 0.0f);
+       glVertex2f(1.0f, 1.0f);
+
+       glEnd();
+
+       glEndList();
+
+
+       // Swap buffer to screen
+       [[ogl_view openGLContext] flushBuffer];
+
+       memcpy(&current_ds, ds, sizeof(DisplayState));
  }

  /*
@@ -243,19 +273,16 @@
  static void cocoa_refresh(DisplayState *ds)
  {
      //printf("cocoa_refresh \n");
-    NSDate *distantPast;
      NSEvent *event;
-    NSAutoreleasePool *pool;
      int grab = 1;
-
-    pool = [ [ NSAutoreleasePool alloc ] init ];
-    distantPast = [ NSDate distantPast ];
-
+    NSDate *distantPast = [ NSDate distantPast ];;
+
      if (is_active_console(vga_console))
          vga_update_display();
+
      do {
-        event = [ NSApp nextEventMatchingMask:NSAnyEventMask  
untilDate:distantPast
-                        inMode: NSDefaultRunLoopMode dequeue:YES ];
+        event = [ window nextEventMatchingMask:NSAnyEventMask  
untilDate:distantPast inMode: NSDefaultRunLoopMode dequeue:YES ];
+
          if (event != nil) {
              switch ([event type]) {
                  case NSKeyDown:
@@ -278,26 +305,74 @@
                          kbd_put_keycode(keycode | 0x80);
                      }
                      break;
+
+
                  case NSScrollWheel:
-
-                case NSLeftMouseDown:
-                case NSLeftMouseUp:
-
-                case NSOtherMouseDown:
-                case NSRightMouseDown:
-
-                case NSOtherMouseUp:
-                case NSRightMouseUp:
-
+                                       if(grab)
+                                       {
+                                               int dz = [event deltaZ];
+
+                                               kbd_mouse_event(0, 0,  
dz, 0);
+                                       }
+                                       break;
+
+
                  case NSMouseMoved:
+                                       if(grab)
+                                       {
+                                               int dx = [event deltaX];
+                                               int dy = [event deltaY];
+
+                                               kbd_mouse_event(dx, dy,  
0, 0);
+                                       }
+                                       break;
+
+
+                case NSOtherMouseDown:
+                case NSOtherMouseUp:
                  case NSOtherMouseDragged:
+                                       if(grab)
+                                       {
+                                               int dx = [event deltaX];
+                                               int dy = [event deltaY];
+                                               int dz = [event deltaZ];
+
+                                               kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_MBUTTON);
+                                       }
+                                       break;
+
+                               case NSRightMouseDown:
+                case NSRightMouseUp:
                  case NSRightMouseDragged:
+                                       if(grab)
+                                       {
+                                               int dx = [event deltaX];
+                                               int dy = [event deltaY];
+                                               int dz = [event deltaZ];
+
+                                               kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_RBUTTON);
+                                       }
+                                       break;
+
+                case NSLeftMouseDown:
+                case NSLeftMouseUp:
                  case NSLeftMouseDragged:
-
-                default: [NSApp sendEvent:event];
+                                       if(grab)
+                                       {
+                                               int dx = [event deltaX];
+                                               int dy = [event deltaY];
+                                               int dz = [event deltaZ];
+
+                                               kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_LBUTTON);
+                                       }
+                                       break;
+
+                default:
+                                       [NSApp sendEvent:event];
              }
          }
      } while(event != nil);
+
  }

  /*
@@ -319,12 +394,72 @@

  void cocoa_display_init(DisplayState *ds, int full_screen)
  {
-    ds->dpy_update = cocoa_update;
-    ds->dpy_resize = cocoa_resize;
-    ds->dpy_refresh = cocoa_refresh;
+    //printf("resizing to %d %d\n", w, h);
+
+       const int w = 640;
+       const int h = 400;
+
+       if(window == nil)
+       {
+               // Init pixel format attribs
+               NSOpenGLPixelFormatAttribute attrs[] =
+               {
+                       NSOpenGLPFAAccelerated,
+                       NSOpenGLPFANoRecovery,
+                       NSOpenGLPFADoubleBuffer,
+                       0
+               };
+
+               NSRect contentRect = NSMakeRect (0, 0, w, h);
+
+               // Get pixel format from OpenGL
+               NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat  
alloc] initWithAttributes:attrs];
+               if (!pixFmt)
+               {
+                       fprintf(stderr, "No pixel format -- exiting");
+                       exit(1);
+               }
+
+               window = [ [ QemuWindow alloc ]  
initWithContentRect:contentRect
+                                                
styleMask: 
NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
+                                                
backing:NSBackingStoreBuffered defer:NO];
+               if(!window)
+               {
+                       fprintf(stderr, "(cocoa) can't create  
window\n");
+                       exit(1);
+               }
+
+               ogl_view = [ [ NSOpenGLView alloc ]  
initWithFrame:contentRect pixelFormat:pixFmt ];
+
+               if(!ogl_view)
+               {
+                       fprintf(stderr, "(cocoa) can't create  
ogl_view\n");
+                       exit(1);
+               }
+
+               [ window setAcceptsMouseMovedEvents:YES ];
+               [ window setTitle:@"Qemu" ];
+               [ window setReleasedWhenClosed:NO ];
+
+               /* set window position */
+               [ window center ];
+               [ window makeKeyAndOrderFront:nil ];
+
+               [ ogl_view setAutoresizingMask: NSViewWidthSizable |  
NSViewHeightSizable ];
+               [ window setContentView:ogl_view ];
+               [ ogl_view release ];
+       }
+
+       ds->dpy_update = cocoa_update;
+       ds->dpy_resize = cocoa_resize;
+       ds->dpy_refresh = cocoa_refresh;

      cocoa_resize(ds, 640, 400);
-
+
+       [ window display ];
+       [ window makeMainWindow ];
+       [ window makeKeyWindow ];
+
      atexit(cocoa_cleanup);
  }

@@ -341,30 +476,13 @@
      Some trick from SDL to use miniwindow
   ------------------------------------------------------
  */
-static void QZ_SetPortAlphaOpaque ()
-{
-    /* Assume 32 bit if( bpp == 32 )*/
-    if ( 1 ) {
-
-        uint32_t    *pixels = (uint32_t*) current_ds.data;
-        uint32_t    rowPixels = current_ds.linesize / 4;
-        uint32_t    i, j;
-
-        for (i = 0; i < current_ds.height; i++)
-            for (j = 0; j < current_ds.width; j++) {
-
-                pixels[ (i * rowPixels) + j ] |= 0xFF000000;
-            }
-    }
-}
+

  @implementation QemuWindow
  - (void)miniaturize:(id)sender
  {

-    /* make the alpha channel opaque so anim won't have holes in it */
-    QZ_SetPortAlphaOpaque ();
-
+    /* make the alpha channel opaque so anim won't have holes in it */
      [ super miniaturize:sender ];

  }
@@ -377,12 +495,10 @@
          UI elements, and restore the SDL surface. This way, no expose  
event
          is required, and the deminiaturize works perfectly.
      */
-
-    /* make sure pixels are fully opaque */
-    QZ_SetPortAlphaOpaque ();
+

      /* save current visible SDL surface */
-    [ self cacheImageInRect:[ qd_view frame ] ];
+    [ self cacheImageInRect:[ ogl_view frame ] ];

      /* let the window manager redraw controls, border, etc */
      [ super display ];
@@ -424,8 +540,8 @@
      {
          NSOpenPanel *op = [[NSOpenPanel alloc] init];

-        cocoa_resize(&current_ds, 640, 400);
-
+               cocoa_display_init(&current_ds, 0);
+
          [op setPrompt:@"Boot image"];

          [op setMessage:@"Select the disk image you want to  
boot.\n\nHit the \"Cancel\" button to quit"];
@@ -449,9 +565,16 @@
      exit(0);
  }

+
+
+
+
+
  - (void)openPanelDidEnd:(NSOpenPanel *)sheet  
returnCode:(int)returnCode contextInfo:(void *)contextInfo
  {
-    if(returnCode == NSCancelButton)
+       [sheet close];
+
+       if(returnCode == NSCancelButton)
      {
          exit(0);
      }

^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: [Qemu-devel] cocoa.m using openGL
@ 2005-05-23 17:31 Peter Stewart
  2005-05-23 19:17 ` Mike Kronenberg
  0 siblings, 1 reply; 18+ messages in thread
From: Peter Stewart @ 2005-05-23 17:31 UTC (permalink / raw)
  To: qemu-devel

Hi,

It looks faster than the original, but I don't have a benchmark, is  
there one?
I would really like a bootable image with Doom 1 on it.

I also added to Makefile.target, the "-framework OpenGL" bit.

ifdef CONFIG_COCOA
VL_OBJS+=cocoa.o
COCOA_LIBS=-F/System/Library/Frameworks -framework Cocoa -framework  
OpenGL
endif



enjoy,
peter.


Here is the diff for cocoa.m ( diff cocoa.m.orig cocoa.m ) (from 0.7.0  
dl):

 > #include <OpenGL/CGLCurrent.h>
 > #include <OpenGL/CGLContext.h>
 >
42,43c45,46
< NSWindow *window = NULL;
< NSQuickDrawView *qd_view = NULL;
---
 > static NSWindow *window = NULL;
 > static NSOpenGLView *ogl_view = NULL;
44a48
 > #define SCREEN_BPP 32
49a54,56
 > GLint screen_tex = 0;
 > GLuint display_list_tex = 0;
 >
64a72
 >
72a81,95
 >
 >       // Make this context current
 >       [[ogl_view openGLContext] makeCurrentContext];
 >
 >       // Bind, update and draw new image
 >       glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
 >
 >       // glTexSubImage2D is faster when not using a texture range
 >       glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA,  
(GLint)ds->width, (GLint)ds->height, 0, GL_BGRA,  
GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
 >
 >       // Use the compiled display list
 >       glCallList(display_list_tex);
 >
 >       // Swap buffer to screen
 >       [[ogl_view openGLContext] flushBuffer];
74,88d96
<     /* Use QDFlushPortBuffer() to flush content to display */
<     RgnHandle dirty = NewRgn ();
<     RgnHandle temp  = NewRgn ();
<
<     SetEmptyRgn (dirty);
<
<     /* Build the region of dirty rectangles */
<     MacSetRectRgn (temp, x, y,
<                         x + w, y + h);
<     MacUnionRgn (dirty, temp, dirty);
<
<     /* Flush the dirty region */
<     QDFlushPortBuffer ( [ qd_view  qdPort ], dirty );
<     DisposeRgn (dirty);
<     DisposeRgn (temp);
98,100c106
<     const int device_bpp = 32;
<     static void *screen_pixels;
<     static int  screen_pitch;
---
 >
101a108,109
 >
 >     // printf("resizing to %d %d\n", w, h);
103,161c111,139
<     //printf("resizing to %d %d\n", w, h);
<
<     contentRect = NSMakeRect (0, 0, w, h);
<     if(window)
<     {
<         [window close];
<         [window release];
<     }
<     window = [ [ QemuWindow alloc ] initWithContentRect:contentRect
<                                    
styleMask: 
NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
<                                   backing:NSBackingStoreBuffered  
defer:NO];
<     if(!window)
<     {
<         fprintf(stderr, "(cocoa) can't create window\n");
<         exit(1);
<     }
<
<     if(qd_view)
<         [qd_view release];
<
<     qd_view = [ [ NSQuickDrawView alloc ] initWithFrame:contentRect ];
<
<     if(!qd_view)
<     {
<          fprintf(stderr, "(cocoa) can't create qd_view\n");
<         exit(1);
<     }
<
<     [ window setAcceptsMouseMovedEvents:YES ];
<     [ window setTitle:@"Qemu" ];
<     [ window setReleasedWhenClosed:NO ];
<
<     /* Set screen to black */
<     [ window setBackgroundColor: [NSColor blackColor] ];
<
<     /* set window position */
<     [ window center ];
<
<     [ qd_view setAutoresizingMask: NSViewWidthSizable |  
NSViewHeightSizable ];
<     [ [ window contentView ] addSubview:qd_view ];
<     [ qd_view release ];
<     [ window makeKeyAndOrderFront:nil ];
<
<     /* Careful here, the window seems to have to be onscreen to do  
that */
<     LockPortBits ( [ qd_view qdPort ] );
<     screen_pixels = GetPixBaseAddr ( GetPortPixMap ( [ qd_view qdPort  
] ) );
<     screen_pitch  = GetPixRowBytes ( GetPortPixMap ( [ qd_view qdPort  
] ) );
<     UnlockPortBits ( [ qd_view qdPort ] );
<     {
<             int vOffset = [ window frame ].size.height -
<                 [ qd_view frame ].size.height - [ qd_view frame  
].origin.y;
<
<             int hOffset = [ qd_view frame ].origin.x;
<
<             screen_pixels += (vOffset * screen_pitch) + hOffset *  
(device_bpp/8);
<     }
<     ds->data = screen_pixels;
<     ds->linesize = screen_pitch;
<     ds->depth = device_bpp;
---
 >     contentRect = NSMakeRect (0, 0, w, h);
 >
 >       [window setContentSize:contentRect.size];
 >       [window update];
 >
 >       [[ogl_view openGLContext] makeCurrentContext];
 >       [[ogl_view openGLContext] update];
 >
 >     glViewport(0, 0, (int) contentRect.size.width, (int)  
contentRect.size.height);
 >
 >       glMatrixMode(GL_PROJECTION);
 >     glLoadIdentity();
 >
 >       glMatrixMode(GL_MODELVIEW);
 >     glLoadIdentity();
 >
 >       // This is used as a init'd flag as well...
 >       if(screen_tex != 0) {
 >               glDeleteTextures(1, &screen_tex);
 >               glDeleteLists(display_list_tex, 1);
 >       }
 >
 >       screen_tex = 1;
 >
 >       if(ds->data != NULL) free(ds->data);
 >       ds->data = (GLubyte *) malloc(w * h * (SCREEN_BPP >> 3));
 >       assert(ds->data != NULL);
 >       ds->linesize = w * (SCREEN_BPP >> 3);
 >     ds->depth = SCREEN_BPP;
164,165c142,195
<
<     current_ds = *ds;
---
 >
 >       // Setup some basic OpenGL stuff as from Apple
 >       glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
 >       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 >       glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
 >       glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
 >
 >       glEnable(GL_TEXTURE_RECTANGLE_EXT);
 >       glBindTexture(GL_TEXTURE_RECTANGLE_EXT, screen_tex);
 >
 >       glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT,  w * h *  
(SCREEN_BPP >> 3), ds->data);
 >
 >       // Use CACHED for VRAM+reused tex  Use SHARED for AGP+used once  
tex
 >       // Note the texture is always changing so use SHARED
 >       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
 >       glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
 >       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 >       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT,  
GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 >       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S,  
GL_CLAMP_TO_EDGE);
 >       glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T,  
GL_CLAMP_TO_EDGE);
 >       glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
 >
 >       glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, w, h, 0,  
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, ds->data);
 >
 >       glFlush();
 >
 >       // Setup a display list to save all the operations below
 >
 >       display_list_tex = glGenLists(1);
 >       glNewList(display_list_tex, GL_COMPILE);
 >
 >       glBegin(GL_QUADS);
 >
 >       glTexCoord2f(0.0f, 0.0f);
 >       glVertex2f(-1.0f, 1.0f);
 >
 >       glTexCoord2f(0.0f, (GLfloat)h);
 >       glVertex2f(-1.0f, -1.0f);
 >
 >       glTexCoord2f((GLfloat)w, (GLfloat)h);
 >       glVertex2f(1.0f, -1.0f);
 >
 >       glTexCoord2f((GLfloat)w, 0.0f);
 >       glVertex2f(1.0f, 1.0f);
 >
 >       glEnd();
 >
 >       glEndList();
 >
 >
 >       // Swap buffer to screen
 >       [[ogl_view openGLContext] flushBuffer];
 >
 >       memcpy(&current_ds, ds, sizeof(DisplayState));
246d275
<     NSDate *distantPast;
248d276
<     NSAutoreleasePool *pool;
250,253c278,279
<
<     pool = [ [ NSAutoreleasePool alloc ] init ];
<     distantPast = [ NSDate distantPast ];
<
---
 >     NSDate *distantPast = [ NSDate distantPast ];;
 >
255a282
 >
257,258c284,285
<         event = [ NSApp nextEventMatchingMask:NSAnyEventMask  
untilDate:distantPast
<                         inMode: NSDefaultRunLoopMode dequeue:YES ];
---
 >         event = [ window nextEventMatchingMask:NSAnyEventMask  
untilDate:distantPast inMode: NSDefaultRunLoopMode dequeue:YES ];
 >
280a308,309
 >
 >
282,291c311,319
<
<                 case NSLeftMouseDown:
<                 case NSLeftMouseUp:
<
<                 case NSOtherMouseDown:
<                 case NSRightMouseDown:
<
<                 case NSOtherMouseUp:
<                 case NSRightMouseUp:
<
---
 >                                       if(grab)
 >                                       {
 >                                               int dz = [event deltaZ];
 >
 >                                               kbd_mouse_event(0, 0,  
dz, 0);
 >                                       }
 >                                       break;
 >
 >
292a321,332
 >                                       if(grab)
 >                                       {
 >                                               int dx = [event deltaX];
 >                                               int dy = [event deltaY];
 >
 >                                               kbd_mouse_event(dx, dy,  
0, 0);
 >                                       }
 >                                       break;
 >
 >
 >                 case NSOtherMouseDown:
 >                 case NSOtherMouseUp:
293a334,345
 >                                       if(grab)
 >                                       {
 >                                               int dx = [event deltaX];
 >                                               int dy = [event deltaY];
 >                                               int dz = [event deltaZ];
 >
 >                                               kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_MBUTTON);
 >                                       }
 >                                       break;
 >
 >                               case NSRightMouseDown:
 >                 case NSRightMouseUp:
294a347,358
 >                                       if(grab)
 >                                       {
 >                                               int dx = [event deltaX];
 >                                               int dy = [event deltaY];
 >                                               int dz = [event deltaZ];
 >
 >                                               kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_RBUTTON);
 >                                       }
 >                                       break;
 >
 >                 case NSLeftMouseDown:
 >                 case NSLeftMouseUp:
296,297c360,371
<
<                 default: [NSApp sendEvent:event];
---
 >                                       if(grab)
 >                                       {
 >                                               int dx = [event deltaX];
 >                                               int dy = [event deltaY];
 >                                               int dz = [event deltaZ];
 >
 >                                               kbd_mouse_event(dx, dy,  
dz, MOUSE_EVENT_LBUTTON);
 >                                       }
 >                                       break;
 >
 >                 default:
 >                                       [NSApp sendEvent:event];
300a375
 >
322,324c397,455
<     ds->dpy_update = cocoa_update;
<     ds->dpy_resize = cocoa_resize;
<     ds->dpy_refresh = cocoa_refresh;
---
 >     //printf("resizing to %d %d\n", w, h);
 >
 >       const int w = 640;
 >       const int h = 400;
 >
 >       if(window == nil)
 >       {
 >               // Init pixel format attribs
 >               NSOpenGLPixelFormatAttribute attrs[] =
 >               {
 >                       NSOpenGLPFAAccelerated,
 >                       NSOpenGLPFANoRecovery,
 >                       NSOpenGLPFADoubleBuffer,
 >                       0
 >               };
 >
 >               NSRect contentRect = NSMakeRect (0, 0, w, h);
 >
 >               // Get pixel format from OpenGL
 >               NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat  
alloc] initWithAttributes:attrs];
 >               if (!pixFmt)
 >               {
 >                       fprintf(stderr, "No pixel format -- exiting");
 >                       exit(1);
 >               }
 >
 >               window = [ [ QemuWindow alloc ]  
initWithContentRect:contentRect
 >                                                
styleMask: 
NSTitledWindowMask|NSMiniaturizableWindowMask|NSClosableWindowMask
 >                                                
backing:NSBackingStoreBuffered defer:NO];
 >               if(!window)
 >               {
 >                       fprintf(stderr, "(cocoa) can't create  
window\n");
 >                       exit(1);
 >               }
 >
 >               ogl_view = [ [ NSOpenGLView alloc ]  
initWithFrame:contentRect pixelFormat:pixFmt ];
 >
 >               if(!ogl_view)
 >               {
 >                       fprintf(stderr, "(cocoa) can't create  
ogl_view\n");
 >                       exit(1);
 >               }
 >
 >               [ window setAcceptsMouseMovedEvents:YES ];
 >               [ window setTitle:@"Qemu" ];
 >               [ window setReleasedWhenClosed:NO ];
 >
 >               /* set window position */
 >               [ window center ];
 >               [ window makeKeyAndOrderFront:nil ];
 >
 >               [ ogl_view setAutoresizingMask: NSViewWidthSizable |  
NSViewHeightSizable ];
 >               [ window setContentView:ogl_view ];
 >               [ ogl_view release ];
 >       }
 >
 >       ds->dpy_update = cocoa_update;
 >       ds->dpy_resize = cocoa_resize;
 >       ds->dpy_refresh = cocoa_refresh;
327c458,462
<
---
 >
 >       [ window display ];
 >       [ window makeMainWindow ];
 >       [ window makeKeyWindow ];
 >
344,359c479
< static void QZ_SetPortAlphaOpaque ()
< {
<     /* Assume 32 bit if( bpp == 32 )*/
<     if ( 1 ) {
<
<         uint32_t    *pixels = (uint32_t*) current_ds.data;
<         uint32_t    rowPixels = current_ds.linesize / 4;
<         uint32_t    i, j;
<
<         for (i = 0; i < current_ds.height; i++)
<             for (j = 0; j < current_ds.width; j++) {
<
<                 pixels[ (i * rowPixels) + j ] |= 0xFF000000;
<             }
<     }
< }
---
 >
365,367c485
<     /* make the alpha channel opaque so anim won't have holes in it */
<     QZ_SetPortAlphaOpaque ();
<
---
 >     /* make the alpha channel opaque so anim won't have holes in it */
380,382c498
<
<     /* make sure pixels are fully opaque */
<     QZ_SetPortAlphaOpaque ();
---
 >
385c501
<     [ self cacheImageInRect:[ qd_view frame ] ];
---
 >     [ self cacheImageInRect:[ ogl_view frame ] ];
427,428c543,544
<         cocoa_resize(&current_ds, 640, 400);
<
---
 >               cocoa_display_init(&current_ds, 0);
 >
451a568,572
 >
 >
 >
 >
 >
454c575,577
<     if(returnCode == NSCancelButton)
---
 >       [sheet close];
 >
 >       if(returnCode == NSCancelButton)

^ permalink raw reply	[flat|nested] 18+ messages in thread
* Re: [Qemu-devel] cocoa.m using openGL
@ 2005-05-23  7:47 Peter Stewart
  2005-05-23  8:38 ` Mike Kronenberg
  0 siblings, 1 reply; 18+ messages in thread
From: Peter Stewart @ 2005-05-23  7:47 UTC (permalink / raw)
  To: qemu-devel

Hi Hetz,

I will do a comparison, and a diff, and add some more comments.

I have a 800Mhz ibook 640M. When I ran Knoppix, and glxgears I got 7fps 
on OpenGL profiler and 5fps reported by glxgears. OpenGL profiler 
reported that a maximum of 5% of the time was being spent in OpenGL. On 
average about 2% of the time was spent in OpenGL. The peak fps was 27 
fps, this happens during the text based startup of Knoppix (the green 
bar with the text spinner). I would like to run doom2 shareware dos 
based to see what fps I get, should be okay I think, but don't know how 
to get a bootable image with the shareware software on it.


thanks,
peter.

^ permalink raw reply	[flat|nested] 18+ messages in thread
* [Qemu-devel] cocoa.m using openGL
@ 2005-05-22 13:00 Peter Stewart
  2005-05-22 13:45 ` Hetz Ben Hamo
                   ` (3 more replies)
  0 siblings, 4 replies; 18+ messages in thread
From: Peter Stewart @ 2005-05-22 13:00 UTC (permalink / raw)
  To: qemu-devel

Hello to all,

esp. Pierre d'Herbemont,

I have changed cocoa.m (0.7.0) to use openGL with very fast texturing. 
I removed the use of QuickDraw. The DisplayState data is now DMA'd to 
the graphics card instead of copied by the CPU. This uses apple's 
texture range extensions. The change means that the transfer of 
"display memory" incurs no CPU overhead. I also put in a bit more mouse 
stuff, and made some other fixes. I can't work out how to get the 
Window to get focus once it loses it, which is really a pain.

I Shark'd it to make sure there wasn't any overhead from the texturing. 
I tested with Knoppix and FreeDOS.

I am not sure if this is of interest to people, I just had a lazy 
weekend. I would like to give the code to the qemu project, but don't 
really know how to.


thanks,
peter.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2005-05-29 14:51 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-05-23 23:58 [Qemu-devel] cocoa.m using openGL Peter Stewart
  -- strict thread matches above, loose matches on Subject: below --
2005-05-23 23:31 Peter Stewart
2005-05-24  0:20 ` Mike Kronenberg
2005-05-23 23:29 Peter Stewart
2005-05-23 17:31 Peter Stewart
2005-05-23 19:17 ` Mike Kronenberg
2005-05-23 21:54   ` Hetz Ben Hamo
2005-05-23  7:47 Peter Stewart
2005-05-23  8:38 ` Mike Kronenberg
2005-05-22 13:00 Peter Stewart
2005-05-22 13:45 ` Hetz Ben Hamo
2005-05-23  7:20 ` Mike Kronenberg
2005-05-24 15:11 ` Mike Kronenberg
2005-05-26 15:09   ` Pierre d'Herbemont
2005-05-27 14:57   ` Pierre d'Herbemont
2005-05-28 18:39     ` Mike Kronenberg
2005-05-29 14:47       ` Pierre d'Herbemont
2005-05-26 14:52 ` Pierre d'Herbemont

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).