import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View 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_

View 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));
}

File diff suppressed because it is too large Load diff

View 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

View 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;
}

File diff suppressed because it is too large Load diff

View 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);
}
}
}
}

View 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 */

File diff suppressed because it is too large Load diff

View 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 */

View 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