mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-24 01:17:34 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
59
gfx/layers/d3d11/BlendShaderConstants.h
Normal file
59
gfx/layers/d3d11/BlendShaderConstants.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- 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_LAYERS_D3D11_BLENDSHADERCONSTANTS_H_
|
||||
#define MOZILLA_GFX_LAYERS_D3D11_BLENDSHADERCONSTANTS_H_
|
||||
|
||||
// These constants are shared between CompositorD3D11 and the blend pixel shader.
|
||||
#define PS_LAYER_RGB 0
|
||||
#define PS_LAYER_RGBA 1
|
||||
#define PS_LAYER_YCBCR 2
|
||||
#define PS_LAYER_COLOR 3
|
||||
|
||||
// These must be in the same order as the Mask enum.
|
||||
#define PS_MASK_NONE 0
|
||||
#define PS_MASK 1
|
||||
|
||||
// These must be in the same order as CompositionOp.
|
||||
#define PS_BLEND_MULTIPLY 0
|
||||
#define PS_BLEND_SCREEN 1
|
||||
#define PS_BLEND_OVERLAY 2
|
||||
#define PS_BLEND_DARKEN 3
|
||||
#define PS_BLEND_LIGHTEN 4
|
||||
#define PS_BLEND_COLOR_DODGE 5
|
||||
#define PS_BLEND_COLOR_BURN 6
|
||||
#define PS_BLEND_HARD_LIGHT 7
|
||||
#define PS_BLEND_SOFT_LIGHT 8
|
||||
#define PS_BLEND_DIFFERENCE 9
|
||||
#define PS_BLEND_EXCLUSION 10
|
||||
#define PS_BLEND_HUE 11
|
||||
#define PS_BLEND_SATURATION 12
|
||||
#define PS_BLEND_COLOR 13
|
||||
#define PS_BLEND_LUMINOSITY 14
|
||||
|
||||
#if defined(__cplusplus)
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
static inline int
|
||||
BlendOpToShaderConstant(gfx::CompositionOp aOp) {
|
||||
return int(aOp) - int(gfx::CompositionOp::OP_MULTIPLY);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
// Sanity checks.
|
||||
namespace {
|
||||
static inline void BlendShaderConstantAsserts() {
|
||||
static_assert(PS_MASK_NONE == int(mozilla::layers::MaskType::MaskNone), "shader constant is out of sync");
|
||||
static_assert(PS_MASK == int(mozilla::layers::MaskType::Mask), "shader constant is out of sync");
|
||||
static_assert(int(mozilla::gfx::CompositionOp::OP_LUMINOSITY) - int(mozilla::gfx::CompositionOp::OP_MULTIPLY) == 14,
|
||||
"shader constants are out of sync");
|
||||
}
|
||||
} // anonymous namespace
|
||||
#endif
|
||||
|
||||
#endif // MOZILLA_GFX_LAYERS_D3D11_BLENDSHADERCONSTANTS_H_
|
||||
184
gfx/layers/d3d11/BlendingHelpers.hlslh
Normal file
184
gfx/layers/d3d11/BlendingHelpers.hlslh
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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/. */
|
||||
|
||||
// Helper functions.
|
||||
float hardlight(float dest, float src) {
|
||||
if (src <= 0.5) {
|
||||
return dest * (2.0 * src);
|
||||
} else {
|
||||
// Note: we substitute (2*src-1) into the screen formula below.
|
||||
return 2.0 * dest + 2.0 * src - 1.0 - 2.0 * dest * src;
|
||||
}
|
||||
}
|
||||
|
||||
float dodge(float dest, float src) {
|
||||
if (dest == 0.0) {
|
||||
return 0.0;
|
||||
} else if (src == 1.0) {
|
||||
return 1.0;
|
||||
} else {
|
||||
return min(1.0, dest / (1.0 - src));
|
||||
}
|
||||
}
|
||||
|
||||
float burn(float dest, float src) {
|
||||
if (dest == 1.0) {
|
||||
return 1.0;
|
||||
} else if (src == 0.0) {
|
||||
return 0.0;
|
||||
} else {
|
||||
return 1.0 - min(1.0, (1.0 - dest) / src);
|
||||
}
|
||||
}
|
||||
|
||||
float darken(float dest) {
|
||||
if (dest <= 0.25) {
|
||||
return ((16.0 * dest - 12.0) * dest + 4.0) * dest;
|
||||
} else {
|
||||
return sqrt(dest);
|
||||
}
|
||||
}
|
||||
|
||||
float softlight(float dest, float src) {
|
||||
if (src <= 0.5) {
|
||||
return dest - (1.0 - 2.0 * src) * dest * (1.0 - dest);
|
||||
} else {
|
||||
return dest + (2.0 * src - 1.0) * (darken(dest) - dest);
|
||||
}
|
||||
}
|
||||
|
||||
float Lum(float3 c) {
|
||||
return dot(float3(0.3, 0.59, 0.11), c);
|
||||
}
|
||||
|
||||
float3 ClipColor(float3 c) {
|
||||
float L = Lum(c);
|
||||
float n = min(min(c.r, c.g), c.b);
|
||||
float x = max(max(c.r, c.g), c.b);
|
||||
if (n < 0.0) {
|
||||
c = L + (((c - L) * L) / (L - n));
|
||||
}
|
||||
if (x > 1.0) {
|
||||
c = L + (((c - L) * (1.0 - L)) / (x - L));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
float3 SetLum(float3 c, float L) {
|
||||
float d = L - Lum(c);
|
||||
return ClipColor(float3(
|
||||
c.r + d,
|
||||
c.g + d,
|
||||
c.b + d));
|
||||
}
|
||||
|
||||
float Sat(float3 c) {
|
||||
return max(max(c.r, c.g), c.b) - min(min(c.r, c.g), c.b);
|
||||
}
|
||||
|
||||
// To use this helper, re-arrange rgb such that r=min, g=mid, and b=max.
|
||||
float3 SetSatInner(float3 c, float s) {
|
||||
if (c.b > c.r) {
|
||||
c.g = (((c.g - c.r) * s) / (c.b - c.r));
|
||||
c.b = s;
|
||||
} else {
|
||||
c.gb = float2(0.0, 0.0);
|
||||
}
|
||||
return float3(0.0, c.g, c.b);
|
||||
}
|
||||
|
||||
float3 SetSat(float3 c, float s) {
|
||||
if (c.r <= c.g) {
|
||||
if (c.g <= c.b) {
|
||||
c.rgb = SetSatInner(c.rgb, s);
|
||||
} else if (c.r <= c.b) {
|
||||
c.rbg = SetSatInner(c.rbg, s);
|
||||
} else {
|
||||
c.brg = SetSatInner(c.brg, s);
|
||||
}
|
||||
} else if (c.r <= c.b) {
|
||||
c.grb = SetSatInner(c.grb, s);
|
||||
} else if (c.g <= c.b) {
|
||||
c.gbr = SetSatInner(c.gbr, s);
|
||||
} else {
|
||||
c.bgr = SetSatInner(c.bgr, s);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
float3 BlendMultiply(float3 dest, float3 src) {
|
||||
return dest * src;
|
||||
}
|
||||
|
||||
float3 BlendScreen(float3 dest, float3 src) {
|
||||
return dest + src - (dest * src);
|
||||
}
|
||||
|
||||
float3 BlendOverlay(float3 dest, float3 src) {
|
||||
return float3(
|
||||
hardlight(src.r, dest.r),
|
||||
hardlight(src.g, dest.g),
|
||||
hardlight(src.b, dest.b));
|
||||
}
|
||||
|
||||
float3 BlendDarken(float3 dest, float3 src) {
|
||||
return min(dest, src);
|
||||
}
|
||||
|
||||
float3 BlendLighten(float3 dest, float3 src) {
|
||||
return max(dest, src);
|
||||
}
|
||||
|
||||
float3 BlendColorDodge(float3 dest, float3 src) {
|
||||
return float3(
|
||||
dodge(dest.r, src.r),
|
||||
dodge(dest.g, src.g),
|
||||
dodge(dest.b, src.b));
|
||||
}
|
||||
|
||||
float3 BlendColorBurn(float3 dest, float3 src) {
|
||||
return float3(
|
||||
burn(dest.r, src.r),
|
||||
burn(dest.g, src.g),
|
||||
burn(dest.b, src.b));
|
||||
}
|
||||
|
||||
float3 BlendHardLight(float3 dest, float3 src) {
|
||||
return float3(
|
||||
hardlight(dest.r, src.r),
|
||||
hardlight(dest.g, src.g),
|
||||
hardlight(dest.b, src.b));
|
||||
}
|
||||
|
||||
float3 BlendSoftLight(float3 dest, float3 src) {
|
||||
return float3(
|
||||
softlight(dest.r, src.r),
|
||||
softlight(dest.g, src.g),
|
||||
softlight(dest.b, src.b));
|
||||
}
|
||||
|
||||
float3 BlendDifference(float3 dest, float3 src) {
|
||||
return abs(dest - src);
|
||||
}
|
||||
|
||||
float3 BlendExclusion(float3 dest, float3 src) {
|
||||
return dest + src - 2.0 * dest * src;
|
||||
}
|
||||
|
||||
float3 BlendHue(float3 dest, float3 src) {
|
||||
return SetLum(SetSat(src, Sat(dest)), Lum(dest));
|
||||
}
|
||||
|
||||
float3 BlendSaturation(float3 dest, float3 src) {
|
||||
return SetLum(SetSat(dest, Sat(src)), Lum(dest));
|
||||
}
|
||||
|
||||
float3 BlendColor(float3 dest, float3 src) {
|
||||
return SetLum(src, Lum(dest));
|
||||
}
|
||||
|
||||
float3 BlendLuminosity(float3 dest, float3 src) {
|
||||
return SetLum(dest, Lum(src));
|
||||
}
|
||||
1586
gfx/layers/d3d11/CompositorD3D11.cpp
Normal file
1586
gfx/layers/d3d11/CompositorD3D11.cpp
Normal file
File diff suppressed because it is too large
Load diff
208
gfx/layers/d3d11/CompositorD3D11.h
Normal file
208
gfx/layers/d3d11/CompositorD3D11.h
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
/* -*- 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_COMPOSITORD3D11_H
|
||||
#define MOZILLA_GFX_COMPOSITORD3D11_H
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "gfx2DGlue.h"
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "TextureD3D11.h"
|
||||
#include <d3d11.h>
|
||||
|
||||
class nsWidget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
#define LOGD3D11(param)
|
||||
|
||||
struct VertexShaderConstants
|
||||
{
|
||||
float layerTransform[4][4];
|
||||
float projection[4][4];
|
||||
float renderTargetOffset[4];
|
||||
gfx::Rect textureCoords;
|
||||
gfx::Rect layerQuad;
|
||||
gfx::Rect maskQuad;
|
||||
float backdropTransform[4][4];
|
||||
};
|
||||
|
||||
struct PixelShaderConstants
|
||||
{
|
||||
float layerColor[4];
|
||||
float layerOpacity[4];
|
||||
int blendConfig[4];
|
||||
float yuvColorMatrix[3][4];
|
||||
};
|
||||
|
||||
struct DeviceAttachmentsD3D11;
|
||||
|
||||
class CompositorD3D11 : public Compositor
|
||||
{
|
||||
public:
|
||||
CompositorD3D11(CompositorBridgeParent* aParent, widget::CompositorWidget* aWidget);
|
||||
~CompositorD3D11();
|
||||
|
||||
virtual CompositorD3D11* AsCompositorD3D11() override { return this; }
|
||||
|
||||
virtual bool Initialize(nsCString* const out_failureReason) override;
|
||||
|
||||
virtual TextureFactoryIdentifier
|
||||
GetTextureFactoryIdentifier() override;
|
||||
|
||||
virtual already_AddRefed<DataTextureSource>
|
||||
CreateDataTextureSource(TextureFlags aFlags = TextureFlags::NO_FLAGS) override;
|
||||
|
||||
virtual bool CanUseCanvasLayerForSize(const gfx::IntSize& aSize) override;
|
||||
virtual int32_t GetMaxTextureSize() const final;
|
||||
|
||||
virtual void MakeCurrent(MakeCurrentFlags aFlags = 0) override {}
|
||||
|
||||
virtual already_AddRefed<CompositingRenderTarget>
|
||||
CreateRenderTarget(const gfx::IntRect &aRect,
|
||||
SurfaceInitMode aInit) override;
|
||||
|
||||
virtual already_AddRefed<CompositingRenderTarget>
|
||||
CreateRenderTargetFromSource(const gfx::IntRect& aRect,
|
||||
const CompositingRenderTarget* aSource,
|
||||
const gfx::IntPoint& aSourcePoint) override;
|
||||
|
||||
virtual void SetRenderTarget(CompositingRenderTarget* aSurface) override;
|
||||
virtual CompositingRenderTarget* GetCurrentRenderTarget() const override
|
||||
{
|
||||
return mCurrentRT;
|
||||
}
|
||||
|
||||
virtual void SetDestinationSurfaceSize(const gfx::IntSize& aSize) override {}
|
||||
|
||||
/**
|
||||
* Declare an offset to use when rendering layers. This will be ignored when
|
||||
* rendering to a target instead of the screen.
|
||||
*/
|
||||
virtual void SetScreenRenderOffset(const ScreenPoint& aOffset) override
|
||||
{
|
||||
if (aOffset.x || aOffset.y) {
|
||||
NS_RUNTIMEABORT("SetScreenRenderOffset not supported by CompositorD3D11.");
|
||||
}
|
||||
// If the offset is 0, 0 that's okay.
|
||||
}
|
||||
|
||||
virtual void ClearRect(const gfx::Rect& aRect) override;
|
||||
|
||||
virtual void DrawQuad(const gfx::Rect &aRect,
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* Flush the current frame to the screen.
|
||||
*/
|
||||
virtual void EndFrame() override;
|
||||
|
||||
/**
|
||||
* Post rendering stuff if the rendering is outside of this Compositor
|
||||
* e.g., by Composer2D
|
||||
*/
|
||||
virtual void EndFrameForExternalComposition(const gfx::Matrix& aTransform) override {}
|
||||
|
||||
/**
|
||||
* Setup the viewport and projection matrix for rendering
|
||||
* 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; }
|
||||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
virtual const char* Name() const override { return "Direct3D 11"; }
|
||||
#endif
|
||||
|
||||
virtual LayersBackend GetBackendType() const override {
|
||||
return LayersBackend::LAYERS_D3D11;
|
||||
}
|
||||
|
||||
virtual void ForcePresent();
|
||||
|
||||
ID3D11Device* GetDevice() { return mDevice; }
|
||||
|
||||
ID3D11DeviceContext* GetDC() { return mContext; }
|
||||
|
||||
private:
|
||||
enum Severity {
|
||||
Recoverable,
|
||||
DebugAssert,
|
||||
Critical,
|
||||
};
|
||||
|
||||
void HandleError(HRESULT hr, Severity aSeverity = DebugAssert);
|
||||
|
||||
// Same as Failed(), except the severity is critical (with no abort) and
|
||||
// a string prefix must be provided.
|
||||
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);
|
||||
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);
|
||||
|
||||
RefPtr<ID3D11DeviceContext> mContext;
|
||||
RefPtr<ID3D11Device> mDevice;
|
||||
RefPtr<IDXGISwapChain> mSwapChain;
|
||||
RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
|
||||
RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
|
||||
|
||||
RefPtr<ID3D11Query> mQuery;
|
||||
|
||||
DeviceAttachmentsD3D11* mAttachments;
|
||||
|
||||
LayoutDeviceIntSize mSize;
|
||||
|
||||
HWND mHwnd;
|
||||
|
||||
D3D_FEATURE_LEVEL mFeatureLevel;
|
||||
|
||||
VertexShaderConstants mVSConstants;
|
||||
PixelShaderConstants mPSConstants;
|
||||
bool mDisableSequenceForNextFrame;
|
||||
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;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
421
gfx/layers/d3d11/CompositorD3D11.hlsl
Normal file
421
gfx/layers/d3d11/CompositorD3D11.hlsl
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "BlendingHelpers.hlslh"
|
||||
#include "BlendShaderConstants.h"
|
||||
|
||||
typedef float4 rect;
|
||||
|
||||
float4x4 mLayerTransform : register(vs, c0);
|
||||
float4x4 mProjection : register(vs, c4);
|
||||
float4 vRenderTargetOffset : register(vs, c8);
|
||||
rect vTextureCoords : register(vs, c9);
|
||||
rect vLayerQuad : register(vs, c10);
|
||||
rect vMaskQuad : register(vs, c11);
|
||||
float4x4 mBackdropTransform : register(vs, c12);
|
||||
|
||||
float4 fLayerColor : register(ps, c0);
|
||||
float fLayerOpacity : register(ps, c1);
|
||||
|
||||
// x = layer type
|
||||
// y = mask type
|
||||
// z = blend op
|
||||
// w = is premultiplied
|
||||
uint4 iBlendConfig : register(ps, c2);
|
||||
|
||||
row_major float3x3 mYuvColorMatrix : register(ps, c3);
|
||||
|
||||
sampler sSampler : register(ps, s0);
|
||||
|
||||
// The mix-blend mega shader uses all variables, so we have to make sure they
|
||||
// are assigned fixed slots.
|
||||
Texture2D tRGB : register(ps, t0);
|
||||
Texture2D tY : register(ps, t1);
|
||||
Texture2D tCb : register(ps, t2);
|
||||
Texture2D tCr : register(ps, t3);
|
||||
Texture2D tRGBWhite : register(ps, t4);
|
||||
Texture2D tMask : register(ps, t5);
|
||||
Texture2D tBackdrop : register(ps, t6);
|
||||
|
||||
struct VS_INPUT {
|
||||
float2 vPosition : POSITION;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 vPosition : SV_Position;
|
||||
float2 vTexCoords : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct VS_MASK_OUTPUT {
|
||||
float4 vPosition : SV_Position;
|
||||
float2 vTexCoords : TEXCOORD0;
|
||||
float3 vMaskCoords : TEXCOORD1;
|
||||
};
|
||||
|
||||
// Combined struct for the mix-blend compatible vertex shaders.
|
||||
struct VS_BLEND_OUTPUT {
|
||||
float4 vPosition : SV_Position;
|
||||
float2 vTexCoords : TEXCOORD0;
|
||||
float3 vMaskCoords : TEXCOORD1;
|
||||
float2 vBackdropCoords : TEXCOORD2;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT {
|
||||
float4 vSrc;
|
||||
float4 vAlpha;
|
||||
};
|
||||
|
||||
float2 TexCoords(const float2 aPosition)
|
||||
{
|
||||
float2 result;
|
||||
const float2 size = vTextureCoords.zw;
|
||||
result.x = vTextureCoords.x + aPosition.x * size.x;
|
||||
result.y = vTextureCoords.y + aPosition.y * size.y;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SamplerState LayerTextureSamplerLinear
|
||||
{
|
||||
Filter = MIN_MAG_MIP_LINEAR;
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
float4 TransformedPosition(float2 aInPosition)
|
||||
{
|
||||
// the current vertex's position on the quad
|
||||
// [x,y,0,1] is mandated by the CSS Transforms spec as the point value to transform
|
||||
float4 position = float4(0, 0, 0, 1);
|
||||
|
||||
// We use 4 component floats to uniquely describe a rectangle, by the structure
|
||||
// of x, y, width, height. This allows us to easily generate the 4 corners
|
||||
// of any rectangle from the 4 corners of the 0,0-1,1 quad that we use as the
|
||||
// stream source for our LayerQuad vertex shader. We do this by doing:
|
||||
// Xout = x + Xin * width
|
||||
// Yout = y + Yin * height
|
||||
float2 size = vLayerQuad.zw;
|
||||
position.x = vLayerQuad.x + aInPosition.x * size.x;
|
||||
position.y = vLayerQuad.y + aInPosition.y * size.y;
|
||||
|
||||
position = mul(mLayerTransform, position);
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
float4 VertexPosition(float4 aTransformedPosition)
|
||||
{
|
||||
float4 result;
|
||||
result.w = aTransformedPosition.w;
|
||||
result.xyz = aTransformedPosition.xyz / aTransformedPosition.w;
|
||||
result -= vRenderTargetOffset;
|
||||
result.xyz *= result.w;
|
||||
|
||||
result = mul(mProjection, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float2 BackdropPosition(float4 aPosition)
|
||||
{
|
||||
// Move the position from clip space (-1,1) into 0..1 space.
|
||||
float2 pos;
|
||||
pos.x = (aPosition.x + 1.0) / 2.0;
|
||||
pos.y = 1.0 - (aPosition.y + 1.0) / 2.0;
|
||||
|
||||
return mul(mBackdropTransform, float4(pos.xy, 0, 1.0)).xy;
|
||||
}
|
||||
|
||||
VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex)
|
||||
{
|
||||
VS_OUTPUT outp;
|
||||
float4 position = TransformedPosition(aVertex.vPosition);
|
||||
|
||||
outp.vPosition = VertexPosition(position);
|
||||
outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
|
||||
|
||||
return outp;
|
||||
}
|
||||
|
||||
VS_MASK_OUTPUT LayerQuadMaskVS(const VS_INPUT aVertex)
|
||||
{
|
||||
VS_MASK_OUTPUT outp;
|
||||
float4 position = TransformedPosition(aVertex.vPosition);
|
||||
|
||||
outp.vPosition = VertexPosition(position);
|
||||
|
||||
// calculate the position on the mask texture
|
||||
outp.vMaskCoords.x = (position.x - vMaskQuad.x) / vMaskQuad.z;
|
||||
outp.vMaskCoords.y = (position.y - vMaskQuad.y) / vMaskQuad.w;
|
||||
// We use the w coord to do non-perspective correct interpolation:
|
||||
// the quad might be transformed in 3D, in which case it will have some
|
||||
// perspective. The graphics card will do perspective-correct interpolation
|
||||
// of the texture, but our mask is already transformed and so we require
|
||||
// linear interpolation. Therefore, we must correct the interpolation
|
||||
// ourselves, we do this by multiplying all coords by w here, and dividing by
|
||||
// w in the pixel shader (post-interpolation), we pass w in outp.vMaskCoords.z.
|
||||
// See http://en.wikipedia.org/wiki/Texture_mapping#Perspective_correctness
|
||||
outp.vMaskCoords.z = 1;
|
||||
outp.vMaskCoords *= position.w;
|
||||
|
||||
outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
|
||||
|
||||
return outp;
|
||||
}
|
||||
|
||||
float4 RGBAShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).r;
|
||||
return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * mask;
|
||||
}
|
||||
|
||||
float4 RGBShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float4 result;
|
||||
result = tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity;
|
||||
result.a = fLayerOpacity;
|
||||
|
||||
float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).r;
|
||||
return result * mask;
|
||||
}
|
||||
|
||||
/* From Rec601:
|
||||
[R] [1.1643835616438356, 0.0, 1.5960267857142858] [ Y - 16]
|
||||
[G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708] x [Cb - 128]
|
||||
[B] [1.1643835616438356, 2.017232142857143, 8.862867620416422e-17] [Cr - 128]
|
||||
|
||||
For [0,1] instead of [0,255], and to 5 places:
|
||||
[R] [1.16438, 0.00000, 1.59603] [ Y - 0.06275]
|
||||
[G] = [1.16438, -0.39176, -0.81297] x [Cb - 0.50196]
|
||||
[B] [1.16438, 2.01723, 0.00000] [Cr - 0.50196]
|
||||
|
||||
From Rec709:
|
||||
[R] [1.1643835616438356, 4.2781193979771426e-17, 1.7927410714285714] [ Y - 16]
|
||||
[G] = [1.1643835616438358, -0.21324861427372963, -0.532909328559444] x [Cb - 128]
|
||||
[B] [1.1643835616438356, 2.1124017857142854, 0.0] [Cr - 128]
|
||||
|
||||
For [0,1] instead of [0,255], and to 5 places:
|
||||
[R] [1.16438, 0.00000, 1.79274] [ Y - 0.06275]
|
||||
[G] = [1.16438, -0.21325, -0.53291] x [Cb - 0.50196]
|
||||
[B] [1.16438, 2.11240, 0.00000] [Cr - 0.50196]
|
||||
*/
|
||||
float4 CalculateYCbCrColor(const float2 aTexCoords)
|
||||
{
|
||||
float3 yuv;
|
||||
float4 color;
|
||||
|
||||
yuv.x = tY.Sample(sSampler, aTexCoords).r - 0.06275;
|
||||
yuv.y = tCb.Sample(sSampler, aTexCoords).r - 0.50196;
|
||||
yuv.z = tCr.Sample(sSampler, aTexCoords).r - 0.50196;
|
||||
|
||||
color.rgb = mul(mYuvColorMatrix, yuv);
|
||||
color.a = 1.0f;
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
float4 YCbCrShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).r;
|
||||
|
||||
return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity * mask;
|
||||
}
|
||||
|
||||
PS_OUTPUT ComponentAlphaShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
PS_OUTPUT result;
|
||||
|
||||
result.vSrc = tRGB.Sample(sSampler, aVertex.vTexCoords);
|
||||
result.vAlpha = 1.0 - tRGBWhite.Sample(sSampler, aVertex.vTexCoords) + result.vSrc;
|
||||
result.vSrc.a = result.vAlpha.g;
|
||||
|
||||
float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).r;
|
||||
result.vSrc *= fLayerOpacity * mask;
|
||||
result.vAlpha *= fLayerOpacity * mask;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 SolidColorShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
|
||||
float mask = tMask.Sample(sSampler, maskCoords).r;
|
||||
return fLayerColor * mask;
|
||||
}
|
||||
|
||||
/*
|
||||
* Un-masked versions
|
||||
*************************************************************
|
||||
*/
|
||||
float4 RGBAShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity;
|
||||
}
|
||||
|
||||
float4 RGBShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float4 result;
|
||||
result = tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity;
|
||||
result.a = fLayerOpacity;
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 YCbCrShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity;
|
||||
}
|
||||
|
||||
PS_OUTPUT ComponentAlphaShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
PS_OUTPUT result;
|
||||
|
||||
result.vSrc = tRGB.Sample(sSampler, aVertex.vTexCoords);
|
||||
result.vAlpha = 1.0 - tRGBWhite.Sample(sSampler, aVertex.vTexCoords) + result.vSrc;
|
||||
result.vSrc.a = result.vAlpha.g;
|
||||
result.vSrc *= fLayerOpacity;
|
||||
result.vAlpha *= fLayerOpacity;
|
||||
return result;
|
||||
}
|
||||
|
||||
float4 SolidColorShader(const VS_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
return fLayerColor;
|
||||
}
|
||||
|
||||
// Mix-blend compatible vertex shaders.
|
||||
VS_BLEND_OUTPUT LayerQuadBlendVS(const VS_INPUT aVertex)
|
||||
{
|
||||
VS_OUTPUT v = LayerQuadVS(aVertex);
|
||||
|
||||
VS_BLEND_OUTPUT o;
|
||||
o.vPosition = v.vPosition;
|
||||
o.vTexCoords = v.vTexCoords;
|
||||
o.vMaskCoords = float3(0, 0, 0);
|
||||
o.vBackdropCoords = BackdropPosition(v.vPosition);
|
||||
return o;
|
||||
}
|
||||
|
||||
VS_BLEND_OUTPUT LayerQuadBlendMaskVS(const VS_INPUT aVertex)
|
||||
{
|
||||
VS_MASK_OUTPUT v = LayerQuadMaskVS(aVertex);
|
||||
|
||||
VS_BLEND_OUTPUT o;
|
||||
o.vPosition = v.vPosition;
|
||||
o.vTexCoords = v.vTexCoords;
|
||||
o.vMaskCoords = v.vMaskCoords;
|
||||
o.vBackdropCoords = BackdropPosition(v.vPosition);
|
||||
return o;
|
||||
}
|
||||
|
||||
// The layer type and mask type are specified as constants. We use these to
|
||||
// call the correct pixel shader to determine the source color for blending.
|
||||
// Unfortunately this also requires some boilerplate to convert VS_BLEND_OUTPUT
|
||||
// to a compatible pixel shader input.
|
||||
float4 ComputeBlendSourceColor(const VS_BLEND_OUTPUT aVertex)
|
||||
{
|
||||
if (iBlendConfig.y == PS_MASK_NONE) {
|
||||
VS_OUTPUT tmp;
|
||||
tmp.vPosition = aVertex.vPosition;
|
||||
tmp.vTexCoords = aVertex.vTexCoords;
|
||||
if (iBlendConfig.x == PS_LAYER_RGB) {
|
||||
return RGBShader(tmp);
|
||||
} else if (iBlendConfig.x == PS_LAYER_RGBA) {
|
||||
return RGBAShader(tmp);
|
||||
} else if (iBlendConfig.x == PS_LAYER_YCBCR) {
|
||||
return YCbCrShader(tmp);
|
||||
}
|
||||
return SolidColorShader(tmp);
|
||||
} else if (iBlendConfig.y == PS_MASK) {
|
||||
VS_MASK_OUTPUT tmp;
|
||||
tmp.vPosition = aVertex.vPosition;
|
||||
tmp.vTexCoords = aVertex.vTexCoords;
|
||||
tmp.vMaskCoords = aVertex.vMaskCoords;
|
||||
|
||||
if (iBlendConfig.x == PS_LAYER_RGB) {
|
||||
return RGBShaderMask(tmp);
|
||||
} else if (iBlendConfig.x == PS_LAYER_RGBA) {
|
||||
return RGBAShaderMask(tmp);
|
||||
} else if (iBlendConfig.x == PS_LAYER_YCBCR) {
|
||||
return YCbCrShaderMask(tmp);
|
||||
}
|
||||
return SolidColorShaderMask(tmp);
|
||||
}
|
||||
|
||||
return float4(0.0, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
float3 ChooseBlendFunc(float3 dest, float3 src)
|
||||
{
|
||||
[flatten] switch (iBlendConfig.z) {
|
||||
case PS_BLEND_MULTIPLY:
|
||||
return BlendMultiply(dest, src);
|
||||
case PS_BLEND_SCREEN:
|
||||
return BlendScreen(dest, src);
|
||||
case PS_BLEND_OVERLAY:
|
||||
return BlendOverlay(dest, src);
|
||||
case PS_BLEND_DARKEN:
|
||||
return BlendDarken(dest, src);
|
||||
case PS_BLEND_LIGHTEN:
|
||||
return BlendLighten(dest, src);
|
||||
case PS_BLEND_COLOR_DODGE:
|
||||
return BlendColorDodge(dest, src);
|
||||
case PS_BLEND_COLOR_BURN:
|
||||
return BlendColorBurn(dest, src);
|
||||
case PS_BLEND_HARD_LIGHT:
|
||||
return BlendHardLight(dest, src);
|
||||
case PS_BLEND_SOFT_LIGHT:
|
||||
return BlendSoftLight(dest, src);
|
||||
case PS_BLEND_DIFFERENCE:
|
||||
return BlendDifference(dest, src);
|
||||
case PS_BLEND_EXCLUSION:
|
||||
return BlendExclusion(dest, src);
|
||||
case PS_BLEND_HUE:
|
||||
return BlendHue(dest, src);
|
||||
case PS_BLEND_SATURATION:
|
||||
return BlendSaturation(dest, src);
|
||||
case PS_BLEND_COLOR:
|
||||
return BlendColor(dest, src);
|
||||
case PS_BLEND_LUMINOSITY:
|
||||
return BlendLuminosity(dest, src);
|
||||
default:
|
||||
return float3(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
float4 BlendShader(const VS_BLEND_OUTPUT aVertex) : SV_Target
|
||||
{
|
||||
float4 backdrop = tBackdrop.Sample(sSampler, aVertex.vBackdropCoords.xy);
|
||||
float4 source = ComputeBlendSourceColor(aVertex);
|
||||
|
||||
// Shortcut when the backdrop or source alpha is 0, otherwise we may leak
|
||||
// infinity into the blend function and return incorrect results.
|
||||
if (backdrop.a == 0.0) {
|
||||
return source;
|
||||
}
|
||||
if (source.a == 0.0) {
|
||||
return float4(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
// The spec assumes there is no premultiplied alpha. The backdrop is always
|
||||
// premultiplied, so undo the premultiply. If the source is premultiplied we
|
||||
// must fix that as well.
|
||||
backdrop.rgb /= backdrop.a;
|
||||
if (iBlendConfig.w) {
|
||||
source.rgb /= source.a;
|
||||
}
|
||||
|
||||
float4 result;
|
||||
result.rgb = ChooseBlendFunc(backdrop.rgb, source.rgb);
|
||||
result.a = source.a;
|
||||
|
||||
// Factor backdrop alpha, then premultiply for the final OP_OVER.
|
||||
result.rgb = (1.0 - backdrop.a) * source.rgb + backdrop.a * result.rgb;
|
||||
result.rgb *= result.a;
|
||||
return result;
|
||||
}
|
||||
9434
gfx/layers/d3d11/CompositorD3D11Shaders.h
Normal file
9434
gfx/layers/d3d11/CompositorD3D11Shaders.h
Normal file
File diff suppressed because it is too large
Load diff
160
gfx/layers/d3d11/ReadbackManagerD3D11.cpp
Normal file
160
gfx/layers/d3d11/ReadbackManagerD3D11.cpp
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 "ReadbackManagerD3D11.h"
|
||||
#include "ReadbackProcessor.h"
|
||||
#include "ReadbackLayer.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
#include "nsIThread.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
namespace layers {
|
||||
|
||||
// Structure that contains the information required to execute a readback task,
|
||||
// the only member accessed off the main thread here is mReadbackTexture. Since
|
||||
// mSink may be released only on the main thread this object should always be
|
||||
// destroyed on the main thread!
|
||||
struct ReadbackTask {
|
||||
// The texture that we copied the contents of the paintedlayer to.
|
||||
RefPtr<ID3D10Texture2D> mReadbackTexture;
|
||||
// The sink that we're trying to read back to.
|
||||
RefPtr<TextureReadbackSink> mSink;
|
||||
};
|
||||
|
||||
// This class is created and dispatched from the Readback thread but it must be
|
||||
// destroyed by the main thread.
|
||||
class ReadbackResultWriterD3D11 final : public nsIRunnable
|
||||
{
|
||||
~ReadbackResultWriterD3D11() {}
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
public:
|
||||
ReadbackResultWriterD3D11(ReadbackTask *aTask) : mTask(aTask) {}
|
||||
|
||||
NS_IMETHOD Run() override
|
||||
{
|
||||
D3D10_TEXTURE2D_DESC desc;
|
||||
mTask->mReadbackTexture->GetDesc(&desc);
|
||||
|
||||
D3D10_MAPPED_TEXTURE2D mappedTex;
|
||||
// Unless there is an error this map should succeed immediately, as we've
|
||||
// recently mapped (and unmapped) this copied data on our task thread.
|
||||
HRESULT hr = mTask->mReadbackTexture->Map(0, D3D10_MAP_READ, 0, &mappedTex);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
mTask->mSink->ProcessReadback(nullptr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
{
|
||||
RefPtr<DataSourceSurface> surf =
|
||||
Factory::CreateWrappingDataSourceSurface((uint8_t*)mappedTex.pData, mappedTex.RowPitch,
|
||||
IntSize(desc.Width, desc.Height),
|
||||
SurfaceFormat::B8G8R8A8);
|
||||
|
||||
mTask->mSink->ProcessReadback(surf);
|
||||
|
||||
MOZ_ASSERT(surf->hasOneRef());
|
||||
}
|
||||
|
||||
mTask->mReadbackTexture->Unmap(0);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsAutoPtr<ReadbackTask> mTask;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS(ReadbackResultWriterD3D11, nsIRunnable)
|
||||
|
||||
DWORD WINAPI ReadbackManagerD3D11::StartTaskThread(void *aManager)
|
||||
{
|
||||
static_cast<ReadbackManagerD3D11*>(aManager)->ProcessTasks();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ReadbackManagerD3D11::ReadbackManagerD3D11()
|
||||
: mRefCnt(0)
|
||||
{
|
||||
::InitializeCriticalSection(&mTaskMutex);
|
||||
mShutdownEvent = ::CreateEventA(nullptr, FALSE, FALSE, nullptr);
|
||||
mTaskSemaphore = ::CreateSemaphoreA(nullptr, 0, 1000000, nullptr);
|
||||
mTaskThread = ::CreateThread(nullptr, 0, StartTaskThread, this, 0, 0);
|
||||
}
|
||||
|
||||
ReadbackManagerD3D11::~ReadbackManagerD3D11()
|
||||
{
|
||||
::SetEvent(mShutdownEvent);
|
||||
|
||||
// This shouldn't take longer than 5 seconds, if it does we're going to choose
|
||||
// to leak the thread and its synchronisation in favor of crashing or freezing
|
||||
DWORD result = ::WaitForSingleObject(mTaskThread, 5000);
|
||||
if (result != WAIT_TIMEOUT) {
|
||||
::DeleteCriticalSection(&mTaskMutex);
|
||||
::CloseHandle(mShutdownEvent);
|
||||
::CloseHandle(mTaskSemaphore);
|
||||
::CloseHandle(mTaskThread);
|
||||
} else {
|
||||
NS_RUNTIMEABORT("ReadbackManager: Task thread did not shutdown in 5 seconds.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ReadbackManagerD3D11::PostTask(ID3D10Texture2D *aTexture, TextureReadbackSink* aSink)
|
||||
{
|
||||
ReadbackTask *task = new ReadbackTask;
|
||||
task->mReadbackTexture = aTexture;
|
||||
task->mSink = aSink;
|
||||
|
||||
::EnterCriticalSection(&mTaskMutex);
|
||||
mPendingReadbackTasks.AppendElement(task);
|
||||
::LeaveCriticalSection(&mTaskMutex);
|
||||
|
||||
::ReleaseSemaphore(mTaskSemaphore, 1, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
ReadbackManagerD3D11::ProcessTasks()
|
||||
{
|
||||
HANDLE handles[] = { mTaskSemaphore, mShutdownEvent };
|
||||
|
||||
while (true) {
|
||||
DWORD result = ::WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
||||
if (result != WAIT_OBJECT_0) {
|
||||
return;
|
||||
}
|
||||
|
||||
::EnterCriticalSection(&mTaskMutex);
|
||||
if (mPendingReadbackTasks.Length() == 0) {
|
||||
NS_RUNTIMEABORT("Trying to read from an empty array, bad bad bad");
|
||||
}
|
||||
ReadbackTask *nextReadbackTask = mPendingReadbackTasks[0].forget();
|
||||
mPendingReadbackTasks.RemoveElementAt(0);
|
||||
::LeaveCriticalSection(&mTaskMutex);
|
||||
|
||||
// We want to block here until the texture contents are available, the
|
||||
// easiest thing is to simply map and unmap.
|
||||
D3D10_MAPPED_TEXTURE2D mappedTex;
|
||||
nextReadbackTask->mReadbackTexture->Map(0, D3D10_MAP_READ, 0, &mappedTex);
|
||||
nextReadbackTask->mReadbackTexture->Unmap(0);
|
||||
|
||||
// We can only send the update to the sink on the main thread, so post an
|
||||
// event there to do so. Ownership of the task is passed from
|
||||
// mPendingReadbackTasks to ReadbackResultWriter here.
|
||||
nsCOMPtr<nsIThread> thread = do_GetMainThread();
|
||||
thread->Dispatch(new ReadbackResultWriterD3D11(nextReadbackTask),
|
||||
nsIEventTarget::DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
65
gfx/layers/d3d11/ReadbackManagerD3D11.h
Normal file
65
gfx/layers/d3d11/ReadbackManagerD3D11.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 GFX_READBACKMANAGERD3D11_H
|
||||
#define GFX_READBACKMANAGERD3D11_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d10_1.h>
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class TextureReadbackSink;
|
||||
struct ReadbackTask;
|
||||
|
||||
class ReadbackManagerD3D11 final
|
||||
{
|
||||
NS_INLINE_DECL_REFCOUNTING(ReadbackManagerD3D11)
|
||||
public:
|
||||
ReadbackManagerD3D11();
|
||||
|
||||
/**
|
||||
* Tell the readback manager to post a readback task.
|
||||
*
|
||||
* @param aTexture D3D10_USAGE_STAGING texture that will contain the data that
|
||||
* was readback.
|
||||
* @param aSink TextureReadbackSink that the resulting DataSourceSurface
|
||||
* should be dispatched to.
|
||||
*/
|
||||
void PostTask(ID3D10Texture2D* aTexture, TextureReadbackSink* aSink);
|
||||
|
||||
private:
|
||||
~ReadbackManagerD3D11();
|
||||
|
||||
static DWORD WINAPI StartTaskThread(void *aManager);
|
||||
|
||||
void ProcessTasks();
|
||||
|
||||
// The invariant maintained by |mTaskSemaphore| is that the readback thread
|
||||
// will awaken from WaitForMultipleObjects() at least once per readback
|
||||
// task enqueued by the main thread. Since the readback thread processes
|
||||
// exactly one task per wakeup (with one exception), no tasks are lost. The
|
||||
// exception is when the readback thread is shut down, which orphans the
|
||||
// remaining tasks, on purpose.
|
||||
HANDLE mTaskSemaphore;
|
||||
// Event signaled when the task thread should shutdown
|
||||
HANDLE mShutdownEvent;
|
||||
// Handle to the task thread
|
||||
HANDLE mTaskThread;
|
||||
|
||||
// FiFo list of readback tasks that are to be executed. Access is synchronized
|
||||
// by mTaskMutex.
|
||||
CRITICAL_SECTION mTaskMutex;
|
||||
nsTArray<nsAutoPtr<ReadbackTask>> mPendingReadbackTasks;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* GFX_READBACKMANAGERD3D11_H */
|
||||
1291
gfx/layers/d3d11/TextureD3D11.cpp
Normal file
1291
gfx/layers/d3d11/TextureD3D11.cpp
Normal file
File diff suppressed because it is too large
Load diff
455
gfx/layers/d3d11/TextureD3D11.h
Normal file
455
gfx/layers/d3d11/TextureD3D11.h
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
/* -*- 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_TEXTURED3D11_H
|
||||
#define MOZILLA_GFX_TEXTURED3D11_H
|
||||
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/layers/Compositor.h"
|
||||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "mozilla/layers/TextureHost.h"
|
||||
#include "gfxWindowsPlatform.h"
|
||||
#include "mozilla/GfxMessageUtils.h"
|
||||
#include <d3d11.h>
|
||||
#include "d3d9.h"
|
||||
#include <vector>
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class MOZ_RAII AutoTextureLock
|
||||
{
|
||||
public:
|
||||
AutoTextureLock(IDXGIKeyedMutex* aMutex, HRESULT& aResult,
|
||||
uint32_t aTimeout = 0);
|
||||
~AutoTextureLock();
|
||||
|
||||
private:
|
||||
RefPtr<IDXGIKeyedMutex> mMutex;
|
||||
HRESULT mResult;
|
||||
};
|
||||
|
||||
class CompositorD3D11;
|
||||
|
||||
class DXGITextureData : public TextureData
|
||||
{
|
||||
public:
|
||||
virtual void FillInfo(TextureData::Info& aInfo) const override;
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
|
||||
|
||||
static DXGITextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
|
||||
|
||||
protected:
|
||||
bool PrepareDrawTargetInLock(OpenMode aMode);
|
||||
|
||||
DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
bool aNeedsClear, bool aNeedsClearWhite,
|
||||
bool aIsForOutOfBandContent);
|
||||
|
||||
virtual void GetDXGIResource(IDXGIResource** aOutResource) = 0;
|
||||
|
||||
// Hold on to the DrawTarget because it is expensive to create one each ::Lock.
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
bool mNeedsClear;
|
||||
bool mNeedsClearWhite;
|
||||
bool mHasSynchronization;
|
||||
bool mIsForOutOfBandContent;
|
||||
};
|
||||
|
||||
class D3D11TextureData : public DXGITextureData
|
||||
{
|
||||
public:
|
||||
// If aDevice is null, use one provided by gfxWindowsPlatform.
|
||||
static DXGITextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ID3D11Device* aDevice = nullptr);
|
||||
static DXGITextureData*
|
||||
Create(gfx::SourceSurface* aSurface,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ID3D11Device* aDevice = nullptr);
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual bool Lock(OpenMode aMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(LayersIPCChannel* aAllocator,
|
||||
LayersBackend aLayersBackend,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const override;
|
||||
|
||||
virtual void SyncWithObject(SyncObject* aSync) override;
|
||||
|
||||
ID3D11Texture2D* GetD3D11Texture() { return mTexture; }
|
||||
|
||||
virtual void Deallocate(LayersIPCChannel* aAllocator) override;
|
||||
|
||||
D3D11TextureData* AsD3D11TextureData() override {
|
||||
return this;
|
||||
}
|
||||
|
||||
~D3D11TextureData();
|
||||
protected:
|
||||
D3D11TextureData(ID3D11Texture2D* aTexture,
|
||||
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
bool aNeedsClear, bool aNeedsClearWhite,
|
||||
bool aIsForOutOfBandContent);
|
||||
|
||||
virtual void GetDXGIResource(IDXGIResource** aOutResource) override;
|
||||
|
||||
static DXGITextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::SourceSurface* aSurface,
|
||||
TextureAllocationFlags aAllocFlags,
|
||||
ID3D11Device* aDevice = nullptr);
|
||||
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
};
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
CreateD3D11extureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
|
||||
ID3D11Device* aDevice,
|
||||
LayersIPCChannel* aAllocator);
|
||||
|
||||
class DXGIYCbCrTextureData : public TextureData
|
||||
{
|
||||
public:
|
||||
static DXGIYCbCrTextureData*
|
||||
Create(TextureFlags aFlags,
|
||||
IUnknown* aTextureY,
|
||||
IUnknown* aTextureCb,
|
||||
IUnknown* aTextureCr,
|
||||
HANDLE aHandleY,
|
||||
HANDLE aHandleCb,
|
||||
HANDLE aHandleCr,
|
||||
const gfx::IntSize& aSize,
|
||||
const gfx::IntSize& aSizeY,
|
||||
const gfx::IntSize& aSizeCbCr);
|
||||
|
||||
static DXGIYCbCrTextureData*
|
||||
Create(TextureFlags aFlags,
|
||||
ID3D11Texture2D* aTextureCb,
|
||||
ID3D11Texture2D* aTextureY,
|
||||
ID3D11Texture2D* aTextureCr,
|
||||
const gfx::IntSize& aSize,
|
||||
const gfx::IntSize& aSizeY,
|
||||
const gfx::IntSize& aSizeCbCr);
|
||||
|
||||
virtual bool Lock(OpenMode) override { return true; }
|
||||
|
||||
virtual void Unlock() override {}
|
||||
|
||||
virtual void FillInfo(TextureData::Info& aInfo) const override;
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override { return nullptr; }
|
||||
|
||||
virtual void Deallocate(LayersIPCChannel* aAllocator) override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface*) override { return false; }
|
||||
|
||||
virtual TextureFlags GetTextureFlags() const override
|
||||
{
|
||||
return TextureFlags::DEALLOCATE_MAIN_THREAD;
|
||||
}
|
||||
|
||||
protected:
|
||||
RefPtr<IUnknown> mHoldRefs[3];
|
||||
HANDLE mHandles[3];
|
||||
gfx::IntSize mSize;
|
||||
gfx::IntSize mSizeY;
|
||||
gfx::IntSize mSizeCbCr;
|
||||
};
|
||||
|
||||
/**
|
||||
* TextureSource that provides with the necessary APIs to be composited by a
|
||||
* CompositorD3D11.
|
||||
*/
|
||||
class TextureSourceD3D11
|
||||
{
|
||||
public:
|
||||
TextureSourceD3D11() : mFormatOverride(DXGI_FORMAT_UNKNOWN) {}
|
||||
virtual ~TextureSourceD3D11() {}
|
||||
|
||||
virtual ID3D11Texture2D* GetD3D11Texture() const { return mTexture; }
|
||||
virtual ID3D11ShaderResourceView* GetShaderResourceView();
|
||||
protected:
|
||||
virtual gfx::IntSize GetSize() const { return mSize; }
|
||||
|
||||
gfx::IntSize mSize;
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
RefPtr<ID3D11ShaderResourceView> mSRV;
|
||||
DXGI_FORMAT mFormatOverride;
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureSource that implements the DataTextureSource interface.
|
||||
* it can be used without a TextureHost and is able to upload texture data
|
||||
* from a gfx::DataSourceSurface.
|
||||
*/
|
||||
class DataTextureSourceD3D11 : public DataTextureSource
|
||||
, public TextureSourceD3D11
|
||||
, public BigImageIterator
|
||||
{
|
||||
public:
|
||||
/// Constructor allowing the texture to perform texture uploads.
|
||||
///
|
||||
/// The texture can be used as an actual DataTextureSource.
|
||||
DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor,
|
||||
TextureFlags aFlags);
|
||||
|
||||
/// Constructor for textures created around DXGI shared handles, disallowing
|
||||
/// texture uploads.
|
||||
///
|
||||
/// The texture CANNOT be used as a DataTextureSource.
|
||||
DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor,
|
||||
ID3D11Texture2D* aTexture);
|
||||
|
||||
virtual ~DataTextureSourceD3D11();
|
||||
|
||||
virtual const char* Name() const override { return "DataTextureSourceD3D11"; }
|
||||
|
||||
// DataTextureSource
|
||||
|
||||
virtual bool Update(gfx::DataSourceSurface* aSurface,
|
||||
nsIntRegion* aDestRegion = nullptr,
|
||||
gfx::IntPoint* aSrcOffset = nullptr) override;
|
||||
|
||||
// TextureSource
|
||||
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() override { return this; }
|
||||
|
||||
virtual ID3D11Texture2D* GetD3D11Texture() const override;
|
||||
|
||||
virtual ID3D11ShaderResourceView* GetShaderResourceView() override;
|
||||
|
||||
// Returns nullptr if this texture was created by a DXGI TextureHost.
|
||||
virtual DataTextureSource* AsDataTextureSource() override { return mAllowTextureUploads ? this : false; }
|
||||
|
||||
virtual void DeallocateDeviceData() override { mTexture = nullptr; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
// BigImageIterator
|
||||
|
||||
virtual BigImageIterator* AsBigImageIterator() override { return mIsTiled ? this : nullptr; }
|
||||
|
||||
virtual size_t GetTileCount() override { return mTileTextures.size(); }
|
||||
|
||||
virtual bool NextTile() override { return (++mCurrentTile < mTileTextures.size()); }
|
||||
|
||||
virtual gfx::IntRect GetTileRect() override;
|
||||
|
||||
virtual void EndBigImageIteration() override { mIterating = false; }
|
||||
|
||||
virtual void BeginBigImageIteration() override
|
||||
{
|
||||
mIterating = true;
|
||||
mCurrentTile = 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
gfx::IntRect GetTileRect(uint32_t aIndex) const;
|
||||
|
||||
void Reset();
|
||||
|
||||
std::vector< RefPtr<ID3D11Texture2D> > mTileTextures;
|
||||
std::vector< RefPtr<ID3D11ShaderResourceView> > mTileSRVs;
|
||||
RefPtr<CompositorD3D11> mCompositor;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
TextureFlags mFlags;
|
||||
uint32_t mCurrentTile;
|
||||
bool mIsTiled;
|
||||
bool mIterating;
|
||||
// Sadly, the code was originally organized so that this class is used both in
|
||||
// the cases where we want to perform texture uploads through the DataTextureSource
|
||||
// interface, and the cases where we wrap the texture around an existing DXGI
|
||||
// handle in which case we should not use it as a DataTextureSource.
|
||||
// This member differentiates the two scenarios. When it is false the texture
|
||||
// "pretends" to not be a DataTextureSource.
|
||||
bool mAllowTextureUploads;
|
||||
};
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
CreateD3D11TextureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
|
||||
ID3D11Device* aDevice,
|
||||
LayersIPCChannel* aAllocator);
|
||||
|
||||
|
||||
/**
|
||||
* A TextureHost for shared D3D11 textures.
|
||||
*/
|
||||
class DXGITextureHostD3D11 : public TextureHost
|
||||
{
|
||||
public:
|
||||
DXGITextureHostD3D11(TextureFlags aFlags,
|
||||
const SurfaceDescriptorD3D10& aDescriptor);
|
||||
|
||||
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
|
||||
|
||||
virtual void DeallocateDeviceData() override {}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool LockWithoutCompositor() override;
|
||||
virtual void UnlockWithoutCompositor() override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool LockInternal();
|
||||
void UnlockInternal();
|
||||
|
||||
RefPtr<ID3D11Device> GetDevice();
|
||||
|
||||
bool OpenSharedHandle();
|
||||
|
||||
RefPtr<ID3D11Texture2D> mTexture;
|
||||
RefPtr<DataTextureSourceD3D11> mTextureSource;
|
||||
RefPtr<CompositorD3D11> mCompositor;
|
||||
gfx::IntSize mSize;
|
||||
WindowsHandle mHandle;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
bool mIsLocked;
|
||||
};
|
||||
|
||||
class DXGIYCbCrTextureHostD3D11 : public TextureHost
|
||||
{
|
||||
public:
|
||||
DXGIYCbCrTextureHostD3D11(TextureFlags aFlags,
|
||||
const SurfaceDescriptorDXGIYCbCr& aDescriptor);
|
||||
|
||||
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
|
||||
|
||||
virtual void DeallocateDeviceData() override{}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override{ return gfx::SurfaceFormat::YUV; }
|
||||
|
||||
// Bug 1305906 fixes YUVColorSpace handling
|
||||
virtual YUVColorSpace GetYUVColorSpace() const override { return YUVColorSpace::BT601; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
RefPtr<ID3D11Device> GetDevice();
|
||||
|
||||
bool OpenSharedHandle();
|
||||
|
||||
RefPtr<ID3D11Texture2D> mTextures[3];
|
||||
RefPtr<DataTextureSourceD3D11> mTextureSources[3];
|
||||
|
||||
RefPtr<CompositorD3D11> mCompositor;
|
||||
gfx::IntSize mSize;
|
||||
WindowsHandle mHandles[3];
|
||||
bool mIsLocked;
|
||||
};
|
||||
|
||||
class CompositingRenderTargetD3D11 : public CompositingRenderTarget,
|
||||
public TextureSourceD3D11
|
||||
{
|
||||
public:
|
||||
CompositingRenderTargetD3D11(ID3D11Texture2D* aTexture,
|
||||
const gfx::IntPoint& aOrigin,
|
||||
DXGI_FORMAT aFormatOverride = DXGI_FORMAT_UNKNOWN);
|
||||
|
||||
virtual const char* Name() const override { return "CompositingRenderTargetD3D11"; }
|
||||
|
||||
virtual TextureSourceD3D11* AsSourceD3D11() override { return this; }
|
||||
|
||||
void BindRenderTarget(ID3D11DeviceContext* aContext);
|
||||
|
||||
virtual gfx::IntSize GetSize() const override;
|
||||
|
||||
void SetSize(const gfx::IntSize& aSize) { mSize = aSize; }
|
||||
|
||||
private:
|
||||
friend class CompositorD3D11;
|
||||
RefPtr<ID3D11RenderTargetView> mRTView;
|
||||
};
|
||||
|
||||
class SyncObjectD3D11 : public SyncObject
|
||||
{
|
||||
public:
|
||||
SyncObjectD3D11(SyncHandle aSyncHandle);
|
||||
virtual void FinalizeFrame();
|
||||
virtual bool IsSyncObjectValid();
|
||||
|
||||
virtual SyncType GetSyncType() { return SyncType::D3D11; }
|
||||
|
||||
void RegisterTexture(ID3D11Texture2D* aTexture);
|
||||
|
||||
private:
|
||||
RefPtr<ID3D11Texture2D> mD3D11Texture;
|
||||
RefPtr<ID3D11Device> mD3D11Device;
|
||||
std::vector<ID3D11Texture2D*> mD3D11SyncedTextures;
|
||||
SyncHandle mHandle;
|
||||
};
|
||||
|
||||
inline uint32_t GetMaxTextureSizeForFeatureLevel(D3D_FEATURE_LEVEL aFeatureLevel)
|
||||
{
|
||||
int32_t maxTextureSize;
|
||||
switch (aFeatureLevel) {
|
||||
case D3D_FEATURE_LEVEL_11_1:
|
||||
case D3D_FEATURE_LEVEL_11_0:
|
||||
maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_10_1:
|
||||
case D3D_FEATURE_LEVEL_10_0:
|
||||
maxTextureSize = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
break;
|
||||
case D3D_FEATURE_LEVEL_9_3:
|
||||
maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
break;
|
||||
default:
|
||||
maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
}
|
||||
return maxTextureSize;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_GFX_TEXTURED3D11_H */
|
||||
50
gfx/layers/d3d11/genshaders.sh
Normal file
50
gfx/layers/d3d11/genshaders.sh
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# 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/.
|
||||
|
||||
tempfile=tmpShaderHeader
|
||||
|
||||
FXC_DEBUG_FLAGS="-Zi -Fd shaders.pdb"
|
||||
FXC_FLAGS=""
|
||||
|
||||
# If DEBUG is in the environment, then rebuild with debug info
|
||||
if [ "$DEBUG" != "" ] ; then
|
||||
FXC_FLAGS="$FXC_DEBUG_FLAGS"
|
||||
fi
|
||||
|
||||
makeShaderVS() {
|
||||
fxc -nologo $FXC_FLAGS -Tvs_4_0_level_9_3 $SRC -E$1 -Vn$1 -Fh$tempfile
|
||||
echo "ShaderBytes s$1 = { $1, sizeof($1) };" >> $tempfile;
|
||||
cat $tempfile >> $DEST
|
||||
}
|
||||
|
||||
makeShaderPS() {
|
||||
fxc -nologo $FXC_FLAGS -Tps_4_0_level_9_3 $SRC -E$1 -Vn$1 -Fh$tempfile
|
||||
echo "ShaderBytes s$1 = { $1, sizeof($1) };" >> $tempfile;
|
||||
cat $tempfile >> $DEST
|
||||
}
|
||||
|
||||
SRC=CompositorD3D11.hlsl
|
||||
DEST=CompositorD3D11Shaders.h
|
||||
|
||||
rm -f $DEST
|
||||
echo "struct ShaderBytes { const void* mData; size_t mLength; };" >> $DEST;
|
||||
makeShaderVS LayerQuadVS
|
||||
makeShaderPS SolidColorShader
|
||||
makeShaderPS RGBShader
|
||||
makeShaderPS RGBAShader
|
||||
makeShaderPS ComponentAlphaShader
|
||||
makeShaderPS YCbCrShader
|
||||
makeShaderVS LayerQuadMaskVS
|
||||
makeShaderPS SolidColorShaderMask
|
||||
makeShaderPS RGBShaderMask
|
||||
makeShaderPS RGBAShaderMask
|
||||
makeShaderPS YCbCrShaderMask
|
||||
makeShaderPS ComponentAlphaShaderMask
|
||||
|
||||
# Mix-blend shaders
|
||||
makeShaderVS LayerQuadBlendVS
|
||||
makeShaderVS LayerQuadBlendMaskVS
|
||||
makeShaderPS BlendShader
|
||||
|
||||
rm $tempfile
|
||||
Loading…
Add table
Add a link
Reference in a new issue