gfx/2d/SourceSurfaceD2D1.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.

michael@0 1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "SourceSurfaceD2D1.h"
michael@0 7 #include "DrawTargetD2D1.h"
michael@0 8 #include "Tools.h"
michael@0 9
michael@0 10 namespace mozilla {
michael@0 11 namespace gfx {
michael@0 12
michael@0 13 SourceSurfaceD2D1::SourceSurfaceD2D1(ID2D1Image *aImage, ID2D1DeviceContext *aDC,
michael@0 14 SurfaceFormat aFormat, const IntSize &aSize,
michael@0 15 DrawTargetD2D1 *aDT)
michael@0 16 : mImage(aImage)
michael@0 17 , mDC(aDC)
michael@0 18 , mDrawTarget(aDT)
michael@0 19 {
michael@0 20 aImage->QueryInterface((ID2D1Bitmap1**)byRef(mRealizedBitmap));
michael@0 21
michael@0 22 mFormat = aFormat;
michael@0 23 mSize = aSize;
michael@0 24 }
michael@0 25
michael@0 26 SourceSurfaceD2D1::~SourceSurfaceD2D1()
michael@0 27 {
michael@0 28 }
michael@0 29
michael@0 30 TemporaryRef<DataSourceSurface>
michael@0 31 SourceSurfaceD2D1::GetDataSurface()
michael@0 32 {
michael@0 33 EnsureRealizedBitmap();
michael@0 34
michael@0 35 RefPtr<ID2D1Bitmap1> softwareBitmap;
michael@0 36 D2D1_BITMAP_PROPERTIES1 props;
michael@0 37 props.dpiX = 96;
michael@0 38 props.dpiY = 96;
michael@0 39 props.pixelFormat = D2DPixelFormat(mFormat);
michael@0 40 props.colorContext = nullptr;
michael@0 41 props.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW |
michael@0 42 D2D1_BITMAP_OPTIONS_CPU_READ;
michael@0 43 mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(softwareBitmap));
michael@0 44
michael@0 45 D2D1_POINT_2U point = D2D1::Point2U(0, 0);
michael@0 46 D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height);
michael@0 47 softwareBitmap->CopyFromBitmap(&point, mRealizedBitmap, &rect);
michael@0 48 return new DataSourceSurfaceD2D1(softwareBitmap, mFormat);
michael@0 49 }
michael@0 50
michael@0 51 void
michael@0 52 SourceSurfaceD2D1::EnsureRealizedBitmap()
michael@0 53 {
michael@0 54 if (mRealizedBitmap) {
michael@0 55 return;
michael@0 56 }
michael@0 57
michael@0 58 RefPtr<ID2D1DeviceContext> dc;
michael@0 59 Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, byRef(dc));
michael@0 60
michael@0 61 D2D1_BITMAP_PROPERTIES1 props;
michael@0 62 props.dpiX = 96;
michael@0 63 props.dpiY = 96;
michael@0 64 props.pixelFormat = D2DPixelFormat(mFormat);
michael@0 65 props.colorContext = nullptr;
michael@0 66 props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
michael@0 67 dc->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mRealizedBitmap));
michael@0 68
michael@0 69 dc->SetTarget(mRealizedBitmap);
michael@0 70
michael@0 71 dc->BeginDraw();
michael@0 72 dc->DrawImage(mImage);
michael@0 73 dc->EndDraw();
michael@0 74 }
michael@0 75
michael@0 76 void
michael@0 77 SourceSurfaceD2D1::DrawTargetWillChange()
michael@0 78 {
michael@0 79 // At this point in time this should always be true here.
michael@0 80 MOZ_ASSERT(mRealizedBitmap);
michael@0 81
michael@0 82 RefPtr<ID2D1Bitmap1> oldBitmap = mRealizedBitmap;
michael@0 83
michael@0 84 D2D1_BITMAP_PROPERTIES1 props;
michael@0 85 props.dpiX = 96;
michael@0 86 props.dpiY = 96;
michael@0 87 props.pixelFormat = D2DPixelFormat(mFormat);
michael@0 88 props.colorContext = nullptr;
michael@0 89 props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
michael@0 90 mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mRealizedBitmap));
michael@0 91
michael@0 92 D2D1_POINT_2U point = D2D1::Point2U(0, 0);
michael@0 93 D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height);
michael@0 94 mRealizedBitmap->CopyFromBitmap(&point, oldBitmap, &rect);
michael@0 95 mImage = mRealizedBitmap;
michael@0 96
michael@0 97 DrawTargetD2D1::mVRAMUsageSS += mSize.width * mSize.height * BytesPerPixel(mFormat);
michael@0 98 mDrawTarget = nullptr;
michael@0 99
michael@0 100 // We now no longer depend on the source surface content remaining the same.
michael@0 101 MarkIndependent();
michael@0 102 }
michael@0 103
michael@0 104 void
michael@0 105 SourceSurfaceD2D1::MarkIndependent()
michael@0 106 {
michael@0 107 if (mDrawTarget) {
michael@0 108 MOZ_ASSERT(mDrawTarget->mSnapshot == this);
michael@0 109 mDrawTarget->mSnapshot = nullptr;
michael@0 110 mDrawTarget = nullptr;
michael@0 111 }
michael@0 112 }
michael@0 113
michael@0 114 DataSourceSurfaceD2D1::DataSourceSurfaceD2D1(ID2D1Bitmap1 *aMappableBitmap, SurfaceFormat aFormat)
michael@0 115 : mBitmap(aMappableBitmap)
michael@0 116 , mFormat(aFormat)
michael@0 117 , mMapped(false)
michael@0 118 {
michael@0 119 }
michael@0 120
michael@0 121 DataSourceSurfaceD2D1::~DataSourceSurfaceD2D1()
michael@0 122 {
michael@0 123 if (mMapped) {
michael@0 124 mBitmap->Unmap();
michael@0 125 }
michael@0 126 }
michael@0 127
michael@0 128 IntSize
michael@0 129 DataSourceSurfaceD2D1::GetSize() const
michael@0 130 {
michael@0 131 D2D1_SIZE_F size = mBitmap->GetSize();
michael@0 132
michael@0 133 return IntSize(int32_t(size.width), int32_t(size.height));
michael@0 134 }
michael@0 135
michael@0 136 uint8_t*
michael@0 137 DataSourceSurfaceD2D1::GetData()
michael@0 138 {
michael@0 139 EnsureMapped();
michael@0 140
michael@0 141 return mMap.bits;
michael@0 142 }
michael@0 143
michael@0 144 bool
michael@0 145 DataSourceSurfaceD2D1::Map(MapType aMapType, MappedSurface *aMappedSurface)
michael@0 146 {
michael@0 147 // DataSourceSurfaces used with the new Map API should not be used with GetData!!
michael@0 148 MOZ_ASSERT(!mMapped);
michael@0 149 MOZ_ASSERT(!mIsMapped);
michael@0 150
michael@0 151 D2D1_MAP_OPTIONS options;
michael@0 152 if (aMapType == MapType::READ) {
michael@0 153 options = D2D1_MAP_OPTIONS_READ;
michael@0 154 } else {
michael@0 155 MOZ_CRASH("No support for Write maps on D2D1 DataSourceSurfaces yet!");
michael@0 156 }
michael@0 157
michael@0 158 D2D1_MAPPED_RECT map;
michael@0 159 mBitmap->Map(D2D1_MAP_OPTIONS_READ, &map);
michael@0 160 aMappedSurface->mData = map.bits;
michael@0 161 aMappedSurface->mStride = map.pitch;
michael@0 162
michael@0 163 mIsMapped = true;
michael@0 164 return true;
michael@0 165 }
michael@0 166
michael@0 167 void
michael@0 168 DataSourceSurfaceD2D1::Unmap()
michael@0 169 {
michael@0 170 MOZ_ASSERT(mIsMapped);
michael@0 171
michael@0 172 mIsMapped = false;
michael@0 173 mBitmap->Unmap();
michael@0 174 }
michael@0 175
michael@0 176 int32_t
michael@0 177 DataSourceSurfaceD2D1::Stride()
michael@0 178 {
michael@0 179 EnsureMapped();
michael@0 180
michael@0 181 return mMap.pitch;
michael@0 182 }
michael@0 183
michael@0 184 void
michael@0 185 DataSourceSurfaceD2D1::EnsureMapped()
michael@0 186 {
michael@0 187 // Do not use GetData() after having used Map!
michael@0 188 MOZ_ASSERT(!mIsMapped);
michael@0 189 if (mMapped) {
michael@0 190 return;
michael@0 191 }
michael@0 192 mBitmap->Map(D2D1_MAP_OPTIONS_READ, &mMap);
michael@0 193 mMapped = true;
michael@0 194 }
michael@0 195
michael@0 196 }
michael@0 197 }

mercurial