Bug 1730055 - Remove unused Effect types. r=gfx-reviewers,lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D125135
This commit is contained in:
Matt Woodrow 2021-09-22 05:27:20 +00:00
parent 2c01dae384
commit 115faf8e91
20 changed files with 55 additions and 1654 deletions

View File

@ -237,30 +237,6 @@ size_t DecomposeIntoNoRepeatRects(const gfx::Rect& aRect,
return 4;
}
gfx::IntRect Compositor::ComputeBackdropCopyRect(
const gfx::Rect& aRect, const gfx::IntRect& aClipRect,
const gfx::Matrix4x4& aTransform, gfx::Matrix4x4* aOutTransform,
gfx::Rect* aOutLayerQuad) {
// Compute the clip.
RefPtr<CompositingRenderTarget> currentRenderTarget =
GetCurrentRenderTarget();
gfx::IntPoint rtOffset = currentRenderTarget->GetOrigin();
gfx::IntSize rtSize = currentRenderTarget->GetSize();
return layers::ComputeBackdropCopyRect(aRect, aClipRect, aTransform,
gfx::IntRect(rtOffset, rtSize),
aOutTransform, aOutLayerQuad);
}
gfx::IntRect Compositor::ComputeBackdropCopyRect(
const gfx::Triangle& aTriangle, const gfx::IntRect& aClipRect,
const gfx::Matrix4x4& aTransform, gfx::Matrix4x4* aOutTransform,
gfx::Rect* aOutLayerQuad) {
gfx::Rect boundingBox = aTriangle.BoundingBox();
return ComputeBackdropCopyRect(boundingBox, aClipRect, aTransform,
aOutTransform, aOutLayerQuad);
}
void Compositor::UnlockAfterComposition(TextureHost* aTexture) {
TextureSourceProvider::UnlockAfterComposition(aTexture);

View File

@ -356,26 +356,6 @@ class Compositor : public TextureSourceProvider {
already_AddRefed<RecordedFrame> RecordFrame(const TimeStamp& aTimeStamp);
protected:
/**
* Given a layer rect, clip, and transform, compute the area of the backdrop
* that needs to be copied for mix-blending. The output transform translates
* from 0..1 space into the backdrop rect space.
*
* The transformed layer quad is also optionally returned - this is the same
* as the result rect, before rounding.
*/
gfx::IntRect ComputeBackdropCopyRect(const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const gfx::Matrix4x4& aTransform,
gfx::Matrix4x4* aOutTransform,
gfx::Rect* aOutLayerQuad = nullptr);
gfx::IntRect ComputeBackdropCopyRect(const gfx::Triangle& aTriangle,
const gfx::IntRect& aClipRect,
const gfx::Matrix4x4& aTransform,
gfx::Matrix4x4* aOutTransform,
gfx::Rect* aOutLayerQuad = nullptr);
/**
* Whether or not the compositor should be prepared to record frames. While
* this returns true, compositors are expected to maintain a full window

View File

@ -117,16 +117,9 @@ MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DiagnosticTypes)
* See gfx/layers/Effects.h
*/
enum class EffectTypes : uint8_t {
MASK,
BLEND_MODE,
COLOR_MATRIX,
MAX_SECONDARY, // sentinel for the count of secondary effect types
RGB,
YCBCR,
NV12,
COMPONENT_ALPHA,
SOLID_COLOR,
RENDER_TARGET,
MAX // sentinel for the count of all effect types
};

View File

@ -24,39 +24,4 @@ void TexturedEffect::PrintInfo(std::stringstream& aStream,
}
aStream << " [filter=" << mSamplingFilter << "]";
}
void EffectMask::PrintInfo(std::stringstream& aStream, const char* aPrefix) {
aStream << aPrefix << nsPrintfCString("EffectMask (0x%p)", this).get()
<< " [size=" << mSize << "]"
<< " [mask-transform=" << mMaskTransform << "]";
}
void EffectRenderTarget::PrintInfo(std::stringstream& aStream,
const char* aPrefix) {
TexturedEffect::PrintInfo(aStream, aPrefix);
aStream << nsPrintfCString(" [render-target=%p]", mRenderTarget.get()).get();
}
void EffectSolidColor::PrintInfo(std::stringstream& aStream,
const char* aPrefix) {
aStream << aPrefix;
aStream << nsPrintfCString("EffectSolidColor (0x%p) [color=%x]", this,
mColor.ToABGR())
.get();
}
void EffectBlendMode::PrintInfo(std::stringstream& aStream,
const char* aPrefix) {
aStream << aPrefix;
aStream << nsPrintfCString("EffectBlendMode (0x%p) [blendmode=%i]", this,
(int)mBlendMode)
.get();
}
void EffectColorMatrix::PrintInfo(std::stringstream& aStream,
const char* aPrefix) {
aStream << aPrefix;
aStream << nsPrintfCString("EffectColorMatrix (0x%p)", this).get()
<< " [matrix=" << mColorMatrix << "]";
}
}

View File

@ -77,59 +77,6 @@ struct TexturedEffect : public Effect {
gfx::SamplingFilter mSamplingFilter;
};
// Support an alpha mask.
struct EffectMask : public Effect {
EffectMask(TextureSource* aMaskTexture, gfx::IntSize aSize,
const gfx::Matrix4x4& aMaskTransform)
: Effect(EffectTypes::MASK),
mMaskTexture(aMaskTexture),
mSize(aSize),
mMaskTransform(aMaskTransform) {}
void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
TextureSource* mMaskTexture;
gfx::IntSize mSize;
gfx::Matrix4x4 mMaskTransform;
};
struct EffectBlendMode : public Effect {
explicit EffectBlendMode(gfx::CompositionOp aBlendMode)
: Effect(EffectTypes::BLEND_MODE), mBlendMode(aBlendMode) {}
virtual const char* Name() { return "EffectBlendMode"; }
void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
gfx::CompositionOp mBlendMode;
};
// Render to a render target rather than the screen.
struct EffectRenderTarget : public TexturedEffect {
explicit EffectRenderTarget(CompositingRenderTarget* aRenderTarget)
: TexturedEffect(EffectTypes::RENDER_TARGET, aRenderTarget, true,
gfx::SamplingFilter::LINEAR),
mRenderTarget(aRenderTarget) {}
const char* Name() override { return "EffectRenderTarget"; }
void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
RefPtr<CompositingRenderTarget> mRenderTarget;
protected:
EffectRenderTarget(EffectTypes aType, CompositingRenderTarget* aRenderTarget)
: TexturedEffect(aType, aRenderTarget, true, gfx::SamplingFilter::LINEAR),
mRenderTarget(aRenderTarget) {}
};
// Render to a render target rather than the screen.
struct EffectColorMatrix : public Effect {
explicit EffectColorMatrix(gfx::Matrix5x4 aMatrix)
: Effect(EffectTypes::COLOR_MATRIX), mColorMatrix(aMatrix) {}
void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
const gfx::Matrix5x4 mColorMatrix;
};
struct EffectRGB : public TexturedEffect {
EffectRGB(TextureSource* aTexture, bool aPremultiplied,
gfx::SamplingFilter aSamplingFilter, bool aFlipped = false)
@ -167,33 +114,8 @@ struct EffectNV12 : public EffectYCbCr {
const char* Name() override { return "EffectNV12"; }
};
struct EffectComponentAlpha : public TexturedEffect {
EffectComponentAlpha(TextureSource* aOnBlack, TextureSource* aOnWhite,
gfx::SamplingFilter aSamplingFilter)
: TexturedEffect(EffectTypes::COMPONENT_ALPHA, nullptr, false,
aSamplingFilter),
mOnBlack(aOnBlack),
mOnWhite(aOnWhite) {}
const char* Name() override { return "EffectComponentAlpha"; }
TextureSource* mOnBlack;
TextureSource* mOnWhite;
};
struct EffectSolidColor : public Effect {
explicit EffectSolidColor(const gfx::DeviceColor& aColor)
: Effect(EffectTypes::SOLID_COLOR), mColor(aColor) {}
void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
gfx::DeviceColor mColor;
};
struct EffectChain {
RefPtr<Effect> mPrimaryEffect;
EnumeratedArray<EffectTypes, EffectTypes::MAX_SECONDARY, RefPtr<Effect>>
mSecondaryEffects;
};
/**
@ -262,28 +184,6 @@ inline already_AddRefed<TexturedEffect> CreateTexturedEffect(
return result.forget();
}
/**
* Create a textured effect based on aSource format and the presence of
* aSourceOnWhite.
*
* aSourceOnWhite can be null.
*/
inline already_AddRefed<TexturedEffect> CreateTexturedEffect(
TextureSource* aSource, TextureSource* aSourceOnWhite,
const gfx::SamplingFilter aSamplingFilter, bool isAlphaPremultiplied) {
MOZ_ASSERT(aSource);
if (aSourceOnWhite) {
MOZ_ASSERT(aSource->GetFormat() == gfx::SurfaceFormat::R8G8B8X8 ||
aSource->GetFormat() == gfx::SurfaceFormat::B8G8R8X8);
MOZ_ASSERT(aSource->GetFormat() == aSourceOnWhite->GetFormat());
return MakeAndAddRef<EffectComponentAlpha>(aSource, aSourceOnWhite,
aSamplingFilter);
}
return CreateTexturedEffect(aSource->GetFormat(), aSource, aSamplingFilter,
isAlphaPremultiplied);
}
/**
* Create a textured effect based on aSource format.
*
@ -291,7 +191,8 @@ inline already_AddRefed<TexturedEffect> CreateTexturedEffect(
*/
inline already_AddRefed<TexturedEffect> CreateTexturedEffect(
TextureSource* aTexture, const gfx::SamplingFilter aSamplingFilter) {
return CreateTexturedEffect(aTexture, nullptr, aSamplingFilter, true);
return CreateTexturedEffect(aTexture->GetFormat(), aTexture, aSamplingFilter,
true);
}
} // namespace layers

View File

@ -64,43 +64,6 @@ void CompositableHost::SetTextureSourceProvider(
mTextureSourceProvider = aProvider;
}
bool CompositableHost::AddMaskEffect(EffectChain& aEffects,
const gfx::Matrix4x4& aTransform) {
CompositableTextureSourceRef source;
RefPtr<TextureHost> host = GetAsTextureHost();
if (!host) {
NS_WARNING("Using compositable with no valid TextureHost as mask");
return false;
}
if (!host->Lock()) {
NS_WARNING("Failed to lock the mask texture");
return false;
}
if (!host->BindTextureSource(source)) {
NS_WARNING(
"The TextureHost was successfully locked but can't provide a "
"TextureSource");
host->Unlock();
return false;
}
MOZ_ASSERT(source);
RefPtr<EffectMask> effect =
new EffectMask(source, source->GetSize(), aTransform);
aEffects.mSecondaryEffects[EffectTypes::MASK] = effect;
return true;
}
void CompositableHost::RemoveMaskEffect() {
RefPtr<TextureHost> host = GetAsTextureHost();
if (host) {
host->Unlock();
}
}
/* static */
already_AddRefed<CompositableHost> CompositableHost::Create(
const TextureInfo& aTextureInfo) {

View File

@ -131,14 +131,6 @@ class CompositableHost {
const TextureInfo& GetTextureInfo() const { return mTextureInfo; }
/**
* Adds a mask effect using this texture as the mask, if possible.
* @return true if the effect was added, false otherwise.
*/
bool AddMaskEffect(EffectChain& aEffects, const gfx::Matrix4x4& aTransform);
void RemoveMaskEffect();
TextureSourceProvider* GetTextureSourceProvider() const;
Layer* GetLayer() const { return mLayer; }

View File

@ -15,51 +15,4 @@
#define PS_LAYER_COLOR 3
#define PS_LAYER_NV12 4
// 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

@ -1,184 +0,0 @@
/* -*- 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));
}

View File

@ -31,10 +31,10 @@
#include "mozilla/StaticPrefs_gfx.h"
#include "mozilla/StaticPrefs_layers.h"
#include "mozilla/Telemetry.h"
#include "BlendShaderConstants.h"
#include "D3D11ShareHandleImage.h"
#include "DeviceAttachmentsD3D11.h"
#include "BlendShaderConstants.h"
#include <versionhelpers.h> // For IsWindows8OrGreater
#include <winsdkver.h>
@ -122,34 +122,6 @@ void CompositorD3D11::SetVertexBuffer(ID3D11Buffer* aBuffer) {
mContext->IASetVertexBuffers(0, 1, &aBuffer, &size, &offset);
}
bool CompositorD3D11::UpdateDynamicVertexBuffer(
const nsTArray<gfx::TexturedTriangle>& aTriangles) {
HRESULT hr;
// Resize the dynamic vertex buffer if needed.
if (!mAttachments->EnsureTriangleBuffer(aTriangles.Length())) {
return false;
}
D3D11_MAPPED_SUBRESOURCE resource{};
hr = mContext->Map(mAttachments->mDynamicVertexBuffer, 0,
D3D11_MAP_WRITE_DISCARD, 0, &resource);
if (Failed(hr, "map dynamic vertex buffer")) {
return false;
}
const nsTArray<TexturedVertex> vertices =
TexturedTrianglesToVertexArray(aTriangles);
memcpy(resource.pData, vertices.Elements(),
vertices.Length() * sizeof(TexturedVertex));
mContext->Unmap(mAttachments->mDynamicVertexBuffer, 0);
return true;
}
bool CompositorD3D11::Initialize(nsCString* const out_failureReason) {
ScopedGfxFeatureReporter reporter("D3D11 Layers");
@ -528,30 +500,6 @@ bool CompositorD3D11::BlitRenderTarget(CompositingRenderTarget* aSource,
return true;
}
bool CompositorD3D11::CopyBackdrop(const gfx::IntRect& aRect,
RefPtr<ID3D11Texture2D>* aOutTexture,
RefPtr<ID3D11ShaderResourceView>* aOutView) {
RefPtr<ID3D11Texture2D> texture =
CreateTexture(aRect, mCurrentRT, aRect.TopLeft());
if (!texture) {
return false;
}
CD3D11_SHADER_RESOURCE_VIEW_DESC desc(D3D11_SRV_DIMENSION_TEXTURE2D,
DXGI_FORMAT_B8G8R8A8_UNORM);
RefPtr<ID3D11ShaderResourceView> srv;
HRESULT hr =
mDevice->CreateShaderResourceView(texture, &desc, getter_AddRefs(srv));
if (FAILED(hr) || !srv) {
return false;
}
*aOutTexture = texture.forget();
*aOutView = srv.forget();
return true;
}
void CompositorD3D11::SetRenderTarget(CompositingRenderTarget* aRenderTarget) {
MOZ_ASSERT(aRenderTarget);
CompositingRenderTargetD3D11* newRT =
@ -572,32 +520,20 @@ void CompositorD3D11::SetRenderTarget(CompositingRenderTarget* aRenderTarget) {
}
}
ID3D11PixelShader* CompositorD3D11::GetPSForEffect(Effect* aEffect,
const bool aUseBlendShader,
const MaskType aMaskType) {
if (aUseBlendShader) {
return mAttachments->mBlendShader[MaskType::MaskNone];
}
ID3D11PixelShader* CompositorD3D11::GetPSForEffect(Effect* aEffect) {
switch (aEffect->mType) {
case EffectTypes::SOLID_COLOR:
return mAttachments->mSolidColorShader[aMaskType];
case EffectTypes::RENDER_TARGET:
return mAttachments->mRGBAShader[aMaskType];
case EffectTypes::RGB: {
SurfaceFormat format =
static_cast<TexturedEffect*>(aEffect)->mTexture->GetFormat();
return (format == SurfaceFormat::B8G8R8A8 ||
format == SurfaceFormat::R8G8B8A8)
? mAttachments->mRGBAShader[aMaskType]
: mAttachments->mRGBShader[aMaskType];
? mAttachments->mRGBAShader
: mAttachments->mRGBShader;
}
case EffectTypes::NV12:
return mAttachments->mNV12Shader[aMaskType];
return mAttachments->mNV12Shader;
case EffectTypes::YCBCR:
return mAttachments->mYCbCrShader[aMaskType];
case EffectTypes::COMPONENT_ALPHA:
return mAttachments->mComponentAlphaShader[aMaskType];
return mAttachments->mYCbCrShader;
default:
NS_WARNING("No shader to load");
return nullptr;
@ -627,11 +563,9 @@ void CompositorD3D11::ClearRect(const gfx::Rect& aRect) {
scissor.bottom = aRect.YMost();
mContext->RSSetScissorRects(1, &scissor);
mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
mContext->VSSetShader(mAttachments->mVSQuadShader[MaskType::MaskNone],
nullptr, 0);
mContext->VSSetShader(mAttachments->mVSQuadShader, nullptr, 0);
mContext->PSSetShader(mAttachments->mSolidColorShader[MaskType::MaskNone],
nullptr, 0);
mContext->PSSetShader(mAttachments->mSolidColorShader, nullptr, 0);
mPSConstants.layerColor[0] = 0;
mPSConstants.layerColor[1] = 0;
mPSConstants.layerColor[2] = 0;
@ -649,78 +583,12 @@ void CompositorD3D11::ClearRect(const gfx::Rect& aRect) {
0xFFFFFFFF);
}
static inline bool EffectHasPremultipliedAlpha(Effect* aEffect) {
if (aEffect->mType == EffectTypes::RGB) {
return static_cast<TexturedEffect*>(aEffect)->mPremultiplied;
}
return true;
}
static inline int EffectToBlendLayerType(Effect* aEffect) {
switch (aEffect->mType) {
case EffectTypes::SOLID_COLOR:
return PS_LAYER_COLOR;
case EffectTypes::RGB: {
gfx::SurfaceFormat format =
static_cast<TexturedEffect*>(aEffect)->mTexture->GetFormat();
return (format == gfx::SurfaceFormat::B8G8R8A8 ||
format == gfx::SurfaceFormat::R8G8B8A8)
? PS_LAYER_RGBA
: PS_LAYER_RGB;
}
case EffectTypes::RENDER_TARGET:
return PS_LAYER_RGBA;
case EffectTypes::YCBCR:
return PS_LAYER_YCBCR;
case EffectTypes::NV12:
return PS_LAYER_NV12;
default:
MOZ_ASSERT_UNREACHABLE("blending not supported for this layer type");
return 0;
}
}
void CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect) {
DrawGeometry(aRect, aRect, aClipRect, aEffectChain, aOpacity, aTransform,
aVisibleRect);
}
void CompositorD3D11::PrepareDynamicVertexBuffer() {
mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
mContext->IASetInputLayout(mAttachments->mDynamicInputLayout);
SetVertexBuffer<TexturedVertex>(mAttachments->mDynamicVertexBuffer);
}
void CompositorD3D11::PrepareStaticVertexBuffer() {
mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
mContext->IASetInputLayout(mAttachments->mInputLayout);
SetVertexBuffer<Vertex>(mAttachments->mVertexBuffer);
}
void CompositorD3D11::Draw(const nsTArray<gfx::TexturedTriangle>& aTriangles,
const gfx::Rect*) {
if (!UpdateConstantBuffers()) {
NS_WARNING("Failed to update shader constant buffers");
return;
}
PrepareDynamicVertexBuffer();
if (!UpdateDynamicVertexBuffer(aTriangles)) {
NS_WARNING("Failed to update shader dynamic buffers");
return;
}
mContext->Draw(3 * aTriangles.Length(), 0);
PrepareStaticVertexBuffer();
}
void CompositorD3D11::Draw(const gfx::Rect& aRect,
const gfx::Rect* aTexCoords) {
Rect layerRects[4] = {aRect};
@ -745,28 +613,12 @@ void CompositorD3D11::Draw(const gfx::Rect& aRect,
}
}
ID3D11VertexShader* CompositorD3D11::GetVSForGeometry(
const nsTArray<gfx::TexturedTriangle>& aTriangles,
const bool aUseBlendShaders, const MaskType aMaskType) {
return aUseBlendShaders ? mAttachments->mVSDynamicBlendShader[aMaskType]
: mAttachments->mVSDynamicShader[aMaskType];
}
ID3D11VertexShader* CompositorD3D11::GetVSForGeometry(
const gfx::Rect& aRect, const bool aUseBlendShaders,
const MaskType aMaskType) {
return aUseBlendShaders ? mAttachments->mVSQuadBlendShader[aMaskType]
: mAttachments->mVSQuadShader[aMaskType];
}
template <typename Geometry>
void CompositorD3D11::DrawGeometry(const Geometry& aGeometry,
const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect) {
void CompositorD3D11::DrawQuad(const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain,
gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect) {
if (mCurrentClip.IsEmpty()) {
return;
}
@ -780,39 +632,6 @@ void CompositorD3D11::DrawGeometry(const Geometry& aGeometry,
mPSConstants.layerOpacity[0] = aOpacity;
bool restoreBlendMode = false;
MaskType maskType = MaskType::MaskNone;
if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) {
maskType = MaskType::Mask;
EffectMask* maskEffect = static_cast<EffectMask*>(
aEffectChain.mSecondaryEffects[EffectTypes::MASK].get());
TextureSourceD3D11* source = maskEffect->mMaskTexture->AsSourceD3D11();
if (!source) {
NS_WARNING("Missing texture source!");
return;
}
ID3D11ShaderResourceView* srView = source->GetShaderResourceView();
mContext->PSSetShaderResources(TexSlot::Mask, 1, &srView);
const gfx::Matrix4x4& maskTransform = maskEffect->mMaskTransform;
NS_ASSERTION(maskTransform.Is2D(),
"How did we end up with a 3D transform here?!");
Rect bounds = Rect(Point(), Size(maskEffect->mSize));
bounds = maskTransform.As2D().TransformBounds(bounds);
Matrix4x4 transform;
transform._11 = 1.0f / bounds.Width();
transform._22 = 1.0f / bounds.Height();
transform._41 = float(-bounds.X()) / bounds.Width();
transform._42 = float(-bounds.Y()) / bounds.Height();
memcpy(mVSConstants.maskTransform, &transform._11, 64);
}
D3D11_RECT scissor;
IntRect clipRect(aClipRect.X(), aClipRect.Y(), aClipRect.Width(),
@ -830,48 +649,14 @@ void CompositorD3D11::DrawGeometry(const Geometry& aGeometry,
scissor.top = clipRect.Y();
scissor.bottom = clipRect.YMost();
bool useBlendShaders = false;
RefPtr<ID3D11Texture2D> mixBlendBackdrop;
gfx::CompositionOp blendMode = gfx::CompositionOp::OP_OVER;
if (aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE]) {
EffectBlendMode* blendEffect = static_cast<EffectBlendMode*>(
aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get());
blendMode = blendEffect->mBlendMode;
// If the blend operation needs to read from the backdrop, copy the
// current render target into a new texture and bind it now.
if (BlendOpIsMixBlendMode(blendMode)) {
gfx::Matrix4x4 backdropTransform;
gfx::IntRect rect = ComputeBackdropCopyRect(aRect, aClipRect, aTransform,
&backdropTransform);
RefPtr<ID3D11ShaderResourceView> srv;
if (CopyBackdrop(rect, &mixBlendBackdrop, &srv) &&
mAttachments->InitBlendShaders()) {
useBlendShaders = true;
ID3D11ShaderResourceView* srView = srv.get();
mContext->PSSetShaderResources(TexSlot::Backdrop, 1, &srView);
memcpy(&mVSConstants.backdropTransform, &backdropTransform._11, 64);
mPSConstants.blendConfig[0] =
EffectToBlendLayerType(aEffectChain.mPrimaryEffect);
mPSConstants.blendConfig[1] = int(maskType);
mPSConstants.blendConfig[2] = BlendOpToShaderConstant(blendMode);
mPSConstants.blendConfig[3] =
EffectHasPremultipliedAlpha(aEffectChain.mPrimaryEffect);
}
}
}
bool restoreBlendMode = false;
mContext->RSSetScissorRects(1, &scissor);
RefPtr<ID3D11VertexShader> vertexShader =
GetVSForGeometry(aGeometry, useBlendShaders, maskType);
RefPtr<ID3D11VertexShader> vertexShader = mAttachments->mVSQuadShader;
RefPtr<ID3D11PixelShader> pixelShader =
GetPSForEffect(aEffectChain.mPrimaryEffect, useBlendShaders, maskType);
GetPSForEffect(aEffectChain.mPrimaryEffect);
mContext->VSSetShader(vertexShader, nullptr, 0);
mContext->PSSetShader(pixelShader, nullptr, 0);
@ -879,17 +664,7 @@ void CompositorD3D11::DrawGeometry(const Geometry& aGeometry,
const Rect* pTexCoordRect = nullptr;
switch (aEffectChain.mPrimaryEffect->mType) {
case EffectTypes::SOLID_COLOR: {
DeviceColor color =
static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get())
->mColor;
mPSConstants.layerColor[0] = color.r * color.a * aOpacity;
mPSConstants.layerColor[1] = color.g * color.a * aOpacity;
mPSConstants.layerColor[2] = color.b * color.a * aOpacity;
mPSConstants.layerColor[3] = color.a * aOpacity;
} break;
case EffectTypes::RGB:
case EffectTypes::RENDER_TARGET: {
case EffectTypes::RGB: {
TexturedEffect* texturedEffect =
static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
@ -1010,42 +785,12 @@ void CompositorD3D11::DrawGeometry(const Geometry& aGeometry,
sourceCr->GetShaderResourceView()};
mContext->PSSetShaderResources(TexSlot::Y, 3, srViews);
} break;
case EffectTypes::COMPONENT_ALPHA: {
MOZ_ASSERT(LayerManager::LayersComponentAlphaEnabled());
MOZ_ASSERT(mAttachments->mComponentBlendState);
EffectComponentAlpha* effectComponentAlpha =
static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
TextureSourceD3D11* sourceOnWhite =
effectComponentAlpha->mOnWhite->AsSourceD3D11();
TextureSourceD3D11* sourceOnBlack =
effectComponentAlpha->mOnBlack->AsSourceD3D11();
if (!sourceOnWhite || !sourceOnBlack) {
NS_WARNING("Missing texture source(s)!");
return;
}
SetSamplerForSamplingFilter(effectComponentAlpha->mSamplingFilter);
pTexCoordRect = &effectComponentAlpha->mTextureCoords;
ID3D11ShaderResourceView* srViews[2] = {
sourceOnBlack->GetShaderResourceView(),
sourceOnWhite->GetShaderResourceView()};
mContext->PSSetShaderResources(TexSlot::RGB, 1, &srViews[0]);
mContext->PSSetShaderResources(TexSlot::RGBWhite, 1, &srViews[1]);
mContext->OMSetBlendState(mAttachments->mComponentBlendState,
sBlendFactor, 0xFFFFFFFF);
restoreBlendMode = true;
} break;
default:
NS_WARNING("Unknown shader type");
return;
}
Draw(aGeometry, pTexCoordRect);
Draw(aRect, pTexCoordRect);
if (restoreBlendMode) {
mContext->OMSetBlendState(mAttachments->mPremulBlendState, sBlendFactor,

View File

@ -142,8 +142,7 @@ class CompositorD3D11 : public Compositor {
bool UpdateConstantBuffers();
void SetSamplerForSamplingFilter(gfx::SamplingFilter aSamplingFilter);
ID3D11PixelShader* GetPSForEffect(Effect* aEffect, const bool aUseBlendShader,
const MaskType aMaskType);
ID3D11PixelShader* GetPSForEffect(Effect* aEffect);
Maybe<gfx::IntRect> BeginFrame(const nsIntRegion& aInvalidRegion,
const Maybe<gfx::IntRect>& aClipRect,
const gfx::IntRect& aRenderBounds,
@ -152,39 +151,13 @@ class CompositorD3D11 : public Compositor {
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);
template <typename Geometry>
void DrawGeometry(const Geometry& aGeometry, const gfx::Rect& aRect,
const gfx::IntRect& aClipRect,
const EffectChain& aEffectChain, gfx::Float aOpacity,
const gfx::Matrix4x4& aTransform,
const gfx::Rect& aVisibleRect);
bool UpdateDynamicVertexBuffer(
const nsTArray<gfx::TexturedTriangle>& aTriangles);
void PrepareDynamicVertexBuffer();
void PrepareStaticVertexBuffer();
// Overloads for rendering both rects and triangles with same rendering path
void Draw(const nsTArray<gfx::TexturedTriangle>& aGeometry,
const gfx::Rect* aTexCoords);
void Draw(const gfx::Rect& aGeometry, const gfx::Rect* aTexCoords);
void Present();
ID3D11VertexShader* GetVSForGeometry(
const nsTArray<gfx::TexturedTriangle>& aTriangles,
const bool aUseBlendShader, const MaskType aMaskType);
ID3D11VertexShader* GetVSForGeometry(const gfx::Rect& aRect,
const bool aUseBlendShader,
const MaskType aMaskType);
template <typename VertexType>
void SetVertexBuffer(ID3D11Buffer* aBuffer);

View File

@ -3,7 +3,6 @@
* 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;
@ -13,8 +12,6 @@ float4x4 mProjection : register(vs, c4);
float4 vRenderTargetOffset : register(vs, c8);
rect vTextureCoords : register(vs, c9);
rect vLayerQuad : register(vs, c10);
float4x4 mMaskTransform : register(vs, c11);
float4x4 mBackdropTransform : register(vs, c15);
float4 fLayerColor : register(ps, c0);
float fLayerOpacity : register(ps, c1);
@ -23,7 +20,6 @@ float fLayerOpacity : register(ps, c1);
// y = mask type
// z = blend op
// w = is premultiplied
uint4 iBlendConfig : register(ps, c2);
float fCoefficient : register(ps, c3);
@ -37,9 +33,6 @@ 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;
@ -55,20 +48,6 @@ struct VS_OUTPUT {
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;
@ -125,16 +104,6 @@ float4 VertexPosition(float4 aTransformedPosition)
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;
@ -146,75 +115,6 @@ VS_OUTPUT LayerQuadVS(const VS_INPUT aVertex)
return outp;
}
float3 MaskCoords(float4 aPosition)
{
// 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
return float3(mul(mMaskTransform, (aPosition / aPosition.w)).xy, 1.0) * aPosition.w;
}
VS_MASK_OUTPUT LayerQuadMaskVS(const VS_INPUT aVertex)
{
float4 position = TransformedPosition(aVertex.vPosition);
VS_MASK_OUTPUT outp;
outp.vPosition = VertexPosition(position);
outp.vMaskCoords = MaskCoords(position);
outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
return outp;
}
VS_OUTPUT LayerDynamicVS(const VS_TEX_INPUT aVertex)
{
VS_OUTPUT outp;
float4 position = float4(aVertex.vPosition, 0, 1);
position = mul(mLayerTransform, position);
outp.vPosition = VertexPosition(position);
outp.vTexCoords = aVertex.vTexCoords;
return outp;
}
VS_MASK_OUTPUT LayerDynamicMaskVS(const VS_TEX_INPUT aVertex)
{
VS_MASK_OUTPUT outp;
float4 position = float4(aVertex.vPosition, 0, 1);
position = mul(mLayerTransform, position);
outp.vPosition = VertexPosition(position);
// calculate the position on the mask texture
outp.vMaskCoords = MaskCoords(position);
outp.vTexCoords = aVertex.vTexCoords;
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]
@ -257,49 +157,11 @@ float4 CalculateNV12Color(const float2 aTexCoords)
return float4(mul(mYuvColorMatrix, yuv), 1.0);
}
float4 YCbCrShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
float4 SolidColorShader(const VS_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;
return fLayerColor;
}
float4 NV12ShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
{
float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
float mask = tMask.Sample(sSampler, maskCoords).r;
return CalculateNV12Color(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;
@ -322,182 +184,3 @@ float4 NV12Shader(const VS_OUTPUT aVertex) : SV_Target
{
return CalculateNV12Color(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;
}
VS_BLEND_OUTPUT LayerDynamicBlendVS(const VS_TEX_INPUT aVertex)
{
VS_OUTPUT v = LayerDynamicVS(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 LayerDynamicBlendMaskVS(const VS_TEX_INPUT aVertex)
{
VS_MASK_OUTPUT v = LayerDynamicMaskVS(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);
} else if (iBlendConfig.x == PS_LAYER_NV12) {
return NV12Shader(tmp);
} else {
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);
} else if (iBlendConfig.x == PS_LAYER_NV12) {
return NV12ShaderMask(tmp);
} else {
return SolidColorShaderMask(tmp);
}
} else {
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;
}

View File

@ -16,11 +16,8 @@ namespace layers {
using namespace gfx;
static const size_t kInitialMaximumTriangles = 64;
DeviceAttachmentsD3D11::DeviceAttachmentsD3D11(ID3D11Device* device)
: mMaximumTriangles(kInitialMaximumTriangles),
mDevice(device),
: mDevice(device),
mContinueInit(true),
mInitialized(false),
mDeviceReset(false) {}
@ -64,37 +61,6 @@ bool DeviceAttachmentsD3D11::Initialize() {
mInitFailureId = "FEATURE_FAILURE_D3D11_VERTEX_BUFFER";
return false;
}
// Create a second input layout for layers with dynamic geometry.
D3D11_INPUT_ELEMENT_DESC dynamicLayout[] = {
{"POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0,
D3D11_INPUT_PER_VERTEX_DATA, 0},
{"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8,
D3D11_INPUT_PER_VERTEX_DATA, 0},
};
hr = mDevice->CreateInputLayout(
dynamicLayout, sizeof(dynamicLayout) / sizeof(D3D11_INPUT_ELEMENT_DESC),
LayerDynamicVS, sizeof(LayerDynamicVS),
getter_AddRefs(mDynamicInputLayout));
if (Failed(hr, "CreateInputLayout")) {
mInitFailureId = "FEATURE_FAILURE_D3D11_INPUT_LAYOUT";
return false;
}
// Allocate memory for the dynamic vertex buffer.
bufferDesc = CD3D11_BUFFER_DESC(
sizeof(TexturedVertex) * mMaximumTriangles * 3, D3D11_BIND_VERTEX_BUFFER,
D3D11_USAGE_DYNAMIC, D3D11_CPU_ACCESS_WRITE);
hr = mDevice->CreateBuffer(&bufferDesc, nullptr,
getter_AddRefs(mDynamicVertexBuffer));
if (Failed(hr, "create dynamic vertex buffer")) {
mInitFailureId = "FEATURE_FAILURE_D3D11_VERTEX_BUFFER";
return false;
}
if (!CreateShaders()) {
mInitFailureId = "FEATURE_FAILURE_D3D11_CREATE_SHADERS";
return false;
@ -194,25 +160,6 @@ bool DeviceAttachmentsD3D11::Initialize() {
return false;
}
if (LayerManager::LayersComponentAlphaEnabled()) {
D3D11_RENDER_TARGET_BLEND_DESC rtBlendComponent = {
TRUE,
D3D11_BLEND_ONE,
D3D11_BLEND_INV_SRC1_COLOR,
D3D11_BLEND_OP_ADD,
D3D11_BLEND_ONE,
D3D11_BLEND_INV_SRC_ALPHA,
D3D11_BLEND_OP_ADD,
D3D11_COLOR_WRITE_ENABLE_ALL};
blendDesc.RenderTarget[0] = rtBlendComponent;
hr = mDevice->CreateBlendState(&blendDesc,
getter_AddRefs(mComponentBlendState));
if (Failed(hr, "create component blender")) {
mInitFailureId = "FEATURE_FAILURE_D3D11_COMP_BLENDER";
return false;
}
}
D3D11_RENDER_TARGET_BLEND_DESC rtBlendDisabled = {
FALSE,
D3D11_BLEND_SRC_ALPHA,
@ -254,49 +201,14 @@ bool DeviceAttachmentsD3D11::InitSyncObject() {
return mSyncObject->Init();
}
bool DeviceAttachmentsD3D11::InitBlendShaders() {
if (!mVSQuadBlendShader[MaskType::MaskNone]) {
InitVertexShader(sLayerQuadBlendVS, mVSQuadBlendShader, MaskType::MaskNone);
InitVertexShader(sLayerQuadBlendMaskVS, mVSQuadBlendShader, MaskType::Mask);
}
if (!mVSDynamicBlendShader[MaskType::MaskNone]) {
InitVertexShader(sLayerDynamicBlendVS, mVSDynamicBlendShader,
MaskType::MaskNone);
InitVertexShader(sLayerDynamicBlendMaskVS, mVSDynamicBlendShader,
MaskType::Mask);
}
if (!mBlendShader[MaskType::MaskNone]) {
InitPixelShader(sBlendShader, mBlendShader, MaskType::MaskNone);
}
return mContinueInit;
}
bool DeviceAttachmentsD3D11::CreateShaders() {
InitVertexShader(sLayerQuadVS, mVSQuadShader, MaskType::MaskNone);
InitVertexShader(sLayerQuadMaskVS, mVSQuadShader, MaskType::Mask);
InitVertexShader(sLayerDynamicVS, mVSDynamicShader, MaskType::MaskNone);
InitVertexShader(sLayerDynamicMaskVS, mVSDynamicShader, MaskType::Mask);
InitPixelShader(sSolidColorShader, mSolidColorShader, MaskType::MaskNone);
InitPixelShader(sSolidColorShaderMask, mSolidColorShader, MaskType::Mask);
InitPixelShader(sRGBShader, mRGBShader, MaskType::MaskNone);
InitPixelShader(sRGBShaderMask, mRGBShader, MaskType::Mask);
InitPixelShader(sRGBAShader, mRGBAShader, MaskType::MaskNone);
InitPixelShader(sRGBAShaderMask, mRGBAShader, MaskType::Mask);
InitPixelShader(sYCbCrShader, mYCbCrShader, MaskType::MaskNone);
InitPixelShader(sYCbCrShaderMask, mYCbCrShader, MaskType::Mask);
InitPixelShader(sNV12Shader, mNV12Shader, MaskType::MaskNone);
InitPixelShader(sNV12ShaderMask, mNV12Shader, MaskType::Mask);
if (LayerManager::LayersComponentAlphaEnabled()) {
InitPixelShader(sComponentAlphaShader, mComponentAlphaShader,
MaskType::MaskNone);
InitPixelShader(sComponentAlphaShaderMask, mComponentAlphaShader,
MaskType::Mask);
}
InitVertexShader(sLayerQuadVS, mVSQuadShader);
InitPixelShader(sSolidColorShader, mSolidColorShader);
InitPixelShader(sRGBShader, mRGBShader);
InitPixelShader(sRGBAShader, mRGBAShader);
InitPixelShader(sYCbCrShader, mYCbCrShader);
InitPixelShader(sNV12Shader, mNV12Shader);
return mContinueInit;
}
@ -333,25 +245,5 @@ bool DeviceAttachmentsD3D11::Failed(HRESULT hr, const char* aContext) {
return true;
}
bool DeviceAttachmentsD3D11::EnsureTriangleBuffer(size_t aNumTriangles) {
if (aNumTriangles > mMaximumTriangles) {
CD3D11_BUFFER_DESC bufferDesc(sizeof(TexturedVertex) * aNumTriangles * 3,
D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_DYNAMIC,
D3D11_CPU_ACCESS_WRITE);
HRESULT hr = mDevice->CreateBuffer(&bufferDesc, nullptr,
getter_AddRefs(mDynamicVertexBuffer));
if (Failed(hr, "resize dynamic vertex buffer")) {
return false;
}
mMaximumTriangles = aNumTriangles;
}
MOZ_ASSERT(mMaximumTriangles >= aNumTriangles);
return true;
}
} // namespace layers
} // namespace mozilla

View File

@ -26,41 +26,23 @@ class DeviceAttachmentsD3D11 final {
public:
static RefPtr<DeviceAttachmentsD3D11> Create(ID3D11Device* aDevice);
bool InitBlendShaders();
bool EnsureTriangleBuffer(size_t aNumTriangles);
bool IsValid() const { return mInitialized; }
const nsCString& GetFailureId() const {
MOZ_ASSERT(!IsValid());
return mInitFailureId;
}
typedef EnumeratedArray<MaskType, MaskType::NumMaskTypes,
RefPtr<ID3D11VertexShader>>
VertexShaderArray;
typedef EnumeratedArray<MaskType, MaskType::NumMaskTypes,
RefPtr<ID3D11PixelShader>>
PixelShaderArray;
RefPtr<ID3D11InputLayout> mInputLayout;
RefPtr<ID3D11InputLayout> mDynamicInputLayout;
RefPtr<ID3D11Buffer> mVertexBuffer;
RefPtr<ID3D11Buffer> mDynamicVertexBuffer;
VertexShaderArray mVSQuadShader;
VertexShaderArray mVSQuadBlendShader;
RefPtr<ID3D11VertexShader> mVSQuadShader;
VertexShaderArray mVSDynamicShader;
VertexShaderArray mVSDynamicBlendShader;
PixelShaderArray mSolidColorShader;
PixelShaderArray mRGBAShader;
PixelShaderArray mRGBShader;
PixelShaderArray mYCbCrShader;
PixelShaderArray mNV12Shader;
PixelShaderArray mComponentAlphaShader;
PixelShaderArray mBlendShader;
RefPtr<ID3D11PixelShader> mSolidColorShader;
RefPtr<ID3D11PixelShader> mRGBAShader;
RefPtr<ID3D11PixelShader> mRGBShader;
RefPtr<ID3D11PixelShader> mYCbCrShader;
RefPtr<ID3D11PixelShader> mNV12Shader;
RefPtr<ID3D11Buffer> mPSConstantBuffer;
RefPtr<ID3D11Buffer> mVSConstantBuffer;
RefPtr<ID3D11RasterizerState> mRasterizerState;
@ -70,7 +52,6 @@ class DeviceAttachmentsD3D11 final {
RefPtr<ID3D11BlendState> mPremulBlendState;
RefPtr<ID3D11BlendState> mPremulCopyState;
RefPtr<ID3D11BlendState> mNonPremulBlendState;
RefPtr<ID3D11BlendState> mComponentBlendState;
RefPtr<ID3D11BlendState> mDisabledBlendState;
RefPtr<SyncObjectHost> mSyncObject;
@ -86,13 +67,13 @@ class DeviceAttachmentsD3D11 final {
bool CreateShaders();
bool InitSyncObject();
void InitVertexShader(const ShaderBytes& aShader, VertexShaderArray& aArray,
MaskType aMaskType) {
InitVertexShader(aShader, getter_AddRefs(aArray[aMaskType]));
void InitVertexShader(const ShaderBytes& aShader,
RefPtr<ID3D11VertexShader>& aDest) {
InitVertexShader(aShader, getter_AddRefs(aDest));
}
void InitPixelShader(const ShaderBytes& aShader, PixelShaderArray& aArray,
MaskType aMaskType) {
InitPixelShader(aShader, getter_AddRefs(aArray[aMaskType]));
void InitPixelShader(const ShaderBytes& aShader,
RefPtr<ID3D11PixelShader>& aDest) {
InitPixelShader(aShader, getter_AddRefs(aDest));
}
void InitVertexShader(const ShaderBytes& aShader, ID3D11VertexShader** aOut);
@ -101,8 +82,6 @@ class DeviceAttachmentsD3D11 final {
bool Failed(HRESULT hr, const char* aContext);
private:
size_t mMaximumTriangles;
// Only used during initialization.
RefPtr<ID3D11Device> mDevice;
bool mContinueInit;

View File

@ -2,13 +2,6 @@
file: CompositorD3D11.hlsl
shaders:
- LayerQuadVS
- LayerDynamicVS
- LayerQuadMaskVS
- LayerDynamicMaskVS
- LayerQuadBlendVS
- LayerQuadBlendMaskVS
- LayerDynamicBlendVS
- LayerDynamicBlendMaskVS
- type: ps_4_0_level_9_3
file: CompositorD3D11.hlsl
@ -16,13 +9,5 @@
- SolidColorShader
- RGBShader
- RGBAShader
- ComponentAlphaShader
- YCbCrShader
- NV12Shader
- SolidColorShaderMask
- RGBShaderMask
- RGBAShaderMask
- YCbCrShaderMask
- NV12ShaderMask
- ComponentAlphaShaderMask
- BlendShader

View File

@ -164,28 +164,6 @@ PerUnitTexturePoolOGL::PerUnitTexturePoolOGL(gl::GLContext* aGL)
PerUnitTexturePoolOGL::~PerUnitTexturePoolOGL() { DestroyTextures(); }
static void BindMaskForProgram(ShaderProgramOGL* aProgram,
TextureSourceOGL* aSourceMask, GLenum aTexUnit,
const gfx::Matrix4x4& aTransform) {
MOZ_ASSERT(LOCAL_GL_TEXTURE0 <= aTexUnit && aTexUnit <= LOCAL_GL_TEXTURE31);
aSourceMask->BindTexture(aTexUnit, gfx::SamplingFilter::LINEAR);
aProgram->SetMaskTextureUnit(aTexUnit - LOCAL_GL_TEXTURE0);
aProgram->SetMaskLayerTransform(aTransform);
}
void CompositorOGL::BindBackdrop(ShaderProgramOGL* aProgram, GLuint aBackdrop,
GLenum aTexUnit) {
MOZ_ASSERT(aBackdrop);
mGLContext->fActiveTexture(aTexUnit);
mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, aBackdrop);
mGLContext->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER,
LOCAL_GL_LINEAR);
mGLContext->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER,
LOCAL_GL_LINEAR);
aProgram->SetBackdropTextureUnit(aTexUnit - LOCAL_GL_TEXTURE0);
}
CompositorOGL::CompositorOGL(widget::CompositorWidget* aWidget,
int aSurfaceWidth, int aSurfaceHeight,
bool aUseExternalSurfaceSize)
@ -413,8 +391,9 @@ bool CompositorOGL::Initialize(nsCString* const out_failureReason) {
mGLContext->fEnable(LOCAL_GL_BLEND);
// initialise a common shader to check that we can actually compile a shader
RefPtr<EffectSolidColor> effect =
new EffectSolidColor(DeviceColor(0, 0, 0, 0));
RefPtr<EffectNV12> effect =
new EffectNV12(nullptr, YUVColorSpace::BT601, ColorRange::LIMITED,
ColorDepth::COLOR_8, SamplingFilter::GOOD);
ShaderConfigOGL config = GetShaderConfigFor(effect);
if (!GetShaderProgramFor(config)) {
*out_failureReason = "FEATURE_FAILURE_OPENGL_COMPILE_SHADER";
@ -1008,16 +987,10 @@ GLuint CompositorOGL::CreateTexture(const IntRect& aRect, bool aCopyFromSource,
}
ShaderConfigOGL CompositorOGL::GetShaderConfigFor(Effect* aEffect,
TextureSourceOGL* aSourceMask,
gfx::CompositionOp aOp,
bool aColorMatrix,
bool aDEAAEnabled) const {
ShaderConfigOGL config;
switch (aEffect->mType) {
case EffectTypes::SOLID_COLOR:
config.SetRenderColor(true);
break;
case EffectTypes::YCBCR: {
config.SetYCbCr(true);
EffectYCbCr* effectYCbCr = static_cast<EffectYCbCr*>(aEffect);
@ -1035,20 +1008,6 @@ ShaderConfigOGL CompositorOGL::GetShaderConfigFor(Effect* aEffect,
config.SetTextureTarget(LOCAL_GL_TEXTURE_2D);
}
break;
case EffectTypes::COMPONENT_ALPHA: {
config.SetComponentAlpha(true);
EffectComponentAlpha* effectComponentAlpha =
static_cast<EffectComponentAlpha*>(aEffect);
gfx::SurfaceFormat format = effectComponentAlpha->mOnWhite->GetFormat();
config.SetRBSwap(format == gfx::SurfaceFormat::B8G8R8A8 ||
format == gfx::SurfaceFormat::B8G8R8X8);
TextureSourceOGL* source = effectComponentAlpha->mOnWhite->AsSourceOGL();
config.SetTextureTarget(source->GetTextureTarget());
break;
}
case EffectTypes::RENDER_TARGET:
config.SetTextureTarget(mFBOTextureTarget);
break;
default: {
MOZ_ASSERT(aEffect->mType == EffectTypes::RGB);
TexturedEffect* texturedEffect = static_cast<TexturedEffect*>(aEffect);
@ -1074,13 +1033,7 @@ ShaderConfigOGL CompositorOGL::GetShaderConfigFor(Effect* aEffect,
break;
}
}
config.SetColorMatrix(aColorMatrix);
config.SetMask(!!aSourceMask);
if (aSourceMask) {
config.SetMaskTextureTarget(aSourceMask->GetTextureTarget());
}
config.SetDEAA(aDEAAEnabled);
config.SetCompositionOp(aOp);
return config;
}
@ -1193,26 +1146,6 @@ void CompositorOGL::DrawGeometry(const Geometry& aGeometry,
return;
}
EffectMask* effectMask;
Rect maskBounds;
if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) {
effectMask = static_cast<EffectMask*>(
aEffectChain.mSecondaryEffects[EffectTypes::MASK].get());
// We're assuming that the gl backend won't cheat and use NPOT
// textures when glContext says it can't (which seems to happen
// on a mac when you force POT textures)
IntSize maskSize = CalculatePOTSize(effectMask->mSize, mGLContext);
const gfx::Matrix4x4& maskTransform = effectMask->mMaskTransform;
NS_ASSERTION(maskTransform.Is2D(),
"How did we end up with a 3D transform here?!");
maskBounds = Rect(Point(), Size(maskSize));
maskBounds = maskTransform.As2D().TransformBounds(maskBounds);
clipRect = clipRect.Intersect(RoundedOut(maskBounds));
}
// Move clipRect into device space.
IntPoint offset = mCurrentRenderTarget->GetOrigin();
clipRect -= offset;
@ -1226,62 +1159,13 @@ void CompositorOGL::DrawGeometry(const Geometry& aGeometry,
FlipY(clipRect.Y() + clipRect.Height()),
clipRect.Width(), clipRect.Height());
MaskType maskType;
TextureSourceOGL* sourceMask = nullptr;
gfx::Matrix4x4 maskQuadTransform;
if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) {
sourceMask = effectMask->mMaskTexture->AsSourceOGL();
// NS_ASSERTION(textureMask->IsAlpha(),
// "OpenGL mask layers must be backed by alpha surfaces");
maskQuadTransform._11 = 1.0f / maskBounds.Width();
maskQuadTransform._22 = 1.0f / maskBounds.Height();
maskQuadTransform._41 = float(-maskBounds.X()) / maskBounds.Width();
maskQuadTransform._42 = float(-maskBounds.Y()) / maskBounds.Height();
maskType = MaskType::Mask;
} else {
maskType = MaskType::MaskNone;
}
// Determine the color if this is a color shader and fold the opacity into
// the color since color shaders don't have an opacity uniform.
DeviceColor color;
if (aEffectChain.mPrimaryEffect->mType == EffectTypes::SOLID_COLOR) {
EffectSolidColor* effectSolidColor =
static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get());
color = effectSolidColor->mColor;
Float opacity = aOpacity * color.a;
color.r *= opacity;
color.g *= opacity;
color.b *= opacity;
color.a = opacity;
// We can fold opacity into the color, so no need to consider it further.
aOpacity = 1.f;
}
bool createdMixBlendBackdropTexture = false;
GLuint mixBlendBackdrop = 0;
gfx::CompositionOp blendMode = gfx::CompositionOp::OP_OVER;
if (aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE]) {
EffectBlendMode* blendEffect = static_cast<EffectBlendMode*>(
aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get());
blendMode = blendEffect->mBlendMode;
}
// Only apply DEAA to quads that have been transformed such that aliasing
// could be visible
bool bEnableAA = StaticPrefs::layers_deaa_enabled() &&
!aTransform.Is2DIntegerTranslation();
bool colorMatrix = aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX];
ShaderConfigOGL config =
GetShaderConfigFor(aEffectChain.mPrimaryEffect, sourceMask, blendMode,
colorMatrix, bEnableAA);
GetShaderConfigFor(aEffectChain.mPrimaryEffect, bEnableAA);
config.SetOpacity(aOpacity != 1.f);
ApplyPrimitiveConfig(config, aGeometry);
@ -1292,59 +1176,21 @@ void CompositorOGL::DrawGeometry(const Geometry& aGeometry,
}
program->SetProjectionMatrix(mProjMatrix);
program->SetLayerTransform(aTransform);
if (colorMatrix) {
EffectColorMatrix* effectColorMatrix = static_cast<EffectColorMatrix*>(
aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX].get());
program->SetColorMatrix(effectColorMatrix->mColorMatrix);
}
if (BlendOpIsMixBlendMode(blendMode)) {
gfx::Matrix4x4 backdropTransform;
if (gl()->IsExtensionSupported(GLContext::NV_texture_barrier)) {
// The NV_texture_barrier extension lets us read directly from the
// backbuffer. Let's do that.
// We need to tell OpenGL about this, so that it can make sure everything
// on the GPU is happening in the right order.
gl()->fTextureBarrier();
mixBlendBackdrop = mCurrentRenderTarget->GetTextureHandle();
} else {
gfx::IntRect rect = ComputeBackdropCopyRect(aRect, clipRect, aTransform,
&backdropTransform);
mixBlendBackdrop =
CreateTexture(rect, true, mCurrentRenderTarget->GetFBO());
createdMixBlendBackdropTexture = true;
}
program->SetBackdropTransform(backdropTransform);
}
program->SetRenderOffset(offset.x, offset.y);
if (aOpacity != 1.f) program->SetLayerOpacity(aOpacity);
if (config.mFeatures & ENABLE_TEXTURE_RECT) {
TextureSourceOGL* source = nullptr;
if (aEffectChain.mPrimaryEffect->mType == EffectTypes::COMPONENT_ALPHA) {
EffectComponentAlpha* effectComponentAlpha =
static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
source = effectComponentAlpha->mOnWhite->AsSourceOGL();
} else {
TexturedEffect* texturedEffect =
static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
source = texturedEffect->mTexture->AsSourceOGL();
}
TexturedEffect* texturedEffect =
static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
source = texturedEffect->mTexture->AsSourceOGL();
// This is used by IOSurface that use 0,0...w,h coordinate rather then
// 0,0..1,1.
program->SetTexCoordMultiplier(source->GetSize().width,
source->GetSize().height);
}
if (sourceMask && config.mFeatures & ENABLE_MASK_TEXTURE_RECT) {
program->SetMaskCoordMultiplier(sourceMask->GetSize().width,
sourceMask->GetSize().height);
}
// XXX kip - These calculations could be performed once per layer rather than
// for every tile. This might belong in Compositor.cpp once DEAA
// is implemented for DirectX.
@ -1418,29 +1264,13 @@ void CompositorOGL::DrawGeometry(const Geometry& aGeometry,
bool didSetBlendMode = false;
switch (aEffectChain.mPrimaryEffect->mType) {
case EffectTypes::SOLID_COLOR: {
program->SetRenderColor(color);
if (maskType != MaskType::MaskNone) {
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE0,
maskQuadTransform);
}
if (mixBlendBackdrop) {
BindBackdrop(program, mixBlendBackdrop, LOCAL_GL_TEXTURE1);
}
didSetBlendMode = SetBlendMode(gl(), blendMode);
BindAndDrawGeometry(program, aGeometry);
} break;
case EffectTypes::RGB: {
TexturedEffect* texturedEffect =
static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
TextureSource* source = texturedEffect->mTexture;
didSetBlendMode =
SetBlendMode(gl(), blendMode, texturedEffect->mPremultiplied);
didSetBlendMode = SetBlendMode(gl(), gfx::CompositionOp::OP_OVER,
texturedEffect->mPremultiplied);
gfx::SamplingFilter samplingFilter = texturedEffect->mSamplingFilter;
@ -1451,14 +1281,6 @@ void CompositorOGL::DrawGeometry(const Geometry& aGeometry,
Matrix4x4 textureTransform = source->AsSourceOGL()->GetTextureTransform();
program->SetTextureTransform(textureTransform);
if (maskType != MaskType::MaskNone) {
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE1,
maskQuadTransform);
}
if (mixBlendBackdrop) {
BindBackdrop(program, mixBlendBackdrop, LOCAL_GL_TEXTURE2);
}
BindAndDrawGeometryWithTextureRect(
program, aGeometry, texturedEffect->mTextureCoords, source);
source->AsSourceOGL()->MaybeFenceTexture();
@ -1492,14 +1314,6 @@ void CompositorOGL::DrawGeometry(const Geometry& aGeometry,
program->SetTextureTransform(Matrix4x4());
program->SetYUVColorSpace(effectYCbCr->mYUVColorSpace);
if (maskType != MaskType::MaskNone) {
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE3,
maskQuadTransform);
}
if (mixBlendBackdrop) {
BindBackdrop(program, mixBlendBackdrop, LOCAL_GL_TEXTURE4);
}
didSetBlendMode = SetBlendMode(gl(), blendMode);
BindAndDrawGeometryWithTextureRect(program, aGeometry,
effectYCbCr->mTextureCoords,
sourceYCbCr->GetSubSource(Y));
@ -1535,109 +1349,12 @@ void CompositorOGL::DrawGeometry(const Geometry& aGeometry,
program->SetTextureTransform(Matrix4x4());
program->SetYUVColorSpace(effectNV12->mYUVColorSpace);
if (maskType != MaskType::MaskNone) {
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE2,
maskQuadTransform);
}
if (mixBlendBackdrop) {
BindBackdrop(program, mixBlendBackdrop, LOCAL_GL_TEXTURE3);
}
didSetBlendMode = SetBlendMode(gl(), blendMode);
BindAndDrawGeometryWithTextureRect(program, aGeometry,
effectNV12->mTextureCoords,
sourceNV12->GetSubSource(Y));
sourceY->MaybeFenceTexture();
sourceCbCr->MaybeFenceTexture();
} break;
case EffectTypes::RENDER_TARGET: {
EffectRenderTarget* effectRenderTarget =
static_cast<EffectRenderTarget*>(aEffectChain.mPrimaryEffect.get());
RefPtr<CompositingRenderTargetOGL> surface =
static_cast<CompositingRenderTargetOGL*>(
effectRenderTarget->mRenderTarget.get());
surface->BindTexture(LOCAL_GL_TEXTURE0, mFBOTextureTarget);
// Drawing is always flipped, but when copying between surfaces we want to
// avoid this, so apply a flip here to cancel the other one out.
Matrix transform;
transform.PreTranslate(0.0, 1.0);
transform.PreScale(1.0f, -1.0f);
program->SetTextureTransform(Matrix4x4::From2D(transform));
program->SetTextureUnit(0);
if (maskType != MaskType::MaskNone) {
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE1,
maskQuadTransform);
}
if (mixBlendBackdrop) {
BindBackdrop(program, mixBlendBackdrop, LOCAL_GL_TEXTURE2);
}
if (config.mFeatures & ENABLE_TEXTURE_RECT) {
// 2DRect case, get the multiplier right for a sampler2DRect
program->SetTexCoordMultiplier(surface->GetSize().width,
surface->GetSize().height);
}
// Drawing is always flipped, but when copying between surfaces we want to
// avoid this. Pass true for the flip parameter to introduce a second flip
// that cancels the other one out.
didSetBlendMode = SetBlendMode(gl(), blendMode);
BindAndDrawGeometry(program, aGeometry);
} break;
case EffectTypes::COMPONENT_ALPHA: {
MOZ_ASSERT(LayerManager::LayersComponentAlphaEnabled());
MOZ_ASSERT(blendMode == gfx::CompositionOp::OP_OVER,
"Can't support blend modes with component alpha!");
EffectComponentAlpha* effectComponentAlpha =
static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
TextureSourceOGL* sourceOnWhite =
effectComponentAlpha->mOnWhite->AsSourceOGL();
TextureSourceOGL* sourceOnBlack =
effectComponentAlpha->mOnBlack->AsSourceOGL();
if (!sourceOnBlack->IsValid() || !sourceOnWhite->IsValid()) {
NS_WARNING("Invalid layer texture for component alpha");
return;
}
sourceOnBlack->BindTexture(LOCAL_GL_TEXTURE0,
effectComponentAlpha->mSamplingFilter);
sourceOnWhite->BindTexture(LOCAL_GL_TEXTURE1,
effectComponentAlpha->mSamplingFilter);
program->SetBlackTextureUnit(0);
program->SetWhiteTextureUnit(1);
program->SetTextureTransform(Matrix4x4());
if (maskType != MaskType::MaskNone) {
BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE2,
maskQuadTransform);
}
// Pass 1.
gl()->fBlendFuncSeparate(LOCAL_GL_ZERO, LOCAL_GL_ONE_MINUS_SRC_COLOR,
LOCAL_GL_ONE, LOCAL_GL_ONE);
program->SetTexturePass2(false);
BindAndDrawGeometryWithTextureRect(program, aGeometry,
effectComponentAlpha->mTextureCoords,
effectComponentAlpha->mOnBlack);
// Pass 2.
gl()->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE, LOCAL_GL_ONE,
LOCAL_GL_ONE);
program->SetTexturePass2(true);
BindAndDrawGeometryWithTextureRect(program, aGeometry,
effectComponentAlpha->mTextureCoords,
effectComponentAlpha->mOnBlack);
mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
LOCAL_GL_ONE,
LOCAL_GL_ONE_MINUS_SRC_ALPHA);
sourceOnBlack->MaybeFenceTexture();
sourceOnWhite->MaybeFenceTexture();
} break;
default:
MOZ_ASSERT(false, "Unhandled effect type");
break;
@ -1647,9 +1364,6 @@ void CompositorOGL::DrawGeometry(const Geometry& aGeometry,
gl()->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA);
}
if (createdMixBlendBackdropTexture) {
gl()->fDeleteTextures(1, &mixBlendBackdrop);
}
// in case rendering has used some other GL context
MakeCurrent();

View File

@ -341,10 +341,8 @@ class CompositorOGL final : public Compositor {
const gfx::IntRect& aRenderBounds,
const nsIntRegion& aOpaqueRegion);
ShaderConfigOGL GetShaderConfigFor(
Effect* aEffect, TextureSourceOGL* aSourceMask = nullptr,
gfx::CompositionOp aOp = gfx::CompositionOp::OP_OVER,
bool aColorMatrix = false, bool aDEAAEnabled = false) const;
ShaderConfigOGL GetShaderConfigFor(Effect* aEffect,
bool aDEAAEnabled = false) const;
ShaderProgramOGL* GetShaderProgramFor(const ShaderConfigOGL& aConfig);
@ -413,13 +411,6 @@ class CompositorOGL final : public Compositor {
gfx::Rect GetTextureCoordinates(gfx::Rect textureRect,
TextureSource* aTexture);
/**
* Bind the texture behind the current render target as the backdrop for a
* mix-blend shader.
*/
void BindBackdrop(ShaderProgramOGL* aProgram, GLuint aBackdrop,
GLenum aTexUnit);
/**
* Copies the content of the current render target to the set transaction
* target.

View File

@ -62,21 +62,9 @@ class KnownUniform {
YTexture,
CbTexture,
CrTexture,
BlackTexture,
WhiteTexture,
MaskTexture,
BackdropTexture,
RenderColor,
TexCoordMultiplier,
CbCrTexCoordMultiplier,
MaskCoordMultiplier,
TexturePass2,
ColorMatrix,
ColorMatrixVector,
BlurRadius,
BlurOffset,
BlurAlpha,
BlurGaussianKernel,
SSEdges,
ViewportSize,
VisibleCenter,

View File

@ -45,21 +45,9 @@ static void AddUniforms(ProgramProfileOGL& aProfile) {
"uYTexture",
"uCbTexture",
"uCrTexture",
"uBlackTexture",
"uWhiteTexture",
"uMaskTexture",
"uBackdropTexture",
"uRenderColor",
"uTexCoordMultiplier",
"uCbCrTexCoordMultiplier",
"uMaskCoordMultiplier",
"uTexturePass2",
"uColorMatrix",
"uColorMatrixVector",
"uBlurRadius",
"uBlurOffset",
"uBlurAlpha",
"uBlurGaussianKernel",
"uSSEdges",
"uViewportSize",
"uVisibleCenter",
@ -1008,26 +996,6 @@ GLuint ShaderProgramOGL::GetProgram() {
return mProgram;
}
void ShaderProgramOGL::SetBlurRadius(float aRX, float aRY) {
float f[] = {aRX, aRY};
SetUniform(KnownUniform::BlurRadius, 2, f);
float gaussianKernel[GAUSSIAN_KERNEL_HALF_WIDTH];
float sum = 0.0f;
for (int i = 0; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
float x = i * GAUSSIAN_KERNEL_STEP;
float sigma = 1.0f;
gaussianKernel[i] =
exp(-x * x / (2 * sigma * sigma)) / sqrt(2 * M_PI * sigma * sigma);
sum += gaussianKernel[i] * (i == 0 ? 1 : 2);
}
for (int i = 0; i < GAUSSIAN_KERNEL_HALF_WIDTH; i++) {
gaussianKernel[i] /= sum;
}
SetArrayUniform(KnownUniform::BlurGaussianKernel, GAUSSIAN_KERNEL_HALF_WIDTH,
gaussianKernel);
}
void ShaderProgramOGL::SetYUVColorSpace(gfx::YUVColorSpace aYUVColorSpace) {
const float* yuvToRgb =
gfxUtils::YuvToRgbMatrix3x3ColumnMajor(aYUVColorSpace);

View File

@ -107,14 +107,6 @@ class ShaderProgramOGL {
SetMatrixUniform(KnownUniform::LayerTransformInverse, aMatrix);
}
void SetMaskLayerTransform(const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(KnownUniform::MaskTransform, aMatrix);
}
void SetBackdropTransform(const gfx::Matrix4x4& aMatrix) {
SetMatrixUniform(KnownUniform::BackdropTransform, aMatrix);
}
void SetDEAAEdges(const gfx::Point3D* aEdges) {
SetArrayUniform(KnownUniform::SSEdges, 4, aEdges);
}
@ -194,31 +186,6 @@ class ShaderProgramOGL {
SetUniform(KnownUniform::CbTexture, aCbCrUnit);
}
void SetBlackTextureUnit(GLint aUnit) {
SetUniform(KnownUniform::BlackTexture, aUnit);
}
void SetWhiteTextureUnit(GLint aUnit) {
SetUniform(KnownUniform::WhiteTexture, aUnit);
}
void SetMaskTextureUnit(GLint aUnit) {
SetUniform(KnownUniform::MaskTexture, aUnit);
}
void SetBackdropTextureUnit(GLint aUnit) {
SetUniform(KnownUniform::BackdropTexture, aUnit);
}
void SetRenderColor(const gfx::DeviceColor& aColor) {
SetUniform(KnownUniform::RenderColor, aColor);
}
void SetColorMatrix(const gfx::Matrix5x4& aColorMatrix) {
SetMatrixUniform(KnownUniform::ColorMatrix, &aColorMatrix._11);
SetUniform(KnownUniform::ColorMatrixVector, 4, &aColorMatrix._51);
}
void SetTexCoordMultiplier(float aWidth, float aHeight) {
float f[] = {aWidth, aHeight};
SetUniform(KnownUniform::TexCoordMultiplier, 2, f);
@ -229,31 +196,8 @@ class ShaderProgramOGL {
SetUniform(KnownUniform::CbCrTexCoordMultiplier, 2, f);
}
void SetMaskCoordMultiplier(float aWidth, float aHeight) {
float f[] = {aWidth, aHeight};
SetUniform(KnownUniform::MaskCoordMultiplier, 2, f);
}
void SetYUVColorSpace(gfx::YUVColorSpace aYUVColorSpace);
// Set whether we want the component alpha shader to return the color
// vector (pass 1, false) or the alpha vector (pass2, true). With support
// for multiple render targets we wouldn't need two passes here.
void SetTexturePass2(bool aFlag) {
SetUniform(KnownUniform::TexturePass2, aFlag ? 1 : 0);
}
void SetBlurRadius(float aRX, float aRY);
void SetBlurAlpha(float aAlpha) {
SetUniform(KnownUniform::BlurAlpha, aAlpha);
}
void SetBlurOffset(float aOffsetX, float aOffsetY) {
float f[] = {aOffsetX, aOffsetY};
SetUniform(KnownUniform::BlurOffset, 2, f);
}
size_t GetTextureCount() const { return mProfile.mTextureCount; }
protected: