gfx/layers/ImageDataSerializer.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 "ImageDataSerializer.h"
     7 #include "gfx2DGlue.h"                  // for SurfaceFormatToImageFormat
     8 #include "gfxImageSurface.h"            // for gfxImageSurface
     9 #include "gfxPoint.h"                   // for gfxIntSize
    10 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
    11 #include "mozilla/gfx/2D.h"             // for DataSourceSurface, Factory
    12 #include "mozilla/gfx/Tools.h"          // for GetAlignedStride, etc
    13 #include "mozilla/mozalloc.h"           // for operator delete, etc
    15 namespace mozilla {
    16 namespace layers {
    18 using namespace gfx;
    20 // The Data is layed out as follows:
    21 //
    22 //  +-------------------+   -++ --+   <-- ImageDataSerializerBase::mData pointer
    23 //  | SurfaceBufferInfo |     |   |
    24 //  +-------------------+   --+   | offset
    25 //  |        ...        |         |
    26 //  +-------------------+   ------+
    27 //  |                   |
    28 //  |       data        |
    29 //  |                   |
    30 //  +-------------------+
    32 // Structure written at the beginning of the data blob containing the image
    33 // (as shown in the figure above). It contains the necessary informations to
    34 // read the image in the blob.
    35 namespace {
    36 struct SurfaceBufferInfo
    37 {
    38   uint32_t width;
    39   uint32_t height;
    40   SurfaceFormat format;
    42   static uint32_t GetOffset()
    43   {
    44     return GetAlignedStride<16>(sizeof(SurfaceBufferInfo));
    45   }
    46 };
    47 } // anonymous namespace
    49 static SurfaceBufferInfo*
    50 GetBufferInfo(uint8_t* aData, size_t aDataSize)
    51 {
    52   return aDataSize >= sizeof(SurfaceBufferInfo)
    53          ? reinterpret_cast<SurfaceBufferInfo*>(aData)
    54          : nullptr;
    55 }
    57 void
    58 ImageDataSerializer::InitializeBufferInfo(IntSize aSize,
    59                                           SurfaceFormat aFormat)
    60 {
    61   SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
    62   MOZ_ASSERT(info); // OK to assert here, this method is client-side-only
    63   info->width = aSize.width;
    64   info->height = aSize.height;
    65   info->format = aFormat;
    66   Validate();
    67 }
    69 static inline uint32_t
    70 ComputeStride(SurfaceFormat aFormat, uint32_t aWidth)
    71 {
    72   return GetAlignedStride<4>(BytesPerPixel(aFormat) * aWidth);
    73 }
    75 uint32_t
    76 ImageDataSerializerBase::ComputeMinBufferSize(IntSize aSize,
    77                                           SurfaceFormat aFormat)
    78 {
    79   uint32_t bufsize = aSize.height * ComputeStride(aFormat, aSize.width);
    80   return SurfaceBufferInfo::GetOffset()
    81        + GetAlignedStride<16>(bufsize);
    82 }
    84 void
    85 ImageDataSerializerBase::Validate()
    86 {
    87   mIsValid = false;
    88   if (!mData) {
    89     return;
    90   }
    91   SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
    92   if (!info) {
    93     return;
    94   }
    95   size_t requiredSize =
    96            ComputeMinBufferSize(IntSize(info->width, info->height), info->format);
    97   mIsValid = requiredSize <= mDataSize;
    98 }
   100 uint8_t*
   101 ImageDataSerializerBase::GetData()
   102 {
   103   MOZ_ASSERT(IsValid());
   104   return mData + SurfaceBufferInfo::GetOffset();
   105 }
   107 uint32_t
   108 ImageDataSerializerBase::GetStride() const
   109 {
   110   MOZ_ASSERT(IsValid());
   111   SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
   112   return ComputeStride(GetFormat(), info->width);
   113 }
   115 IntSize
   116 ImageDataSerializerBase::GetSize() const
   117 {
   118   MOZ_ASSERT(IsValid());
   119   SurfaceBufferInfo* info = GetBufferInfo(mData, mDataSize);
   120   return IntSize(info->width, info->height);
   121 }
   123 SurfaceFormat
   124 ImageDataSerializerBase::GetFormat() const
   125 {
   126   MOZ_ASSERT(IsValid());
   127   return GetBufferInfo(mData, mDataSize)->format;
   128 }
   130 TemporaryRef<gfxImageSurface>
   131 ImageDataSerializerBase::GetAsThebesSurface()
   132 {
   133   MOZ_ASSERT(IsValid());
   134   IntSize size = GetSize();
   135   return new gfxImageSurface(GetData(),
   136                              gfxIntSize(size.width, size.height),
   137                              GetStride(),
   138                              SurfaceFormatToImageFormat(GetFormat()));
   139 }
   141 TemporaryRef<DrawTarget>
   142 ImageDataSerializerBase::GetAsDrawTarget(gfx::BackendType aBackend)
   143 {
   144   MOZ_ASSERT(IsValid());
   145   return gfx::Factory::CreateDrawTargetForData(aBackend,
   146                                                GetData(), GetSize(),
   147                                                GetStride(), GetFormat());
   148 }
   150 TemporaryRef<gfx::DataSourceSurface>
   151 ImageDataSerializerBase::GetAsSurface()
   152 {
   153   MOZ_ASSERT(IsValid());
   154   return Factory::CreateWrappingDataSourceSurface(GetData(),
   155                                                   GetStride(),
   156                                                   GetSize(),
   157                                                   GetFormat());
   158 }
   160 } // namespace layers
   161 } // namespace mozilla

mercurial