gecko/gfx/2d/SourceSurfaceD2D1.cpp
Ryan VanderMeulen b6c67c877a Backed out 11 changesets (bug 1083101) for causing mass Windows 7 test failures.
Backed out changeset 42d192dbf938 (bug 1083101)
Backed out changeset 0a6cc12c33d7 (bug 1083101)
Backed out changeset b82291c07e0e (bug 1083101)
Backed out changeset 2d32462f6c58 (bug 1083101)
Backed out changeset c234e70021a7 (bug 1083101)
Backed out changeset 23a3870672ae (bug 1083101)
Backed out changeset 78f3c70cf1cb (bug 1083101)
Backed out changeset 86f55d9695f0 (bug 1083101)
Backed out changeset 6b8940305079 (bug 1083101)
Backed out changeset 5efc1e52e4e9 (bug 1083101)
Backed out changeset dd266975e407 (bug 1083101)

CLOSED TREE
2015-09-01 11:35:02 -04:00

241 lines
5.7 KiB
C++

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SourceSurfaceD2D1.h"
#include "DrawTargetD2D1.h"
#include "Tools.h"
namespace mozilla {
namespace gfx {
SourceSurfaceD2D1::SourceSurfaceD2D1(ID2D1Image *aImage, ID2D1DeviceContext *aDC,
SurfaceFormat aFormat, const IntSize &aSize,
DrawTargetD2D1 *aDT)
: mImage(aImage)
, mDC(aDC)
, mDrawTarget(aDT)
, mDevice(Factory::GetD2D1Device())
{
aImage->QueryInterface((ID2D1Bitmap1**)byRef(mRealizedBitmap));
mFormat = aFormat;
mSize = aSize;
}
SourceSurfaceD2D1::~SourceSurfaceD2D1()
{
}
bool
SourceSurfaceD2D1::IsValid() const
{
return mDevice == Factory::GetD2D1Device();
}
already_AddRefed<DataSourceSurface>
SourceSurfaceD2D1::GetDataSurface()
{
HRESULT hr;
if (!EnsureRealizedBitmap()) {
gfxCriticalError() << "Failed to realize a bitmap, device " << hexa(mDevice);
return nullptr;
}
RefPtr<ID2D1Bitmap1> softwareBitmap;
D2D1_BITMAP_PROPERTIES1 props;
props.dpiX = 96;
props.dpiY = 96;
props.pixelFormat = D2DPixelFormat(mFormat);
props.colorContext = nullptr;
props.bitmapOptions = D2D1_BITMAP_OPTIONS_CANNOT_DRAW |
D2D1_BITMAP_OPTIONS_CPU_READ;
hr = mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(softwareBitmap));
if (FAILED(hr)) {
gfxCriticalError() << "Failed to create software bitmap: " << mSize << " Code: " << hexa(hr);
return nullptr;
}
D2D1_POINT_2U point = D2D1::Point2U(0, 0);
D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height);
hr = softwareBitmap->CopyFromBitmap(&point, mRealizedBitmap, &rect);
if (FAILED(hr)) {
gfxWarning() << "Failed to readback into software bitmap. Code: " << hexa(hr);
return nullptr;
}
return MakeAndAddRef<DataSourceSurfaceD2D1>(softwareBitmap, mFormat);
}
bool
SourceSurfaceD2D1::EnsureRealizedBitmap()
{
if (mRealizedBitmap) {
return true;
}
// Why aren't we using mDevice here or anywhere else?
ID2D1Device* device = Factory::GetD2D1Device();
if (!device) {
return false;
}
RefPtr<ID2D1DeviceContext> dc;
device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, byRef(dc));
D2D1_BITMAP_PROPERTIES1 props;
props.dpiX = 96;
props.dpiY = 96;
props.pixelFormat = D2DPixelFormat(mFormat);
props.colorContext = nullptr;
props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
dc->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mRealizedBitmap));
dc->SetTarget(mRealizedBitmap);
dc->BeginDraw();
dc->DrawImage(mImage);
dc->EndDraw();
return true;
}
void
SourceSurfaceD2D1::DrawTargetWillChange()
{
// At this point in time this should always be true here.
MOZ_ASSERT(mRealizedBitmap);
RefPtr<ID2D1Bitmap1> oldBitmap = mRealizedBitmap;
D2D1_BITMAP_PROPERTIES1 props;
props.dpiX = 96;
props.dpiY = 96;
props.pixelFormat = D2DPixelFormat(mFormat);
props.colorContext = nullptr;
props.bitmapOptions = D2D1_BITMAP_OPTIONS_TARGET;
HRESULT hr = mDC->CreateBitmap(D2DIntSize(mSize), nullptr, 0, props, (ID2D1Bitmap1**)byRef(mRealizedBitmap));
if (FAILED(hr)) {
gfxCriticalError() << "Failed to create bitmap to make DrawTarget copy. Size: " << mSize << " Code: " << hexa(hr);
MarkIndependent();
return;
}
D2D1_POINT_2U point = D2D1::Point2U(0, 0);
D2D1_RECT_U rect = D2D1::RectU(0, 0, mSize.width, mSize.height);
mRealizedBitmap->CopyFromBitmap(&point, oldBitmap, &rect);
mImage = mRealizedBitmap;
DrawTargetD2D1::mVRAMUsageSS += mSize.width * mSize.height * BytesPerPixel(mFormat);
// We now no longer depend on the source surface content remaining the same.
MarkIndependent();
}
void
SourceSurfaceD2D1::MarkIndependent()
{
if (mDrawTarget) {
MOZ_ASSERT(mDrawTarget->mSnapshot == this);
mDrawTarget->mSnapshot = nullptr;
mDrawTarget = nullptr;
}
}
DataSourceSurfaceD2D1::DataSourceSurfaceD2D1(ID2D1Bitmap1 *aMappableBitmap, SurfaceFormat aFormat)
: mBitmap(aMappableBitmap)
, mFormat(aFormat)
, mMapped(false)
{
}
DataSourceSurfaceD2D1::~DataSourceSurfaceD2D1()
{
if (mMapped) {
mBitmap->Unmap();
}
}
IntSize
DataSourceSurfaceD2D1::GetSize() const
{
D2D1_SIZE_F size = mBitmap->GetSize();
return IntSize(int32_t(size.width), int32_t(size.height));
}
uint8_t*
DataSourceSurfaceD2D1::GetData()
{
EnsureMapped();
return mMap.bits;
}
bool
DataSourceSurfaceD2D1::Map(MapType aMapType, MappedSurface *aMappedSurface)
{
// DataSourceSurfaces used with the new Map API should not be used with GetData!!
MOZ_ASSERT(!mMapped);
MOZ_ASSERT(!mIsMapped);
D2D1_MAP_OPTIONS options;
if (aMapType == MapType::READ) {
options = D2D1_MAP_OPTIONS_READ;
} else {
MOZ_CRASH("No support for Write maps on D2D1 DataSourceSurfaces yet!");
}
D2D1_MAPPED_RECT map;
if (FAILED(mBitmap->Map(D2D1_MAP_OPTIONS_READ, &map))) {
gfxCriticalError() << "Failed to map bitmap.";
return false;
}
aMappedSurface->mData = map.bits;
aMappedSurface->mStride = map.pitch;
mIsMapped = !!aMappedSurface->mData;
return mIsMapped;
}
void
DataSourceSurfaceD2D1::Unmap()
{
MOZ_ASSERT(mIsMapped);
mIsMapped = false;
mBitmap->Unmap();
}
int32_t
DataSourceSurfaceD2D1::Stride()
{
EnsureMapped();
return mMap.pitch;
}
void
DataSourceSurfaceD2D1::EnsureMapped()
{
// Do not use GetData() after having used Map!
MOZ_ASSERT(!mIsMapped);
if (mMapped) {
return;
}
if (FAILED(mBitmap->Map(D2D1_MAP_OPTIONS_READ, &mMap))) {
gfxCriticalError() << "Failed to map bitmap.";
return;
}
mMapped = true;
}
}
}