mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1247775 - Part 3: Remove Moz2D code to support Direct2D 1.0. r=dvander
MozReview-Commit-ID: KBZSqIdx0OC
This commit is contained in:
parent
206deeea3f
commit
50913b47b8
11
gfx/2d/2D.h
11
gfx/2d/2D.h
@ -36,8 +36,6 @@ typedef _cairo_surface cairo_surface_t;
|
||||
struct _cairo_scaled_font;
|
||||
typedef _cairo_scaled_font cairo_scaled_font_t;
|
||||
|
||||
struct ID3D10Device1;
|
||||
struct ID3D10Texture2D;
|
||||
struct ID3D11Texture2D;
|
||||
struct ID3D11Device;
|
||||
struct ID2D1Device;
|
||||
@ -1364,14 +1362,6 @@ public:
|
||||
#endif
|
||||
|
||||
#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 void SetDirect3D11Device(ID3D11Device *aDevice);
|
||||
@ -1394,7 +1384,6 @@ public:
|
||||
|
||||
private:
|
||||
static ID2D1Device *mD2D1Device;
|
||||
static ID3D10Device1 *mD3D10Device;
|
||||
static ID3D11Device *mD3D11Device;
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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_ */
|
@ -5,24 +5,32 @@
|
||||
|
||||
#include <initguid.h>
|
||||
#include "DrawTargetD2D1.h"
|
||||
#include "DrawTargetD2D.h"
|
||||
#include "FilterNodeSoftware.h"
|
||||
#include "GradientStopsD2D.h"
|
||||
#include "SourceSurfaceD2D1.h"
|
||||
#include "SourceSurfaceD2D.h"
|
||||
#include "RadialGradientEffectD2D1.h"
|
||||
|
||||
#include "HelpersD2D.h"
|
||||
#include "FilterNodeD2D1.h"
|
||||
#include "ExtendInputEffectD2D1.h"
|
||||
#include "Tools.h"
|
||||
|
||||
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 gfx {
|
||||
|
||||
uint64_t DrawTargetD2D1::mVRAMUsageDT;
|
||||
uint64_t DrawTargetD2D1::mVRAMUsageSS;
|
||||
IDWriteFactory *DrawTargetD2D1::mDWriteFactory;
|
||||
ID2D1Factory1* DrawTargetD2D1::mFactory = nullptr;
|
||||
|
||||
ID2D1Factory1 *D2DFactory1()
|
||||
@ -604,7 +612,7 @@ DrawTargetD2D1::FillGlyphs(ScaledFont *aFont,
|
||||
DWRITE_MEASURING_MODE_NATURAL, &userRect);
|
||||
|
||||
RefPtr<ID2D1PathGeometry> path;
|
||||
D2DFactory()->CreatePathGeometry(getter_AddRefs(path));
|
||||
factory()->CreatePathGeometry(getter_AddRefs(path));
|
||||
RefPtr<ID2D1GeometrySink> sink;
|
||||
path->Open(getter_AddRefs(sink));
|
||||
AddRectToSink(sink, userRect);
|
||||
@ -1060,27 +1068,79 @@ DrawTargetD2D1::factory()
|
||||
return mFactory;
|
||||
}
|
||||
|
||||
ID2D1Factory* d2dFactory = D2DFactory();
|
||||
if (!d2dFactory) {
|
||||
RefPtr<ID2D1Factory> factory;
|
||||
D2D1CreateFactoryFunc createD2DFactory;
|
||||
HMODULE d2dModule = LoadLibraryW(L"d2d1.dll");
|
||||
createD2DFactory = (D2D1CreateFactoryFunc)
|
||||
GetProcAddress(d2dModule, "D2D1CreateFactory");
|
||||
|
||||
if (!createD2DFactory) {
|
||||
gfxWarning() << "Failed to locate D2D1CreateFactory function.";
|
||||
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;
|
||||
}
|
||||
|
||||
hr = factory->QueryInterface((ID2D1Factory1**)&mFactory);
|
||||
if (FAILED(hr) || !mFactory) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ExtendInputEffectD2D1::Register(mFactory);
|
||||
RadialGradientEffectD2D1::Register(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
|
||||
DrawTargetD2D1::CleanupD2D()
|
||||
{
|
||||
if (mFactory) {
|
||||
RadialGradientEffectD2D1::Unregister(mFactory);
|
||||
ExtendInputEffectD2D1::Unregister(mFactory);
|
||||
mFactory->Release();
|
||||
mFactory = nullptr;
|
||||
}
|
||||
|
@ -35,7 +35,6 @@
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include "DrawTargetD2D.h"
|
||||
#include "DrawTargetD2D1.h"
|
||||
#include "ScaledFontDWrite.h"
|
||||
#include "NativeFontResourceDWrite.h"
|
||||
@ -161,7 +160,6 @@ int32_t LoggingPrefs::sGfxLogLevel =
|
||||
LOG_DEFAULT);
|
||||
|
||||
#ifdef WIN32
|
||||
ID3D10Device1 *Factory::mD3D10Device;
|
||||
ID3D11Device *Factory::mD3D11Device;
|
||||
ID2D1Device *Factory::mD2D1Device;
|
||||
#endif
|
||||
@ -315,15 +313,6 @@ Factory::CreateDrawTarget(BackendType aBackend, const IntSize &aSize, SurfaceFor
|
||||
RefPtr<DrawTarget> retVal;
|
||||
switch (aBackend) {
|
||||
#ifdef WIN32
|
||||
case BackendType::DIRECT2D:
|
||||
{
|
||||
RefPtr<DrawTargetD2D> newTarget;
|
||||
newTarget = new DrawTargetD2D();
|
||||
if (newTarget->Init(aSize, aFormat)) {
|
||||
retVal = newTarget;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BackendType::DIRECT2D1_1:
|
||||
{
|
||||
RefPtr<DrawTargetD2D1> newTarget;
|
||||
@ -499,8 +488,6 @@ Factory::GetMaxSurfaceSize(BackendType aType)
|
||||
return DrawTargetSkia::GetMaxSurfaceSize();
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
case BackendType::DIRECT2D:
|
||||
return DrawTargetD2D::GetMaxSurfaceSize();
|
||||
case BackendType::DIRECT2D1_1:
|
||||
return DrawTargetD2D1::GetMaxSurfaceSize();
|
||||
#endif
|
||||
@ -611,87 +598,6 @@ Factory::CreateDualDrawTarget(DrawTarget *targetA, DrawTarget *targetB)
|
||||
|
||||
|
||||
#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>
|
||||
Factory::CreateDrawTargetForD3D11Texture(ID3D11Texture2D *aTexture, SurfaceFormat aFormat)
|
||||
{
|
||||
@ -767,13 +673,13 @@ Factory::CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams)
|
||||
uint64_t
|
||||
Factory::GetD2DVRAMUsageDrawTarget()
|
||||
{
|
||||
return DrawTargetD2D::mVRAMUsageDT;
|
||||
return DrawTargetD2D1::mVRAMUsageDT;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
Factory::GetD2DVRAMUsageSourceSurface()
|
||||
{
|
||||
return DrawTargetD2D::mVRAMUsageSS;
|
||||
return DrawTargetD2D1::mVRAMUsageSS;
|
||||
}
|
||||
|
||||
void
|
||||
@ -784,7 +690,6 @@ Factory::D2DCleanup()
|
||||
mD2D1Device = nullptr;
|
||||
}
|
||||
DrawTargetD2D1::CleanupD2D();
|
||||
DrawTargetD2D::CleanupD2D();
|
||||
}
|
||||
|
||||
already_AddRefed<ScaledFont>
|
||||
|
@ -8,9 +8,6 @@
|
||||
#include "Logging.h"
|
||||
|
||||
#include "SourceSurfaceD2D1.h"
|
||||
#include "SourceSurfaceD2D.h"
|
||||
#include "SourceSurfaceD2DTarget.h"
|
||||
#include "DrawTargetD2D.h"
|
||||
#include "DrawTargetD2D1.h"
|
||||
#include "ExtendInputEffectD2D1.h"
|
||||
|
||||
@ -159,8 +156,6 @@ already_AddRefed<ID2D1Image> GetImageForSourceSurface(DrawTarget *aDT, SourceSur
|
||||
switch (aDT->GetBackendType()) {
|
||||
case BackendType::DIRECT2D1_1:
|
||||
return static_cast<DrawTargetD2D1*>(aDT)->GetImageForSurface(aSurface, ExtendMode::CLAMP);
|
||||
case BackendType::DIRECT2D:
|
||||
return static_cast<DrawTargetD2D*>(aDT)->GetImageForSurface(aSurface);
|
||||
default:
|
||||
gfxDevCrash(LogReason::FilterNodeD2D1Backend) << "Unknown draw target type! " << (int)aDT->GetBackendType();
|
||||
return nullptr;
|
||||
|
@ -25,9 +25,8 @@
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
||||
ID2D1Factory* D2DFactory();
|
||||
|
||||
ID2D1Factory1* D2DFactory1();
|
||||
static ID2D1Factory* D2DFactory() { return D2DFactory1(); }
|
||||
|
||||
static inline D2D1_POINT_2F D2DPoint(const Point &aPoint)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
#include "DrawTargetD2D.h"
|
||||
#include "DrawTargetD2D1.h"
|
||||
#include "Logging.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
|
||||
@ -69,7 +69,7 @@ public:
|
||||
{
|
||||
if (!mInstance) {
|
||||
mInstance = new DWriteFontFileLoader();
|
||||
DrawTargetD2D::GetDWriteFactory()->
|
||||
DrawTargetD2D1::GetDWriteFactory()->
|
||||
RegisterFontFileLoader(mInstance);
|
||||
}
|
||||
return mInstance;
|
||||
@ -221,7 +221,7 @@ already_AddRefed<NativeFontResourceDWrite>
|
||||
NativeFontResourceDWrite::Create(uint8_t *aFontData, uint32_t aDataLength,
|
||||
bool aNeedsCairo)
|
||||
{
|
||||
IDWriteFactory *factory = DrawTargetD2D::GetDWriteFactory();
|
||||
IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory();
|
||||
if (!factory) {
|
||||
gfxWarning() << "Failed to get DWrite Factory.";
|
||||
return nullptr;
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "PathD2D.h"
|
||||
#include "HelpersD2D.h"
|
||||
#include <math.h>
|
||||
#include "DrawTargetD2D.h"
|
||||
#include "DrawTargetD2D1.h"
|
||||
#include "Logging.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -351,7 +351,7 @@ already_AddRefed<PathBuilder>
|
||||
PathD2D::TransformedCopyToBuilder(const Matrix &aTransform, FillRule aFillRule) const
|
||||
{
|
||||
RefPtr<ID2D1PathGeometry> path;
|
||||
HRESULT hr = DrawTargetD2D::factory()->CreatePathGeometry(getter_AddRefs(path));
|
||||
HRESULT hr = DrawTargetD2D1::factory()->CreatePathGeometry(getter_AddRefs(path));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
gfxWarning() << "Failed to create PathGeometry. Code: " << hexa(hr);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* 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 "DrawTargetD2D.h"
|
||||
#include "DrawTargetD2D1.h"
|
||||
#include "ScaledFontDWrite.h"
|
||||
#include "PathD2D.h"
|
||||
|
||||
@ -120,7 +120,7 @@ ScaledFontDWrite::GetSkTypeface()
|
||||
{
|
||||
MOZ_ASSERT(mFont);
|
||||
if (!mTypeface) {
|
||||
IDWriteFactory *factory = DrawTargetD2D::GetDWriteFactory();
|
||||
IDWriteFactory *factory = DrawTargetD2D1::GetDWriteFactory();
|
||||
mTypeface = SkCreateTypefaceFromDWriteFont(factory, mFontFace, mFont, mFontFamily);
|
||||
}
|
||||
return mTypeface;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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_ */
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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_ */
|
@ -123,7 +123,7 @@ enum class DrawTargetType : int8_t {
|
||||
|
||||
enum class BackendType : int8_t {
|
||||
NONE = 0,
|
||||
DIRECT2D,
|
||||
DIRECT2D, // Used for version independent D2D objects.
|
||||
COREGRAPHICS,
|
||||
COREGRAPHICS_ACCELERATED,
|
||||
CAIRO,
|
||||
|
@ -66,7 +66,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
SOURCES += [
|
||||
'DrawTargetD2D.cpp',
|
||||
'DrawTargetD2D1.cpp',
|
||||
'ExtendInputEffectD2D1.cpp',
|
||||
'FilterNodeD2D1.cpp',
|
||||
@ -77,9 +76,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
'RadialGradientEffectD2D1.cpp',
|
||||
'ScaledFontDWrite.cpp',
|
||||
'ScaledFontWin.cpp',
|
||||
'SourceSurfaceD2D.cpp',
|
||||
'SourceSurfaceD2D1.cpp',
|
||||
'SourceSurfaceD2DTarget.cpp',
|
||||
]
|
||||
DEFINES['WIN32'] = True
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user