Bug 1247775 - Part 3: Remove Moz2D code to support Direct2D 1.0. r=dvander

MozReview-Commit-ID: KBZSqIdx0OC
This commit is contained in:
Bas Schouten 2016-02-12 02:11:50 +01:00
parent 782d2b90b1
commit 7e3f410fb0
16 changed files with 78 additions and 4076 deletions

View File

@ -36,8 +36,6 @@ typedef _cairo_surface cairo_surface_t;
struct _cairo_scaled_font; struct _cairo_scaled_font;
typedef _cairo_scaled_font cairo_scaled_font_t; typedef _cairo_scaled_font cairo_scaled_font_t;
struct ID3D10Device1;
struct ID3D10Texture2D;
struct ID3D11Texture2D; struct ID3D11Texture2D;
struct ID3D11Device; struct ID3D11Device;
struct ID2D1Device; struct ID2D1Device;
@ -1364,14 +1362,6 @@ public:
#endif #endif
#ifdef WIN32 #ifdef WIN32
static already_AddRefed<DrawTarget> CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
static already_AddRefed<DrawTarget>
CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA,
ID3D10Texture2D *aTextureB,
SurfaceFormat aFormat);
static void SetDirect3D10Device(ID3D10Device1 *aDevice);
static ID3D10Device1 *GetDirect3D10Device();
static already_AddRefed<DrawTarget> CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat); static already_AddRefed<DrawTarget> CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat);
static void SetDirect3D11Device(ID3D11Device *aDevice); static void SetDirect3D11Device(ID3D11Device *aDevice);
@ -1394,7 +1384,6 @@ public:
private: private:
static ID2D1Device *mD2D1Device; static ID2D1Device *mD2D1Device;
static ID3D10Device1 *mD3D10Device;
static ID3D11Device *mD3D11Device; static ID3D11Device *mD3D11Device;
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,290 +0,0 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_DRAWTARGETD2D_H_
#define MOZILLA_GFX_DRAWTARGETD2D_H_
#include "2D.h"
#include "PathD2D.h"
#include <d3d10_1.h>
#include "HelpersD2D.h"
#include <vector>
#include <sstream>
#include <unordered_set>
struct IDWriteFactory;
namespace mozilla {
namespace gfx {
class SourceSurfaceD2DTarget;
class SourceSurfaceD2D;
class GradientStopsD2D;
class ScaledFontDWrite;
const int32_t kLayerCacheSize = 5;
struct PrivateD3D10DataD2D
{
RefPtr<ID3D10Effect> mEffect;
RefPtr<ID3D10InputLayout> mInputLayout;
RefPtr<ID3D10Buffer> mVB;
RefPtr<ID3D10BlendState> mBlendStates[size_t(CompositionOp::OP_COUNT)];
};
class DrawTargetD2D : public DrawTarget
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DrawTargetD2D, override)
DrawTargetD2D();
virtual ~DrawTargetD2D();
virtual DrawTargetType GetType() const override { return DrawTargetType::HARDWARE_RASTER; }
virtual BackendType GetBackendType() const override { return BackendType::DIRECT2D; }
virtual already_AddRefed<SourceSurface> Snapshot() override;
virtual IntSize GetSize() override { return mSize; }
virtual void Flush() override;
virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest,
const Rect &aSource,
const DrawSurfaceOptions &aSurfOptions = DrawSurfaceOptions(),
const DrawOptions &aOptions = DrawOptions()) override;
virtual void DrawFilter(FilterNode *aNode,
const Rect &aSourceRect,
const Point &aDestPoint,
const DrawOptions &aOptions = DrawOptions()) override;
virtual void DrawSurfaceWithShadow(SourceSurface *aSurface,
const Point &aDest,
const Color &aColor,
const Point &aOffset,
Float aSigma,
CompositionOp aOperator) override;
virtual void ClearRect(const Rect &aRect) override;
virtual void MaskSurface(const Pattern &aSource,
SourceSurface *aMask,
Point aOffset,
const DrawOptions &aOptions = DrawOptions()) override;
virtual void CopySurface(SourceSurface *aSurface,
const IntRect &aSourceRect,
const IntPoint &aDestination) override;
virtual void FillRect(const Rect &aRect,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions()) override;
virtual void StrokeRect(const Rect &aRect,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions()) override;
virtual void StrokeLine(const Point &aStart,
const Point &aEnd,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions()) override;
virtual void Stroke(const Path *aPath,
const Pattern &aPattern,
const StrokeOptions &aStrokeOptions = StrokeOptions(),
const DrawOptions &aOptions = DrawOptions()) override;
virtual void Fill(const Path *aPath,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions()) override;
virtual void FillGlyphs(ScaledFont *aFont,
const GlyphBuffer &aBuffer,
const Pattern &aPattern,
const DrawOptions &aOptions = DrawOptions(),
const GlyphRenderingOptions *aRenderingOptions = nullptr) override;
virtual void Mask(const Pattern &aSource,
const Pattern &aMask,
const DrawOptions &aOptions = DrawOptions()) override;
virtual void PushClip(const Path *aPath) override;
virtual void PushClipRect(const Rect &aRect) override;
virtual void PopClip() override;
virtual already_AddRefed<SourceSurface> CreateSourceSurfaceFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat) const override;
virtual already_AddRefed<SourceSurface> OptimizeSourceSurface(SourceSurface *aSurface) const override;
virtual already_AddRefed<SourceSurface>
CreateSourceSurfaceFromNativeSurface(const NativeSurface &aSurface) const override;
virtual already_AddRefed<DrawTarget>
CreateSimilarDrawTarget(const IntSize &aSize, SurfaceFormat aFormat) const override;
virtual already_AddRefed<PathBuilder> CreatePathBuilder(FillRule aFillRule = FillRule::FILL_WINDING) const override;
virtual already_AddRefed<GradientStops>
CreateGradientStops(GradientStop *aStops,
uint32_t aNumStops,
ExtendMode aExtendMode = ExtendMode::CLAMP) const override;
virtual already_AddRefed<FilterNode> CreateFilter(FilterType aType) override;
virtual bool SupportsRegionClipping() const override { return false; }
virtual void *GetNativeSurface(NativeSurfaceType aType) override;
bool Init(const IntSize &aSize, SurfaceFormat aFormat);
bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
bool InitD3D10Data();
uint32_t GetByteSize() const;
already_AddRefed<ID2D1Layer> GetCachedLayer();
void PopCachedLayer(ID2D1RenderTarget *aRT);
already_AddRefed<ID2D1Image> GetImageForSurface(SourceSurface *aSurface);
static ID2D1Factory *factory();
static void CleanupD2D();
static IDWriteFactory *GetDWriteFactory();
ID2D1RenderTarget *GetRT() { return mRT; }
static uint32_t GetMaxSurfaceSize() {
return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
}
operator std::string() const {
std::stringstream stream;
stream << "DrawTargetD2D(" << this << ")";
return stream.str();
}
static uint64_t mVRAMUsageDT;
static uint64_t mVRAMUsageSS;
private:
already_AddRefed<ID2D1Bitmap>
GetBitmapForSurface(SourceSurface *aSurface,
Rect &aSource);
friend class AutoSaveRestoreClippedOut;
friend class SourceSurfaceD2DTarget;
typedef std::unordered_set<DrawTargetD2D*> TargetSet;
bool InitD2DRenderTarget();
void PrepareForDrawing(ID2D1RenderTarget *aRT);
// This function will mark the surface as changing, and make sure any
// copy-on-write snapshots are notified.
void MarkChanged();
void FlushTransformToRT() {
if (mTransformDirty) {
mRT->SetTransform(D2DMatrix(mTransform));
mTransformDirty = false;
}
}
void AddDependencyOnSource(SourceSurfaceD2DTarget* aSource);
ID3D10BlendState *GetBlendStateForOperator(CompositionOp aOperator);
ID2D1RenderTarget *GetRTForOperation(CompositionOp aOperator, const Pattern &aPattern);
void FinalizeRTForOperation(CompositionOp aOperator, const Pattern &aPattern, const Rect &aBounds); void EnsureViews();
void PopAllClips();
void PushClipsToRT(ID2D1RenderTarget *aRT);
void PopClipsFromRT(ID2D1RenderTarget *aRT);
// This function ensures mCurrentClipMaskTexture contains a texture containing
// a mask corresponding with the current DrawTarget clip. See
// GetClippedGeometry for a description of aClipBounds.
void EnsureClipMaskTexture(IntRect *aClipBounds);
bool FillGlyphsManual(ScaledFontDWrite *aFont,
const GlyphBuffer &aBuffer,
const Color &aColor,
IDWriteRenderingParams *aParams,
const DrawOptions &aOptions = DrawOptions());
already_AddRefed<ID2D1RenderTarget> CreateRTForTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat);
// This returns the clipped geometry, in addition it returns aClipBounds which
// represents the intersection of all pixel-aligned rectangular clips that
// are currently set. The returned clipped geometry must be clipped by these
// bounds to correctly reflect the total clip. This is in device space.
already_AddRefed<ID2D1Geometry> GetClippedGeometry(IntRect *aClipBounds);
bool GetDeviceSpaceClipRect(D2D1_RECT_F& aClipRect, bool& aIsPixelAligned);
already_AddRefed<ID2D1Brush> CreateBrushForPattern(const Pattern &aPattern, Float aAlpha = 1.0f);
already_AddRefed<ID3D10Texture2D> CreateGradientTexture(const GradientStopsD2D *aStops);
already_AddRefed<ID3D10Texture2D> CreateTextureForAnalysis(IDWriteGlyphRunAnalysis *aAnalysis, const IntRect &aBounds);
void SetupEffectForRadialGradient(const RadialGradientPattern *aPattern);
void SetupStateForRendering();
// Set the scissor rect to a certain IntRects, resets the scissor rect to
// surface bounds when nullptr is specified.
void SetScissorToRect(IntRect *aRect);
void PushD2DLayer(ID2D1RenderTarget *aRT, ID2D1Geometry *aGeometry, ID2D1Layer *aLayer, const D2D1_MATRIX_3X2_F &aTransform);
static const uint32_t test = 4;
IntSize mSize;
RefPtr<ID3D10Device1> mDevice;
RefPtr<ID3D10Texture2D> mTexture;
RefPtr<ID3D10Texture2D> mCurrentClipMaskTexture;
RefPtr<ID2D1Geometry> mCurrentClippedGeometry;
// This is only valid if mCurrentClippedGeometry is non-null. And will
// only be the intersection of all pixel-aligned retangular clips. This is in
// device space.
IntRect mCurrentClipBounds;
mutable RefPtr<ID2D1RenderTarget> mRT;
// We store this to prevent excessive SetTextRenderingParams calls.
RefPtr<IDWriteRenderingParams> mTextRenderingParams;
// Temporary texture and render target used for supporting alternative operators.
RefPtr<ID3D10Texture2D> mTempTexture;
RefPtr<ID3D10RenderTargetView> mRTView;
RefPtr<ID3D10ShaderResourceView> mSRView;
RefPtr<ID2D1RenderTarget> mTempRT;
RefPtr<ID3D10RenderTargetView> mTempRTView;
// List of pushed clips.
struct PushedClip
{
RefPtr<ID2D1Layer> mLayer;
D2D1_RECT_F mBounds;
union {
// If mPath is non-nullptr, the mTransform member will be used, otherwise
// the mIsPixelAligned member is valid.
D2D1_MATRIX_3X2_F mTransform;
bool mIsPixelAligned;
};
RefPtr<PathD2D> mPath;
};
std::vector<PushedClip> mPushedClips;
// We cache ID2D1Layer objects as it causes D2D to keep around textures that
// serve as the temporary surfaces for these operations. As texture creation
// is quite expensive this considerably improved performance.
// Careful here, RAII will not ensure destruction of the RefPtrs.
RefPtr<ID2D1Layer> mCachedLayers[kLayerCacheSize];
uint32_t mCurrentCachedLayer;
// The latest snapshot of this surface. This needs to be told when this
// target is modified. We keep it alive as a cache.
RefPtr<SourceSurfaceD2DTarget> mSnapshot;
// A list of targets we need to flush when we're modified.
TargetSet mDependentTargets;
// A list of targets which have this object in their mDependentTargets set
TargetSet mDependingOnTargets;
// True of the current clip stack is pushed to the main RT.
bool mClipsArePushed;
PrivateD3D10DataD2D *mPrivateData;
static ID2D1Factory *mFactory;
static IDWriteFactory *mDWriteFactory;
};
}
}
#endif /* MOZILLA_GFX_DRAWTARGETD2D_H_ */

View File

@ -5,24 +5,32 @@
#include <initguid.h> #include <initguid.h>
#include "DrawTargetD2D1.h" #include "DrawTargetD2D1.h"
#include "DrawTargetD2D.h"
#include "FilterNodeSoftware.h" #include "FilterNodeSoftware.h"
#include "GradientStopsD2D.h" #include "GradientStopsD2D.h"
#include "SourceSurfaceD2D1.h" #include "SourceSurfaceD2D1.h"
#include "SourceSurfaceD2D.h"
#include "RadialGradientEffectD2D1.h" #include "RadialGradientEffectD2D1.h"
#include "HelpersD2D.h" #include "HelpersD2D.h"
#include "FilterNodeD2D1.h" #include "FilterNodeD2D1.h"
#include "ExtendInputEffectD2D1.h"
#include "Tools.h" #include "Tools.h"
using namespace std; using namespace std;
// decltype is not usable for overloaded functions.
typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
D2D1_FACTORY_TYPE factoryType,
REFIID iid,
CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
void **factory
);
namespace mozilla { namespace mozilla {
namespace gfx { namespace gfx {
uint64_t DrawTargetD2D1::mVRAMUsageDT; uint64_t DrawTargetD2D1::mVRAMUsageDT;
uint64_t DrawTargetD2D1::mVRAMUsageSS; uint64_t DrawTargetD2D1::mVRAMUsageSS;
IDWriteFactory *DrawTargetD2D1::mDWriteFactory;
ID2D1Factory1* DrawTargetD2D1::mFactory = nullptr; ID2D1Factory1* DrawTargetD2D1::mFactory = nullptr;
ID2D1Factory1 *D2DFactory1() ID2D1Factory1 *D2DFactory1()
@ -604,7 +612,7 @@ DrawTargetD2D1::FillGlyphs(ScaledFont *aFont,
DWRITE_MEASURING_MODE_NATURAL, &userRect); DWRITE_MEASURING_MODE_NATURAL, &userRect);
RefPtr<ID2D1PathGeometry> path; RefPtr<ID2D1PathGeometry> path;
D2DFactory()->CreatePathGeometry(getter_AddRefs(path)); factory()->CreatePathGeometry(getter_AddRefs(path));
RefPtr<ID2D1GeometrySink> sink; RefPtr<ID2D1GeometrySink> sink;
path->Open(getter_AddRefs(sink)); path->Open(getter_AddRefs(sink));
AddRectToSink(sink, userRect); AddRectToSink(sink, userRect);
@ -1060,27 +1068,79 @@ DrawTargetD2D1::factory()
return mFactory; return mFactory;
} }
ID2D1Factory* d2dFactory = D2DFactory(); RefPtr<ID2D1Factory> factory;
if (!d2dFactory) { D2D1CreateFactoryFunc createD2DFactory;
HMODULE d2dModule = LoadLibraryW(L"d2d1.dll");
createD2DFactory = (D2D1CreateFactoryFunc)
GetProcAddress(d2dModule, "D2D1CreateFactory");
if (!createD2DFactory) {
gfxWarning() << "Failed to locate D2D1CreateFactory function.";
return nullptr; return nullptr;
} }
HRESULT hr = d2dFactory->QueryInterface((ID2D1Factory1**)&mFactory); D2D1_FACTORY_OPTIONS options;
#ifdef _DEBUG
options.debugLevel = D2D1_DEBUG_LEVEL_WARNING;
#else
options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
#endif
//options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
if (FAILED(hr)) { HRESULT hr = createD2DFactory(D2D1_FACTORY_TYPE_MULTI_THREADED,
__uuidof(ID2D1Factory),
&options,
getter_AddRefs(factory));
if (FAILED(hr) || !factory) {
gfxWarning() << "Failed to create Direct2D factory.";
return nullptr; return nullptr;
} }
hr = factory->QueryInterface((ID2D1Factory1**)&mFactory);
if (FAILED(hr) || !mFactory) {
return nullptr;
}
ExtendInputEffectD2D1::Register(mFactory);
RadialGradientEffectD2D1::Register(mFactory); RadialGradientEffectD2D1::Register(mFactory);
return mFactory; return mFactory;
} }
IDWriteFactory*
DrawTargetD2D1::GetDWriteFactory()
{
if (mDWriteFactory) {
return mDWriteFactory;
}
decltype(DWriteCreateFactory)* createDWriteFactory;
HMODULE dwriteModule = LoadLibraryW(L"dwrite.dll");
createDWriteFactory = (decltype(DWriteCreateFactory)*)
GetProcAddress(dwriteModule, "DWriteCreateFactory");
if (!createDWriteFactory) {
gfxWarning() << "Failed to locate DWriteCreateFactory function.";
return nullptr;
}
HRESULT hr = createDWriteFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&mDWriteFactory));
if (FAILED(hr)) {
gfxWarning() << "Failed to create DWrite Factory.";
}
return mDWriteFactory;
}
void void
DrawTargetD2D1::CleanupD2D() DrawTargetD2D1::CleanupD2D()
{ {
if (mFactory) { if (mFactory) {
RadialGradientEffectD2D1::Unregister(mFactory); RadialGradientEffectD2D1::Unregister(mFactory);
ExtendInputEffectD2D1::Unregister(mFactory);
mFactory->Release(); mFactory->Release();
mFactory = nullptr; mFactory = nullptr;
} }

View File

@ -35,7 +35,6 @@
#endif #endif
#ifdef WIN32 #ifdef WIN32
#include "DrawTargetD2D.h"
#include "DrawTargetD2D1.h" #include "DrawTargetD2D1.h"
#include "ScaledFontDWrite.h" #include "ScaledFontDWrite.h"
#include "NativeFontResourceDWrite.h" #include "NativeFontResourceDWrite.h"
@ -161,7 +160,6 @@ int32_t LoggingPrefs::sGfxLogLevel =
LOG_DEFAULT); LOG_DEFAULT);
#ifdef WIN32 #ifdef WIN32
ID3D10Device1 *Factory::mD3D10Device;
ID3D11Device *Factory::mD3D11Device; ID3D11Device *Factory::mD3D11Device;
ID2D1Device *Factory::mD2D1Device; ID2D1Device *Factory::mD2D1Device;
#endif #endif
@ -315,15 +313,6 @@ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFor
RefPtr<DrawTarget> retVal; RefPtr<DrawTarget> retVal;
switch (aBackend) { switch (aBackend) {
#ifdef WIN32 #ifdef WIN32
case BackendType::DIRECT2D:
{
RefPtr<DrawTargetD2D> newTarget;
newTarget = new DrawTargetD2D();
if (newTarget->Init(aSize, aFormat)) {
retVal = newTarget;
}
break;
}
case BackendType::DIRECT2D1_1: case BackendType::DIRECT2D1_1:
{ {
RefPtr<DrawTargetD2D1> newTarget; RefPtr<DrawTargetD2D1> newTarget;
@ -499,8 +488,6 @@ Factory::GetMaxSurfaceSize(BackendType aType)
return DrawTargetSkia::GetMaxSurfaceSize(); return DrawTargetSkia::GetMaxSurfaceSize();
#endif #endif
#ifdef WIN32 #ifdef WIN32
case BackendType::DIRECT2D:
return DrawTargetD2D::GetMaxSurfaceSize();
case BackendType::DIRECT2D1_1: case BackendType::DIRECT2D1_1:
return DrawTargetD2D1::GetMaxSurfaceSize(); return DrawTargetD2D1::GetMaxSurfaceSize();
#endif #endif
@ -611,87 +598,6 @@ Factory::CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB)
#ifdef WIN32 #ifdef WIN32
already_AddRefed<DrawTarget>
Factory::CreateDrawTargetForD3D10Texture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat)
{
MOZ_ASSERT(aTexture);
RefPtr<DrawTargetD2D> newTarget;
newTarget = new DrawTargetD2D();
if (newTarget->Init(aTexture, aFormat)) {
RefPtr<DrawTarget> retVal = newTarget;
if (mRecorder) {
retVal = new DrawTargetRecording(mRecorder, retVal, true);
}
return retVal.forget();
}
gfxWarning() << "Failed to create draw target for D3D10 texture.";
// Failed
return nullptr;
}
already_AddRefed<DrawTarget>
Factory::CreateDualDrawTargetForD3D10Textures(ID3D10Texture2D *aTextureA,
ID3D10Texture2D *aTextureB,
SurfaceFormat aFormat)
{
MOZ_ASSERT(aTextureA && aTextureB);
RefPtr<DrawTargetD2D> newTargetA;
RefPtr<DrawTargetD2D> newTargetB;
newTargetA = new DrawTargetD2D();
if (!newTargetA->Init(aTextureA, aFormat)) {
gfxWarning() << "Failed to create dual draw target for D3D10 texture.";
return nullptr;
}
newTargetB = new DrawTargetD2D();
if (!newTargetB->Init(aTextureB, aFormat)) {
gfxWarning() << "Failed to create new draw target for D3D10 texture.";
return nullptr;
}
RefPtr<DrawTarget> newTarget =
new DrawTargetDual(newTargetA, newTargetB);
RefPtr<DrawTarget> retVal = newTarget;
if (mRecorder) {
retVal = new DrawTargetRecording(mRecorder, retVal);
}
return retVal.forget();
}
void
Factory::SetDirect3D10Device(ID3D10Device1 *aDevice)
{
// do not throw on failure; return error codes and disconnect the device
// On Windows 8 error codes are the default, but on Windows 7 the
// default is to throw (or perhaps only with some drivers?)
if (aDevice) {
aDevice->SetExceptionMode(0);
}
mD3D10Device = aDevice;
}
ID3D10Device1*
Factory::GetDirect3D10Device()
{
#ifdef DEBUG
if (mD3D10Device) {
UINT mode = mD3D10Device->GetExceptionMode();
MOZ_ASSERT(0 == mode);
}
#endif
return mD3D10Device;
}
already_AddRefed<DrawTarget> already_AddRefed<DrawTarget>
Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat) Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat)
{ {
@ -767,13 +673,13 @@ Factory::CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams)
uint64_t uint64_t
Factory::GetD2DVRAMUsageDrawTarget() Factory::GetD2DVRAMUsageDrawTarget()
{ {
return DrawTargetD2D::mVRAMUsageDT; return DrawTargetD2D1::mVRAMUsageDT;
} }
uint64_t uint64_t
Factory::GetD2DVRAMUsageSourceSurface() Factory::GetD2DVRAMUsageSourceSurface()
{ {
return DrawTargetD2D::mVRAMUsageSS; return DrawTargetD2D1::mVRAMUsageSS;
} }
void void
@ -784,7 +690,6 @@ Factory::D2DCleanup()
mD2D1Device = nullptr; mD2D1Device = nullptr;
} }
DrawTargetD2D1::CleanupD2D(); DrawTargetD2D1::CleanupD2D();
DrawTargetD2D::CleanupD2D();
} }
already_AddRefed<ScaledFont> already_AddRefed<ScaledFont>

View File

@ -8,9 +8,6 @@
#include "Logging.h" #include "Logging.h"
#include "SourceSurfaceD2D1.h" #include "SourceSurfaceD2D1.h"
#include "SourceSurfaceD2D.h"
#include "SourceSurfaceD2DTarget.h"
#include "DrawTargetD2D.h"
#include "DrawTargetD2D1.h" #include "DrawTargetD2D1.h"
#include "ExtendInputEffectD2D1.h" #include "ExtendInputEffectD2D1.h"
@ -159,8 +156,6 @@ already_AddRefed<ID2D1Image> GetImageForSourceSurface(DrawTarget *aDT, SourceSur
switch (aDT->GetBackendType()) { switch (aDT->GetBackendType()) {
case BackendType::DIRECT2D1_1: case BackendType::DIRECT2D1_1:
return static_cast<DrawTargetD2D1*>(aDT)->GetImageForSurface(aSurface, ExtendMode::CLAMP); return static_cast<DrawTargetD2D1*>(aDT)->GetImageForSurface(aSurface, ExtendMode::CLAMP);
case BackendType::DIRECT2D:
return static_cast<DrawTargetD2D*>(aDT)->GetImageForSurface(aSurface);
default: default:
gfxDevCrash(LogReason::FilterNodeD2D1Backend) << "Unknown draw target type! " << (int)aDT->GetBackendType(); gfxDevCrash(LogReason::FilterNodeD2D1Backend) << "Unknown draw target type! " << (int)aDT->GetBackendType();
return nullptr; return nullptr;

View File

@ -25,9 +25,8 @@
namespace mozilla { namespace mozilla {
namespace gfx { namespace gfx {
ID2D1Factory* D2DFactory();
ID2D1Factory1* D2DFactory1(); ID2D1Factory1* D2DFactory1();
static ID2D1Factory* D2DFactory() { return D2DFactory1(); }
static inline D2D1_POINT_2F D2DPoint(const Point &aPoint) static inline D2D1_POINT_2F D2DPoint(const Point &aPoint)
{ {

View File

@ -8,7 +8,7 @@
#include <unordered_map> #include <unordered_map>
#include "DrawTargetD2D.h" #include "DrawTargetD2D1.h"
#include "Logging.h" #include "Logging.h"
#include "mozilla/RefPtr.h" #include "mozilla/RefPtr.h"
@ -69,7 +69,7 @@ public:
{ {
if (!mInstance) { if (!mInstance) {
mInstance = new DWriteFontFileLoader(); mInstance = new DWriteFontFileLoader();
DrawTargetD2D::GetDWriteFactory()-> DrawTargetD2D1::GetDWriteFactory()->
RegisterFontFileLoader(mInstance); RegisterFontFileLoader(mInstance);
} }
return mInstance; return mInstance;
@ -221,7 +221,7 @@ already_AddRefed<NativeFontResourceDWrite>
NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength, NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength,
bool aNeedsCairo) bool aNeedsCairo)
{ {
IDWriteFactory *factory = DrawTargetD2D::GetDWriteFactory(); IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory();
if (!factory) { if (!factory) {
gfxWarning() << "Failed to get DWrite Factory."; gfxWarning() << "Failed to get DWrite Factory.";
return nullptr; return nullptr;

View File

@ -6,7 +6,7 @@
#include "PathD2D.h" #include "PathD2D.h"
#include "HelpersD2D.h" #include "HelpersD2D.h"
#include <math.h> #include <math.h>
#include "DrawTargetD2D.h" #include "DrawTargetD2D1.h"
#include "Logging.h" #include "Logging.h"
namespace mozilla { namespace mozilla {
@ -351,7 +351,7 @@ already_AddRefed<PathBuilder>
PathD2D::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const PathD2D::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
{ {
RefPtr<ID2D1PathGeometry> path; RefPtr<ID2D1PathGeometry> path;
HRESULT hr = DrawTargetD2D::factory()->CreatePathGeometry(getter_AddRefs(path)); HRESULT hr = DrawTargetD2D1::factory()->CreatePathGeometry(getter_AddRefs(path));
if (FAILED(hr)) { if (FAILED(hr)) {
gfxWarning() << "Failed to create PathGeometry. Code: " << hexa(hr); gfxWarning() << "Failed to create PathGeometry. Code: " << hexa(hr);

View File

@ -3,7 +3,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DrawTargetD2D.h" #include "DrawTargetD2D1.h"
#include "ScaledFontDWrite.h" #include "ScaledFontDWrite.h"
#include "PathD2D.h" #include "PathD2D.h"
@ -120,7 +120,7 @@ ScaledFontDWrite::GetSkTypeface()
{ {
MOZ_ASSERT(mFont); MOZ_ASSERT(mFont);
if (!mTypeface) { if (!mTypeface) {
IDWriteFactory *factory = DrawTargetD2D::GetDWriteFactory(); IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory();
mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mFont, mFontFamily); mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mFont, mFontFamily);
} }
return mTypeface; return mTypeface;

View File

@ -1,317 +0,0 @@
/* -*- 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 "SourceSurfaceD2D.h"
#include "DrawTargetD2D.h"
#include "Logging.h"
#include "Tools.h"
namespace mozilla {
namespace gfx {
SourceSurfaceD2D::SourceSurfaceD2D()
{
}
SourceSurfaceD2D::~SourceSurfaceD2D()
{
if (mBitmap) {
DrawTargetD2D::mVRAMUsageSS -= GetByteSize();
}
}
IntSize
SourceSurfaceD2D::GetSize() const
{
return mSize;
}
SurfaceFormat
SourceSurfaceD2D::GetFormat() const
{
return mFormat;
}
bool
SourceSurfaceD2D::IsValid() const
{
return mDevice == Factory::GetDirect3D10Device();
}
already_AddRefed<DataSourceSurface>
SourceSurfaceD2D::GetDataSurface()
{
RefPtr<DataSourceSurfaceD2D> result = new DataSourceSurfaceD2D(this);
if (result->IsValid()) {
return result.forget();
}
return nullptr;
}
bool
SourceSurfaceD2D::InitFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat,
ID2D1RenderTarget *aRT)
{
HRESULT hr;
mFormat = aFormat;
mSize = aSize;
if ((uint32_t)aSize.width > aRT->GetMaximumBitmapSize() ||
(uint32_t)aSize.height > aRT->GetMaximumBitmapSize()) {
gfxDebug() << "Bitmap does not fit in texture.";
return false;
}
D2D1_BITMAP_PROPERTIES props = D2D1::BitmapProperties(D2DPixelFormat(aFormat));
hr = aRT->CreateBitmap(D2DIntSize(aSize), props, getter_AddRefs(mBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hexa(hr);
return false;
}
hr = mBitmap->CopyFromMemory(nullptr, aData, aStride);
if (FAILED(hr)) {
gfxWarning() << "Failed to copy data to D2D bitmap. Code: " << hexa(hr);
return false;
}
DrawTargetD2D::mVRAMUsageSS += GetByteSize();
mDevice = Factory::GetDirect3D10Device();
return true;
}
bool
SourceSurfaceD2D::InitFromTexture(ID3D10Texture2D *aTexture,
SurfaceFormat aFormat,
ID2D1RenderTarget *aRT)
{
HRESULT hr;
RefPtr<IDXGISurface> surf;
hr = aTexture->QueryInterface((IDXGISurface**)&surf);
if (FAILED(hr)) {
gfxWarning() << "Failed to QI texture to surface. Code: " << hexa(hr);
return false;
}
D3D10_TEXTURE2D_DESC desc;
aTexture->GetDesc(&desc);
mSize = IntSize(desc.Width, desc.Height);
mFormat = aFormat;
D2D1_BITMAP_PROPERTIES props = D2D1::BitmapProperties(D2DPixelFormat(aFormat));
hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, getter_AddRefs(mBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed to create SharedBitmap. Code: " << hexa(hr);
return false;
}
aTexture->GetDevice(getter_AddRefs(mDevice));
DrawTargetD2D::mVRAMUsageSS += GetByteSize();
return true;
}
uint32_t
SourceSurfaceD2D::GetByteSize() const
{
return mSize.width * mSize.height * BytesPerPixel(mFormat);
}
DataSourceSurfaceD2D::DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface)
: mTexture(nullptr)
, mFormat(aSourceSurface->mFormat)
, mSize(aSourceSurface->mSize)
, mMapped(false)
{
// We allocate ourselves a regular D3D surface (sourceTexture) and paint the
// D2D bitmap into it via a DXGI render target. Then we need to copy
// sourceTexture into a staging texture (mTexture), which we will lazily map
// to get the data.
CD3D10_TEXTURE2D_DESC desc(DXGIFormat(mFormat), mSize.width, mSize.height);
desc.MipLevels = 1;
desc.Usage = D3D10_USAGE_DEFAULT;
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
RefPtr<ID3D10Texture2D> sourceTexture;
HRESULT hr = aSourceSurface->mDevice->CreateTexture2D(&desc, nullptr,
getter_AddRefs(sourceTexture));
if (FAILED(hr)) {
gfxWarning() << "Failed to create texture. Code: " << hexa(hr);
return;
}
RefPtr<IDXGISurface> dxgiSurface;
hr = sourceTexture->QueryInterface((IDXGISurface**)getter_AddRefs(dxgiSurface));
if (FAILED(hr)) {
gfxWarning() << "Failed to create DXGI surface. Code: " << hexa(hr);
return;
}
D2D1_RENDER_TARGET_PROPERTIES rtProps = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED));
RefPtr<ID2D1RenderTarget> renderTarget;
hr = DrawTargetD2D::factory()->CreateDxgiSurfaceRenderTarget(dxgiSurface,
&rtProps,
getter_AddRefs(renderTarget));
if (FAILED(hr)) {
gfxWarning() << "Failed to create render target. Code: " << hexa(hr);
return;
}
renderTarget->BeginDraw();
renderTarget->Clear(D2D1::ColorF(0, 0.0f));
if (aSourceSurface->GetFormat() != SurfaceFormat::A8) {
renderTarget->DrawBitmap(aSourceSurface->mBitmap,
D2D1::RectF(0, 0,
Float(mSize.width),
Float(mSize.height)));
} else {
RefPtr<ID2D1SolidColorBrush> brush;
renderTarget->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), getter_AddRefs(brush));
renderTarget->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
renderTarget->FillOpacityMask(aSourceSurface->mBitmap, brush, D2D1_OPACITY_MASK_CONTENT_GRAPHICS);
}
hr = renderTarget->EndDraw();
if (FAILED(hr)) {
gfxWarning() << "Failed to draw bitmap. Code: " << hexa(hr);
return;
}
desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ | D3D10_CPU_ACCESS_WRITE;
desc.Usage = D3D10_USAGE_STAGING;
desc.BindFlags = 0;
hr = aSourceSurface->mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(mTexture));
if (FAILED(hr)) {
gfxWarning() << "Failed to create staging texture. Code: " << hexa(hr);
mTexture = nullptr;
return;
}
aSourceSurface->mDevice->CopyResource(mTexture, sourceTexture);
}
DataSourceSurfaceD2D::~DataSourceSurfaceD2D()
{
if (mMapped) {
mTexture->Unmap(0);
}
}
unsigned char*
DataSourceSurfaceD2D::GetData()
{
EnsureMappedTexture();
if (!mMapped) {
return nullptr;
}
return reinterpret_cast<unsigned char*>(mData.pData);
}
int32_t
DataSourceSurfaceD2D::Stride()
{
EnsureMappedTexture();
if (!mMapped) {
return 0;
}
return mData.RowPitch;
}
IntSize
DataSourceSurfaceD2D::GetSize() const
{
return mSize;
}
SurfaceFormat
DataSourceSurfaceD2D::GetFormat() const
{
return mFormat;
}
bool
DataSourceSurfaceD2D::Map(MapType aMapType, MappedSurface *aMappedSurface)
{
// DataSourceSurfaces used with the new Map API should not be used with GetData!!
MOZ_ASSERT(!mMapped);
MOZ_ASSERT(!mIsMapped);
if (!mTexture) {
return false;
}
D3D10_MAP mapType;
if (aMapType == MapType::READ) {
mapType = D3D10_MAP_READ;
} else if (aMapType == MapType::WRITE) {
mapType = D3D10_MAP_WRITE;
} else {
mapType = D3D10_MAP_READ_WRITE;
}
D3D10_MAPPED_TEXTURE2D map;
HRESULT hr = mTexture->Map(0, mapType, 0, &map);
if (FAILED(hr)) {
gfxWarning() << "Texture map failed with code: " << hexa(hr);
return false;
}
aMappedSurface->mData = (uint8_t*)map.pData;
aMappedSurface->mStride = map.RowPitch;
mIsMapped = !!aMappedSurface->mData;
return mIsMapped;
}
void
DataSourceSurfaceD2D::Unmap()
{
MOZ_ASSERT(mIsMapped);
mIsMapped = false;
mTexture->Unmap(0);
}
void
DataSourceSurfaceD2D::EnsureMappedTexture()
{
// Do not use GetData() after having used Map!
MOZ_ASSERT(!mIsMapped);
if (mMapped ||
!mTexture) {
return;
}
HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mData);
if (FAILED(hr)) {
gfxWarning() << "Failed to map texture. Code: " << hexa(hr);
mTexture = nullptr;
} else {
mMapped = true;
}
}
}
}

View File

@ -1,90 +0,0 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_SOURCESURFACED2D_H_
#define MOZILLA_GFX_SOURCESURFACED2D_H_
#include "2D.h"
#include "HelpersD2D.h"
#include <vector>
namespace mozilla {
namespace gfx {
class DataSourceSurfaceD2D;
class SourceSurfaceD2D : public SourceSurface
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceD2D)
SourceSurfaceD2D();
~SourceSurfaceD2D();
virtual SurfaceType GetType() const { return SurfaceType::D2D1_BITMAP; }
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const;
virtual bool IsValid() const;
virtual already_AddRefed<DataSourceSurface> GetDataSurface();
ID2D1Bitmap *GetBitmap() { return mBitmap; }
bool InitFromData(unsigned char *aData,
const IntSize &aSize,
int32_t aStride,
SurfaceFormat aFormat,
ID2D1RenderTarget *aRT);
bool InitFromTexture(ID3D10Texture2D *aTexture,
SurfaceFormat aFormat,
ID2D1RenderTarget *aRT);
private:
friend class DrawTargetD2D;
friend class DataSourceSurfaceD2D;
uint32_t GetByteSize() const;
RefPtr<ID2D1Bitmap> mBitmap;
// We need to keep this pointer here to check surface validity.
RefPtr<ID3D10Device> mDevice;
SurfaceFormat mFormat;
IntSize mSize;
};
class DataSourceSurfaceD2D : public DataSourceSurface
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceD2D)
DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface);
virtual ~DataSourceSurfaceD2D();
virtual unsigned char* GetData();
virtual int32_t Stride();
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const;
virtual bool Map(MapType, MappedSurface *aMappedSurface);
virtual void Unmap();
bool IsValid()
{
return mTexture;
}
private:
void EnsureMappedTexture();
RefPtr<ID3D10Texture2D> mTexture;
D3D10_MAPPED_TEXTURE2D mData;
SurfaceFormat mFormat;
IntSize mSize;
bool mMapped;
};
}
}
#endif /* MOZILLA_GFX_SOURCESURFACED2D_H_ */

View File

@ -1,325 +0,0 @@
/* -*- 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 "SourceSurfaceD2DTarget.h"
#include "Logging.h"
#include "DrawTargetD2D.h"
#include "Tools.h"
#include <algorithm>
namespace mozilla {
namespace gfx {
SourceSurfaceD2DTarget::SourceSurfaceD2DTarget(DrawTargetD2D* aDrawTarget,
ID3D10Texture2D* aTexture,
SurfaceFormat aFormat)
: mDrawTarget(aDrawTarget)
, mTexture(aTexture)
, mFormat(aFormat)
, mOwnsCopy(false)
{
}
SourceSurfaceD2DTarget::~SourceSurfaceD2DTarget()
{
// We don't need to do anything special here to notify our mDrawTarget. It must
// already have cleared its mSnapshot field, otherwise this object would
// be kept alive.
if (mOwnsCopy) {
IntSize size = GetSize();
DrawTargetD2D::mVRAMUsageSS -= size.width * size.height * BytesPerPixel(mFormat);
}
}
IntSize
SourceSurfaceD2DTarget::GetSize() const
{
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
return IntSize(desc.Width, desc.Height);
}
SurfaceFormat
SourceSurfaceD2DTarget::GetFormat() const
{
return mFormat;
}
already_AddRefed<DataSourceSurface>
SourceSurfaceD2DTarget::GetDataSurface()
{
RefPtr<DataSourceSurfaceD2DTarget> dataSurf =
new DataSourceSurfaceD2DTarget(mFormat);
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ;
desc.Usage = D3D10_USAGE_STAGING;
desc.BindFlags = 0;
desc.MiscFlags = 0;
if (!Factory::GetDirect3D10Device()) {
gfxCriticalError() << "Invalid D3D10 device in D2D target surface (GDS)";
return nullptr;
}
HRESULT hr = Factory::GetDirect3D10Device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(dataSurf->mTexture));
if (FAILED(hr)) {
gfxDebug() << "Failed to create staging texture for SourceSurface. Code: " << hexa(hr);
return nullptr;
}
Factory::GetDirect3D10Device()->CopyResource(dataSurf->mTexture, mTexture);
return dataSurf.forget();
}
void*
SourceSurfaceD2DTarget::GetNativeSurface(NativeSurfaceType aType)
{
if (aType == NativeSurfaceType::D3D10_TEXTURE) {
return static_cast<void*>(mTexture.get());
}
return nullptr;
}
ID3D10ShaderResourceView*
SourceSurfaceD2DTarget::GetSRView()
{
if (mSRView) {
return mSRView;
}
if (!Factory::GetDirect3D10Device()) {
gfxCriticalError() << "Invalid D3D10 device in D2D target surface (SRV)";
return nullptr;
}
HRESULT hr = Factory::GetDirect3D10Device()->CreateShaderResourceView(mTexture, nullptr, getter_AddRefs(mSRView));
if (FAILED(hr)) {
gfxWarning() << "Failed to create ShaderResourceView. Code: " << hexa(hr);
}
return mSRView;
}
void
SourceSurfaceD2DTarget::DrawTargetWillChange()
{
RefPtr<ID3D10Texture2D> oldTexture = mTexture;
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
// Our original texture might implement the keyed mutex flag. We shouldn't
// need that here. We actually specifically don't want it since we don't lock
// our texture for usage!
desc.MiscFlags = 0;
// Get a copy of the surface data so the content at snapshot time was saved.
Factory::GetDirect3D10Device()->CreateTexture2D(&desc, nullptr, getter_AddRefs(mTexture));
Factory::GetDirect3D10Device()->CopyResource(mTexture, oldTexture);
mBitmap = nullptr;
DrawTargetD2D::mVRAMUsageSS += desc.Width * desc.Height * BytesPerPixel(mFormat);
mOwnsCopy = true;
// We now no longer depend on the source surface content remaining the same.
MarkIndependent();
}
ID2D1Bitmap*
SourceSurfaceD2DTarget::GetBitmap(ID2D1RenderTarget *aRT)
{
if (mBitmap) {
return mBitmap;
}
HRESULT hr;
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
IntSize size(desc.Width, desc.Height);
RefPtr<IDXGISurface> surf;
hr = mTexture->QueryInterface((IDXGISurface**)getter_AddRefs(surf));
if (FAILED(hr)) {
gfxWarning() << "Failed to query interface texture to DXGISurface. Code: " << hexa(hr);
return nullptr;
}
D2D1_BITMAP_PROPERTIES props = D2D1::BitmapProperties(D2DPixelFormat(mFormat));
hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, getter_AddRefs(mBitmap));
if (FAILED(hr)) {
// This seems to happen for SurfaceFormat::A8 sometimes...
hr = aRT->CreateBitmap(D2D1::SizeU(desc.Width, desc.Height),
D2D1::BitmapProperties(D2DPixelFormat(mFormat)),
getter_AddRefs(mBitmap));
if (FAILED(hr)) {
gfxWarning() << "Failed in CreateBitmap. Code: " << hexa(hr);
return nullptr;
}
RefPtr<ID2D1RenderTarget> rt;
if (mDrawTarget) {
rt = mDrawTarget->mRT;
}
if (!rt) {
// Okay, we already separated from our drawtarget. And we're an A8
// surface the only way we can get to a bitmap is by creating a
// a rendertarget and from there copying to a bitmap! Terrible!
RefPtr<IDXGISurface> surface;
hr = mTexture->QueryInterface((IDXGISurface**)getter_AddRefs(surface));
if (FAILED(hr)) {
gfxWarning() << "Failed to QI texture to surface.";
return nullptr;
}
D2D1_RENDER_TARGET_PROPERTIES props =
D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2DPixelFormat(mFormat));
hr = DrawTargetD2D::factory()->CreateDxgiSurfaceRenderTarget(surface, props, getter_AddRefs(rt));
if (FAILED(hr)) {
gfxWarning() << "Failed to create D2D render target for texture.";
return nullptr;
}
}
mBitmap->CopyFromRenderTarget(nullptr, rt, nullptr);
return mBitmap;
}
return mBitmap;
}
void
SourceSurfaceD2DTarget::MarkIndependent()
{
if (mDrawTarget) {
MOZ_ASSERT(mDrawTarget->mSnapshot == this);
mDrawTarget->mSnapshot = nullptr;
mDrawTarget = nullptr;
}
}
DataSourceSurfaceD2DTarget::DataSourceSurfaceD2DTarget(SurfaceFormat aFormat)
: mFormat(aFormat)
, mMapped(false)
{
}
DataSourceSurfaceD2DTarget::~DataSourceSurfaceD2DTarget()
{
if (mMapped) {
mTexture->Unmap(0);
}
}
IntSize
DataSourceSurfaceD2DTarget::GetSize() const
{
D3D10_TEXTURE2D_DESC desc;
mTexture->GetDesc(&desc);
return IntSize(desc.Width, desc.Height);
}
SurfaceFormat
DataSourceSurfaceD2DTarget::GetFormat() const
{
return mFormat;
}
uint8_t*
DataSourceSurfaceD2DTarget::GetData()
{
EnsureMapped();
return (unsigned char*)mMap.pData;
}
int32_t
DataSourceSurfaceD2DTarget::Stride()
{
EnsureMapped();
return mMap.RowPitch;
}
bool
DataSourceSurfaceD2DTarget::Map(MapType aMapType, MappedSurface *aMappedSurface)
{
// DataSourceSurfaces used with the new Map API should not be used with GetData!!
MOZ_ASSERT(!mMapped);
MOZ_ASSERT(!mIsMapped);
if (!mTexture) {
return false;
}
D3D10_MAP mapType;
if (aMapType == MapType::READ) {
mapType = D3D10_MAP_READ;
} else if (aMapType == MapType::WRITE) {
mapType = D3D10_MAP_WRITE;
} else {
mapType = D3D10_MAP_READ_WRITE;
}
D3D10_MAPPED_TEXTURE2D map;
HRESULT hr = mTexture->Map(0, mapType, 0, &map);
if (FAILED(hr)) {
gfxWarning() << "Texture map failed with code: " << hexa(hr);
return false;
}
aMappedSurface->mData = (uint8_t*)map.pData;
aMappedSurface->mStride = map.RowPitch;
mIsMapped = !!aMappedSurface->mData;
return mIsMapped;
}
void
DataSourceSurfaceD2DTarget::Unmap()
{
MOZ_ASSERT(mIsMapped);
mIsMapped = false;
mTexture->Unmap(0);
}
void
DataSourceSurfaceD2DTarget::EnsureMapped()
{
// Do not use GetData() after having used Map!
MOZ_ASSERT(!mIsMapped);
if (!mMapped) {
HRESULT hr = mTexture->Map(0, D3D10_MAP_READ, 0, &mMap);
if (FAILED(hr)) {
gfxWarning() << "Failed to map texture to memory. Code: " << hexa(hr);
return;
}
mMapped = true;
}
}
}
}

View File

@ -1,90 +0,0 @@
/* -*- 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/. */
#ifndef MOZILLA_GFX_SOURCESURFACED2DTARGET_H_
#define MOZILLA_GFX_SOURCESURFACED2DTARGET_H_
#include "2D.h"
#include "HelpersD2D.h"
#include <vector>
#include <d3d10_1.h>
namespace mozilla {
namespace gfx {
class DrawTargetD2D;
class SourceSurfaceD2DTarget : public SourceSurface
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceD2DTarget)
SourceSurfaceD2DTarget(DrawTargetD2D* aDrawTarget, ID3D10Texture2D* aTexture,
SurfaceFormat aFormat);
~SourceSurfaceD2DTarget();
virtual SurfaceType GetType() const { return SurfaceType::D2D1_DRAWTARGET; }
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const;
virtual already_AddRefed<DataSourceSurface> GetDataSurface();
virtual void *GetNativeSurface(NativeSurfaceType aType);
DrawTargetD2D* GetDT() { return mDrawTarget; }
ID2D1Bitmap *GetBitmap(ID2D1RenderTarget *aRT);
private:
friend class DrawTargetD2D;
ID3D10ShaderResourceView *GetSRView();
// This function is called by the draw target this texture belongs to when
// it is about to be changed. The texture will be required to make a copy
// of itself when this happens.
void DrawTargetWillChange();
// This will mark the surface as no longer depending on its drawtarget,
// this may happen on destruction or copying.
void MarkIndependent();
RefPtr<ID3D10ShaderResourceView> mSRView;
RefPtr<ID2D1Bitmap> mBitmap;
// Non-null if this is a "lazy copy" of the given draw target.
// Null if we've made a copy. The target is not kept alive, otherwise we'd
// have leaks since it might keep us alive. If the target is destroyed, it
// will notify us.
DrawTargetD2D* mDrawTarget;
mutable RefPtr<ID3D10Texture2D> mTexture;
SurfaceFormat mFormat;
bool mOwnsCopy;
};
class DataSourceSurfaceD2DTarget : public DataSourceSurface
{
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(DataSourceSurfaceD2DTarget)
DataSourceSurfaceD2DTarget(SurfaceFormat aFormat);
~DataSourceSurfaceD2DTarget();
virtual SurfaceType GetType() const { return SurfaceType::DATA; }
virtual IntSize GetSize() const;
virtual SurfaceFormat GetFormat() const;
virtual uint8_t *GetData();
virtual int32_t Stride();
virtual bool Map(MapType, MappedSurface *aMappedSurface);
virtual void Unmap();
private:
friend class SourceSurfaceD2DTarget;
void EnsureMapped();
mutable RefPtr<ID3D10Texture2D> mTexture;
SurfaceFormat mFormat;
D3D10_MAPPED_TEXTURE2D mMap;
bool mMapped;
};
}
}
#endif /* MOZILLA_GFX_SOURCESURFACED2DTARGET_H_ */

View File

@ -123,7 +123,7 @@ enum class DrawTargetType : int8_t {
enum class BackendType : int8_t { enum class BackendType : int8_t {
NONE = 0, NONE = 0,
DIRECT2D, DIRECT2D, // Used for version independent D2D objects.
COREGRAPHICS, COREGRAPHICS,
COREGRAPHICS_ACCELERATED, COREGRAPHICS_ACCELERATED,
CAIRO, CAIRO,

View File

@ -66,7 +66,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):
] ]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
SOURCES += [ SOURCES += [
'DrawTargetD2D.cpp',
'DrawTargetD2D1.cpp', 'DrawTargetD2D1.cpp',
'ExtendInputEffectD2D1.cpp', 'ExtendInputEffectD2D1.cpp',
'FilterNodeD2D1.cpp', 'FilterNodeD2D1.cpp',
@ -77,9 +76,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
'RadialGradientEffectD2D1.cpp', 'RadialGradientEffectD2D1.cpp',
'ScaledFontDWrite.cpp', 'ScaledFontDWrite.cpp',
'ScaledFontWin.cpp', 'ScaledFontWin.cpp',
'SourceSurfaceD2D.cpp',
'SourceSurfaceD2D1.cpp', 'SourceSurfaceD2D1.cpp',
'SourceSurfaceD2DTarget.cpp',
] ]
DEFINES['WIN32'] = True DEFINES['WIN32'] = True