gfx/cairo/win32-d3dsurface9.patch

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     1 diff --git a/gfx/cairo/cairo/src/cairo-rename.h b/gfx/cairo/cairo/src/cairo-rename.h
     2 --- a/gfx/cairo/cairo/src/cairo-rename.h
     3 +++ b/gfx/cairo/cairo/src/cairo-rename.h
     4 @@ -335,16 +335,17 @@
     5  #define cairo_win32_font_face_create_for_logfontw_hfont _moz_cairo_win32_font_face_create_for_logfontw_hfont
     6  #define cairo_win32_printing_surface_create _moz_cairo_win32_printing_surface_create
     7  #define cairo_win32_scaled_font_done_font _moz_cairo_win32_scaled_font_done_font
     8  #define cairo_win32_scaled_font_get_device_to_logical _moz_cairo_win32_scaled_font_get_device_to_logical
     9  #define cairo_win32_scaled_font_get_logical_to_device _moz_cairo_win32_scaled_font_get_logical_to_device
    10  #define cairo_win32_scaled_font_get_metrics_factor _moz_cairo_win32_scaled_font_get_metrics_factor
    11  #define cairo_win32_scaled_font_select_font _moz_cairo_win32_scaled_font_select_font
    12  #define cairo_win32_surface_create _moz_cairo_win32_surface_create
    13 +#define cairo_win32_surface_create_with_d3dsurface9 _moz_cairo_win32_surface_create_with_d3dsurface9
    14  #define cairo_win32_surface_create_with_ddb _moz_cairo_win32_surface_create_with_ddb
    15  #define cairo_win32_surface_create_with_dib _moz_cairo_win32_surface_create_with_dib
    16  #define cairo_win32_surface_get_dc _moz_cairo_win32_surface_get_dc
    17  #define cairo_win32_surface_get_image _moz_cairo_win32_surface_get_image
    18  #define cairo_xcb_surface_create _moz_cairo_xcb_surface_create
    19  #define cairo_xcb_surface_create_for_bitmap _moz_cairo_xcb_surface_create_for_bitmap
    20  #define cairo_xcb_surface_create_with_xrender_format _moz_cairo_xcb_surface_create_with_xrender_format
    21  #define cairo_xcb_surface_set_size _moz_cairo_xcb_surface_set_size
    22 diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
    23 --- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
    24 +++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
    25 @@ -1852,16 +1852,17 @@ cairo_win32_printing_surface_create (HDC
    26      }
    28      _cairo_surface_clipper_init (&surface->clipper,
    29  				 _cairo_win32_printing_surface_clipper_intersect_clip_path);
    31      surface->image = NULL;
    32      surface->format = CAIRO_FORMAT_RGB24;
    33      surface->content = CAIRO_CONTENT_COLOR_ALPHA;
    34 +    surface->d3d9surface = NULL;
    36      surface->dc = hdc;
    37      surface->bitmap = NULL;
    38      surface->is_dib = FALSE;
    39      surface->saved_dc_bitmap = NULL;
    40      surface->brush = NULL;
    41      surface->old_brush = NULL;
    42      surface->font_subsets = _cairo_scaled_font_subsets_create_scaled ();
    43 diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h
    44 --- a/gfx/cairo/cairo/src/cairo-win32-private.h
    45 +++ b/gfx/cairo/cairo/src/cairo-win32-private.h
    46 @@ -54,16 +54,18 @@ CAIRO_BEGIN_DECLS
    48  typedef struct _cairo_win32_surface {
    49      cairo_surface_t base;
    51      cairo_format_t format;
    53      HDC dc;
    55 +    struct IDirect3DSurface9 *d3d9surface;
    56 +
    57      /* We create off-screen surfaces as DIBs or DDBs, based on what we created
    58       * originally*/
    59      HBITMAP bitmap;
    60      cairo_bool_t is_dib;
    62      /* Used to save the initial 1x1 monochrome bitmap for the DC to
    63       * select back into the DC before deleting the DC and our
    64       * bitmap. For Windows XP, this doesn't seem to be necessary
    65 diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c
    66 --- a/gfx/cairo/cairo/src/cairo-win32-surface.c
    67 +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c
    68 @@ -54,16 +54,17 @@
    69  #include "cairo-win32-private.h"
    70  #include "cairo-scaled-font-subsets-private.h"
    71  #include "cairo-surface-fallback-private.h"
    72  #include "cairo-surface-clipper-private.h"
    73  #include "cairo-gstate-private.h"
    74  #include "cairo-private.h"
    75  #include <wchar.h>
    76  #include <windows.h>
    77 +#include <d3d9.h>
    79  #if defined(__MINGW32__) && !defined(ETO_PDY)
    80  # define ETO_PDY 0x2000
    81  #endif
    83  #undef DEBUG_COMPOSITE
    85  /* for older SDKs */
    86 @@ -384,16 +385,17 @@ static cairo_surface_t *
    88      surface->image = cairo_image_surface_create_for_data (bits, format,
    89  							  width, height, rowstride);
    90      status = surface->image->status;
    91      if (status)
    92  	goto FAIL;
    94      surface->format = format;
    95 +    surface->d3d9surface = NULL;
    97      surface->clip_rect.x = 0;
    98      surface->clip_rect.y = 0;
    99      surface->clip_rect.width = width;
   100      surface->clip_rect.height = height;
   102      surface->initial_clip_rgn = NULL;
   103      surface->had_simple_clip = FALSE;
   104 @@ -481,26 +483,73 @@ cairo_status_t
   105      if (surface->bitmap) {
   106  	SelectObject (surface->dc, surface->saved_dc_bitmap);
   107  	DeleteObject (surface->bitmap);
   108  	DeleteDC (surface->dc);
   109      } else {
   110  	_cairo_win32_restore_initial_clip (surface);
   111      }
   113 +    if (surface->d3d9surface) {
   114 +        IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc);
   115 +        IDirect3DSurface9_Release (surface->d3d9surface);
   116 +    }
   117 +
   118      if (surface->initial_clip_rgn)
   119  	DeleteObject (surface->initial_clip_rgn);
   121      if (surface->font_subsets != NULL)
   122  	_cairo_scaled_font_subsets_destroy (surface->font_subsets);
   124      return CAIRO_STATUS_SUCCESS;
   125  }
   127  static cairo_status_t
   128 +_cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t  *surface,
   129 +				   int                     x,
   130 +				   int                     y,
   131 +				   int                     width,
   132 +				   int                     height,
   133 +				   cairo_image_surface_t **local_out)
   134 +{
   135 +    cairo_image_surface_t *local;
   136 +    cairo_int_status_t status;
   137 +
   138 +    RECT rectin = { x, y, x+width, y+height };
   139 +    D3DLOCKED_RECT rectout;
   140 +    HRESULT hr;
   141 +    hr = IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc);
   142 +    hr = IDirect3DSurface9_LockRect (surface->d3d9surface,
   143 +	                             &rectout, &rectin, 0);
   144 +    surface->dc = 0; // Don't use the DC when this is locked!
   145 +    if (hr) {
   146 +        IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
   147 +        return CAIRO_INT_STATUS_UNSUPPORTED;
   148 +    }
   149 +    local = cairo_image_surface_create_for_data (rectout.pBits,
   150 +	                                         surface->format,
   151 +						 width, height,
   152 +						 rectout.Pitch);
   153 +    if (local == NULL) {
   154 +	IDirect3DSurface9_UnlockRect (surface->d3d9surface);
   155 +	IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
   156 +        return CAIRO_INT_STATUS_UNSUPPORTED;
   157 +    }
   158 +    if (local->base.status) {
   159 +	IDirect3DSurface9_UnlockRect (surface->d3d9surface);
   160 +	IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
   161 +        return local->base.status;
   162 +    }
   163 +
   164 +    *local_out = local;
   165 +
   166 +    return CAIRO_STATUS_SUCCESS;
   167 +}
   168 +
   169 +static cairo_status_t
   170  _cairo_win32_surface_get_subimage (cairo_win32_surface_t  *surface,
   171  				   int                     x,
   172  				   int                     y,
   173  				   int                     width,
   174  				   int                     height,
   175  				   cairo_win32_surface_t **local_out)
   176  {
   177      cairo_win32_surface_t *local;
   178 @@ -599,17 +648,16 @@ static void
   179  }
   181  static cairo_status_t
   182  _cairo_win32_surface_acquire_source_image (void                    *abstract_surface,
   183  					   cairo_image_surface_t  **image_out,
   184  					   void                   **image_extra)
   185  {
   186      cairo_win32_surface_t *surface = abstract_surface;
   187 -    cairo_win32_surface_t *local;
   188      cairo_status_t status;
   190      if (!surface->image && !surface->is_dib && surface->bitmap &&
   191  	(surface->flags & CAIRO_WIN32_SURFACE_CAN_CONVERT_TO_DIB) != 0)
   192      {
   193  	/* This is a DDB, and we're being asked to use it as a source for
   194  	 * something that we couldn't support natively.  So turn it into
   195  	 * a DIB, so that we have an equivalent image surface, as long
   196 @@ -619,69 +667,109 @@ static cairo_status_t
   197      }
   199      if (surface->image) {
   200  	*image_out = (cairo_image_surface_t *)surface->image;
   201  	*image_extra = NULL;
   202  	return CAIRO_STATUS_SUCCESS;
   203      }
   205 -    status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0,
   206 -						surface->extents.width,
   207 -						surface->extents.height, &local);
   208 -    if (status)
   209 -	return status;
   210 -
   211 -    *image_out = (cairo_image_surface_t *)local->image;
   212 -    *image_extra = local;
   213 +    if (surface->d3d9surface) {
   214 +	cairo_image_surface_t *local;
   215 +	status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface, 0, 0,
   216 +						      surface->extents.width,
   217 +						      surface->extents.height, &local);
   218 +	if (status)
   219 +	    return status;
   220 +
   221 +	*image_out = local;
   222 +	*image_extra = surface;
   223 +    } else {
   224 +	cairo_win32_surface_t *local;
   225 +	status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0,
   226 +						    surface->extents.width,
   227 +						    surface->extents.height, &local);
   228 +	if (status)
   229 +	    return status;
   230 +
   231 +	*image_out = (cairo_image_surface_t *)local->image;
   232 +	*image_extra = local;
   233 +    }
   234 +    // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points
   235 +    // to the original surface to get back the d3d9surface and properly unlock.
   236 +
   237      return CAIRO_STATUS_SUCCESS;
   238  }
   240  static void
   241  _cairo_win32_surface_release_source_image (void                   *abstract_surface,
   242  					   cairo_image_surface_t  *image,
   243  					   void                   *image_extra)
   244  {
   245 +    cairo_win32_surface_t *surface = abstract_surface;
   246      cairo_win32_surface_t *local = image_extra;
   248 -    if (local)
   249 +    if (local && local->d3d9surface) {
   250 +	IDirect3DSurface9_UnlockRect (local->d3d9surface);
   251 +	IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc);
   252 +	cairo_surface_destroy ((cairo_surface_t *)image);
   253 +    } else {
   254  	cairo_surface_destroy ((cairo_surface_t *)local);
   255 +    }
   256  }
   258  static cairo_status_t
   259  _cairo_win32_surface_acquire_dest_image (void                    *abstract_surface,
   260  					 cairo_rectangle_int_t   *interest_rect,
   261  					 cairo_image_surface_t  **image_out,
   262  					 cairo_rectangle_int_t   *image_rect,
   263  					 void                   **image_extra)
   264  {
   265      cairo_win32_surface_t *surface = abstract_surface;
   266 -    cairo_win32_surface_t *local = NULL;
   267      cairo_status_t status;
   269      if (surface->image) {
   270  	GdiFlush();
   272  	*image_out = (cairo_image_surface_t *) surface->image;
   273  	*image_extra = NULL;
   274  	*image_rect = surface->extents;
   275  	return CAIRO_STATUS_SUCCESS;
   276      }
   278 -    status = _cairo_win32_surface_get_subimage (abstract_surface,
   279 +    if (surface->d3d9surface) {
   280 +	cairo_image_surface_t *local = NULL;
   281 +	status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface,
   282  						interest_rect->x,
   283  						interest_rect->y,
   284  						interest_rect->width,
   285 -						interest_rect->height,
   286 -						&local);
   287 -    if (status)
   288 -	return status;
   289 -
   290 -    *image_out = (cairo_image_surface_t *) local->image;
   291 -    *image_extra = local;
   292 +						interest_rect->height, &local);
   293 +
   294 +	if (status)
   295 +	    return status;
   296 +
   297 +	*image_out = local;
   298 +	*image_extra = surface;
   299 +    } else {
   300 +	cairo_win32_surface_t *local = NULL;
   301 +	status = _cairo_win32_surface_get_subimage (abstract_surface,
   302 +						interest_rect->x,
   303 +						interest_rect->y,
   304 +						interest_rect->width,
   305 +						interest_rect->height, &local);
   306 +
   307 +	if (status)
   308 +	    return status;
   309 +
   310 +	*image_out = (cairo_image_surface_t *) local->image;
   311 +	*image_extra = local;
   312 +    }
   313 +    // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points
   314 +    // to the original surface to get back the d3d9surface and properly unlock.
   315 +
   316      *image_rect = *interest_rect;
   317      return CAIRO_STATUS_SUCCESS;
   318  }
   320  static void
   321  _cairo_win32_surface_release_dest_image (void                    *abstract_surface,
   322  					 cairo_rectangle_int_t   *interest_rect,
   323  					 cairo_image_surface_t   *image,
   324 @@ -689,29 +777,37 @@ static void
   325  					 void                    *image_extra)
   326  {
   327      cairo_win32_surface_t *surface = abstract_surface;
   328      cairo_win32_surface_t *local = image_extra;
   330      if (!local)
   331  	return;
   333 -    /* clear any clip that's currently set on the surface
   334 -       so that we can blit uninhibited. */
   335 -    _cairo_win32_surface_set_clip_region (surface, NULL);
   336 -
   337 -    if (!BitBlt (surface->dc,
   338 -		 image_rect->x, image_rect->y,
   339 -		 image_rect->width, image_rect->height,
   340 -		 local->dc,
   341 -		 0, 0,
   342 -		 SRCCOPY))
   343 -	_cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image");
   344 -
   345 -    cairo_surface_destroy ((cairo_surface_t *)local);
   346 +    if (local->d3d9surface) {
   347 +	IDirect3DSurface9_UnlockRect (local->d3d9surface);
   348 +	IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc);
   349 +	cairo_surface_destroy ((cairo_surface_t *)image);
   350 +    } else {
   351 +
   352 +	/* clear any clip that's currently set on the surface
   353 +	   so that we can blit uninhibited. */
   354 +	_cairo_win32_surface_set_clip_region (surface, NULL);
   355 +
   356 +	if (!BitBlt (surface->dc,
   357 +		     image_rect->x, image_rect->y,
   358 +		     image_rect->width, image_rect->height,
   359 +		     local->dc,
   360 +		     0, 0,
   361 +		     SRCCOPY))
   362 +	    _cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image");
   363 +
   364 +	cairo_surface_destroy ((cairo_surface_t *)local);
   365 +    }
   366 +
   367  }
   369  cairo_status_t
   370  _cairo_win32_surface_set_clip_region (void           *abstract_surface,
   371  				      cairo_region_t *region)
   372  {
   373      cairo_win32_surface_t *surface = abstract_surface;
   374      cairo_status_t status = CAIRO_STATUS_SUCCESS;
   375 @@ -1849,16 +1945,17 @@ cairo_win32_surface_create_internal (HDC
   376  	free (surface);
   377  	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
   378      }
   380      surface->clip_region = NULL;
   381      surface->image = NULL;
   382      surface->format = format;
   384 +    surface->d3d9surface = NULL;
   385      surface->dc = hdc;
   386      surface->bitmap = NULL;
   387      surface->is_dib = FALSE;
   388      surface->saved_dc_bitmap = NULL;
   389      surface->brush = NULL;
   390      surface->old_brush = NULL;
   391      surface->font_subsets = NULL;
   393 @@ -2009,16 +2106,29 @@ cairo_win32_surface_create_with_ddb (HDC
   395  FINISH:
   396      if (screen_dc)
   397  	ReleaseDC (NULL, screen_dc);
   399      return (cairo_surface_t*) new_surf;
   400  }
   402 +cairo_public cairo_surface_t *
   403 +cairo_win32_surface_create_with_d3dsurface9 (IDirect3DSurface9 *surface)
   404 +{
   405 +    HDC dc;
   406 +    cairo_win32_surface_t *win_surface;
   407 +
   408 +    IDirect3DSurface9_AddRef (surface);
   409 +    IDirect3DSurface9_GetDC (surface, &dc);
   410 +    win_surface = cairo_win32_surface_create_internal(dc, CAIRO_FORMAT_RGB24);
   411 +    win_surface->d3d9surface = surface;
   412 +    return (cairo_surface_t*) win_surface;
   413 +
   414 +}
   415  /**
   416   * _cairo_surface_is_win32:
   417   * @surface: a #cairo_surface_t
   418   *
   419   * Checks if a surface is a win32 surface.  This will
   420   * return False if this is a win32 printing surface; use
   421   * _cairo_surface_is_win32_printing() to check for that.
   422   *
   423 diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h
   424 --- a/gfx/cairo/cairo/src/cairo-win32.h
   425 +++ b/gfx/cairo/cairo/src/cairo-win32.h
   426 @@ -59,17 +59,16 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
   427                                       cairo_format_t format,
   428                                       int width,
   429                                       int height);
   431  cairo_public cairo_surface_t *
   432  cairo_win32_surface_create_with_dib (cairo_format_t format,
   433                                       int width,
   434                                       int height);
   435 -
   436  cairo_public HDC
   437  cairo_win32_surface_get_dc (cairo_surface_t *surface);
   439  cairo_public HDC
   440  cairo_win32_get_dc_with_clip (cairo_t *cr);
   442  cairo_public cairo_surface_t *
   443  cairo_win32_surface_get_image (cairo_surface_t *surface);
   444 @@ -143,16 +142,21 @@ cairo_dwrite_scaled_font_get_force_GDI_classic(cairo_scaled_font_t *dwrite_scale
   445  void
   446  cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode);
   448  int
   449  cairo_dwrite_get_cleartype_rendering_mode();
   451  #endif /* CAIRO_HAS_DWRITE_FONT */
   453 +struct IDirect3DSurface9;
   454 +cairo_public cairo_surface_t *
   455 +cairo_win32_surface_create_with_d3dsurface9 (struct IDirect3DSurface9 *surface);
   456 +
   457 +
   458  #if CAIRO_HAS_D2D_SURFACE
   460  struct _cairo_device
   461  {
   462      int type;
   463      int refcount;
   464  };

mercurial