Menu

Main Menu
Talk Get Daily Search

Member's Online

    User Name
    Password

    Compositor Scaling Sample Code

    Reply
    ArnimS | # 1 | 2009-11-04, 21:49 | Report

    Code:
    /*
       Posted by someone who may or may not want their name on this 
       gcc -Wall -o parent-test parent-test.c \
           `pkg-config --cflags --libs gtk+-2.0 hildon-1`
      
     */
    
    #include <cairo.h>
    #include <gtk/gtk.h>
    #include <glib.h>
    #include <math.h>
    #include <stdlib.h>
    #include <hildon/hildon.h>
    
    static gint X_SIZE = 320;
    static gint Y_SIZE = 240;
    
    static gint X_POS = 0;
    static gint Y_POS = 56;
    
    static gint X_FULL = 800;
    static gint Y_FULL = 424;
    
    static gdouble X_SCALE = 2.5;  /* X_FULL / X_SIZE */
    static gdouble Y_SCALE = 1.77; /* Y_FULL / Y_SIZE */
    
    
    /** Simple drawing widget **/
    
    static void
    drawing_button_event (GtkWidget *drawing,
    		      GdkEventButton *event,
    		      cairo_t *context)
    {
      cairo_new_path (context);
      cairo_move_to (context, event->x + 5, event->y);
      cairo_arc (context, event->x, event->y, 5, 0, 2 * M_PI);
      if (event->type == GDK_BUTTON_PRESS)
        cairo_set_source_rgb (context, 1.0, 0.0, 0.0);
      else
        cairo_set_source_rgb (context, 0.0, 0.0, 1.0);
      cairo_fill (context);
    }
    
    static void
    drawing_realize (GtkWidget *drawing,
    		 gpointer user_data)
    {
      cairo_t *context;
      context = gdk_cairo_create (GDK_DRAWABLE (drawing->window));
      gtk_widget_add_events (drawing,
    			 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
      g_signal_connect (drawing, "button-press-event",
    		    G_CALLBACK (drawing_button_event), context);
      g_signal_connect (drawing, "button-release-event",
    		    G_CALLBACK (drawing_button_event), context);
    }
    
    static GtkWidget *
    get_drawing_widget (void)
    {
      GtkWidget *drawing = gtk_drawing_area_new ();
      GtkRequisition *req;
      g_signal_connect (drawing, "realize",
    		    G_CALLBACK (drawing_realize), NULL);
      return drawing;
    }
    
    /** Test application **/
    
    static void
    window_button_proxy (GtkWidget *widget,
    		     GdkEventButton *event,
    		     GtkWidget *proxy)
    {
      GdkEventButton *newev = (GdkEventButton *) gdk_event_copy ((GdkEvent *) event);
      newev->window = proxy->window;
      newev->x = (gint) (newev->x / X_SCALE);
      newev->y = (gint) (newev->y / Y_SCALE);
      gdk_event_put ((GdkEvent *) newev);
    }
    
    static void
    button_clicked (GtkWidget *widget, HildonAnimationActor *actor)
    {
      static gboolean fullscreen = FALSE;
    
      if (fullscreen) {
        hildon_animation_actor_set_scale (actor, 1.0, 1.0);
        fullscreen = FALSE;
      }
      else {
        hildon_animation_actor_set_scale (actor, X_SCALE, Y_SCALE);
        fullscreen = TRUE;
      }
    }
    
    
    int
    main (int argc,
          char *argv[])
    {
      HildonAnimationActor *actor;
      GtkWidget *window, *drawing;
      HildonProgram *program;
      GdkColor pink = { .red = 0xffff, .green = 0x9999, .blue = 0x9999 };
    
      gtk_init (&argc, &argv);
    
      window = hildon_stackable_window_new ();
      gtk_widget_modify_bg (GTK_WIDGET (window), GTK_STATE_NORMAL, &pink);
      g_signal_connect (G_OBJECT (window), "delete_event",
    		    G_CALLBACK (gtk_main_quit), NULL);
      gtk_widget_add_events (window,
    			 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
    
      actor = HILDON_ANIMATION_ACTOR (hildon_animation_actor_new());
      gtk_widget_add_events (GTK_WIDGET (actor),
    			 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
      gtk_window_resize (GTK_WINDOW (actor), X_SIZE, Y_SIZE);
      hildon_animation_actor_set_position (actor, X_POS, Y_POS);
      hildon_animation_actor_set_parent (actor, GTK_WINDOW (window));
      hildon_animation_actor_set_scale (actor, X_SCALE, Y_SCALE);
    
      drawing = get_drawing_widget ();
      gtk_container_add (GTK_CONTAINER (actor), drawing);
    
      g_signal_connect (window, "button-press-event",
    		    G_CALLBACK (window_button_proxy), drawing);
      g_signal_connect (window, "button-release-event",
    		    G_CALLBACK (window_button_proxy), drawing);
    
      gtk_widget_show_all (GTK_WIDGET (actor));
      gtk_widget_show_all (GTK_WIDGET (window));
    
      gtk_main ();
      return 0;
    }

    Edit | Forward | Quote | Quick Reply | Thanks
    The Following 6 Users Say Thank You to ArnimS For This Useful Post:
    b-man, Bundyo, hopbeat, javispedro, lcuk, qwerty12

     
    lcuk | # 2 | 2009-11-04, 21:52 | Report

    pupnik,
    anonymous code drops hurt more than they help.
    please explain what problem it solves and who might need it.

    Edit | Forward | Quote | Quick Reply | Thanks
    The Following 3 Users Say Thank You to lcuk For This Useful Post:
    jeremiah, Johnx

     
    mikec | # 3 | 2009-11-04, 21:55 | Report

    lcuk

    isnt that World or Warcraft port in 10 lines

    Mike C

    Edit | Forward | Quote | Quick Reply | Thanks

     
    lcuk | # 4 | 2009-11-04, 22:02 | Report

    lol mikec
    i see the code, but i dont see what to do with it.
    its not needed by normal gtk apps, and i doubt pupnik would just randomly post something like this without reason.
    i am just interested to know how it should be used and when we might need it.

    Edit | Forward | Quote | Quick Reply | Thanks

     
    b-man | # 5 | 2009-11-07, 00:15 | Report

    screenshot


    Edit | Forward | Quote | Quick Reply | Thanks

     
    Bundyo | # 6 | 2009-11-07, 07:22 | Report

    I don't see anything top secret in here, hildon_animation_actor is documented and was discussed on the mailing list.

    Edit | Forward | Quote | Quick Reply | Thanks
    The Following User Says Thank You to Bundyo For This Useful Post:
    qwerty12

     
    javispedro | # 7 | 2009-11-14, 17:58 | Report

    It was commented by Konttori (sorry, but can't think why he wouldn't want his name on it, specially if he posted it publicly on IRC ) that the scaling part wouldn't work in the first firmware version -- but will in later versions.

    The snippet's method should be basically the fastest way to scale 2d output in the N900 since:

    -Software scaling:

    Source bitmap ---(scale in soft)---> scaled bitmap ---(XPutImage/XSHMPut) ---> scaled X11 pixmap ---(hildon-desktop: texture-from-pixmap)--> scaled powervr texture ---(powervr render)--> screen

    (2d buffer is uploaded once to the powervr, in scaled, "large" form)

    - Use a EGL window context:

    Source bitmap ---(glTexImage)---> powervr texture ---(powervr scale&render) ---> scaled framebuffer ---(XPutImage/XSHMPut) ---> scaled X11 pixmap ---(hildon-desktop: texture-from-pixmap)--> scaled powervr texture ---(powervr render)--> screen

    (longer path, the texture might even be uploaded _twice_ to powervr! -- in which case it is even slower than pure software scaling)

    - Snippet's method:

    Source bitmap ---(XPutImage/XSHMPut) ---> X11 pixmap ---(hildon-desktop: texture-from-pixmap)--> powervr texture ---(powervr scale&render)--> screen

    As you can see, the 2d buffer is uploaded once to powervr and in non scaled form, and hildon-desktop manages the scaling -- less bandwidth used, thus fastest.

    Edit | Forward | Quote | Quick Reply | Thanks
    The Following 4 Users Say Thank You to javispedro For This Useful Post:
    b-man, conny, lcuk, pelago

     
    konttori | # 8 | 2009-11-20, 05:42 | Report

    Fullscreen windowns will be able to also use non-composited mode, so some of the steps can be skipped for those.

    What the compositor scaling provides also is bilinear filtering, which should also look pretty good, but might not be as good as some dedicated game scalers.

    Edit | Forward | Quote | Quick Reply | Thanks
    The Following 3 Users Say Thank You to konttori For This Useful Post:
    conny, javispedro, qwerty12

     
vBulletin® Version 3.8.8
Normal Logout