--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -42,25 +42,33 @@ namespace layers {
static bool CanUsePartialPresents(ID3D11Device* aDevice);
struct Vertex
{
float position[2];
};
+struct TexturedVertex
+{
+ float position[2];
+ float texCoords[2];
+};
+
// {1E4D7BEB-D8EC-4A0B-BF0A-63E6DE129425}
static const GUID sDeviceAttachmentsD3D11 =
{ 0x1e4d7beb, 0xd8ec, 0x4a0b, { 0xbf, 0xa, 0x63, 0xe6, 0xde, 0x12, 0x94, 0x25 } };
// {88041664-C835-4AA8-ACB8-7EC832357ED8}
static const GUID sLayerManagerCount =
{ 0x88041664, 0xc835, 0x4aa8, { 0xac, 0xb8, 0x7e, 0xc8, 0x32, 0x35, 0x7e, 0xd8 } };
const FLOAT sBlendFactor[] = { 0, 0, 0, 0 };
+static const size_t kInitialMaximumTriangles = 64;
+
namespace TexSlot {
static const int RGB = 0;
static const int Y = 1;
static const int Cb = 2;
static const int Cr = 3;
static const int RGBWhite = 4;
static const int Mask = 5;
static const int Backdrop = 6;
@@ -79,31 +87,39 @@ struct DeviceAttachmentsD3D11
bool InitSyncObject();
typedef EnumeratedArray<MaskType, MaskType::NumMaskTypes, RefPtr<ID3D11VertexShader>>
VertexShaderArray;
typedef EnumeratedArray<MaskType, MaskType::NumMaskTypes, RefPtr<ID3D11PixelShader>>
PixelShaderArray;
RefPtr<ID3D11InputLayout> mInputLayout;
+ RefPtr<ID3D11InputLayout> mDynamicInputLayout;
+
RefPtr<ID3D11Buffer> mVertexBuffer;
+ RefPtr<ID3D11Buffer> mDynamicVertexBuffer;
VertexShaderArray mVSQuadShader;
VertexShaderArray mVSQuadBlendShader;
+
+ VertexShaderArray mVSDynamicShader;
+ VertexShaderArray mVSDynamicBlendShader;
+
PixelShaderArray mSolidColorShader;
PixelShaderArray mRGBAShader;
PixelShaderArray mRGBShader;
PixelShaderArray mYCbCrShader;
PixelShaderArray mComponentAlphaShader;
PixelShaderArray mBlendShader;
RefPtr<ID3D11Buffer> mPSConstantBuffer;
RefPtr<ID3D11Buffer> mVSConstantBuffer;
RefPtr<ID3D11RasterizerState> mRasterizerState;
RefPtr<ID3D11SamplerState> mLinearSamplerState;
RefPtr<ID3D11SamplerState> mPointSamplerState;
+
RefPtr<ID3D11BlendState> mPremulBlendState;
RefPtr<ID3D11BlendState> mNonPremulBlendState;
RefPtr<ID3D11BlendState> mComponentBlendState;
RefPtr<ID3D11BlendState> mDisabledBlendState;
RefPtr<IDXGIResource> mSyncTexture;
HANDLE mSyncHandle;
private:
@@ -145,16 +161,17 @@ private:
CompositorD3D11::CompositorD3D11(CompositorBridgeParent* aParent, widget::CompositorWidget* aWidget)
: Compositor(aWidget, aParent)
, mAttachments(nullptr)
, mHwnd(nullptr)
, mDisableSequenceForNextFrame(false)
, mAllowPartialPresents(false)
, mVerifyBuffersFailed(false)
+ , mMaximumTriangles(kInitialMaximumTriangles)
{
}
CompositorD3D11::~CompositorD3D11()
{
if (mDevice) {
int referenceCount = 0;
UINT size = sizeof(referenceCount);
@@ -173,16 +190,84 @@ CompositorD3D11::~CompositorD3D11()
// which hold a reference to the device.
mDevice->SetPrivateData(sDeviceAttachmentsD3D11, 0, nullptr);
delete attachments;
}
}
}
+
+template<typename VertexType>
+void
+CompositorD3D11::SetVertexBuffer(ID3D11Buffer* aBuffer)
+{
+ UINT size = sizeof(VertexType);
+ UINT offset = 0;
+ mContext->IASetVertexBuffers(0, 1, &aBuffer, &size, &offset);
+}
+
+bool
+CompositorD3D11::SupportsLayerGeometry() const
+{
+ return gfxPrefs::D3D11LayerGeometry();
+}
+
+bool
+CompositorD3D11::UpdateDynamicVertexBuffer(const nsTArray<gfx::TexturedTriangle>& aTriangles)
+{
+ HRESULT hr;
+
+ // Resize the dynamic vertex buffer if needed.
+ if (aTriangles.Length() > mMaximumTriangles) {
+ CD3D11_BUFFER_DESC bufferDesc(sizeof(TexturedVertex) * aTriangles.Length() * 3,
+ D3D11_BIND_VERTEX_BUFFER,
+ D3D11_USAGE_DYNAMIC,
+ D3D11_CPU_ACCESS_WRITE);
+
+ hr = mDevice->CreateBuffer(&bufferDesc, nullptr,
+ getter_AddRefs(mAttachments->mDynamicVertexBuffer));
+
+ if (Failed(hr, "resize dynamic vertex buffer")) {
+ return false;
+ }
+
+ mMaximumTriangles = aTriangles.Length();
+ }
+
+ MOZ_ASSERT(mMaximumTriangles >= aTriangles.Length());
+
+ D3D11_MAPPED_SUBRESOURCE resource {};
+ hr = mContext->Map(mAttachments->mDynamicVertexBuffer, 0,
+ D3D11_MAP_WRITE_DISCARD, 0, &resource);
+
+ if (Failed(hr, "map dynamic vertex buffer")) {
+ return false;
+ }
+
+ const auto vertexFromPoints = [](const gfx::Point& p, const gfx::Point& t) {
+ return TexturedVertex { { p.x, p.y }, { t.x, t.y } };
+ };
+
+ nsTArray<TexturedVertex> vertices;
+
+ for (const gfx::TexturedTriangle& t : aTriangles) {
+ vertices.AppendElement(vertexFromPoints(t.p1, t.textureCoords.p1));
+ vertices.AppendElement(vertexFromPoints(t.p2, t.textureCoords.p2));
+ vertices.AppendElement(vertexFromPoints(t.p3, t.textureCoords.p3));
+ }
+
+ memcpy(resource.pData, vertices.Elements(),
+ vertices.Length() * sizeof(TexturedVertex));
+
+ mContext->Unmap(mAttachments->mDynamicVertexBuffer, 0);
+
+ return true;
+}
+
bool
CompositorD3D11::Initialize(nsCString* const out_failureReason)
{
ScopedGfxFeatureReporter reporter("D3D11 Layers");
HRESULT hr;
mDevice = DeviceManagerDx::Get()->GetCompositorDevice();
@@ -240,18 +325,47 @@ CompositorD3D11::Initialize(nsCString* c
}
Vertex vertices[] = { {{0.0, 0.0}}, {{1.0, 0.0}}, {{0.0, 1.0}}, {{1.0, 1.0}} };
CD3D11_BUFFER_DESC bufferDesc(sizeof(vertices), D3D11_BIND_VERTEX_BUFFER);
D3D11_SUBRESOURCE_DATA data;
data.pSysMem = (void*)vertices;
hr = mDevice->CreateBuffer(&bufferDesc, &data, getter_AddRefs(mAttachments->mVertexBuffer));
+ if (Failed(hr, "create vertex buffer")) {
+ *out_failureReason = "FEATURE_FAILURE_D3D11_VERTEX_BUFFER";
+ return false;
+ }
- if (Failed(hr, "create vertex buffer")) {
+ // Create a second input layout for layers with dynamic geometry.
+ D3D11_INPUT_ELEMENT_DESC dynamicLayout[] =
+ {
+ { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+ };
+
+ hr = mDevice->CreateInputLayout(dynamicLayout,
+ sizeof(dynamicLayout) / sizeof(D3D11_INPUT_ELEMENT_DESC),
+ LayerDynamicVS,
+ sizeof(LayerDynamicVS),
+ getter_AddRefs(mAttachments->mDynamicInputLayout));
+
+ if (Failed(hr, "CreateInputLayout")) {
+ *out_failureReason = "FEATURE_FAILURE_D3D11_INPUT_LAYOUT";
+ return false;
+ }
+
+ // Allocate memory for the dynamic vertex buffer.
+ bufferDesc = CD3D11_BUFFER_DESC(sizeof(TexturedVertex) * mMaximumTriangles * 3,
+ D3D11_BIND_VERTEX_BUFFER,
+ D3D11_USAGE_DYNAMIC,
+ D3D11_CPU_ACCESS_WRITE);
+
+ hr = mDevice->CreateBuffer(&bufferDesc, nullptr, getter_AddRefs(mAttachments->mDynamicVertexBuffer));
+ if (Failed(hr, "create dynamic vertex buffer")) {
*out_failureReason = "FEATURE_FAILURE_D3D11_VERTEX_BUFFER";
return false;
}
if (!mAttachments->CreateShaders()) {
*out_failureReason = "FEATURE_FAILURE_D3D11_CREATE_SHADERS";
return false;
}
@@ -628,18 +742,24 @@ CompositorD3D11::SetRenderTarget(Composi
newRT->GetProjection(projection, depthEnable, zNear, zFar);
PrepareViewport(newRT->GetSize(), projection, zNear, zFar);
} else {
PrepareViewport(newRT->GetSize());
}
}
ID3D11PixelShader*
-CompositorD3D11::GetPSForEffect(Effect* aEffect, MaskType aMaskType)
+CompositorD3D11::GetPSForEffect(Effect* aEffect,
+ const bool aUseBlendShader,
+ const MaskType aMaskType)
{
+ if (aUseBlendShader) {
+ return mAttachments->mBlendShader[MaskType::MaskNone];
+ }
+
switch (aEffect->mType) {
case EffectTypes::SOLID_COLOR:
return mAttachments->mSolidColorShader[aMaskType];
case EffectTypes::RENDER_TARGET:
return mAttachments->mRGBAShader[aMaskType];
case EffectTypes::RGB: {
SurfaceFormat format = static_cast<TexturedEffect*>(aEffect)->mTexture->GetFormat();
return (format == SurfaceFormat::B8G8R8A8 || format == SurfaceFormat::R8G8B8A8)
@@ -728,16 +848,126 @@ EffectToBlendLayerType(Effect* aEffect)
void
CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect)
{
+ DrawGeometry(aRect, aRect, aClipRect, aEffectChain,
+ aOpacity, aTransform, aVisibleRect);
+}
+
+void
+CompositorD3D11::DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,
+ const gfx::Rect& aRect,
+ const gfx::IntRect& aClipRect,
+ const EffectChain& aEffectChain,
+ gfx::Float aOpacity,
+ const gfx::Matrix4x4& aTransform,
+ const gfx::Rect& aVisibleRect)
+{
+ DrawGeometry(aTriangles, aRect, aClipRect, aEffectChain,
+ aOpacity, aTransform, aVisibleRect);
+}
+
+void
+CompositorD3D11::PrepareDynamicVertexBuffer()
+{
+ mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
+ mContext->IASetInputLayout(mAttachments->mDynamicInputLayout);
+ SetVertexBuffer<TexturedVertex>(mAttachments->mDynamicVertexBuffer);
+}
+
+void
+CompositorD3D11::PrepareStaticVertexBuffer()
+{
+ mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ mContext->IASetInputLayout(mAttachments->mInputLayout);
+ SetVertexBuffer<Vertex>(mAttachments->mVertexBuffer);
+}
+
+void
+CompositorD3D11::Draw(const nsTArray<gfx::TexturedTriangle>& aTriangles,
+ const gfx::Rect*)
+{
+ if (!UpdateConstantBuffers()) {
+ NS_WARNING("Failed to update shader constant buffers");
+ return;
+ }
+
+ PrepareDynamicVertexBuffer();
+
+ if (!UpdateDynamicVertexBuffer(aTriangles)) {
+ NS_WARNING("Failed to update shader dynamic buffers");
+ return;
+ }
+
+ mContext->Draw(3 * aTriangles.Length(), 0);
+
+ PrepareStaticVertexBuffer();
+}
+
+void
+CompositorD3D11::Draw(const gfx::Rect& aRect,
+ const gfx::Rect* aTexCoords)
+{
+ Rect layerRects[4] = { aRect };
+ Rect textureRects[4] = { };
+ size_t rects = 1;
+
+ if (aTexCoords) {
+ rects = DecomposeIntoNoRepeatRects(aRect, *aTexCoords,
+ &layerRects, &textureRects);
+ }
+
+ for (size_t i = 0; i < rects; i++) {
+ mVSConstants.layerQuad = layerRects[i];
+ mVSConstants.textureCoords = textureRects[i];
+
+ if (!UpdateConstantBuffers()) {
+ NS_WARNING("Failed to update shader constant buffers");
+ break;
+ }
+
+ mContext->Draw(4, 0);
+ }
+}
+
+ID3D11VertexShader*
+CompositorD3D11::GetVSForGeometry(const nsTArray<gfx::TexturedTriangle>& aTriangles,
+ const bool aUseBlendShaders,
+ const MaskType aMaskType)
+{
+ return aUseBlendShaders
+ ? mAttachments->mVSDynamicBlendShader[aMaskType]
+ : mAttachments->mVSDynamicShader[aMaskType];
+}
+
+ID3D11VertexShader*
+CompositorD3D11::GetVSForGeometry(const gfx::Rect& aRect,
+ const bool aUseBlendShaders,
+ const MaskType aMaskType)
+{
+ return aUseBlendShaders
+ ? mAttachments->mVSQuadBlendShader[aMaskType]
+ : mAttachments->mVSQuadShader[aMaskType];
+}
+
+template<typename Geometry>
+void
+CompositorD3D11::DrawGeometry(const Geometry& aGeometry,
+ const gfx::Rect& aRect,
+ const gfx::IntRect& aClipRect,
+ const EffectChain& aEffectChain,
+ gfx::Float aOpacity,
+ const gfx::Matrix4x4& aTransform,
+ const gfx::Rect& aVisibleRect)
+{
if (mCurrentClip.IsEmpty()) {
return;
}
MOZ_ASSERT(mCurrentRT, "No render target");
memcpy(&mVSConstants.layerTransform, &aTransform._11, 64);
IntPoint origin = mCurrentRT->GetOrigin();
@@ -783,19 +1013,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
return;
}
scissor.left = clipRect.x;
scissor.right = clipRect.XMost();
scissor.top = clipRect.y;
scissor.bottom = clipRect.YMost();
- RefPtr<ID3D11VertexShader> vertexShader = mAttachments->mVSQuadShader[maskType];
- RefPtr<ID3D11PixelShader> pixelShader = GetPSForEffect(aEffectChain.mPrimaryEffect, maskType);
-
+ bool useBlendShaders = false;
RefPtr<ID3D11Texture2D> mixBlendBackdrop;
gfx::CompositionOp blendMode = gfx::CompositionOp::OP_OVER;
if (aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE]) {
EffectBlendMode *blendEffect =
static_cast<EffectBlendMode*>(aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get());
blendMode = blendEffect->mBlendMode;
// If the blend operation needs to read from the backdrop, copy the
@@ -803,34 +1031,39 @@ CompositorD3D11::DrawQuad(const gfx::Rec
if (BlendOpIsMixBlendMode(blendMode)) {
gfx::Matrix4x4 backdropTransform;
gfx::IntRect rect = ComputeBackdropCopyRect(aRect, aClipRect, aTransform, &backdropTransform);
RefPtr<ID3D11ShaderResourceView> srv;
if (CopyBackdrop(rect, &mixBlendBackdrop, &srv) &&
mAttachments->InitBlendShaders())
{
- vertexShader = mAttachments->mVSQuadBlendShader[maskType];
- pixelShader = mAttachments->mBlendShader[MaskType::MaskNone];
+ useBlendShaders = true;
ID3D11ShaderResourceView* srView = srv.get();
mContext->PSSetShaderResources(TexSlot::Backdrop, 1, &srView);
memcpy(&mVSConstants.backdropTransform, &backdropTransform._11, 64);
mPSConstants.blendConfig[0] = EffectToBlendLayerType(aEffectChain.mPrimaryEffect);
mPSConstants.blendConfig[1] = int(maskType);
mPSConstants.blendConfig[2] = BlendOpToShaderConstant(blendMode);
mPSConstants.blendConfig[3] = EffectHasPremultipliedAlpha(aEffectChain.mPrimaryEffect);
}
}
}
mContext->RSSetScissorRects(1, &scissor);
- mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+
+ RefPtr<ID3D11VertexShader> vertexShader =
+ GetVSForGeometry(aGeometry, useBlendShaders, maskType);
+
+ RefPtr<ID3D11PixelShader> pixelShader =
+ GetPSForEffect(aEffectChain.mPrimaryEffect, useBlendShaders, maskType);
+
mContext->VSSetShader(vertexShader, nullptr, 0);
mContext->PSSetShader(pixelShader, nullptr, 0);
const Rect* pTexCoordRect = nullptr;
switch (aEffectChain.mPrimaryEffect->mType) {
case EffectTypes::SOLID_COLOR: {
Color color =
@@ -930,42 +1163,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
restoreBlendMode = true;
}
break;
default:
NS_WARNING("Unknown shader type");
return;
}
- if (pTexCoordRect) {
- Rect layerRects[4];
- Rect textureRects[4];
- size_t rects = DecomposeIntoNoRepeatRects(aRect,
- *pTexCoordRect,
- &layerRects,
- &textureRects);
- for (size_t i = 0; i < rects; i++) {
- mVSConstants.layerQuad = layerRects[i];
- mVSConstants.textureCoords = textureRects[i];
-
- if (!UpdateConstantBuffers()) {
- NS_WARNING("Failed to update shader constant buffers");
- break;
- }
- mContext->Draw(4, 0);
- }
- } else {
- mVSConstants.layerQuad = aRect;
-
- if (!UpdateConstantBuffers()) {
- NS_WARNING("Failed to update shader constant buffers");
- } else {
- mContext->Draw(4, 0);
- }
- }
+ Draw(aGeometry, pTexCoordRect);
if (restoreBlendMode) {
mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor, 0xFFFFFFFF);
}
}
void
CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
@@ -1029,22 +1237,17 @@ CompositorD3D11::BeginFrame(const nsIntR
}
if (clipRect.IsEmpty()) {
CancelFrame();
*aRenderBoundsOut = IntRect();
return;
}
- mContext->IASetInputLayout(mAttachments->mInputLayout);
-
- ID3D11Buffer* buffer = mAttachments->mVertexBuffer;
- UINT size = sizeof(Vertex);
- UINT offset = 0;
- mContext->IASetVertexBuffers(0, 1, &buffer, &size, &offset);
+ PrepareStaticVertexBuffer();
mInvalidRect = IntRect(invalidRect.x, invalidRect.y, invalidRect.width, invalidRect.height);
mInvalidRegion = invalidRegionSafe;
if (aClipRectOut) {
*aClipRectOut = IntRect(0, 0, mSize.width, mSize.height);
}
if (aRenderBoundsOut) {
@@ -1399,28 +1602,37 @@ DeviceAttachmentsD3D11::InitSyncObject()
bool
DeviceAttachmentsD3D11::InitBlendShaders()
{
if (!mVSQuadBlendShader[MaskType::MaskNone]) {
InitVertexShader(sLayerQuadBlendVS, mVSQuadBlendShader, MaskType::MaskNone);
InitVertexShader(sLayerQuadBlendMaskVS, mVSQuadBlendShader, MaskType::Mask);
}
+
+ if (!mVSDynamicBlendShader[MaskType::MaskNone]) {
+ InitVertexShader(sLayerDynamicBlendVS, mVSDynamicBlendShader, MaskType::MaskNone);
+ InitVertexShader(sLayerDynamicBlendMaskVS, mVSDynamicBlendShader, MaskType::Mask);
+ }
+
if (!mBlendShader[MaskType::MaskNone]) {
InitPixelShader(sBlendShader, mBlendShader, MaskType::MaskNone);
}
return mInitOkay;
}
bool
DeviceAttachmentsD3D11::CreateShaders()
{
InitVertexShader(sLayerQuadVS, mVSQuadShader, MaskType::MaskNone);
InitVertexShader(sLayerQuadMaskVS, mVSQuadShader, MaskType::Mask);
+ InitVertexShader(sLayerDynamicVS, mVSDynamicShader, MaskType::MaskNone);
+ InitVertexShader(sLayerDynamicMaskVS, mVSDynamicShader, MaskType::Mask);
+
InitPixelShader(sSolidColorShader, mSolidColorShader, MaskType::MaskNone);
InitPixelShader(sSolidColorShaderMask, mSolidColorShader, MaskType::Mask);
InitPixelShader(sRGBShader, mRGBShader, MaskType::MaskNone);
InitPixelShader(sRGBShaderMask, mRGBShader, MaskType::Mask);
InitPixelShader(sRGBAShader, mRGBAShader, MaskType::MaskNone);
InitPixelShader(sRGBAShaderMask, mRGBAShader, MaskType::Mask);
InitPixelShader(sYCbCrShader, mYCbCrShader, MaskType::MaskNone);
InitPixelShader(sYCbCrShaderMask, mYCbCrShader, MaskType::Mask);
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -96,17 +96,17 @@ public:
const gfx::IntRect &aClipRect,
const EffectChain &aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect) override;
/**
* Start a new frame. If aClipRectIn is null, sets *aClipRectOut to the
- * screen dimensions.
+ * screen dimensions.
*/
virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
const gfx::IntRect *aClipRectIn,
const gfx::IntRect& aRenderBounds,
const nsIntRegion& aOpaqueRegion,
gfx::IntRect *aClipRectOut = nullptr,
gfx::IntRect *aRenderBoundsOut = nullptr) override;
@@ -122,16 +122,18 @@ public:
* to a window of the given dimensions.
*/
virtual void PrepareViewport(const gfx::IntSize& aSize);
virtual void PrepareViewport(const gfx::IntSize& aSize, const gfx::Matrix4x4& aProjection,
float aZNear, float aZFar);
virtual bool SupportsPartialTextureUpdate() override { return true; }
+ virtual bool SupportsLayerGeometry() const override;
+
#ifdef MOZ_DUMP_PAINTING
virtual const char* Name() const override { return "Direct3D 11"; }
#endif
virtual LayersBackend GetBackendType() const override {
return LayersBackend::LAYERS_D3D11;
}
@@ -155,25 +157,68 @@ private:
bool Failed(HRESULT hr, const char* aContext);
// ensure mSize is up to date with respect to mWidget
void EnsureSize();
bool VerifyBufferSize();
bool UpdateRenderTarget();
bool UpdateConstantBuffers();
void SetSamplerForSamplingFilter(gfx::SamplingFilter aSamplingFilter);
- ID3D11PixelShader* GetPSForEffect(Effect *aEffect, MaskType aMaskType);
+
+ ID3D11PixelShader* GetPSForEffect(Effect* aEffect,
+ const bool aUseBlendShader,
+ const MaskType aMaskType);
void PaintToTarget();
RefPtr<ID3D11Texture2D> CreateTexture(const gfx::IntRect& aRect,
const CompositingRenderTarget* aSource,
const gfx::IntPoint& aSourcePoint);
bool CopyBackdrop(const gfx::IntRect& aRect,
RefPtr<ID3D11Texture2D>* aOutTexture,
RefPtr<ID3D11ShaderResourceView>* aOutView);
+ virtual void DrawTriangles(const nsTArray<gfx::TexturedTriangle>& aTriangles,
+ const gfx::Rect& aRect,
+ const gfx::IntRect& aClipRect,
+ const EffectChain& aEffectChain,
+ gfx::Float aOpacity,
+ const gfx::Matrix4x4& aTransform,
+ const gfx::Rect& aVisibleRect) override;
+
+ template<typename Geometry>
+ void DrawGeometry(const Geometry& aGeometry,
+ const gfx::Rect& aRect,
+ const gfx::IntRect& aClipRect,
+ const EffectChain& aEffectChain,
+ gfx::Float aOpacity,
+ const gfx::Matrix4x4& aTransform,
+ const gfx::Rect& aVisibleRect);
+
+ bool UpdateDynamicVertexBuffer(const nsTArray<gfx::TexturedTriangle>& aTriangles);
+
+ void PrepareDynamicVertexBuffer();
+ void PrepareStaticVertexBuffer();
+
+ // Overloads for rendering both rects and triangles with same rendering path
+ void Draw(const nsTArray<gfx::TexturedTriangle>& aGeometry,
+ const gfx::Rect* aTexCoords);
+
+ void Draw(const gfx::Rect& aGeometry,
+ const gfx::Rect* aTexCoords);
+
+ ID3D11VertexShader* GetVSForGeometry(const nsTArray<gfx::TexturedTriangle>& aTriangles,
+ const bool aUseBlendShader,
+ const MaskType aMaskType);
+
+ ID3D11VertexShader* GetVSForGeometry(const gfx::Rect& aRect,
+ const bool aUseBlendShader,
+ const MaskType aMaskType);
+
+ template<typename VertexType>
+ void SetVertexBuffer(ID3D11Buffer* aBuffer);
+
RefPtr<ID3D11DeviceContext> mContext;
RefPtr<ID3D11Device> mDevice;
RefPtr<IDXGISwapChain> mSwapChain;
RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
RefPtr<ID3D11Query> mQuery;
@@ -191,14 +236,16 @@ private:
bool mAllowPartialPresents;
gfx::IntRect mInvalidRect;
// This is the clip rect applied to the default DrawTarget (i.e. the window)
gfx::IntRect mCurrentClip;
nsIntRegion mInvalidRegion;
bool mVerifyBuffersFailed;
+
+ size_t mMaximumTriangles;
};
}
}
#endif