1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/2d/SourceSurfaceD2D1.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,197 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "SourceSurfaceD2D1.h" 1.10 +#include "DrawTargetD2D1.h" 1.11 +#include "Tools.h" 1.12 + 1.13 +namespace mozilla { 1.14 +namespace gfx { 1.15 + 1.16 +SourceSurfaceD2D1::SourceSurfaceD2D1(ID2D1Image *aImage, ID2D1DeviceContext *aDC, 1.17 + SurfaceFormat aFormat, const IntSize &aSize, 1.18 + DrawTargetD2D1 *aDT) 1.19 + : mImage(aImage) 1.20 + , mDC(aDC) 1.21 + , mDrawTarget(aDT) 1.22 +{ 1.23 + aImage->QueryInterface((ID2D1Bitmap1**)byRef(mRealizedBitmap)); 1.24 + 1.25 + mFormat = aFormat; 1.26 + mSize = aSize; 1.27 +} 1.28 + 1.29 +SourceSurfaceD2D1::~SourceSurfaceD2D1() 1.30 +{ 1.31 +} 1.32 + 1.33 +TemporaryRef<DataSourceSurface> 1.34 +SourceSurfaceD2D1::GetDataSurface() 1.35 +{ 1.36 + EnsureRealizedBitmap(); 1.37 + 1.38 + RefPtr<ID2D1Bitmap1> softwareBitmap; 1.39 + D2D1_BITMAP_PROPERTIES1 props; 1.40 + props.dpiX = 96; 1.41 + props.dpiY = 96; 1.42 + props.pixelFormat = D2DPixelFormat(mFormat); 1.43 + props.colorContext = nullptr; 1.44 + props.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW | 1.45 + D2D1_BITMAP_OPTIONS_CPU_READ; 1.46 + mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(softwareBitmap)); 1.47 + 1.48 + D2D1_POINT_2U point = D2D1::Point2U(0, 0); 1.49 + D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height); 1.50 + softwareBitmap->CopyFromBitmap(&point, mRealizedBitmap, &rect); 1.51 + return new DataSourceSurfaceD2D1(softwareBitmap, mFormat); 1.52 +} 1.53 + 1.54 +void 1.55 +SourceSurfaceD2D1::EnsureRealizedBitmap() 1.56 +{ 1.57 + if (mRealizedBitmap) { 1.58 + return; 1.59 + } 1.60 + 1.61 + RefPtr<ID2D1DeviceContext> dc; 1.62 + Factory::GetD2D1Device()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, byRef(dc)); 1.63 + 1.64 + D2D1_BITMAP_PROPERTIES1 props; 1.65 + props.dpiX = 96; 1.66 + props.dpiY = 96; 1.67 + props.pixelFormat = D2DPixelFormat(mFormat); 1.68 + props.colorContext = nullptr; 1.69 + props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; 1.70 + dc->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mRealizedBitmap)); 1.71 + 1.72 + dc->SetTarget(mRealizedBitmap); 1.73 + 1.74 + dc->BeginDraw(); 1.75 + dc->DrawImage(mImage); 1.76 + dc->EndDraw(); 1.77 +} 1.78 + 1.79 +void 1.80 +SourceSurfaceD2D1::DrawTargetWillChange() 1.81 +{ 1.82 + // At this point in time this should always be true here. 1.83 + MOZ_ASSERT(mRealizedBitmap); 1.84 + 1.85 + RefPtr<ID2D1Bitmap1> oldBitmap = mRealizedBitmap; 1.86 + 1.87 + D2D1_BITMAP_PROPERTIES1 props; 1.88 + props.dpiX = 96; 1.89 + props.dpiY = 96; 1.90 + props.pixelFormat = D2DPixelFormat(mFormat); 1.91 + props.colorContext = nullptr; 1.92 + props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET; 1.93 + mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mRealizedBitmap)); 1.94 + 1.95 + D2D1_POINT_2U point = D2D1::Point2U(0, 0); 1.96 + D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height); 1.97 + mRealizedBitmap->CopyFromBitmap(&point, oldBitmap, &rect); 1.98 + mImage = mRealizedBitmap; 1.99 + 1.100 + DrawTargetD2D1::mVRAMUsageSS += mSize.width * mSize.height * BytesPerPixel(mFormat); 1.101 + mDrawTarget = nullptr; 1.102 + 1.103 + // We now no longer depend on the source surface content remaining the same. 1.104 + MarkIndependent(); 1.105 +} 1.106 + 1.107 +void 1.108 +SourceSurfaceD2D1::MarkIndependent() 1.109 +{ 1.110 + if (mDrawTarget) { 1.111 + MOZ_ASSERT(mDrawTarget->mSnapshot == this); 1.112 + mDrawTarget->mSnapshot = nullptr; 1.113 + mDrawTarget = nullptr; 1.114 + } 1.115 +} 1.116 + 1.117 +DataSourceSurfaceD2D1::DataSourceSurfaceD2D1(ID2D1Bitmap1 *aMappableBitmap, SurfaceFormat aFormat) 1.118 + : mBitmap(aMappableBitmap) 1.119 + , mFormat(aFormat) 1.120 + , mMapped(false) 1.121 +{ 1.122 +} 1.123 + 1.124 +DataSourceSurfaceD2D1::~DataSourceSurfaceD2D1() 1.125 +{ 1.126 + if (mMapped) { 1.127 + mBitmap->Unmap(); 1.128 + } 1.129 +} 1.130 + 1.131 +IntSize 1.132 +DataSourceSurfaceD2D1::GetSize() const 1.133 +{ 1.134 + D2D1_SIZE_F size = mBitmap->GetSize(); 1.135 + 1.136 + return IntSize(int32_t(size.width), int32_t(size.height)); 1.137 +} 1.138 + 1.139 +uint8_t* 1.140 +DataSourceSurfaceD2D1::GetData() 1.141 +{ 1.142 + EnsureMapped(); 1.143 + 1.144 + return mMap.bits; 1.145 +} 1.146 + 1.147 +bool 1.148 +DataSourceSurfaceD2D1::Map(MapType aMapType, MappedSurface *aMappedSurface) 1.149 +{ 1.150 + // DataSourceSurfaces used with the new Map API should not be used with GetData!! 1.151 + MOZ_ASSERT(!mMapped); 1.152 + MOZ_ASSERT(!mIsMapped); 1.153 + 1.154 + D2D1_MAP_OPTIONS options; 1.155 + if (aMapType == MapType::READ) { 1.156 + options = D2D1_MAP_OPTIONS_READ; 1.157 + } else { 1.158 + MOZ_CRASH("No support for Write maps on D2D1 DataSourceSurfaces yet!"); 1.159 + } 1.160 + 1.161 + D2D1_MAPPED_RECT map; 1.162 + mBitmap->Map(D2D1_MAP_OPTIONS_READ, &map); 1.163 + aMappedSurface->mData = map.bits; 1.164 + aMappedSurface->mStride = map.pitch; 1.165 + 1.166 + mIsMapped = true; 1.167 + return true; 1.168 +} 1.169 + 1.170 +void 1.171 +DataSourceSurfaceD2D1::Unmap() 1.172 +{ 1.173 + MOZ_ASSERT(mIsMapped); 1.174 + 1.175 + mIsMapped = false; 1.176 + mBitmap->Unmap(); 1.177 +} 1.178 + 1.179 +int32_t 1.180 +DataSourceSurfaceD2D1::Stride() 1.181 +{ 1.182 + EnsureMapped(); 1.183 + 1.184 + return mMap.pitch; 1.185 +} 1.186 + 1.187 +void 1.188 +DataSourceSurfaceD2D1::EnsureMapped() 1.189 +{ 1.190 + // Do not use GetData() after having used Map! 1.191 + MOZ_ASSERT(!mIsMapped); 1.192 + if (mMapped) { 1.193 + return; 1.194 + } 1.195 + mBitmap->Map(D2D1_MAP_OPTIONS_READ, &mMap); 1.196 + mMapped = true; 1.197 +} 1.198 + 1.199 +} 1.200 +}