gfx/2d/SourceSurfaceCairo.cpp

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 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "SourceSurfaceCairo.h"
     7 #include "DrawTargetCairo.h"
     8 #include "HelpersCairo.h"
     9 #include "DataSourceSurfaceWrapper.h"
    11 #include "cairo.h"
    13 namespace mozilla {
    14 namespace gfx {
    16 static SurfaceFormat
    17 CairoFormatToSurfaceFormat(cairo_format_t format)
    18 {
    19   switch (format)
    20   {
    21     case CAIRO_FORMAT_ARGB32:
    22       return SurfaceFormat::B8G8R8A8;
    23     case CAIRO_FORMAT_RGB24:
    24       return SurfaceFormat::B8G8R8X8;
    25     case CAIRO_FORMAT_A8:
    26       return SurfaceFormat::A8;
    27     default:
    28       return SurfaceFormat::B8G8R8A8;
    29   }
    30 }
    32 SourceSurfaceCairo::SourceSurfaceCairo(cairo_surface_t* aSurface,
    33                                        const IntSize& aSize,
    34                                        const SurfaceFormat& aFormat,
    35                                        DrawTargetCairo* aDrawTarget /* = nullptr */)
    36  : mSize(aSize)
    37  , mFormat(aFormat)
    38  , mSurface(aSurface)
    39  , mDrawTarget(aDrawTarget)
    40 {
    41   cairo_surface_reference(mSurface);
    42 }
    44 SourceSurfaceCairo::~SourceSurfaceCairo()
    45 {
    46   cairo_surface_destroy(mSurface);
    47 }
    49 IntSize
    50 SourceSurfaceCairo::GetSize() const
    51 {
    52   return mSize;
    53 }
    55 SurfaceFormat
    56 SourceSurfaceCairo::GetFormat() const
    57 {
    58   return mFormat;
    59 }
    61 TemporaryRef<DataSourceSurface>
    62 SourceSurfaceCairo::GetDataSurface()
    63 {
    64   RefPtr<DataSourceSurface> dataSurf;
    66   if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) {
    67     dataSurf = new DataSourceSurfaceCairo(mSurface);
    68   } else {
    69     cairo_surface_t* imageSurf = cairo_image_surface_create(GfxFormatToCairoFormat(mFormat),
    70                                                             mSize.width, mSize.height);
    72     // Fill the new image surface with the contents of our surface.
    73     cairo_t* ctx = cairo_create(imageSurf);
    74     cairo_set_source_surface(ctx, mSurface, 0, 0);
    75     cairo_paint(ctx);
    76     cairo_destroy(ctx);
    78     dataSurf = new DataSourceSurfaceCairo(imageSurf);
    79     cairo_surface_destroy(imageSurf);
    80   }
    82   // We also need to make sure that the returned surface has
    83   // surface->GetType() == SurfaceType::DATA.
    84   dataSurf = new DataSourceSurfaceWrapper(dataSurf);
    86   return dataSurf;
    87 }
    89 cairo_surface_t*
    90 SourceSurfaceCairo::GetSurface() const
    91 {
    92   return mSurface;
    93 }
    95 void
    96 SourceSurfaceCairo::DrawTargetWillChange()
    97 {
    98   if (mDrawTarget) {
    99     mDrawTarget = nullptr;
   101     // We're about to lose our version of the surface, so make a copy of it.
   102     cairo_surface_t* surface = cairo_surface_create_similar(mSurface,
   103                                                             GfxFormatToCairoContent(mFormat),
   104                                                             mSize.width, mSize.height);
   105     cairo_t* ctx = cairo_create(surface);
   106     cairo_pattern_t* pat = cairo_pattern_create_for_surface(mSurface);
   107     cairo_set_source(ctx, pat);
   108     cairo_paint(ctx);
   109     cairo_destroy(ctx);
   110     cairo_pattern_destroy(pat);
   112     // Swap in this new surface.
   113     cairo_surface_destroy(mSurface);
   114     mSurface = surface;
   115   }
   116 }
   118 DataSourceSurfaceCairo::DataSourceSurfaceCairo(cairo_surface_t* imageSurf)
   119  : mImageSurface(imageSurf)
   120 {
   121   cairo_surface_reference(mImageSurface);
   122 }
   124 DataSourceSurfaceCairo::~DataSourceSurfaceCairo()
   125 {
   126   cairo_surface_destroy(mImageSurface);
   127 }
   129 unsigned char *
   130 DataSourceSurfaceCairo::GetData()
   131 {
   132   return cairo_image_surface_get_data(mImageSurface);
   133 }
   135 int32_t
   136 DataSourceSurfaceCairo::Stride()
   137 {
   138   return cairo_image_surface_get_stride(mImageSurface);
   139 }
   141 IntSize
   142 DataSourceSurfaceCairo::GetSize() const
   143 {
   144   IntSize size;
   145   size.width = cairo_image_surface_get_width(mImageSurface);
   146   size.height = cairo_image_surface_get_height(mImageSurface);
   148   return size;
   149 }
   151 SurfaceFormat
   152 DataSourceSurfaceCairo::GetFormat() const
   153 {
   154   return CairoFormatToSurfaceFormat(cairo_image_surface_get_format(mImageSurface));
   155 }
   157 cairo_surface_t*
   158 DataSourceSurfaceCairo::GetSurface() const
   159 {
   160   return mImageSurface;
   161 }
   163 }
   164 }

mercurial