Re: gdk/win32 and cairo [was: Cairo now a dependency of HEAD GTK+]



On Mon, 2005-02-07 at 22:05 +0100, Hans Breuer wrote:
> On 04.02.2005 00:31, Owen Taylor wrote:
> > Just committed a change to make GTK+ HEAD depend on Cairo.
> Below you'll find my first attempt on integrating Cairo
> rendering with gdk/win32. I've tried to put descriptive
> comments in the code, here a short summary of the problem:
> 
> cairo_win32(set_target|create_surface) requires a HDC - a
> device context - to render to. My patch provides one by
> gdk_win32_hdc_get(). But due to the nature of DCs this
> device context needs to be released before it can be
> used for something else, i.e. 'draw' it into another
> device context.
>
> The current pattern of Gdk is to draw onto a backing store
> pixmap which finally gets blitted on the visible window.
> That involves two DCs: source pixmap, destination window.
> But as long as Cairo's suface DC isn't released that
> call will fail. (SelectObject() in blit_from_pixmap())

The GTK+ code currently is organized around one DC per
GC. My thought is that we should be moving more towards
one-DC-per-GdkDrawable. If we have a DC associated with
the GdkPixmap, then we can use that DC both for passing
to Cairo and for BitBlt from that surface to another.
There is no need to select the bitmap into another DC.

The obvious response here is "that's a lot of DCs".
I don't think DC's are the critically scarce resource in 
current Windows that they once were, but yes, it is.

The model I'm thinking about to deal with that is "weak reference". 

 gdk_win32_drawable_set_cairo_target() looks something like:

  if (win32_impl->cairo_surface) {
      cairo_set_target_surface (cr, win32_impl->cairo_surface);
  } else {
      win32_impl->dc = CreateDC(...)
      win32_impl->cairo_surface = cairo_win32_surface_new (...);
     
      cairo_surface_set_user_data (win32_impl->cairo_surface,
                                   win32_impl,
                                   free_dc_and_clear_cairo_surface);
                                  
      cairo_set_target_surface (cr, win32_impl->cairo_surface);
      
      cairo_surface_destroy (win32_impl->cairo_surface);
  }

In the case of temporarily drawing on the surface once you 
cairo_destroy() the cairo_t, the surface will be freed, and cleared
out of win32_impl->cairo_surface. But for begin_paint(), end_paint()
we can make sure that a single DC and cairo_surface exist from the
begin_paint() all the way through the end paint.

That's pretty schematic but I think essentially workable. 

Regards,
					Owen





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]