mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1730055 - Remove unused Effect types. r=gfx-reviewers,lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D125135
This commit is contained in:
parent
2c01dae384
commit
115faf8e91
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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 << "]";
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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; }
|
||||
|
@ -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_
|
||||
|
@ -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));
|
||||
}
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user